From patchwork Wed Aug 14 09:37:17 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matteo Delfino X-Patchwork-Id: 2844290 Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 22E59BF546 for ; Wed, 14 Aug 2013 09:37:37 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E577820413 for ; Wed, 14 Aug 2013 09:37:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9C5152040F for ; Wed, 14 Aug 2013 09:37:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751526Ab3HNJhd (ORCPT ); Wed, 14 Aug 2013 05:37:33 -0400 Received: from mail-wg0-f47.google.com ([74.125.82.47]:53589 "EHLO mail-wg0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751399Ab3HNJhd (ORCPT ); Wed, 14 Aug 2013 05:37:33 -0400 Received: by mail-wg0-f47.google.com with SMTP id j13so7493361wgh.14 for ; Wed, 14 Aug 2013 02:37:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=TLodgoVE3+UDhu23HR0WuY1seaVzxMr9CRJ98k28JDU=; b=IiVxx+6dYV3JmxoKwuKc6zofazqV01Hwo4R1e/elNh1GUrcNwZtuNIUkDILDFfklzm OCw5TvY0kGROpZCKlw0Z3NEtczCgvU3w/rSp2h4dp5tPnhsafuBn+d8Ov2W+kQFeFOaz kAURRKFwqmgWJ+zciJtaZYVNU3SYo1ClIHPY44qLGXnKW4gDV8BiyoOKIbWKrHsK8IXh xd70yTxcYOhl2nNc9iQ0srZlpruYNoczh6UQHEbowDfW+FSTicw01v9F5VETOqOfyd51 thLg2tFnaPyLrVnRErI0eIA/lD7VH4qPvOiw2I7/lvBnmUVsaPLz8za1c9g1W2JPSQ42 w6cA== X-Received: by 10.180.86.226 with SMTP id s2mr1325318wiz.7.1376473051700; Wed, 14 Aug 2013 02:37:31 -0700 (PDT) Received: from localhost.localdomain (host48-207-dynamic.0-79-r.retail.telecomitalia.it. [79.0.207.48]) by mx.google.com with ESMTPSA id gg10sm1773836wib.1.2013.08.14.02.37.30 for (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 14 Aug 2013 02:37:31 -0700 (PDT) From: Matteo Delfino To: Dmitry Torokhov Cc: linux-input@vger.kernel.org Subject: [PATCH] Input: elantech - fix packet check for v3 and v4 hardware Date: Wed, 14 Aug 2013 11:37:17 +0200 Message-Id: <1376473037-11211-1-git-send-email-kendatsuba@gmail.com> X-Mailer: git-send-email 1.7.10.4 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The signatures of v3 and v4 packets change depending on the value of a hardware flag called 'crc_enabled'. The packet type detection must change accordingly. This patch also restores a consistency check for v4 packets inadvertently removed by commit: 9eebed7de660c0b5ab129a9de4f89d20b60de68c Input: elantech - fix for newer hardware versions (v7) A note about the naming convention: v3 hardware is associated with IC body v5 while v4 hardware is associated with IC body v6 and v7. The above commit refers to IC body v7, not to v7 hardware. Tested on Samsung NP730U3E (fw = 0x675f05, ICv7, crc_enabled = 1) Tested-by: Giovanni Frigione Signed-off-by: Matteo Delfino --- Hello Dmitry, this patch is based on some information provided by elantech. It has been successfully tested on the above v4 hardware so the information seems to be reliable. More testing is needed on v3 hardware with crc_enabled=1 (if there's such hardware out there..). The behaviour should be unchanged for v3 and v4 hardware with crc_enabled=0 (the vast majority). I was asked to CC stable kernels too since this patch restores a consistency check on v4 packets removed by a previous commit already queued in linux-3.5.y-queue but, considering the above, I think it's best to leave this decision to you. Best regards, Matteo drivers/input/mouse/elantech.c | 44 ++++++++++++++++++++++++++++++++++++---- drivers/input/mouse/elantech.h | 1 + 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 57b2637..8551dca 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -672,6 +672,7 @@ static int elantech_packet_check_v2(struct psmouse *psmouse) */ static int elantech_packet_check_v3(struct psmouse *psmouse) { + struct elantech_data *etd = psmouse->private; const u8 debounce_packet[] = { 0xc4, 0xff, 0xff, 0x02, 0xff, 0xff }; unsigned char *packet = psmouse->packet; @@ -682,19 +683,48 @@ static int elantech_packet_check_v3(struct psmouse *psmouse) if (!memcmp(packet, debounce_packet, sizeof(debounce_packet))) return PACKET_DEBOUNCE; - if ((packet[0] & 0x0c) == 0x04 && (packet[3] & 0xcf) == 0x02) - return PACKET_V3_HEAD; + /* + * If the hardware flag 'crc_enabled' is set the packets have + * different signatures. + */ + if (etd->crc_enabled) { + if ((packet[3] & 0x09) == 0x08) + return PACKET_V3_HEAD; + + if ((packet[3] & 0x09) == 0x09) + return PACKET_V3_TAIL; + } else { + if ((packet[0] & 0x0c) == 0x04 && (packet[3] & 0xcf) == 0x02) + return PACKET_V3_HEAD; - if ((packet[0] & 0x0c) == 0x0c && (packet[3] & 0xce) == 0x0c) - return PACKET_V3_TAIL; + if ((packet[0] & 0x0c) == 0x0c && (packet[3] & 0xce) == 0x0c) + return PACKET_V3_TAIL; + } return PACKET_UNKNOWN; } static int elantech_packet_check_v4(struct psmouse *psmouse) { + struct elantech_data *etd = psmouse->private; unsigned char *packet = psmouse->packet; unsigned char packet_type = packet[3] & 0x03; + bool sanity_check; + + /* + * Sanity check based on the constant bits of a packet. + * The constant bits change depending on the value of + * the hardware flag 'crc_enabled' but are the same for + * every packet, regardless of the type. + */ + if (etd->crc_enabled) + sanity_check = ((packet[3] & 0x08) == 0x00); + else + sanity_check = ((packet[0] & 0x0c) == 0x04 && + (packet[3] & 0x1c) == 0x10); + + if (!sanity_check) + return PACKET_UNKNOWN; switch (packet_type) { case 0: @@ -1313,6 +1343,12 @@ static int elantech_set_properties(struct elantech_data *etd) etd->reports_pressure = true; } + /* + * The signatures of v3 and v4 packets change depending on the + * value of this hardware flag. + */ + etd->crc_enabled = ((etd->fw_version & 0x4000) == 0x4000); + return 0; } diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h index 46db3be..036a04a 100644 --- a/drivers/input/mouse/elantech.h +++ b/drivers/input/mouse/elantech.h @@ -129,6 +129,7 @@ struct elantech_data { bool paritycheck; bool jumpy_cursor; bool reports_pressure; + bool crc_enabled; unsigned char hw_version; unsigned int fw_version; unsigned int single_finger_reports;