From patchwork Mon Aug 1 06:47:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: margeyang X-Patchwork-Id: 12933582 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 A342AC00144 for ; Mon, 1 Aug 2022 06:48:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231866AbiHAGr7 (ORCPT ); Mon, 1 Aug 2022 02:47:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46610 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234464AbiHAGrn (ORCPT ); Mon, 1 Aug 2022 02:47:43 -0400 Received: from mail-pg1-x52f.google.com (mail-pg1-x52f.google.com [IPv6:2607:f8b0:4864:20::52f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 79DCD63F5 for ; Sun, 31 Jul 2022 23:47:17 -0700 (PDT) Received: by mail-pg1-x52f.google.com with SMTP id i71so3357149pge.9 for ; Sun, 31 Jul 2022 23:47:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=synaptics-corp-partner-google-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id; bh=UockhMzW1MKAwp8ZPFnrYbu87PaXsC6GeLfvEKDP3s8=; b=vbHnDb2Py1FWhiTAR+HmRBbaKgVwqP5YPOTlVGXOOAgRryXqb4GZKOtg/pKParMpRe LPHUioLQCkXsss0eTx8kvuOIbYNKbZxY244k/0Q+eQTnDP39nhF8QaV+2rhYTVOH6tqL oGL69kNa7/OwFlJLBP3ZFqFFRGXtvSLHEsPVr+nig71mCcaYe7s+69R0JJjVrMEV4PRu mNI2LrnJLaRGHXY0e32WU0GIVOzEKwAQBG596hUCTBPwz9oizuxjv6MAvdAVtP/UVJVU V0qqYcNDzE6Z1anegdrQbSTKGp4JJ+CgaJAw3qp8FuMc8go4EG/s+h+zKTdb+f+Yn2kt J45w== 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; bh=UockhMzW1MKAwp8ZPFnrYbu87PaXsC6GeLfvEKDP3s8=; b=N0iHyPvUmnoTsmDxbfSSOZZpyJVDzjtw5sad1tEzmxo+fpt2Q4fsJO+9x1v+MBmxeG CfV50L0DoO73E/aHzThpRT3wuXntuuazMtYMPZbvUmEicJ9nqR52ou3lfpYmDmWrBsg9 EDUUQASkFf+KbuGyU8csKlK5Vwqn4wIxq/gOdehDfA54A3xwrkG6Nh26PK8SLcWU+XtI SIBeJbvZeqotP1Vc9LBm1G+iAK5IkYsYcgp53Yztq70ypKnkWYy26Kc11B7fIswRv/fW C3yxFY5MUBiwgNyvaT7sMcJCpuTlj1pURx69GEbvLez+TaMHxO/OFQJgm5U242ZmDIO/ OTEA== X-Gm-Message-State: ACgBeo1UJkqHjtPYtqT96kfIM3D9FpdCbpHtmF01Ct+c9sV/7tQChGIk KyO1o3OYwNtYc0bpRY2YMTUgVA== X-Google-Smtp-Source: AGRyM1teMxs7nXdi0Y0OlAxCIQ0k2o6fXAR9xhbrozkRGKrFRQXyYDvsnIByKbmXFxDFxwBALpRmxw== X-Received: by 2002:a62:3346:0:b0:52a:c0cb:ae8 with SMTP id z67-20020a623346000000b0052ac0cb0ae8mr14830623pfz.37.1659336436976; Sun, 31 Jul 2022 23:47:16 -0700 (PDT) Received: from localhost.localdomain ([63.222.17.38]) by smtp.gmail.com with ESMTPSA id h6-20020a17090a130600b001f4d711e165sm4249841pja.11.2022.07.31.23.47.14 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sun, 31 Jul 2022 23:47:16 -0700 (PDT) From: margeyang To: dmitry.torokhov@gmail.com, linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Cc: marge.yang@tw.synaptics.com, derek.chegn@tw.synaptcs.com, vincent.huang@tw.synaptics.com, Marge Yang Subject: [PATCH] Input: synaptics-rmi4 - add support for F03 Date: Mon, 1 Aug 2022 14:47:05 +0800 Message-Id: <1659336425-2614-1-git-send-email-marge.yang@synaptics.corp-partner.google.com> X-Mailer: git-send-email 2.7.4 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org From: Marge Yang RMI4 F03 supports the Stick function, it's designed to support relative packet. This patch adds to support complete relative packet. When timeout error or parity error happens, sends 0xFE command to ask Re-send stick packet again. Supports some conditions to filter wrong relative packet. Signed-off-by: Marge Yang --- drivers/input/rmi4/rmi_f03.c | 82 ++++++++++++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 4 deletions(-) diff --git a/drivers/input/rmi4/rmi_f03.c b/drivers/input/rmi4/rmi_f03.c index c194b1664b10..57f03dfcb4ff 100644 --- a/drivers/input/rmi4/rmi_f03.c +++ b/drivers/input/rmi4/rmi_f03.c @@ -23,8 +23,12 @@ #define RMI_F03_BYTES_PER_DEVICE_SHIFT 4 #define RMI_F03_QUEUE_LENGTH 0x0F +#define RMI_F03_RESET_STYK 0xFE + #define PSMOUSE_OOB_EXTRA_BTNS 0x01 +#define RELATIVE_PACKET_SIZE 0x03 + struct f03_data { struct rmi_function *fn; @@ -36,7 +40,8 @@ struct f03_data { u8 device_count; u8 rx_queue_length; }; - +int iwritecommandcounter; +unsigned int ipacketindex; int rmi_f03_overwrite_button(struct rmi_function *fn, unsigned int button, int value) { @@ -87,7 +92,7 @@ static int rmi_f03_pt_write(struct serio *id, unsigned char val) __func__, error); return error; } - + iwritecommandcounter++; return 0; } @@ -197,10 +202,12 @@ static int rmi_f03_register_pt(struct f03_data *f03) static int rmi_f03_probe(struct rmi_function *fn) { + struct device *dev = &fn->dev; struct f03_data *f03; int error; - + iwritecommandcounter = 0; + ipacketindex = 0; f03 = devm_kzalloc(dev, sizeof(struct f03_data), GFP_KERNEL); if (!f03) return -ENOMEM; @@ -251,9 +258,12 @@ static irqreturn_t rmi_f03_attention(int irq, void *ctx) const u8 ob_len = f03->rx_queue_length * RMI_F03_OB_SIZE; u8 obs[RMI_F03_QUEUE_LENGTH * RMI_F03_OB_SIZE]; u8 ob_status; + static u8 ob_dataArry[RELATIVE_PACKET_SIZE]; u8 ob_data; unsigned int serio_flags; + static unsigned int serio_flagsArry[RELATIVE_PACKET_SIZE]; int i; + int error; if (drvdata->attn_data.data) { @@ -284,6 +294,22 @@ static irqreturn_t rmi_f03_attention(int irq, void *ctx) ob_data = obs[i + RMI_F03_OB_DATA_OFFSET]; serio_flags = 0; + if (ob_status & (RMI_F03_OB_FLAG_TIMEOUT | RMI_F03_OB_FLAG_PARITY)) { + // Send resend command to stick when timeout or parity error. + // Driver can receive the last stick packet. + + error = rmi_write(f03->fn->rmi_dev, f03->fn->fd.data_base_addr, + RMI_F03_RESET_STYK); + if (error) { + dev_err(&f03->fn->dev, + "%s: Failed to rmi_write to F03 TX register (%d).\n", + __func__, error); + return error; + } + ipacketindex = 0; + break; + } + if (!(ob_status & RMI_F03_RX_DATA_OFB)) continue; @@ -298,9 +324,57 @@ static irqreturn_t rmi_f03_attention(int irq, void *ctx) serio_flags & SERIO_TIMEOUT ? 'Y' : 'N', serio_flags & SERIO_PARITY ? 'Y' : 'N'); - serio_interrupt(f03->serio, ob_data, serio_flags); + if (iwritecommandcounter > 0) { + // Read Acknowledge Byte after writing the PS2 command. + // It is not trackpoint data. + serio_interrupt(f03->serio, ob_data, serio_flags); + + } else { + // The relative-mode PS/2 packet format is as follows: + // + // bit position position (as array of bytes) + // 7 6 5 4 3 2 1 0 + // =================================+ + // Yov Xov DY8 DX8 1 M R L | DATA[0] + // DX[7:0] | DATA[1] + // DY[7:0] | DATA[2] + // =================================+ + // Yov: Y overflow + // Xov: X overflow + if ((ipacketindex == 0) && (ob_data & ((BIT(7)|BIT(6))))) { + dev_err(&f03->fn->dev, + "%s: X or Y is overflow. (%x)\n", + __func__, ob_data); + break; + } else if ((ipacketindex == 0) && !(ob_data & BIT(3))) { + dev_err(&f03->fn->dev, + "%s: New BIT 3 is not 1 for the first byte\n", + __func__); + } else { + if (ipacketindex >= RELATIVE_PACKET_SIZE) { + ipacketindex = 0; + } else { + ob_dataArry[ipacketindex] = ob_data; + serio_flagsArry[ipacketindex] = serio_flags; + ipacketindex++; + } + if (ipacketindex == RELATIVE_PACKET_SIZE) { + serio_interrupt(f03->serio, ob_dataArry[0], + serio_flagsArry[0]); + serio_interrupt(f03->serio, ob_dataArry[1], + serio_flagsArry[1]); + serio_interrupt(f03->serio, ob_dataArry[2], + serio_flagsArry[2]); + ipacketindex = 0; + } + } + } } + if (iwritecommandcounter > 0) { + ipacketindex = 0; + iwritecommandcounter = iwritecommandcounter - 1; + } return IRQ_HANDLED; }