From patchwork Tue Jan 18 07:26:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 12716020 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 376E2C433EF for ; Tue, 18 Jan 2022 07:26:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234285AbiARH0f (ORCPT ); Tue, 18 Jan 2022 02:26:35 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43410 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234037AbiARH0d (ORCPT ); Tue, 18 Jan 2022 02:26:33 -0500 Received: from mail-pg1-x52d.google.com (mail-pg1-x52d.google.com [IPv6:2607:f8b0:4864:20::52d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C3C7AC061574; Mon, 17 Jan 2022 23:26:33 -0800 (PST) Received: by mail-pg1-x52d.google.com with SMTP id i8so13121937pgt.13; Mon, 17 Jan 2022 23:26:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=V0/xeb/ltQYaEaF113sypfFpexckyEO/l19a8/MnbB0=; b=NfgJNWaqhS8piWDRfV9g5I3M7ApDQ2XvtoYhCRfaS+d7AR50shzyQIotLT3zdSHNBx N3Jbj6DtwpFLebXYIYvMY29+BSnqzAv5K1WFkYS8AE/J5Z4zkDCkwRVEaWTFZ4nnPW9Y Yt3t3Az3RIYB2MPvXE99lJwJ0dCIYNsUca3h5Eb+bRD+W+2AxRvYUySYSUBhR/R3PpDr dvMJ89SLo9zZxh6DU8NUyQ35MbgPBXVtIe16M+5r5YXcIjzMfMElKYRU+W3Ba0QRvBpD NschROAPDFsqWZ4tqGtiBsbFMwHoaQOq5rmookkp14cT2eb153N9M+TpBmFincp1zW47 LbIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=V0/xeb/ltQYaEaF113sypfFpexckyEO/l19a8/MnbB0=; b=68q8T2DsWXGtAwZE7rayT+kwPd8SLwY3vrWtJPsTbUObpS5AhtAcZUR07WA9KW39iC YrsEdttOAVuKyjPiPtKr7blET7xnN/gN+DoZLqNIeS+dZvJxYgRZr/DHBykV8fehgiDr T4220SHi915Fu94AjkxHJzNIKTeSmT+MQ/mg3eBHbzlPdJ0fsIMGkE7fDPHPaOBh/n3E Pxu8h72H67YnJ1xnZCNaKQA4Eox4Kqk6jJfnD9a8kstela0DdF27c2yhOyNWOUWhY4qc Pbhi5kLG+5e6WW6iKOxdzJWK/yuzANo+YJ+IBjsejI7TcLsd3lX+tmFEoPpDT+WeUUst 8goQ== X-Gm-Message-State: AOAM5313bh1omYdn4s2PsUEuNIIaoJmSsh0wT6GgAiO5xBoFlUI+4NQ4 gB3QGJYR9R4ARP13k/hqW+M= X-Google-Smtp-Source: ABdhPJySuGgE/LOdJB7H2LXfyH0/wfP+Sp291d9HnX7lvDs2GqjEHCGkHHY0/IEj6qHnoGyEjXe4UQ== X-Received: by 2002:a63:6c03:: with SMTP id h3mr21624014pgc.604.1642490793264; Mon, 17 Jan 2022 23:26:33 -0800 (PST) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:202:201:bf2e:59:5029:f4c5]) by smtp.gmail.com with ESMTPSA id y18sm11079816pfl.156.2022.01.17.23.26.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 23:26:32 -0800 (PST) From: Dmitry Torokhov To: Jiri Kosina , Benjamin Tissoires Cc: Angela Czubak , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 01/12] HID: i2c-hid: fix handling numbered reports with IDs of 15 and above Date: Mon, 17 Jan 2022 23:26:17 -0800 Message-Id: <20220118072628.1617172-2-dmitry.torokhov@gmail.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> References: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org From: Angela Czubak Special handling of numbered reports with IDs of 15 and above is only needed when executing what HID-I2C spec is calling "Class Specific Requests", and not when simply sending output reports. Additionally, our mangling of report ID in i2c_hid_set_or_send_report() resulted in incorrect report ID being written into SET_REPORT command payload. To solve it let's move all the report ID manipulation into __i2c_hid_command() where we form the command data structure. Signed-off-by: Angela Czubak Signed-off-by: Dmitry Torokhov --- drivers/hid/i2c-hid/i2c-hid-core.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index 517141138b00..bd7b0eeca3ea 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -97,6 +97,7 @@ union command { __le16 reg; __u8 reportTypeID; __u8 opcode; + __u8 reportID; } __packed c; }; @@ -232,7 +233,13 @@ static int __i2c_hid_command(struct i2c_client *client, if (length > 2) { cmd->c.opcode = command->opcode; - cmd->c.reportTypeID = reportID | reportType << 4; + if (reportID < 0x0F) { + cmd->c.reportTypeID = reportType << 4 | reportID; + } else { + cmd->c.reportTypeID = reportType << 4 | 0x0F; + cmd->c.reportID = reportID; + length++; + } } memcpy(cmd->data + length, args, args_len); @@ -293,18 +300,13 @@ static int i2c_hid_get_report(struct i2c_client *client, u8 reportType, u8 reportID, unsigned char *buf_recv, int data_len) { struct i2c_hid *ihid = i2c_get_clientdata(client); - u8 args[3]; + u8 args[2]; int ret; int args_len = 0; u16 readRegister = le16_to_cpu(ihid->hdesc.wDataRegister); i2c_hid_dbg(ihid, "%s\n", __func__); - if (reportID >= 0x0F) { - args[args_len++] = reportID; - reportID = 0x0F; - } - args[args_len++] = readRegister & 0xFF; args[args_len++] = readRegister >> 8; @@ -350,18 +352,12 @@ static int i2c_hid_set_or_send_report(struct i2c_client *client, u8 reportType, size = 2 /* size */ + (reportID ? 1 : 0) /* reportID */ + data_len /* buf */; - args_len = (reportID >= 0x0F ? 1 : 0) /* optional third byte */ + - 2 /* dataRegister */ + + args_len = 2 /* dataRegister */ + size /* args */; if (!use_data && maxOutputLength == 0) return -ENOSYS; - if (reportID >= 0x0F) { - args[index++] = reportID; - reportID = 0x0F; - } - /* * use the data register for feature reports or if the device does not * support the output register From patchwork Tue Jan 18 07:26:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 12716021 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7AE2DC433EF for ; Tue, 18 Jan 2022 07:26:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244610AbiARH0h (ORCPT ); Tue, 18 Jan 2022 02:26:37 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43420 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240195AbiARH0g (ORCPT ); Tue, 18 Jan 2022 02:26:36 -0500 Received: from mail-pg1-x530.google.com (mail-pg1-x530.google.com [IPv6:2607:f8b0:4864:20::530]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 89C6CC061574; Mon, 17 Jan 2022 23:26:35 -0800 (PST) Received: by mail-pg1-x530.google.com with SMTP id i8so13122039pgt.13; Mon, 17 Jan 2022 23:26:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=QEq+uVvJXtHzn7krujbcpKdPooiYBjQ4fGtzjepCNoY=; b=h3hElGWedXHRNZmBkfSL2+dM3RO48nMzzFDgCJYEg7NTuJVG4OJXQtcG1RtaVNTbj1 ycunQUqmVXHGYHJSrALdpc7tgacS4eYMgh9wq10OOMAdBFp3TdHwOlXaYeZAQMjx0mLH GcZS7lBITYjQV5WI45cKrK4MASniwrpVvkwVJZxPpDu3IwDSTrDSwKqyiR3nk22BDgY9 /PNAC1BGUS4seqaGBflgYdJEIdek49IwFtWs0/88qMNC6QMgDhLVaNxTQn9TrSfpolfZ OjJgprIBs4mrRKyYI4tWFhx0NdxtaI+advqx6um8FPa4FqcNEvCtNBYqYwPcBY/Bf3y+ DPTQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=QEq+uVvJXtHzn7krujbcpKdPooiYBjQ4fGtzjepCNoY=; b=xV7a/TqSak2J5lGzb+hO1+jTAICf8W70W8G3c4hzalkJLby1/2TV0laNki0kkDClDc yKWb/W87eC09ilh8onLDGrkzu50f2DkfxTVVXYdYCWENfXseiDbCo7HLViRleZhaxXZh 7rdtwcs6C+LjMzPt5y948fqGyXygKaSH+Xnwxt4BJ9S0hRhbSaFMeq4XfxvjKaMXZJtu PD850q9xA0PIT9siaAnuswnq3f2dj1/BN9IYB9NuKiwHCfo0meBaNqw0PnuvcdVkITzj xsiibR+82FyJHadZ6TKbiF143u/TSdQd/kvaTM2Ich1z/5HrLPSOOfQCGXg9sgrxFsZM 6JTA== X-Gm-Message-State: AOAM532d22M/E+k9xv0y0gv9sPJ7yXiIYfI4uh8Hf4RTPNieCE2FThbm eJ1I+RqFh3FtNxZtbn2Iims= X-Google-Smtp-Source: ABdhPJy/ZJB70obNRENGozEl97E+pIF3JSy47LHY2WfQUJ0IQycmV7lHEXlKdCrekcjj/VqT+17zaA== X-Received: by 2002:a63:e64a:: with SMTP id p10mr22245025pgj.331.1642490794970; Mon, 17 Jan 2022 23:26:34 -0800 (PST) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:202:201:bf2e:59:5029:f4c5]) by smtp.gmail.com with ESMTPSA id y18sm11079816pfl.156.2022.01.17.23.26.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 23:26:34 -0800 (PST) From: Dmitry Torokhov To: Jiri Kosina , Benjamin Tissoires Cc: Angela Czubak , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 02/12] HID: i2c-hid: fix GET/SET_REPORT for unnumbered reports Date: Mon, 17 Jan 2022 23:26:18 -0800 Message-Id: <20220118072628.1617172-3-dmitry.torokhov@gmail.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> References: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Internally kernel prepends all report buffers, for both numbered and unnumbered reports, with report ID, therefore to properly handle unnumbered reports we should For the same reason we should skip the first byte of the buffer when calling i2c_hid_set_or_send_report() which then will take care of properly formatting the transfer buffer based on its separate report ID argument along with report payload. Fixes: 9b5a9ae88573 ("HID: i2c-hid: implement ll_driver transport-layer callbacks") Signed-off-by: Dmitry Torokhov --- drivers/hid/i2c-hid/i2c-hid-core.c | 32 ++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index bd7b0eeca3ea..b383003ff676 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -611,6 +611,17 @@ static int i2c_hid_get_raw_report(struct hid_device *hid, if (report_type == HID_OUTPUT_REPORT) return -EINVAL; + /* + * In case of unnumbered reports the response from the device will + * not have the report ID that the upper layers expect, so we need + * to stash it the buffer ourselves and adjust the data size. + */ + if (!report_number) { + buf[0] = 0; + buf++; + count--; + } + /* +2 bytes to include the size of the reply in the query buffer */ ask_count = min(count + 2, (size_t)ihid->bufsize); @@ -632,6 +643,9 @@ static int i2c_hid_get_raw_report(struct hid_device *hid, count = min(count, ret_count - 2); memcpy(buf, ihid->rawbuf + 2, count); + if (!report_number) + count++; + return count; } @@ -648,17 +662,19 @@ static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf, mutex_lock(&ihid->reset_lock); - if (report_id) { - buf++; - count--; - } - + /* + * Note that both numbered and unnumbered reports passed here + * are supposed to have report ID stored in the 1st byte of the + * buffer, so we strip it off unconditionally before passing payload + * to i2c_hid_set_or_send_report which takes care of encoding + * everything properly. + */ ret = i2c_hid_set_or_send_report(client, report_type == HID_FEATURE_REPORT ? 0x03 : 0x02, - report_id, buf, count, use_data); + report_id, buf + 1, count - 1, use_data); - if (report_id && ret >= 0) - ret++; /* add report_id to the number of transfered bytes */ + if (ret >= 0) + ret++; /* add report_id to the number of transferred bytes */ mutex_unlock(&ihid->reset_lock); From patchwork Tue Jan 18 07:26:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 12716022 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 62057C433EF for ; Tue, 18 Jan 2022 07:26:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244758AbiARH0j (ORCPT ); Tue, 18 Jan 2022 02:26:39 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43424 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244677AbiARH0h (ORCPT ); Tue, 18 Jan 2022 02:26:37 -0500 Received: from mail-pg1-x52c.google.com (mail-pg1-x52c.google.com [IPv6:2607:f8b0:4864:20::52c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F0C66C061574; Mon, 17 Jan 2022 23:26:36 -0800 (PST) Received: by mail-pg1-x52c.google.com with SMTP id x83so13127365pgx.4; Mon, 17 Jan 2022 23:26:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ES83obJErk0lZ4kelhdPyHXgtGt2UP7T+Eb9i5keaTM=; b=Dof1I0AksaKXl49yzZAExVWINZ4MxevKOcEeLwdD2dE/gECkf8YV+E24U/LyroD5kK pXwQz+F2yWZITKUZn0xafEOhs0MbvYnLQKOQ0XbmqyL3q9Kcvkwi63Ni1uzC0EXlEFnL qv8YECHIcW5R4rwZUV6qqsN07vvrEJUMcqzCINd+6i42zrh7Rqirr+1i3z1nOqZZ9QaW myNRdfGwzSLk/bRsYXouXgNZkxdSltiRdhpHBvCo6PgeV/WvGre8PYHy+eI2qDwSE0ao RSh24CPa3wPnsuEETTCnqBrXdcRXcAbyFx1s/ZHoVCAzOGX7dUpc99dVdl3ZfDlaJ93v fV5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ES83obJErk0lZ4kelhdPyHXgtGt2UP7T+Eb9i5keaTM=; b=0lmI4SwNpBWQBmGMyQwi2IT2HP/bj0aSYfiGZms2ePxms6Ehc4e/OjuR24DCXgDhYr Jd6Xgn4mnMzscGzixcLVxQaE22ffp8Yr9GIyGFdIGTrWqvfPQk7dhLbNqEpUG9WEWYvv +49YgLiaAfqIHinADaWJSctey48lPMlO8f7xztsf6j5OGqWlDhGWY2JIk7w83V2UKD2C ZOxumTTTra22NT50vzjtGhAZhmss2OiKyeUdf5m25KyVgM/nzdMiFg+5AVSEQFe6s8d7 WKtniT6kRs/MBIdPb7TaSb3uXW+85U1pwrRg0dTjR4scgMZTSIn+PpB6GXR6xhq6CbCD QfwQ== X-Gm-Message-State: AOAM533E16Ppf9nJIpniwHJljJZ5kd5cglg5YZmpouajCF26i5wTDkdb YiW+sSMF6DEU16dfc+y3GwU= X-Google-Smtp-Source: ABdhPJymuOUypPqjMMF/NOLafAl1UOlyqABEc3f57QAFEh5XJVlNnxaTYWSoD+d3uKT51lpzk2IzLw== X-Received: by 2002:a65:6859:: with SMTP id q25mr18771789pgt.452.1642490796350; Mon, 17 Jan 2022 23:26:36 -0800 (PST) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:202:201:bf2e:59:5029:f4c5]) by smtp.gmail.com with ESMTPSA id y18sm11079816pfl.156.2022.01.17.23.26.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 23:26:35 -0800 (PST) From: Dmitry Torokhov To: Jiri Kosina , Benjamin Tissoires Cc: Angela Czubak , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 03/12] HID: i2c-hid: use "struct i2c_hid" as argument in most calls Date: Mon, 17 Jan 2022 23:26:19 -0800 Message-Id: <20220118072628.1617172-4-dmitry.torokhov@gmail.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> References: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org The main object in the driver is struct i2c_hid so it makes more sense to pass it around instead of passing i2c_client and then fetching i2c_hid associated with it. Signed-off-by: Dmitry Torokhov --- drivers/hid/i2c-hid/i2c-hid-core.c | 75 ++++++++++++++---------------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index b383003ff676..bae3e7a9b2e4 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -208,12 +208,12 @@ static u32 i2c_hid_lookup_quirk(const u16 idVendor, const u16 idProduct) return quirks; } -static int __i2c_hid_command(struct i2c_client *client, +static int __i2c_hid_command(struct i2c_hid *ihid, const struct i2c_hid_cmd *command, u8 reportID, u8 reportType, u8 *args, int args_len, unsigned char *buf_recv, int data_len) { - struct i2c_hid *ihid = i2c_get_clientdata(client); + struct i2c_client *client = ihid->client; union command *cmd = (union command *)ihid->cmdbuf; int ret; struct i2c_msg msg[2]; @@ -288,18 +288,17 @@ static int __i2c_hid_command(struct i2c_client *client, return ret; } -static int i2c_hid_command(struct i2c_client *client, +static int i2c_hid_command(struct i2c_hid *ihid, const struct i2c_hid_cmd *command, unsigned char *buf_recv, int data_len) { - return __i2c_hid_command(client, command, 0, 0, NULL, 0, + return __i2c_hid_command(ihid, command, 0, 0, NULL, 0, buf_recv, data_len); } -static int i2c_hid_get_report(struct i2c_client *client, u8 reportType, +static int i2c_hid_get_report(struct i2c_hid *ihid, u8 reportType, u8 reportID, unsigned char *buf_recv, int data_len) { - struct i2c_hid *ihid = i2c_get_clientdata(client); u8 args[2]; int ret; int args_len = 0; @@ -310,10 +309,10 @@ static int i2c_hid_get_report(struct i2c_client *client, u8 reportType, args[args_len++] = readRegister & 0xFF; args[args_len++] = readRegister >> 8; - ret = __i2c_hid_command(client, &hid_get_report_cmd, reportID, + ret = __i2c_hid_command(ihid, &hid_get_report_cmd, reportID, reportType, args, args_len, buf_recv, data_len); if (ret) { - dev_err(&client->dev, + dev_err(&ihid->client->dev, "failed to retrieve report from device.\n"); return ret; } @@ -323,17 +322,16 @@ static int i2c_hid_get_report(struct i2c_client *client, u8 reportType, /** * i2c_hid_set_or_send_report: forward an incoming report to the device - * @client: the i2c_client of the device + * @ihid: the i2c hid device * @reportType: 0x03 for HID_FEATURE_REPORT ; 0x02 for HID_OUTPUT_REPORT * @reportID: the report ID * @buf: the actual data to transfer, without the report ID * @data_len: size of buf * @use_data: true: use SET_REPORT HID command, false: send plain OUTPUT report */ -static int i2c_hid_set_or_send_report(struct i2c_client *client, u8 reportType, +static int i2c_hid_set_or_send_report(struct i2c_hid *ihid, u8 reportType, u8 reportID, unsigned char *buf, size_t data_len, bool use_data) { - struct i2c_hid *ihid = i2c_get_clientdata(client); u8 *args = ihid->argsbuf; const struct i2c_hid_cmd *hidcmd; int ret; @@ -380,19 +378,19 @@ static int i2c_hid_set_or_send_report(struct i2c_client *client, u8 reportType, memcpy(&args[index], buf, data_len); - ret = __i2c_hid_command(client, hidcmd, reportID, + ret = __i2c_hid_command(ihid, hidcmd, reportID, reportType, args, args_len, NULL, 0); if (ret) { - dev_err(&client->dev, "failed to set a report to device.\n"); + dev_err(&ihid->client->dev, + "failed to set a report to device.\n"); return ret; } return data_len; } -static int i2c_hid_set_power(struct i2c_client *client, int power_state) +static int i2c_hid_set_power(struct i2c_hid *ihid, int power_state) { - struct i2c_hid *ihid = i2c_get_clientdata(client); int ret; i2c_hid_dbg(ihid, "%s\n", __func__); @@ -404,18 +402,18 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state) */ if (power_state == I2C_HID_PWR_ON && ihid->quirks & I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV) { - ret = i2c_hid_command(client, &hid_set_power_cmd, NULL, 0); + ret = i2c_hid_command(ihid, &hid_set_power_cmd, NULL, 0); /* Device was already activated */ if (!ret) goto set_pwr_exit; } - ret = __i2c_hid_command(client, &hid_set_power_cmd, power_state, + ret = __i2c_hid_command(ihid, &hid_set_power_cmd, power_state, 0, NULL, 0, NULL, 0); - if (ret) - dev_err(&client->dev, "failed to change power setting.\n"); + dev_err(&ihid->client->dev, + "failed to change power setting.\n"); set_pwr_exit: @@ -434,9 +432,8 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state) return ret; } -static int i2c_hid_hwreset(struct i2c_client *client) +static int i2c_hid_hwreset(struct i2c_hid *ihid) { - struct i2c_hid *ihid = i2c_get_clientdata(client); int ret; i2c_hid_dbg(ihid, "%s\n", __func__); @@ -448,22 +445,22 @@ static int i2c_hid_hwreset(struct i2c_client *client) */ mutex_lock(&ihid->reset_lock); - ret = i2c_hid_set_power(client, I2C_HID_PWR_ON); + ret = i2c_hid_set_power(ihid, I2C_HID_PWR_ON); if (ret) goto out_unlock; i2c_hid_dbg(ihid, "resetting...\n"); - ret = i2c_hid_command(client, &hid_reset_cmd, NULL, 0); + ret = i2c_hid_command(ihid, &hid_reset_cmd, NULL, 0); if (ret) { - dev_err(&client->dev, "failed to reset device.\n"); - i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); + dev_err(&ihid->client->dev, "failed to reset device.\n"); + i2c_hid_set_power(ihid, I2C_HID_PWR_SLEEP); goto out_unlock; } /* At least some SIS devices need this after reset */ if (!(ihid->quirks & I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET)) - ret = i2c_hid_set_power(client, I2C_HID_PWR_ON); + ret = i2c_hid_set_power(ihid, I2C_HID_PWR_ON); out_unlock: mutex_unlock(&ihid->reset_lock); @@ -625,7 +622,7 @@ static int i2c_hid_get_raw_report(struct hid_device *hid, /* +2 bytes to include the size of the reply in the query buffer */ ask_count = min(count + 2, (size_t)ihid->bufsize); - ret = i2c_hid_get_report(client, + ret = i2c_hid_get_report(ihid, report_type == HID_FEATURE_REPORT ? 0x03 : 0x01, report_number, ihid->rawbuf, ask_count); @@ -669,7 +666,7 @@ static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf, * to i2c_hid_set_or_send_report which takes care of encoding * everything properly. */ - ret = i2c_hid_set_or_send_report(client, + ret = i2c_hid_set_or_send_report(ihid, report_type == HID_FEATURE_REPORT ? 0x03 : 0x02, report_id, buf + 1, count - 1, use_data); @@ -724,7 +721,7 @@ static int i2c_hid_parse(struct hid_device *hid) } do { - ret = i2c_hid_hwreset(client); + ret = i2c_hid_hwreset(ihid); if (ret) msleep(1000); } while (tries-- > 0 && ret); @@ -748,7 +745,7 @@ static int i2c_hid_parse(struct hid_device *hid) i2c_hid_dbg(ihid, "asking HID report descriptor\n"); - ret = i2c_hid_command(client, &hid_report_descr_cmd, + ret = i2c_hid_command(ihid, &hid_report_descr_cmd, rdesc, rsize); if (ret) { hid_err(hid, "reading report descriptor failed\n"); @@ -868,11 +865,11 @@ static int i2c_hid_fetch_hid_descriptor(struct i2c_hid *ihid) *i2c_hid_get_dmi_i2c_hid_desc_override(client->name); } else { i2c_hid_dbg(ihid, "Fetching the HID descriptor\n"); - ret = i2c_hid_command(client, &hid_descr_cmd, + ret = i2c_hid_command(ihid, &hid_descr_cmd, ihid->hdesc_buffer, sizeof(struct i2c_hid_desc)); if (ret) { - dev_err(&client->dev, "hid_descr_cmd failed\n"); + dev_err(&ihid->client->dev, "hid_descr_cmd failed\n"); return -ENODEV; } } @@ -882,7 +879,7 @@ static int i2c_hid_fetch_hid_descriptor(struct i2c_hid *ihid) * bytes 2-3 -> bcdVersion (has to be 1.00) */ /* check bcdVersion == 1.0 */ if (le16_to_cpu(hdesc->bcdVersion) != 0x0100) { - dev_err(&client->dev, + dev_err(&ihid->client->dev, "unexpected HID descriptor bcdVersion (0x%04hx)\n", le16_to_cpu(hdesc->bcdVersion)); return -ENODEV; @@ -891,8 +888,8 @@ static int i2c_hid_fetch_hid_descriptor(struct i2c_hid *ihid) /* Descriptor length should be 30 bytes as per the specification */ dsize = le16_to_cpu(hdesc->wHIDDescLength); if (dsize != sizeof(struct i2c_hid_desc)) { - dev_err(&client->dev, "weird size of HID descriptor (%u)\n", - dsize); + dev_err(&ihid->client->dev, + "weird size of HID descriptor (%u)\n", dsize); return -ENODEV; } i2c_hid_dbg(ihid, "HID Descriptor: %*ph\n", dsize, ihid->hdesc_buffer); @@ -1059,7 +1056,7 @@ void i2c_hid_core_shutdown(struct i2c_client *client) { struct i2c_hid *ihid = i2c_get_clientdata(client); - i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); + i2c_hid_set_power(ihid, I2C_HID_PWR_SLEEP); free_irq(client->irq, ihid); i2c_hid_core_shutdown_tail(ihid); @@ -1082,7 +1079,7 @@ static int i2c_hid_core_suspend(struct device *dev) } /* Save some power */ - i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); + i2c_hid_set_power(ihid, I2C_HID_PWR_SLEEP); disable_irq(client->irq); @@ -1130,9 +1127,9 @@ static int i2c_hid_core_resume(struct device *dev) * let's still reset them here. */ if (ihid->quirks & I2C_HID_QUIRK_RESET_ON_RESUME) - ret = i2c_hid_hwreset(client); + ret = i2c_hid_hwreset(ihid); else - ret = i2c_hid_set_power(client, I2C_HID_PWR_ON); + ret = i2c_hid_set_power(ihid, I2C_HID_PWR_ON); if (ret) return ret; From patchwork Tue Jan 18 07:26:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 12716023 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CB4DCC433FE for ; Tue, 18 Jan 2022 07:26:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244979AbiARH0k (ORCPT ); Tue, 18 Jan 2022 02:26:40 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43440 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244864AbiARH0i (ORCPT ); Tue, 18 Jan 2022 02:26:38 -0500 Received: from mail-pg1-x531.google.com (mail-pg1-x531.google.com [IPv6:2607:f8b0:4864:20::531]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7C5F0C061574; Mon, 17 Jan 2022 23:26:38 -0800 (PST) Received: by mail-pg1-x531.google.com with SMTP id f8so13143142pgf.8; Mon, 17 Jan 2022 23:26:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=vzFET2Y0lUKHdKshKTuEKMzUv5HlVgdjcJJcn/1bC04=; b=OeUpP4CeWl9U9kbR4FZp+tPxMAY4ogckXiNydU1cYbMrSgCLiq/+z/jOUBMhn+lUSK 1ZJ1iMrCPKWNoBhnkMiPPeHlJeccEImCDrH8khiMKpLtEbJvtG19GbDAhTIGGmg92UJu ojh4fbvwpW/jBB29TP0kGxZ3nN4diSXwXmBRaJbGBy2M/D/UKTsKCIo3Ne0Z6PnINOQR Iq2NnA9Xnog6qbbuUHGVRNd8SinNGsL4smvLc7CHRFfoJMiFkW5qPHqmlo7hKtMsiWNV cHrJex3++s25wVSoosilGLIfCjg+Q0nV9cGNwBPe8VLZNkXr0+42wCeiNAyF0mh892j7 BwIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=vzFET2Y0lUKHdKshKTuEKMzUv5HlVgdjcJJcn/1bC04=; b=q+1/U+4ofdpZ+1r1Xt9k90k2Hc9cs6F5x85k/AHgh//L1hiKBdEO2wM8q5FauO1V1W MELs5BPibkTYJEifrMOQRFe9dIsmxjuJWTlgEoMBZf4Q2JLXl+3xEt6hxxtAnHX7cQ8o a55E+VMeQNKc7qLREuii10NZ5HJY5ulo0VetdtMrv+nMAOpquQ5cW6NzSArCIOfVO0r1 Rst5SrwUP64kiSuA2vKwLgXF/gyzFrbC8ErF5h9TI+gjyeIvARiopUZC1MIgUxNLoJEj 3iEmkouleBPwIvuW/RfNYbP1LJzutRo3y6yAqEd2e9mw1ccWfuFBKmQqKdy68weqp8FP +MsQ== X-Gm-Message-State: AOAM533jr82iebQqN0XGCDu+phxxL7aOx/qXAOM412t0meHISctMQsDm WM5Q9OlwlHuABF5CAwbLMZZMFH8g8Rk= X-Google-Smtp-Source: ABdhPJzdt1aGugShvdV7GUkM2IIA6QRZ+IY+3HnmK7atesh8lmRnG/6Bl6nWh51f5XGbNqL/W8MzYA== X-Received: by 2002:a63:864a:: with SMTP id x71mr8332724pgd.618.1642490797916; Mon, 17 Jan 2022 23:26:37 -0800 (PST) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:202:201:bf2e:59:5029:f4c5]) by smtp.gmail.com with ESMTPSA id y18sm11079816pfl.156.2022.01.17.23.26.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 23:26:36 -0800 (PST) From: Dmitry Torokhov To: Jiri Kosina , Benjamin Tissoires Cc: Angela Czubak , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 04/12] HID: i2c-hid: refactor reset command Date: Mon, 17 Jan 2022 23:26:20 -0800 Message-Id: <20220118072628.1617172-5-dmitry.torokhov@gmail.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> References: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org "Reset" is the only command that needs to wait for interrupt from the device before continuing, so let's factor our waiting logic from __i2c_hid_command() to make it simpler. Signed-off-by: Dmitry Torokhov --- drivers/hid/i2c-hid/i2c-hid-core.c | 63 ++++++++++++++++++------------ 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index bae3e7a9b2e4..6c1741d9211d 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -88,7 +88,6 @@ struct i2c_hid_cmd { unsigned int registerIndex; __u8 opcode; unsigned int length; - bool wait; }; union command { @@ -114,8 +113,7 @@ static const struct i2c_hid_cmd hid_report_descr_cmd = { .opcode = 0x00, .length = 2 }; /* commands */ -static const struct i2c_hid_cmd hid_reset_cmd = { I2C_HID_CMD(0x01), - .wait = true }; +static const struct i2c_hid_cmd hid_reset_cmd = { I2C_HID_CMD(0x01) }; static const struct i2c_hid_cmd hid_get_report_cmd = { I2C_HID_CMD(0x02) }; static const struct i2c_hid_cmd hid_set_report_cmd = { I2C_HID_CMD(0x03) }; static const struct i2c_hid_cmd hid_set_power_cmd = { I2C_HID_CMD(0x08) }; @@ -220,7 +218,6 @@ static int __i2c_hid_command(struct i2c_hid *ihid, int msg_num = 1; int length = command->length; - bool wait = command->wait; unsigned int registerIndex = command->registerIndex; /* special case for hid_descr_cmd */ @@ -261,9 +258,6 @@ static int __i2c_hid_command(struct i2c_hid *ihid, set_bit(I2C_HID_READ_PENDING, &ihid->flags); } - if (wait) - set_bit(I2C_HID_RESET_PENDING, &ihid->flags); - ret = i2c_transfer(client->adapter, msg, msg_num); if (data_len > 0) @@ -272,20 +266,7 @@ static int __i2c_hid_command(struct i2c_hid *ihid, if (ret != msg_num) return ret < 0 ? ret : -EIO; - ret = 0; - - if (wait && (ihid->quirks & I2C_HID_QUIRK_NO_IRQ_AFTER_RESET)) { - msleep(100); - } else if (wait) { - i2c_hid_dbg(ihid, "%s: waiting...\n", __func__); - if (!wait_event_timeout(ihid->wait, - !test_bit(I2C_HID_RESET_PENDING, &ihid->flags), - msecs_to_jiffies(5000))) - ret = -ENODATA; - i2c_hid_dbg(ihid, "%s: finished.\n", __func__); - } - - return ret; + return 0; } static int i2c_hid_command(struct i2c_hid *ihid, @@ -432,6 +413,39 @@ static int i2c_hid_set_power(struct i2c_hid *ihid, int power_state) return ret; } +static int i2c_hid_execute_reset(struct i2c_hid *ihid) +{ + int ret; + + i2c_hid_dbg(ihid, "resetting...\n"); + + set_bit(I2C_HID_RESET_PENDING, &ihid->flags); + + ret = i2c_hid_command(ihid, &hid_reset_cmd, NULL, 0); + if (ret) { + dev_err(&ihid->client->dev, "failed to reset device.\n"); + goto out; + } + + if (ihid->quirks & I2C_HID_QUIRK_NO_IRQ_AFTER_RESET) { + msleep(100); + goto out; + } + + i2c_hid_dbg(ihid, "%s: waiting...\n", __func__); + if (!wait_event_timeout(ihid->wait, + !test_bit(I2C_HID_RESET_PENDING, &ihid->flags), + msecs_to_jiffies(5000))) { + ret = -ENODATA; + goto out; + } + i2c_hid_dbg(ihid, "%s: finished.\n", __func__); + +out: + clear_bit(I2C_HID_RESET_PENDING, &ihid->flags); + return ret; +} + static int i2c_hid_hwreset(struct i2c_hid *ihid) { int ret; @@ -449,11 +463,10 @@ static int i2c_hid_hwreset(struct i2c_hid *ihid) if (ret) goto out_unlock; - i2c_hid_dbg(ihid, "resetting...\n"); - - ret = i2c_hid_command(ihid, &hid_reset_cmd, NULL, 0); + ret = i2c_hid_execute_reset(ihid); if (ret) { - dev_err(&ihid->client->dev, "failed to reset device.\n"); + dev_err(&ihid->client->dev, + "failed to reset device: %d\n", ret); i2c_hid_set_power(ihid, I2C_HID_PWR_SLEEP); goto out_unlock; } From patchwork Tue Jan 18 07:26:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 12716024 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D7223C433EF for ; Tue, 18 Jan 2022 07:26:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245198AbiARH0t (ORCPT ); Tue, 18 Jan 2022 02:26:49 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43450 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245003AbiARH0k (ORCPT ); Tue, 18 Jan 2022 02:26:40 -0500 Received: from mail-pf1-x42e.google.com (mail-pf1-x42e.google.com [IPv6:2607:f8b0:4864:20::42e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2E026C06161C; Mon, 17 Jan 2022 23:26:40 -0800 (PST) Received: by mail-pf1-x42e.google.com with SMTP id 128so12314415pfe.12; Mon, 17 Jan 2022 23:26:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=k+ph1/QN1j4IUgMje1r3voGZ5lWOAeDuTQ2adMCwVo4=; b=d9IrUOz1Qx2Ta+vK+JxM+FjX3giOOtnWxsZxAith22VZ9u1OzLfLGPxgRV2P7c8qbF Wd81PF21eA/yYvDsAOl2iUwJ8PaQIN4cJKIyXM8wjVg8sxUspJVV14GmtJrNQdNHe6by TdbZA+VGr5nGfylMiBRQE3oyHiVlRmR/pQdiiOC9feZTMj2Q9heU5WKuK2xeHOXl1yzN P98J7bN1b+KZHx+j4ldEXi+SDB1LjdAtlyRfnfLksJcZ/MIzksv+dT4fdfIWyVU9Trq0 e5wApwwDvL8CRL82d/icWLkp1qlOc8M2Pyyis+7O8T+3gAfKFhtQTv4lN9SDO0tLetUk Mp3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=k+ph1/QN1j4IUgMje1r3voGZ5lWOAeDuTQ2adMCwVo4=; b=GgE3WkadAYKySQg+8wyUfuvo6nq1dOa5f5mShUBDecHy9Vvyd/hT/Q7UsivEoIUXwH c+Jk+fSQ+s09zjxKfR6kXHFGf8RquMzuxp43ohb0NvZKXyOYq6zhEgc+ocJ1OUXMRQ1Y V1xc4NvYQ71t/IugYpg6ClSwf0ukFyF9eapbeuYInaPFqUorwinQ50h23qQJbjbmaI0i RTUIyMflTWv+6ezvhfywfA6JjrctRUnWDZ+Z0xUWJq4yFindfD1JOK4uaXIEjgAdPROm VHueUn7qGhgKTi/5ufs8ggG86Z+iD86h2vShxWAp49r3E7njReli7KMWafelCQGNqmAL p3Aw== X-Gm-Message-State: AOAM533yZYOYQovGJmdiMLSrUvPj0AyKGjFla33v5t8VDShgvLZbDHST OFiS3KlRoDwvOuMi3XKArso= X-Google-Smtp-Source: ABdhPJwoFtTgwbO/ax9ClEazGtTyGQl8RDqbAevp+ac5daYdSvOADsp/NAzsJJMADXFwHGh2ciaEDA== X-Received: by 2002:a63:3e0e:: with SMTP id l14mr21803126pga.223.1642490799442; Mon, 17 Jan 2022 23:26:39 -0800 (PST) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:202:201:bf2e:59:5029:f4c5]) by smtp.gmail.com with ESMTPSA id y18sm11079816pfl.156.2022.01.17.23.26.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 23:26:38 -0800 (PST) From: Dmitry Torokhov To: Jiri Kosina , Benjamin Tissoires Cc: Angela Czubak , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 05/12] HID: i2c-hid: explicitly code setting and sending reports Date: Mon, 17 Jan 2022 23:26:21 -0800 Message-Id: <20220118072628.1617172-6-dmitry.torokhov@gmail.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> References: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Instead of relying on __i2c_hid_command() that tries to handle all commands and because of that is very complicated, let's define a new dumb helper i2c_hid_xfer() that actually transfers (write and read) data, and use it when sending and setting reports. By doing that we can save on number of copy operations we have to execute, and make logic of sending reports much clearer. Signed-off-by: Dmitry Torokhov --- drivers/hid/i2c-hid/i2c-hid-core.c | 269 ++++++++++++++++------------- 1 file changed, 151 insertions(+), 118 deletions(-) diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index 6c1741d9211d..c48b75bd81e0 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "../hid-ids.h" #include "i2c-hid.h" @@ -47,6 +48,15 @@ #define I2C_HID_QUIRK_BAD_INPUT_SIZE BIT(6) #define I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET BIT(7) +/* Command opcodes */ +#define I2C_HID_OPCODE_RESET 0x01 +#define I2C_HID_OPCODE_GET_REPORT 0x02 +#define I2C_HID_OPCODE_SET_REPORT 0x03 +#define I2C_HID_OPCODE_GET_IDLE 0x04 +#define I2C_HID_OPCODE_SET_IDLE 0x05 +#define I2C_HID_OPCODE_GET_PROTOCOL 0x06 +#define I2C_HID_OPCODE_SET_PROTOCOL 0x07 +#define I2C_HID_OPCODE_SET_POWER 0x08 /* flags */ #define I2C_HID_STARTED 0 @@ -90,16 +100,6 @@ struct i2c_hid_cmd { unsigned int length; }; -union command { - u8 data[0]; - struct cmd { - __le16 reg; - __u8 reportTypeID; - __u8 opcode; - __u8 reportID; - } __packed c; -}; - #define I2C_HID_CMD(opcode_) \ .opcode = opcode_, .length = 4, \ .registerIndex = offsetof(struct i2c_hid_desc, wCommandRegister) @@ -115,9 +115,7 @@ static const struct i2c_hid_cmd hid_report_descr_cmd = { /* commands */ static const struct i2c_hid_cmd hid_reset_cmd = { I2C_HID_CMD(0x01) }; static const struct i2c_hid_cmd hid_get_report_cmd = { I2C_HID_CMD(0x02) }; -static const struct i2c_hid_cmd hid_set_report_cmd = { I2C_HID_CMD(0x03) }; static const struct i2c_hid_cmd hid_set_power_cmd = { I2C_HID_CMD(0x08) }; -static const struct i2c_hid_cmd hid_no_cmd = { .length = 0 }; /* * These definitions are not used here, but are defined by the spec. @@ -144,7 +142,6 @@ struct i2c_hid { u8 *inbuf; /* Input buffer */ u8 *rawbuf; /* Raw Input buffer */ u8 *cmdbuf; /* Command buffer */ - u8 *argsbuf; /* Command arguments buffer */ unsigned long flags; /* device flags */ unsigned long quirks; /* Various quirks */ @@ -206,67 +203,90 @@ static u32 i2c_hid_lookup_quirk(const u16 idVendor, const u16 idProduct) return quirks; } +static int i2c_hid_xfer(struct i2c_hid *ihid, + u8 *send_buf, int send_len, u8 *recv_buf, int recv_len) +{ + struct i2c_client *client = ihid->client; + struct i2c_msg msgs[2] = { 0 }; + int n = 0; + int ret; + + if (send_len) { + i2c_hid_dbg(ihid, "%s: cmd=%*ph\n", + __func__, send_len, send_buf); + + msgs[n].addr = client->addr; + msgs[n].flags = client->flags & I2C_M_TEN; + msgs[n].len = send_len; + msgs[n].buf = send_buf; + n++; + } + + if (recv_len) { + msgs[n].addr = client->addr; + msgs[n].flags = (client->flags & I2C_M_TEN) | I2C_M_RD; + msgs[n].len = recv_len; + msgs[n].buf = recv_buf; + n++; + + set_bit(I2C_HID_READ_PENDING, &ihid->flags); + } + + ret = i2c_transfer(client->adapter, msgs, n); + + if (recv_len) + clear_bit(I2C_HID_READ_PENDING, &ihid->flags); + + if (ret != n) + return ret < 0 ? ret : -EIO; + + return 0; +} + +static size_t i2c_hid_encode_command(u8 *buf, u8 opcode, + int report_type, int report_id) +{ + size_t length = 0; + + if (report_id < 0x0F) { + buf[length++] = report_type << 4 | report_id; + buf[length++] = opcode; + } else { + buf[length++] = report_type << 4 | 0x0F; + buf[length++] = opcode; + buf[length++] = report_id; + } + + return length; +} + static int __i2c_hid_command(struct i2c_hid *ihid, const struct i2c_hid_cmd *command, u8 reportID, u8 reportType, u8 *args, int args_len, unsigned char *buf_recv, int data_len) { - struct i2c_client *client = ihid->client; - union command *cmd = (union command *)ihid->cmdbuf; - int ret; - struct i2c_msg msg[2]; - int msg_num = 1; - int length = command->length; unsigned int registerIndex = command->registerIndex; /* special case for hid_descr_cmd */ if (command == &hid_descr_cmd) { - cmd->c.reg = ihid->wHIDDescRegister; + *(__le16 *)ihid->cmdbuf = ihid->wHIDDescRegister; } else { - cmd->data[0] = ihid->hdesc_buffer[registerIndex]; - cmd->data[1] = ihid->hdesc_buffer[registerIndex + 1]; + ihid->cmdbuf[0] = ihid->hdesc_buffer[registerIndex]; + ihid->cmdbuf[1] = ihid->hdesc_buffer[registerIndex + 1]; } if (length > 2) { - cmd->c.opcode = command->opcode; - if (reportID < 0x0F) { - cmd->c.reportTypeID = reportType << 4 | reportID; - } else { - cmd->c.reportTypeID = reportType << 4 | 0x0F; - cmd->c.reportID = reportID; - length++; - } + length = sizeof(__le16) + /* register */ + i2c_hid_encode_command(ihid->cmdbuf + sizeof(__le16), + command->opcode, + reportType, reportID); } - memcpy(cmd->data + length, args, args_len); + memcpy(ihid->cmdbuf + length, args, args_len); length += args_len; - i2c_hid_dbg(ihid, "%s: cmd=%*ph\n", __func__, length, cmd->data); - - msg[0].addr = client->addr; - msg[0].flags = client->flags & I2C_M_TEN; - msg[0].len = length; - msg[0].buf = cmd->data; - if (data_len > 0) { - msg[1].addr = client->addr; - msg[1].flags = client->flags & I2C_M_TEN; - msg[1].flags |= I2C_M_RD; - msg[1].len = data_len; - msg[1].buf = buf_recv; - msg_num = 2; - set_bit(I2C_HID_READ_PENDING, &ihid->flags); - } - - ret = i2c_transfer(client->adapter, msg, msg_num); - - if (data_len > 0) - clear_bit(I2C_HID_READ_PENDING, &ihid->flags); - - if (ret != msg_num) - return ret < 0 ? ret : -EIO; - - return 0; + return i2c_hid_xfer(ihid, ihid->cmdbuf, length, buf_recv, data_len); } static int i2c_hid_command(struct i2c_hid *ihid, @@ -301,70 +321,81 @@ static int i2c_hid_get_report(struct i2c_hid *ihid, u8 reportType, return 0; } +static size_t i2c_hid_format_report(u8 *buf, int report_id, + const u8 *data, size_t size) +{ + size_t length = sizeof(__le16); /* reserve space to store size */ + + if (report_id) + buf[length++] = report_id; + + memcpy(buf + length, data, size); + length += size; + + /* Store overall size in the beginning of the buffer */ + put_unaligned_le16(length, buf); + + return length; +} + /** * i2c_hid_set_or_send_report: forward an incoming report to the device * @ihid: the i2c hid device - * @reportType: 0x03 for HID_FEATURE_REPORT ; 0x02 for HID_OUTPUT_REPORT - * @reportID: the report ID + * @report_type: 0x03 for HID_FEATURE_REPORT ; 0x02 for HID_OUTPUT_REPORT + * @report_id: the report ID * @buf: the actual data to transfer, without the report ID * @data_len: size of buf - * @use_data: true: use SET_REPORT HID command, false: send plain OUTPUT report + * @do_set: true: use SET_REPORT HID command, false: send plain OUTPUT report */ -static int i2c_hid_set_or_send_report(struct i2c_hid *ihid, u8 reportType, - u8 reportID, unsigned char *buf, size_t data_len, bool use_data) +static int i2c_hid_set_or_send_report(struct i2c_hid *ihid, + u8 report_type, u8 report_id, + const u8 *buf, size_t data_len, + bool do_set) { - u8 *args = ihid->argsbuf; - const struct i2c_hid_cmd *hidcmd; - int ret; - u16 dataRegister = le16_to_cpu(ihid->hdesc.wDataRegister); - u16 outputRegister = le16_to_cpu(ihid->hdesc.wOutputRegister); - u16 maxOutputLength = le16_to_cpu(ihid->hdesc.wMaxOutputLength); - u16 size; - int args_len; - int index = 0; + size_t length = 0; + int error; i2c_hid_dbg(ihid, "%s\n", __func__); if (data_len > ihid->bufsize) return -EINVAL; - size = 2 /* size */ + - (reportID ? 1 : 0) /* reportID */ + - data_len /* buf */; - args_len = 2 /* dataRegister */ + - size /* args */; - - if (!use_data && maxOutputLength == 0) + if (!do_set && le16_to_cpu(ihid->hdesc.wMaxOutputLength) == 0) return -ENOSYS; - /* - * use the data register for feature reports or if the device does not - * support the output register - */ - if (use_data) { - args[index++] = dataRegister & 0xFF; - args[index++] = dataRegister >> 8; - hidcmd = &hid_set_report_cmd; + if (do_set) { + /* Command register goes first */ + *(__le16 *)ihid->cmdbuf = ihid->hdesc.wCommandRegister; + length += sizeof(__le16); + /* Next is SET_REPORT command */ + length += i2c_hid_encode_command(ihid->cmdbuf + length, + I2C_HID_OPCODE_SET_REPORT, + report_type, report_id); + /* + * Report data will go into the data register. Because + * command can be either 2 or 3 bytes destination for + * the data register may be not aligned. + */ + put_unaligned_le16(le16_to_cpu(ihid->hdesc.wDataRegister), + ihid->cmdbuf + length); + length += sizeof(__le16); } else { - args[index++] = outputRegister & 0xFF; - args[index++] = outputRegister >> 8; - hidcmd = &hid_no_cmd; + /* + * With simple "send report" all data goes into the output + * register. + */ + *(__le16 *)ihid->cmdbuf = ihid->hdesc.wCommandRegister; + length += sizeof(__le16); } - args[index++] = size & 0xFF; - args[index++] = size >> 8; - - if (reportID) - args[index++] = reportID; + length += i2c_hid_format_report(ihid->cmdbuf + length, + report_id, buf, data_len); - memcpy(&args[index], buf, data_len); - - ret = __i2c_hid_command(ihid, hidcmd, reportID, - reportType, args, args_len, NULL, 0); - if (ret) { + error = i2c_hid_xfer(ihid, ihid->cmdbuf, length, NULL, 0); + if (error) { dev_err(&ihid->client->dev, - "failed to set a report to device.\n"); - return ret; + "failed to set a report to device: %d\n", error); + return error; } return data_len; @@ -575,31 +606,33 @@ static void i2c_hid_free_buffers(struct i2c_hid *ihid) { kfree(ihid->inbuf); kfree(ihid->rawbuf); - kfree(ihid->argsbuf); kfree(ihid->cmdbuf); ihid->inbuf = NULL; ihid->rawbuf = NULL; ihid->cmdbuf = NULL; - ihid->argsbuf = NULL; ihid->bufsize = 0; } static int i2c_hid_alloc_buffers(struct i2c_hid *ihid, size_t report_size) { - /* the worst case is computed from the set_report command with a - * reportID > 15 and the maximum report length */ - int args_len = sizeof(__u8) + /* ReportID */ - sizeof(__u8) + /* optional ReportID byte */ - sizeof(__u16) + /* data register */ - sizeof(__u16) + /* size of the report */ - report_size; /* report */ + /* + * The worst case is computed from the set_report command with a + * reportID > 15 and the maximum report length. + */ + int cmd_len = sizeof(__le16) + /* command register */ + sizeof(u8) + /* encoded report type/ID */ + sizeof(u8) + /* opcode */ + sizeof(u8) + /* optional 3rd byte report ID */ + sizeof(__le16) + /* data register */ + sizeof(__le16) + /* report data size */ + sizeof(u8) + /* report ID if numbered report */ + report_size; ihid->inbuf = kzalloc(report_size, GFP_KERNEL); ihid->rawbuf = kzalloc(report_size, GFP_KERNEL); - ihid->argsbuf = kzalloc(args_len, GFP_KERNEL); - ihid->cmdbuf = kzalloc(sizeof(union command) + args_len, GFP_KERNEL); + ihid->cmdbuf = kzalloc(cmd_len, GFP_KERNEL); - if (!ihid->inbuf || !ihid->rawbuf || !ihid->argsbuf || !ihid->cmdbuf) { + if (!ihid->inbuf || !ihid->rawbuf || !ihid->cmdbuf) { i2c_hid_free_buffers(ihid); return -ENOMEM; } @@ -659,8 +692,9 @@ static int i2c_hid_get_raw_report(struct hid_device *hid, return count; } -static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf, - size_t count, unsigned char report_type, bool use_data) +static int i2c_hid_output_raw_report(struct hid_device *hid, + const u8 *buf, size_t count, + u8 report_type, bool do_set) { struct i2c_client *client = hid->driver_data; struct i2c_hid *ihid = i2c_get_clientdata(client); @@ -681,7 +715,7 @@ static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf, */ ret = i2c_hid_set_or_send_report(ihid, report_type == HID_FEATURE_REPORT ? 0x03 : 0x02, - report_id, buf + 1, count - 1, use_data); + report_id, buf + 1, count - 1, do_set); if (ret >= 0) ret++; /* add report_id to the number of transferred bytes */ @@ -691,11 +725,10 @@ static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf, return ret; } -static int i2c_hid_output_report(struct hid_device *hid, __u8 *buf, - size_t count) +static int i2c_hid_output_report(struct hid_device *hid, u8 *buf, size_t count) { return i2c_hid_output_raw_report(hid, buf, count, HID_OUTPUT_REPORT, - false); + false); } static int i2c_hid_raw_request(struct hid_device *hid, unsigned char reportnum, From patchwork Tue Jan 18 07:26:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 12716025 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0E7D9C433F5 for ; Tue, 18 Jan 2022 07:27:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245454AbiARH1H (ORCPT ); Tue, 18 Jan 2022 02:27:07 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43460 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234427AbiARH0l (ORCPT ); Tue, 18 Jan 2022 02:26:41 -0500 Received: from mail-pg1-x536.google.com (mail-pg1-x536.google.com [IPv6:2607:f8b0:4864:20::536]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C0803C061401; Mon, 17 Jan 2022 23:26:41 -0800 (PST) Received: by mail-pg1-x536.google.com with SMTP id h23so13142515pgk.11; Mon, 17 Jan 2022 23:26:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xK1aCyNEs72Nz6kllo8Nxz5IKBPWt0j4OPgxiYbFIoY=; b=BTKCQBne31e6RluyS/R2Sx6f76juUN1wI5IsdkjgC4xwnA/O8BHAilL+eLCi+iBA9z qdgd259NjDQXF14RIZDnbV+73ytj6bAGLFRMUziXUJb+5kXW5s/nIX3nsl5inatSV4Mc GZF64tpcAEPo9DkWJK7x4FZjzeLKDkOoMtZUUhQ4DQ2nAk/u80Uk1LceBFaTjKT9oiTe rxMTX1YgFvQoNuden1ewRcfPVHjmO7WdguMlypPX28UDyyzancnCDsqOfj/DkQKyfEEr 5zEOZBJASBW9N9rUqfXEmWC41qZVmF4HXIrHbMCuTSbXnWnYmTUZF9I9NLQ80Y2t4Ceu 2EgA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xK1aCyNEs72Nz6kllo8Nxz5IKBPWt0j4OPgxiYbFIoY=; b=fBBiyMO9oZ3WJA7Y/UvaJV9T7ISegjspCS8N+RYRkwgdpU1MyZa6S6ZKhW8DIE3hu9 17cUz1A/cJt3Ft+gq/rbnWUB+t/VSNm/jR4Kscbq2afKf0/oOz9zLu2b9GWlIcsLwlZt +HtHU4bpsO/TUadP2L1sR9yQJ0jeS4kXKpdPNZG/VB5tfoY01sVh0qyurMP7uYdAiV7c X0E1XF8r8SW2y+jRk0cc4XKjuExyQB2mW/PqaNYQ1GDzByDEzLI04zmR8VCSaYCFXTQm +3w5pGFZtPnv6FI2/3xqirNZ4eghd1X5r+k8oeJBEf2CxoQmuKmsTY3ujriw3jwZmOKU fplg== X-Gm-Message-State: AOAM5326DYrYhVgwy9ythrBiILiD32n8mkIfKVExxDENPWAarZRrofMC JlBu2yJE0mtjLBsIf3OHUy0= X-Google-Smtp-Source: ABdhPJzzPLF6lfzlxQRptNhBBnQCaa5RDkKbvUWy4FX/KXDeGi/pOW3eInFMte354z638l7vRzbRnA== X-Received: by 2002:a63:720c:: with SMTP id n12mr22481147pgc.1.1642490801186; Mon, 17 Jan 2022 23:26:41 -0800 (PST) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:202:201:bf2e:59:5029:f4c5]) by smtp.gmail.com with ESMTPSA id y18sm11079816pfl.156.2022.01.17.23.26.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 23:26:39 -0800 (PST) From: Dmitry Torokhov To: Jiri Kosina , Benjamin Tissoires Cc: Angela Czubak , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 06/12] HID: i2c-hid: define i2c_hid_read_register() and use it Date: Mon, 17 Jan 2022 23:26:22 -0800 Message-Id: <20220118072628.1617172-7-dmitry.torokhov@gmail.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> References: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Handling simple read of device registers in __i2c_hid_command() makes it too complicated and the need of special handling for the HID descriptor register adds even more complexity. Instead, let's create simple i2c_hid_read_register() helper on base of i2c_hid_xfer() and use it. Signed-off-by: Dmitry Torokhov --- drivers/hid/i2c-hid/i2c-hid-core.c | 45 +++++++++++++++--------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index c48b75bd81e0..b1a2c6ad374d 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -104,14 +104,6 @@ struct i2c_hid_cmd { .opcode = opcode_, .length = 4, \ .registerIndex = offsetof(struct i2c_hid_desc, wCommandRegister) -/* fetch HID descriptor */ -static const struct i2c_hid_cmd hid_descr_cmd = { .length = 2 }; -/* fetch report descriptors */ -static const struct i2c_hid_cmd hid_report_descr_cmd = { - .registerIndex = offsetof(struct i2c_hid_desc, - wReportDescRegister), - .opcode = 0x00, - .length = 2 }; /* commands */ static const struct i2c_hid_cmd hid_reset_cmd = { I2C_HID_CMD(0x01) }; static const struct i2c_hid_cmd hid_get_report_cmd = { I2C_HID_CMD(0x02) }; @@ -243,6 +235,14 @@ static int i2c_hid_xfer(struct i2c_hid *ihid, return 0; } +static int i2c_hid_read_register(struct i2c_hid *ihid, __le16 reg, + void *buf, size_t len) +{ + *(__le16 *)ihid->cmdbuf = reg; + + return i2c_hid_xfer(ihid, ihid->cmdbuf, sizeof(__le16), buf, len); +} + static size_t i2c_hid_encode_command(u8 *buf, u8 opcode, int report_type, int report_id) { @@ -268,13 +268,8 @@ static int __i2c_hid_command(struct i2c_hid *ihid, int length = command->length; unsigned int registerIndex = command->registerIndex; - /* special case for hid_descr_cmd */ - if (command == &hid_descr_cmd) { - *(__le16 *)ihid->cmdbuf = ihid->wHIDDescRegister; - } else { - ihid->cmdbuf[0] = ihid->hdesc_buffer[registerIndex]; - ihid->cmdbuf[1] = ihid->hdesc_buffer[registerIndex + 1]; - } + ihid->cmdbuf[0] = ihid->hdesc_buffer[registerIndex]; + ihid->cmdbuf[1] = ihid->hdesc_buffer[registerIndex + 1]; if (length > 2) { length = sizeof(__le16) + /* register */ @@ -791,8 +786,9 @@ static int i2c_hid_parse(struct hid_device *hid) i2c_hid_dbg(ihid, "asking HID report descriptor\n"); - ret = i2c_hid_command(ihid, &hid_report_descr_cmd, - rdesc, rsize); + ret = i2c_hid_read_register(ihid, + ihid->hdesc.wReportDescRegister, + rdesc, rsize); if (ret) { hid_err(hid, "reading report descriptor failed\n"); kfree(rdesc); @@ -902,7 +898,7 @@ static int i2c_hid_fetch_hid_descriptor(struct i2c_hid *ihid) struct i2c_client *client = ihid->client; struct i2c_hid_desc *hdesc = &ihid->hdesc; unsigned int dsize; - int ret; + int error; /* i2c hid fetch using a fixed descriptor size (30 bytes) */ if (i2c_hid_get_dmi_i2c_hid_desc_override(client->name)) { @@ -911,11 +907,14 @@ static int i2c_hid_fetch_hid_descriptor(struct i2c_hid *ihid) *i2c_hid_get_dmi_i2c_hid_desc_override(client->name); } else { i2c_hid_dbg(ihid, "Fetching the HID descriptor\n"); - ret = i2c_hid_command(ihid, &hid_descr_cmd, - ihid->hdesc_buffer, - sizeof(struct i2c_hid_desc)); - if (ret) { - dev_err(&ihid->client->dev, "hid_descr_cmd failed\n"); + error = i2c_hid_read_register(ihid, + ihid->wHIDDescRegister, + &ihid->hdesc, + sizeof(ihid->hdesc)); + if (error) { + dev_err(&ihid->client->dev, + "failed to fetch HID descriptor: %d\n", + error); return -ENODEV; } } From patchwork Tue Jan 18 07:26:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 12716026 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2941CC433EF for ; Tue, 18 Jan 2022 07:27:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245665AbiARH13 (ORCPT ); Tue, 18 Jan 2022 02:27:29 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43498 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245189AbiARH0t (ORCPT ); Tue, 18 Jan 2022 02:26:49 -0500 Received: from mail-pj1-x102e.google.com (mail-pj1-x102e.google.com [IPv6:2607:f8b0:4864:20::102e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8B50FC06174E; Mon, 17 Jan 2022 23:26:43 -0800 (PST) Received: by mail-pj1-x102e.google.com with SMTP id hv15so22492997pjb.5; Mon, 17 Jan 2022 23:26:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=v5cTrYGjBflhhMN+moNPPDrBhqrz1YMurZIOtJGj4T8=; b=PnRPOQlOkC0+w2q3TwAX4p9rjPF13nnic+JiOLS5P8IioE7xRg7kDifNJFNd5SlbkQ j6dMtDwMty2mP0hn8n7tVG7AsxYnsioWbIicTCvWfJ7+VEgLgTjWC9mi6SrU8GY4mkqw 8WOVL9z6/eUBlcsEgbtA8NYreBsjnoduNm4xGaIRz9HSLa2PNOMAqf8sQwLEyELf/a0J CpgPBR8xt9HtpFbvqLXBeggS+AWdI+ZiM0bBYvz8aDrisIduD3nFtxV0d2gzn6xqdLhD Lc2Nh/rYifYppCk1Z91OpwuTIlfnkxQOHSu5DD8+Up0OQql7j9S7tLIOuz0xkiU7lQMY E6kQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=v5cTrYGjBflhhMN+moNPPDrBhqrz1YMurZIOtJGj4T8=; b=UCRI4YXQ0i3Ln1FdCUe48HQjTM8QlanY189CJxlkeccsEWmcxqUjX2pTI+3ms227SM qOi2+pTbRC0tpBz7RMVmCmLgIxCMym1BpLZPhx9EdQXpjwP8aTTJoGee8u1N5OYLkQ7p lzNhZDuU9TC/5y9c9TUqhdGwrUY5ihvaE1DJxSKnq2Owc3Dsei7XhdwrVyVqH8LD2z2R /wxrr6CdE3naBCKl2K3tiQj8u4K4aBf73t+QsX5d+0Xxxmn7Vh4DnEdt+STqDzgup8tZ EUOZHyOdKVYiRhvBorz4LyRK/L9D+p0XI/sstKQlqpObYfj0K8Pnf2DD9aVOXz0EHLrB iQqg== X-Gm-Message-State: AOAM532CqZjDoGq9S2+hV42PS/kiNAVYOPad/6ROIjZvnq3j+xKIedKX vSmWHMj6/kqqWuUj0C+6MEqxtMSch5Q= X-Google-Smtp-Source: ABdhPJyGmwVLeZUI6G30LQqbTTobWIVDhijM49SVWx7lgNZEcFLEghjxLpa0gExdKXDoVRn9AtBD+w== X-Received: by 2002:a17:902:ecc9:b0:14a:7a70:1fb8 with SMTP id a9-20020a170902ecc900b0014a7a701fb8mr25230777plh.22.1642490803026; Mon, 17 Jan 2022 23:26:43 -0800 (PST) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:202:201:bf2e:59:5029:f4c5]) by smtp.gmail.com with ESMTPSA id y18sm11079816pfl.156.2022.01.17.23.26.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 23:26:42 -0800 (PST) From: Dmitry Torokhov To: Jiri Kosina , Benjamin Tissoires Cc: Angela Czubak , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 07/12] HID: i2c-hid: create a helper for SET_POWER command Date: Mon, 17 Jan 2022 23:26:23 -0800 Message-Id: <20220118072628.1617172-8-dmitry.torokhov@gmail.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> References: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Another case where creating a dedicated helper allows for cleaner code that shows exactly what communication happens with the device when toggling its power. Signed-off-by: Dmitry Torokhov --- drivers/hid/i2c-hid/i2c-hid-core.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index b1a2c6ad374d..da673e3f2910 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -107,7 +107,6 @@ struct i2c_hid_cmd { /* commands */ static const struct i2c_hid_cmd hid_reset_cmd = { I2C_HID_CMD(0x01) }; static const struct i2c_hid_cmd hid_get_report_cmd = { I2C_HID_CMD(0x02) }; -static const struct i2c_hid_cmd hid_set_power_cmd = { I2C_HID_CMD(0x08) }; /* * These definitions are not used here, but are defined by the spec. @@ -396,6 +395,22 @@ static int i2c_hid_set_or_send_report(struct i2c_hid *ihid, return data_len; } +static int i2c_hid_set_power_command(struct i2c_hid *ihid, int power_state) +{ + size_t length; + + /* SET_POWER uses command register */ + *(__le16 *)ihid->cmdbuf = ihid->hdesc.wCommandRegister; + length = sizeof(__le16); + + /* Now the command itself */ + length += i2c_hid_encode_command(ihid->cmdbuf + length, + I2C_HID_OPCODE_SET_POWER, + 0, power_state); + + return i2c_hid_xfer(ihid, ihid->cmdbuf, length, NULL, 0); +} + static int i2c_hid_set_power(struct i2c_hid *ihid, int power_state) { int ret; @@ -409,15 +424,14 @@ static int i2c_hid_set_power(struct i2c_hid *ihid, int power_state) */ if (power_state == I2C_HID_PWR_ON && ihid->quirks & I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV) { - ret = i2c_hid_command(ihid, &hid_set_power_cmd, NULL, 0); + ret = i2c_hid_set_power_command(ihid, I2C_HID_PWR_ON); /* Device was already activated */ if (!ret) goto set_pwr_exit; } - ret = __i2c_hid_command(ihid, &hid_set_power_cmd, power_state, - 0, NULL, 0, NULL, 0); + ret = i2c_hid_set_power_command(ihid, power_state); if (ret) dev_err(&ihid->client->dev, "failed to change power setting.\n"); From patchwork Tue Jan 18 07:26:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 12716028 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C1324C433FE for ; Tue, 18 Jan 2022 07:27:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245107AbiARH1l (ORCPT ); Tue, 18 Jan 2022 02:27:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43558 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245410AbiARH1F (ORCPT ); Tue, 18 Jan 2022 02:27:05 -0500 Received: from mail-pg1-x536.google.com (mail-pg1-x536.google.com [IPv6:2607:f8b0:4864:20::536]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 160AEC061753; Mon, 17 Jan 2022 23:26:45 -0800 (PST) Received: by mail-pg1-x536.google.com with SMTP id t32so13125619pgm.7; Mon, 17 Jan 2022 23:26:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=C+G0JoqHk9MHyC89islo0SeNocmMaP3foPpVXqYBGEg=; b=RQ3cifQrU4BE4SCz9CJFD9YnebPR8r9bSam51P5U7Ex6EgaEWsV6J1KuB8rGvFGwiD xd8Qhyc0a7vUeJTc1xUX7fI9zG62DX4E1ZtAyD6JYvTiGk8Q0t8xvBl2q4zV1MBRPewv 5blby41KXuVFpC9u8lxnxa0GzHqeLf6qjAwJI6/RH91d65bIGyDqbeSlnNRZRVan9qYR 0SecNmy/nhJSRfsGnzFUjm9oBx2nKZl/QB14+nvH3igk0w2nhZGOkLebFO521wZdxgTl CZ9al1oVxaI3kcH50k+7RKIcBiXFFrsUoixlRG4/vgdDpRI1e2PqeWyKUSl6MxA8xkPN KuZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=C+G0JoqHk9MHyC89islo0SeNocmMaP3foPpVXqYBGEg=; b=Cdrc5FO8rVd5iC0bY0BSw7S+sx0DEUkZYdUsjegjZujX6qUnTzwAw7oXztJfRvv/8Q bB/jf+MlK8CuMFHZ5aoJu7zlC7q5KfDVhoojN95w9m3Fnz7ynUvQ0Ue6kNkntU+DIRl7 +XKLrsGTB6PmAw8DoGTm0CRxsUzsotslwZmpp4Ka/eBttV6m/fWKSXum3oRFowmLf5A2 Fac613mzoDN6aLog9K4LDcKAmHggEFLbI71IdHkYgXHf9e8uPsEJeWNg8ZUasyzxC+UE 7q8mPfOFROe9cWjDdMTWctav/ocZubfBvxVblQJw7c1IkdxjicS4Md6D1O4fUDSsMVJg yAIg== X-Gm-Message-State: AOAM533OAOmqhxGPjhN8mNo2PH0Ufiljr9Fy8MSCtjZjFZD/K/Cupo+z T9WtBAbD7aQ0xRD/bU/J6dbn+yJrsAk= X-Google-Smtp-Source: ABdhPJx6WF+fulXii6EXo6BdGddcJf2GslDii+H89qhlP4sEBDhyL8fhvirKm3h8MtrW79Hlo4tSGQ== X-Received: by 2002:a05:6a00:1988:b0:4c3:b9cd:f09a with SMTP id d8-20020a056a00198800b004c3b9cdf09amr11725662pfl.2.1642490804460; Mon, 17 Jan 2022 23:26:44 -0800 (PST) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:202:201:bf2e:59:5029:f4c5]) by smtp.gmail.com with ESMTPSA id y18sm11079816pfl.156.2022.01.17.23.26.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 23:26:43 -0800 (PST) From: Dmitry Torokhov To: Jiri Kosina , Benjamin Tissoires Cc: Angela Czubak , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 08/12] HID: i2c-hid: convert i2c_hid_execute_reset() to use i2c_hid_xfer() Date: Mon, 17 Jan 2022 23:26:24 -0800 Message-Id: <20220118072628.1617172-9-dmitry.torokhov@gmail.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> References: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org This will allow us to drop i2c_hid_command() wrapper and get close to removing __i2c_hid_command(). Signed-off-by: Dmitry Torokhov --- drivers/hid/i2c-hid/i2c-hid-core.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index da673e3f2910..1515fc892e61 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -105,7 +105,6 @@ struct i2c_hid_cmd { .registerIndex = offsetof(struct i2c_hid_desc, wCommandRegister) /* commands */ -static const struct i2c_hid_cmd hid_reset_cmd = { I2C_HID_CMD(0x01) }; static const struct i2c_hid_cmd hid_get_report_cmd = { I2C_HID_CMD(0x02) }; /* @@ -283,14 +282,6 @@ static int __i2c_hid_command(struct i2c_hid *ihid, return i2c_hid_xfer(ihid, ihid->cmdbuf, length, buf_recv, data_len); } -static int i2c_hid_command(struct i2c_hid *ihid, - const struct i2c_hid_cmd *command, - unsigned char *buf_recv, int data_len) -{ - return __i2c_hid_command(ihid, command, 0, 0, NULL, 0, - buf_recv, data_len); -} - static int i2c_hid_get_report(struct i2c_hid *ihid, u8 reportType, u8 reportID, unsigned char *buf_recv, int data_len) { @@ -455,13 +446,21 @@ static int i2c_hid_set_power(struct i2c_hid *ihid, int power_state) static int i2c_hid_execute_reset(struct i2c_hid *ihid) { + size_t length = 0; int ret; i2c_hid_dbg(ihid, "resetting...\n"); + /* Prepare reset command. Command register goes first. */ + *(__le16 *)ihid->cmdbuf = ihid->hdesc.wCommandRegister; + length += sizeof(__le16); + /* Next is RESET command itself */ + length += i2c_hid_encode_command(ihid->cmdbuf + length, + I2C_HID_OPCODE_RESET, 0, 0); + set_bit(I2C_HID_RESET_PENDING, &ihid->flags); - ret = i2c_hid_command(ihid, &hid_reset_cmd, NULL, 0); + ret = i2c_hid_xfer(ihid, ihid->cmdbuf, length, NULL, 0); if (ret) { dev_err(&ihid->client->dev, "failed to reset device.\n"); goto out; From patchwork Tue Jan 18 07:26:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 12716027 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 32E7BC433EF for ; Tue, 18 Jan 2022 07:27:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245424AbiARH1k (ORCPT ); Tue, 18 Jan 2022 02:27:40 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43560 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245414AbiARH1F (ORCPT ); Tue, 18 Jan 2022 02:27:05 -0500 Received: from mail-pf1-x42e.google.com (mail-pf1-x42e.google.com [IPv6:2607:f8b0:4864:20::42e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 833B8C061755; Mon, 17 Jan 2022 23:26:46 -0800 (PST) Received: by mail-pf1-x42e.google.com with SMTP id i17so12301368pfk.11; Mon, 17 Jan 2022 23:26:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=NshJlE4fbQHE7g31yBf1Bf/x2G6pGiGg+SM9MONafno=; b=DoeAfJgfEOOlwisvdc5WFl1pMOl9L2Wpvx+nmurtEu0Bn0RxUk7KHaYPn8HONZV2/w BfseDLL3gVFVgiKcd2h/tvGEHyM+u0bzEGFEx7WAzRbxE88Bl55ytRXQqO4biSb+dc3z nup2PTCU7GQ5kyo0UbQ4IStnAy5D5n8XsT7XsOg+SSg0KSCrshXIrBlaK/r6jS3TEqP/ oYgGAZKowVX3Rjy4wa8vkG3StjTlBFJNiwIMRVEm0c74wne0LL9nB/nIbyUOu7joQw+X q6XWNJq08dycDw7I/MvtyshxWTAq47uEVawHyyHOl8wJx9MMuI/EGIlY9yyzzg8hKyfU EmQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=NshJlE4fbQHE7g31yBf1Bf/x2G6pGiGg+SM9MONafno=; b=hLyJGV5BV7v91hTBK2niCM/wxKoQI+Zk9SH9U0bwcBtzNp/zhbVXuflJRwC5PXmD5O Aq0nGMVvNC4tUGkMC/ZsenRA9NtrE89aS9UkuX8Cj9ryi+PPAHhSWVvTRHCZh0MwdA2u oBGYfhJZ4akSbg2JsR+oSUkJEIxuIDhznsF2rdLXxXksFXHYG7pHCxc10iFgDrRQ3wNX wjHMpAF1P6BeWXmpZ5wAFhZlt7pZUS7AdHo4gj5X2KVnDb3K4LQ/KIPv8n3QXpbqDxjc It8gSytq0FHZbYgzemlQqLEvkL9nP+wc29UuxIoWnB69/uf7p2D6x/oXM9Fe6S8xxhhJ Fdnw== X-Gm-Message-State: AOAM533JmT1VWJOKfBCzjyedqA40Sdj/lu3AMSEPTiFLbOu7amZSK5zP ArweT0aJhdPK5rpT7g3DW3E= X-Google-Smtp-Source: ABdhPJyRY0j3v5h0gMb2ouP6F3Fqv+k/gqBodjtKLEk5TvrXajU1Vg9I6BQxypgv3Lhb10aG7J8BDw== X-Received: by 2002:a63:be0a:: with SMTP id l10mr22316301pgf.542.1642490805914; Mon, 17 Jan 2022 23:26:45 -0800 (PST) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:202:201:bf2e:59:5029:f4c5]) by smtp.gmail.com with ESMTPSA id y18sm11079816pfl.156.2022.01.17.23.26.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 23:26:44 -0800 (PST) From: Dmitry Torokhov To: Jiri Kosina , Benjamin Tissoires Cc: Angela Czubak , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 09/12] HID: i2c-hid: rework i2c_hid_get_report() to use i2c_hid_xfer() Date: Mon, 17 Jan 2022 23:26:25 -0800 Message-Id: <20220118072628.1617172-10-dmitry.torokhov@gmail.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> References: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Explicitly prepare command for i2c_hid_get_report() which makes the logic clearer and allows us to get rid of __i2c_hid_command() and related command definitions. Signed-off-by: Dmitry Torokhov --- drivers/hid/i2c-hid/i2c-hid-core.c | 150 ++++++++++++----------------- 1 file changed, 59 insertions(+), 91 deletions(-) diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index 1515fc892e61..433b6692f277 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -94,29 +94,6 @@ struct i2c_hid_desc { __le32 reserved; } __packed; -struct i2c_hid_cmd { - unsigned int registerIndex; - __u8 opcode; - unsigned int length; -}; - -#define I2C_HID_CMD(opcode_) \ - .opcode = opcode_, .length = 4, \ - .registerIndex = offsetof(struct i2c_hid_desc, wCommandRegister) - -/* commands */ -static const struct i2c_hid_cmd hid_get_report_cmd = { I2C_HID_CMD(0x02) }; - -/* - * These definitions are not used here, but are defined by the spec. - * Keeping them here for documentation purposes. - * - * static const struct i2c_hid_cmd hid_get_idle_cmd = { I2C_HID_CMD(0x04) }; - * static const struct i2c_hid_cmd hid_set_idle_cmd = { I2C_HID_CMD(0x05) }; - * static const struct i2c_hid_cmd hid_get_protocol_cmd = { I2C_HID_CMD(0x06) }; - * static const struct i2c_hid_cmd hid_set_protocol_cmd = { I2C_HID_CMD(0x07) }; - */ - /* The main device structure */ struct i2c_hid { struct i2c_client *client; /* i2c client */ @@ -258,52 +235,62 @@ static size_t i2c_hid_encode_command(u8 *buf, u8 opcode, return length; } -static int __i2c_hid_command(struct i2c_hid *ihid, - const struct i2c_hid_cmd *command, u8 reportID, - u8 reportType, u8 *args, int args_len, - unsigned char *buf_recv, int data_len) +static int i2c_hid_get_report(struct i2c_hid *ihid, + u8 report_type, u8 report_id, + u8 *recv_buf, size_t recv_len) { - int length = command->length; - unsigned int registerIndex = command->registerIndex; - - ihid->cmdbuf[0] = ihid->hdesc_buffer[registerIndex]; - ihid->cmdbuf[1] = ihid->hdesc_buffer[registerIndex + 1]; + size_t length = 0; + size_t ret_count; + int error; - if (length > 2) { - length = sizeof(__le16) + /* register */ - i2c_hid_encode_command(ihid->cmdbuf + sizeof(__le16), - command->opcode, - reportType, reportID); - } + i2c_hid_dbg(ihid, "%s\n", __func__); - memcpy(ihid->cmdbuf + length, args, args_len); - length += args_len; + /* Command register goes first */ + *(__le16 *)ihid->cmdbuf = ihid->hdesc.wCommandRegister; + length += sizeof(__le16); + /* Next is GET_REPORT command */ + length += i2c_hid_encode_command(ihid->cmdbuf + length, + I2C_HID_OPCODE_GET_REPORT, + report_type, report_id); + /* + * Device will send report data through data register. Because + * command can be either 2 or 3 bytes destination for the data + * register may be not aligned. + */ + put_unaligned_le16(le16_to_cpu(ihid->hdesc.wDataRegister), + ihid->cmdbuf + length); + length += sizeof(__le16); - return i2c_hid_xfer(ihid, ihid->cmdbuf, length, buf_recv, data_len); -} + /* + * In addition to report data device will supply data length + * in the first 2 bytes of the response, so adjust . + */ + error = i2c_hid_xfer(ihid, ihid->cmdbuf, length, + ihid->rawbuf, recv_len + sizeof(__le16)); + if (error) { + dev_err(&ihid->client->dev, + "failed to set a report to device: %d\n", error); + return error; + } -static int i2c_hid_get_report(struct i2c_hid *ihid, u8 reportType, - u8 reportID, unsigned char *buf_recv, int data_len) -{ - u8 args[2]; - int ret; - int args_len = 0; - u16 readRegister = le16_to_cpu(ihid->hdesc.wDataRegister); + /* The buffer is sufficiently aligned */ + ret_count = le16_to_cpup((__le16 *)ihid->rawbuf); - i2c_hid_dbg(ihid, "%s\n", __func__); + /* Check for empty report response */ + if (ret_count <= sizeof(__le16)) + return 0; - args[args_len++] = readRegister & 0xFF; - args[args_len++] = readRegister >> 8; + recv_len = min(recv_len, ret_count - sizeof(__le16)); + memcpy(recv_buf, ihid->rawbuf + sizeof(__le16), recv_len); - ret = __i2c_hid_command(ihid, &hid_get_report_cmd, reportID, - reportType, args, args_len, buf_recv, data_len); - if (ret) { + if (report_id && recv_len != 0 && recv_buf[0] != report_id) { dev_err(&ihid->client->dev, - "failed to retrieve report from device.\n"); - return ret; + "device returned incorrect report (%d vs %d expected)\n", + recv_buf[0], report_id); + return -EINVAL; } - return 0; + return recv_len; } static size_t i2c_hid_format_report(u8 *buf, int report_id, @@ -651,13 +638,12 @@ static int i2c_hid_alloc_buffers(struct i2c_hid *ihid, size_t report_size) } static int i2c_hid_get_raw_report(struct hid_device *hid, - unsigned char report_number, __u8 *buf, size_t count, - unsigned char report_type) + u8 report_type, u8 report_id, + u8 *buf, size_t count) { struct i2c_client *client = hid->driver_data; struct i2c_hid *ihid = i2c_get_clientdata(client); - size_t ret_count, ask_count; - int ret; + int ret_count; if (report_type == HID_OUTPUT_REPORT) return -EINVAL; @@ -667,42 +653,24 @@ static int i2c_hid_get_raw_report(struct hid_device *hid, * not have the report ID that the upper layers expect, so we need * to stash it the buffer ourselves and adjust the data size. */ - if (!report_number) { + if (!report_id) { buf[0] = 0; buf++; count--; } - /* +2 bytes to include the size of the reply in the query buffer */ - ask_count = min(count + 2, (size_t)ihid->bufsize); - - ret = i2c_hid_get_report(ihid, + ret_count = i2c_hid_get_report(ihid, report_type == HID_FEATURE_REPORT ? 0x03 : 0x01, - report_number, ihid->rawbuf, ask_count); - - if (ret < 0) - return ret; - - ret_count = ihid->rawbuf[0] | (ihid->rawbuf[1] << 8); - - if (ret_count <= 2) - return 0; - - ret_count = min(ret_count, ask_count); - - /* The query buffer contains the size, dropping it in the reply */ - count = min(count, ret_count - 2); - memcpy(buf, ihid->rawbuf + 2, count); + report_id, buf, count); - if (!report_number) - count++; + if (ret_count > 0 && !report_id) + ret_count++; - return count; + return ret_count; } -static int i2c_hid_output_raw_report(struct hid_device *hid, - const u8 *buf, size_t count, - u8 report_type, bool do_set) +static int i2c_hid_output_raw_report(struct hid_device *hid, u8 report_type, + const u8 *buf, size_t count, bool do_set) { struct i2c_client *client = hid->driver_data; struct i2c_hid *ihid = i2c_get_clientdata(client); @@ -735,7 +703,7 @@ static int i2c_hid_output_raw_report(struct hid_device *hid, static int i2c_hid_output_report(struct hid_device *hid, u8 *buf, size_t count) { - return i2c_hid_output_raw_report(hid, buf, count, HID_OUTPUT_REPORT, + return i2c_hid_output_raw_report(hid, HID_OUTPUT_REPORT, buf, count, false); } @@ -745,11 +713,11 @@ static int i2c_hid_raw_request(struct hid_device *hid, unsigned char reportnum, { switch (reqtype) { case HID_REQ_GET_REPORT: - return i2c_hid_get_raw_report(hid, reportnum, buf, len, rtype); + return i2c_hid_get_raw_report(hid, rtype, reportnum, buf, len); case HID_REQ_SET_REPORT: if (buf[0] != reportnum) return -EINVAL; - return i2c_hid_output_raw_report(hid, buf, len, rtype, true); + return i2c_hid_output_raw_report(hid, rtype, buf, len, true); default: return -EIO; } From patchwork Tue Jan 18 07:26:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 12716031 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9DA95C43217 for ; Tue, 18 Jan 2022 07:27:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245735AbiARH1r (ORCPT ); Tue, 18 Jan 2022 02:27:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43646 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244562AbiARH12 (ORCPT ); Tue, 18 Jan 2022 02:27:28 -0500 Received: from mail-pg1-x533.google.com (mail-pg1-x533.google.com [IPv6:2607:f8b0:4864:20::533]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 14102C061574; Mon, 17 Jan 2022 23:26:48 -0800 (PST) Received: by mail-pg1-x533.google.com with SMTP id q75so5413932pgq.5; Mon, 17 Jan 2022 23:26:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=yecptQTSi6NHIXvVrHT44imb/ZHLpBwj2o/CiNFNizM=; b=hVhfzXlx7zb7Mv7XXWzaSW0qeRU9iNGFs0tfo1QhR//6OhkcPL7ziN9w2xznA2uKpN xtxHufpWkn/67SM5UAPZNS5yyJGIm13iAB5+0vh+D8796jtEsx2976HeswgUWqZy/BnA cE/jphJBbqqjMlVFlgwzO8kURtRwRwTh1bsQpLe1YeJ34tRUuDUserWr+e228GnEO7cI ysZV6BES2xN18x/Q8Ww4XJ0qnnrIItnKrRvfvDwxRMGHomrDZ66ZVQq0THOGK4LLVeiS Xv2xUaqjsIJ00o9vIGdhFHeSNE+ePBBD6jHyRYyWnmAjKerDJWDXRMIwhK+qmNz0bitv au1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=yecptQTSi6NHIXvVrHT44imb/ZHLpBwj2o/CiNFNizM=; b=eoHBA/l1Dale03VqzYwitIjUgysT9XEV5IoXzUOkqhoVe05DV7D5e4B4dz0b8D75fu o5nZ89ZMwi4OubXurcvtXn1lHkLJRvXI4b8HfnA7Tk/xK0QuOaqzwt/pSIPvOBAGnxdU xyDU5BM5TijGymNZuURYvYXQve5t+dpUuYoN+OUWrk1P89PWlTtoLL7fHjo7bc2EvHR9 pcYqJmgDBBbCi7fBjNPtgZ2LzX4wiD2rHVie1vz9thzuLpOAtvJcF3Bc5+4RQawIh2HU glcPmw9Rv7DTxqtCAmte7sy/V0cC+NUV4LUSWUu68rYQBiXbKgv3F3GEyPqcLXw84L+M b2mQ== X-Gm-Message-State: AOAM530pUxZHH5KFUaHGwClhOtFIiGBHpsws13phj0NSBqfApCc1oo5T i/alNinxDLW484guk+A/5yY= X-Google-Smtp-Source: ABdhPJyrm9834y/iiIqzI1/VwpK5Aibqv1C5Ymyrcrsd6Nz92eHyDJe++I1AdzOzsSCD8fyuziCAOA== X-Received: by 2002:a63:c5e:: with SMTP id 30mr14979339pgm.522.1642490807480; Mon, 17 Jan 2022 23:26:47 -0800 (PST) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:202:201:bf2e:59:5029:f4c5]) by smtp.gmail.com with ESMTPSA id y18sm11079816pfl.156.2022.01.17.23.26.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 23:26:46 -0800 (PST) From: Dmitry Torokhov To: Jiri Kosina , Benjamin Tissoires Cc: Angela Czubak , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 10/12] HID: i2c-hid: use helpers to do endian conversion in i2c_hid_get_input() Date: Mon, 17 Jan 2022 23:26:26 -0800 Message-Id: <20220118072628.1617172-11-dmitry.torokhov@gmail.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> References: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org It is better to use helpers to do endian conversion as it documents and draws attention to it, and might be a bit more performant as well. Signed-off-by: Dmitry Torokhov --- drivers/hid/i2c-hid/i2c-hid-core.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index 433b6692f277..07c2ea057013 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -508,9 +508,9 @@ static int i2c_hid_hwreset(struct i2c_hid *ihid) static void i2c_hid_get_input(struct i2c_hid *ihid) { + u16 size = le16_to_cpu(ihid->hdesc.wMaxInputLength); + u16 ret_size; int ret; - u32 ret_size; - int size = le16_to_cpu(ihid->hdesc.wMaxInputLength); if (size > ihid->bufsize) size = ihid->bufsize; @@ -525,8 +525,8 @@ static void i2c_hid_get_input(struct i2c_hid *ihid) return; } - ret_size = ihid->inbuf[0] | ihid->inbuf[1] << 8; - + /* Receiving buffer is properly aligned */ + ret_size = le16_to_cpup((__le16 *)ihid->inbuf); if (!ret_size) { /* host or device initiated RESET completed */ if (test_and_clear_bit(I2C_HID_RESET_PENDING, &ihid->flags)) @@ -534,19 +534,20 @@ static void i2c_hid_get_input(struct i2c_hid *ihid) return; } - if (ihid->quirks & I2C_HID_QUIRK_BOGUS_IRQ && ret_size == 0xffff) { - dev_warn_once(&ihid->client->dev, "%s: IRQ triggered but " - "there's no data\n", __func__); + if ((ihid->quirks & I2C_HID_QUIRK_BOGUS_IRQ) && ret_size == 0xffff) { + dev_warn_once(&ihid->client->dev, + "%s: IRQ triggered but there's no data\n", + __func__); return; } - if ((ret_size > size) || (ret_size < 2)) { + if (ret_size > size || ret_size < sizeof(__le16)) { if (ihid->quirks & I2C_HID_QUIRK_BAD_INPUT_SIZE) { - ihid->inbuf[0] = size & 0xff; - ihid->inbuf[1] = size >> 8; + *(__le16 *)ihid->inbuf = cpu_to_le16(size); ret_size = size; } else { - dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n", + dev_err(&ihid->client->dev, + "%s: incomplete report (%d/%d)\n", __func__, size, ret_size); return; } @@ -555,10 +556,9 @@ static void i2c_hid_get_input(struct i2c_hid *ihid) i2c_hid_dbg(ihid, "input: %*ph\n", ret_size, ihid->inbuf); if (test_bit(I2C_HID_STARTED, &ihid->flags)) - hid_input_report(ihid->hid, HID_INPUT_REPORT, ihid->inbuf + 2, - ret_size - 2, 1); - - return; + hid_input_report(ihid->hid, HID_INPUT_REPORT, + ihid->inbuf + sizeof(__le16), + ret_size - sizeof(__le16), 1); } static irqreturn_t i2c_hid_irq(int irq, void *dev_id) From patchwork Tue Jan 18 07:26:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 12716029 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9E91AC433F5 for ; Tue, 18 Jan 2022 07:27:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245717AbiARH1p (ORCPT ); Tue, 18 Jan 2022 02:27:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43490 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245616AbiARH12 (ORCPT ); Tue, 18 Jan 2022 02:27:28 -0500 Received: from mail-pg1-x533.google.com (mail-pg1-x533.google.com [IPv6:2607:f8b0:4864:20::533]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C2FA6C06173E; Mon, 17 Jan 2022 23:26:49 -0800 (PST) Received: by mail-pg1-x533.google.com with SMTP id f8so13143445pgf.8; Mon, 17 Jan 2022 23:26:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0qfNABkAMQ9lvs4J9n2+LJ7pGeCibSui0x9nCGYBI3Y=; b=cbrGOr4JycopPRJMZi+ClDgmEqcX39wdf6ziVx4RcPAFoO9hLROE7FlXdUtu+K8F1a mqrIkuX184E1KHWXXu9PHESah/ABUweD1mhe2NOcmzihU/CyOD6dl4bGDAR0cpX+VFeM bc9bthP9ngOeAJcBEJ+aOpESL/4XYLdOR8/4J36rogfGe6Amyw2AeKIgJcaycDfGX7c/ zUqbz2TZPOitbrV4WkIG0GFF3XQfVTVN5WH0fLvbZb+hdqogAsyMFlQ0/b/R2YQ12Gl8 GJ22E5+2+M/kZxv13yklRwjH7hgy9CiIM6iYVf7cHCg6/ppo5xLtsYaDxkPdeV0y2NAs r6Pg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=0qfNABkAMQ9lvs4J9n2+LJ7pGeCibSui0x9nCGYBI3Y=; b=Z/2ykLTQ/Nff7RPNfO5he/w042AARGdTfS8Qyh4w6dptTTPz1ZkNFqShQjiRlV1e5J GY2LZ+RAWPxCFMpg/Q1vHvLAygoCdEz3FlpOv/mxBOHC4kK8AXxLPc23GPM3W977ntf+ qFCDu08P106S+TKAbx749/AfG8KPJUPYNZC8UzoI7i2tbxbyZXnxz1TT5F+zpLqtNOAL yUNbunVOr9kGHXKsyjAYVUyGRaB0THGm9YEWka9xIdGSxoKz4gxRui2pncTAzhya+WaQ qkz2w00ib2YiPaVO1bEelVQ5FtDvNPwELRiyW+OKuLMKyfKxbPBHjoUEJrWSfvGqSpEE ENbQ== X-Gm-Message-State: AOAM533Xq8tQ9nKmW/IJrF4sEJiRMFYK/dglj5YZOQCyg18BYCyKe/mQ P+8zaoygrw6LgxbOMLFjBUQ= X-Google-Smtp-Source: ABdhPJwf5qRqctWXExur5xWVlFGQNa4ZqwDd40VH9XCc9/6x9YkW5V7oSqSASyhXVwSiPN/fDBPMbw== X-Received: by 2002:a63:4f03:: with SMTP id d3mr7670077pgb.311.1642490809191; Mon, 17 Jan 2022 23:26:49 -0800 (PST) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:202:201:bf2e:59:5029:f4c5]) by smtp.gmail.com with ESMTPSA id y18sm11079816pfl.156.2022.01.17.23.26.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 23:26:47 -0800 (PST) From: Dmitry Torokhov To: Jiri Kosina , Benjamin Tissoires Cc: Angela Czubak , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 11/12] HID: i2c-hid: no longer need raw access to HID descriptor structure Date: Mon, 17 Jan 2022 23:26:27 -0800 Message-Id: <20220118072628.1617172-12-dmitry.torokhov@gmail.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> References: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org We can stop defining a union for HID descriptor data as we now only access individual members of it by names and using proper types instead of accessing by offset from the beginning of the data structure. Signed-off-by: Dmitry Torokhov --- drivers/hid/i2c-hid/i2c-hid-core.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index 07c2ea057013..aa7c573b35bc 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -98,10 +98,7 @@ struct i2c_hid_desc { struct i2c_hid { struct i2c_client *client; /* i2c client */ struct hid_device *hid; /* pointer to corresponding HID dev */ - union { - __u8 hdesc_buffer[sizeof(struct i2c_hid_desc)]; - struct i2c_hid_desc hdesc; /* the HID Descriptor */ - }; + struct i2c_hid_desc hdesc; /* the HID Descriptor */ __le16 wHIDDescRegister; /* location of the i2c * register of the HID * descriptor. */ @@ -918,7 +915,7 @@ static int i2c_hid_fetch_hid_descriptor(struct i2c_hid *ihid) "weird size of HID descriptor (%u)\n", dsize); return -ENODEV; } - i2c_hid_dbg(ihid, "HID Descriptor: %*ph\n", dsize, ihid->hdesc_buffer); + i2c_hid_dbg(ihid, "HID Descriptor: %*ph\n", dsize, &ihid->hdesc); return 0; } From patchwork Tue Jan 18 07:26:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 12716030 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2EFD8C4332F for ; Tue, 18 Jan 2022 07:27:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245731AbiARH1q (ORCPT ); Tue, 18 Jan 2022 02:27:46 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43648 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245617AbiARH12 (ORCPT ); Tue, 18 Jan 2022 02:27:28 -0500 Received: from mail-pg1-x529.google.com (mail-pg1-x529.google.com [IPv6:2607:f8b0:4864:20::529]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4BC03C06175A; Mon, 17 Jan 2022 23:26:51 -0800 (PST) Received: by mail-pg1-x529.google.com with SMTP id q75so5414056pgq.5; Mon, 17 Jan 2022 23:26:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6FvLWa2TvyJ6Dd9BiAJ7VPRCB014iQemLHUSFzvWnWU=; b=h3iIB2y8FkG6MKnZaDBFUhMwfS62Rr7ktzTHy3yh2ICJyDJRH0rBiw7WLu3lZWGry7 uVPQYqiY02ci2moKyxdUlEHCTMXRXuRQwrsUkJLzRuAo7pN80bYoYYVN35m39oiq3SnH U2WjSqamnusgMkMAsp5rjwLBi61kv/P2KeSGYxME/lyM12zf0Fb1EgJlKOGh2wPuIrDJ 8qIwG9Np7wmBvmCj3mzZaTLYKqcbdMLo9arQQFiJgnkwnUMk+A60PafPr0vNiTp9xJmB xdQGX0T7dy6xRuKlJOItr4bmC2oWJnmAtiubM4fEv1j9+pKD32R+PKg1ZVRj4bjul5Tq TJfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=6FvLWa2TvyJ6Dd9BiAJ7VPRCB014iQemLHUSFzvWnWU=; b=L/BuxlG+dWGiXpvzUoPYyi638kTlH0GnHZ6FYOrO7k6gqZiYSVmZvyIJKbFCszOZWf QTbmsHW4Oosbvxfyh9Z3AnIhCz0UOuxrUNPommP5VEjSkoeQOT2vBjQvTq9EEtqC8ftG XOLSw/oFuwuw+2i64hjS9yUhAENjfEDHTkSpbc/7VvskrgqSSzbsnApy7uFAI8e42zg3 sMp68ZhE5jn8ZejNI9PwdA3dL7yR4g2E/paVuaHIkcgxO48M7v669zCJKk6RMB+tTPb8 cxpuDZYMGtx7oFpFF3M66ZLsenahBadTzIW+wwo+gpcuVEGbOUjzOp8s6HNDqMM4RdDl ficQ== X-Gm-Message-State: AOAM531SSBotrpU1zT5vYZrpGyAHBVgF9dpr/DFZK0SAR6bTC1L6i3SD 4g5/0kLWbftyC+MztBbK+mc7DskrHGw= X-Google-Smtp-Source: ABdhPJztueEeTXZP+eCSDmu5GHanYJ4WiG6kPm9zlg+DjVkc4ncXIWE0B3PfTtorjbKJYarWOkoKEg== X-Received: by 2002:a63:8b4a:: with SMTP id j71mr22134690pge.430.1642490810698; Mon, 17 Jan 2022 23:26:50 -0800 (PST) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:202:201:bf2e:59:5029:f4c5]) by smtp.gmail.com with ESMTPSA id y18sm11079816pfl.156.2022.01.17.23.26.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 23:26:49 -0800 (PST) From: Dmitry Torokhov To: Jiri Kosina , Benjamin Tissoires Cc: Angela Czubak , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 12/12] HID: i2c-hid: note that I2C xfer buffers are DMA-safe Date: Mon, 17 Jan 2022 23:26:28 -0800 Message-Id: <20220118072628.1617172-13-dmitry.torokhov@gmail.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> References: <20220118072628.1617172-1-dmitry.torokhov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org All I2C communications in the driver use driver-private buffers that are DMA-safe, so mark them as such. Signed-off-by: Dmitry Torokhov --- drivers/hid/i2c-hid/i2c-hid-core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index aa7c573b35bc..92dd86c42975 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -180,7 +180,7 @@ static int i2c_hid_xfer(struct i2c_hid *ihid, __func__, send_len, send_buf); msgs[n].addr = client->addr; - msgs[n].flags = client->flags & I2C_M_TEN; + msgs[n].flags = (client->flags & I2C_M_TEN) | I2C_M_DMA_SAFE; msgs[n].len = send_len; msgs[n].buf = send_buf; n++; @@ -188,7 +188,8 @@ static int i2c_hid_xfer(struct i2c_hid *ihid, if (recv_len) { msgs[n].addr = client->addr; - msgs[n].flags = (client->flags & I2C_M_TEN) | I2C_M_RD; + msgs[n].flags = (client->flags & I2C_M_TEN) | + I2C_M_RD | I2C_M_DMA_SAFE; msgs[n].len = recv_len; msgs[n].buf = recv_buf; n++;