From patchwork Tue Oct 29 07:19:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wang, Jiada" X-Patchwork-Id: 11217385 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 470CD1390 for ; Tue, 29 Oct 2019 07:22:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 24AE92086A for ; Tue, 29 Oct 2019 07:22:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733073AbfJ2HWX (ORCPT ); Tue, 29 Oct 2019 03:22:23 -0400 Received: from esa1.mentor.iphmx.com ([68.232.129.153]:7825 "EHLO esa1.mentor.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1733055AbfJ2HWV (ORCPT ); Tue, 29 Oct 2019 03:22:21 -0400 IronPort-SDR: A3NZwHfZCu7rvpi5uvCH1VoWojyGPTs1/hpDGf+/GbjD9APXgsPTyXcL01l4RAdH7cO+Q8FIY8 48RcLrz5BEaPQsXVcOL6mzRWhzKvLja27x6bpKMzyIIN+ebKStDdD1sth+IjtoJR3JcFJu7aPn Fp2TxhPZNnKPbp3CVEjAF1DDnbTbJjInEOq7VtRU8U1lfufzpHfdvqcZtp5kUdcYkGVBuTgQ28 K12Zt0fb+PaPK0AecOG13St8PPGD60yss3/p84JNkNvrndz2lIZ2VCNZvpPAbPM8GlR9C+hOu5 g4o= X-IronPort-AV: E=Sophos;i="5.68,243,1569312000"; d="scan'208";a="44509430" Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa1.mentor.iphmx.com with ESMTP; 28 Oct 2019 23:22:21 -0800 IronPort-SDR: ra4HRK96oXIGb07wRictRV5lMpzgVzUNAQrTCNABtznTYSSZWwvXKEQUzhibU5f5icGu65KUDm bWlDA6na5kl6QEPB6mS0oUO7q4oSlvXWej8+UmoHJG4e+YyBoU+4e6Oj0Zy2MYgaNb3vJcIjc5 WQrIsENmA+NMkfseFoPdEeog+kYDuuFfrTDb9rP6tzX/kBjMXTb0fLWaTNhRiP9+2msLFuOdA8 10FUR2ytIP79h+w+kStR5xGxvfystWiAHraVMS0heIglqe/tNVjOEohR8RVg1vgMIedBVLpjZU fRs= From: Jiada Wang To: , , , CC: , , , , Subject: [PATCH v4 35/48] Input: atmel_mxt_ts: Add support for run self-test routine. Date: Tue, 29 Oct 2019 16:19:57 +0900 Message-ID: <20191029072010.8492-36-jiada_wang@mentor.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191029072010.8492-1-jiada_wang@mentor.com> References: <20191029072010.8492-1-jiada_wang@mentor.com> MIME-Version: 1.0 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org From: Nikhil Ravindran The self test object T25 runs self test routines in device to find faults Sysfs entry add to start self test routine and read back the test results for atmel touchcontrollers.The feature will be used for A-IVI and CAF projects. Signed-off-by: Nikhil Ravindran Signed-off-by: George G. Davis Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 111 +++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index f8c273bd1429..c5192f71a4fa 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -336,6 +336,9 @@ struct mxt_data { u8 t100_aux_ampl; u8 t100_aux_area; u8 t100_aux_vect; + u16 T25_address; + u8 T25_reportid; + u8 t25_msg[6]; bool debug_enabled; bool debug_v2_enabled; u8 *debug_msg_data; @@ -413,6 +416,8 @@ struct mxt_data { /* Indicates whether device is updating configuration */ bool updating_config; + + bool t25_status; }; struct mxt_vb2_buffer { @@ -1359,6 +1364,24 @@ static void mxt_proc_t93_messages(struct mxt_data *data, u8 *msg) dev_debug(dev, "T93 report double tap %d\n", status); } +static void mxt_proc_t25_messages(struct mxt_data *data, u8 *msg) +{ + struct device *dev = &data->client->dev; + + /* Output debug if status has changed */ + dev_dbg(dev, "T25 Status 0x%x Info: %x %x %x %x %x\n", + msg[1], + msg[2], + msg[3], + msg[4], + msg[5], + msg[6]); + + /* Save current status */ + memcpy(&data->t25_msg[0], &msg[1], sizeof(data->t25_msg)); + data->t25_status = false; +} + static int mxt_proc_message(struct mxt_data *data, u8 *message) { u8 report_id = message[0]; @@ -1389,6 +1412,8 @@ static int mxt_proc_message(struct mxt_data *data, u8 *message) } else if (report_id == data->T19_reportid) { mxt_input_button(data, message); data->update_input = true; + } else if (report_id == data->T25_reportid) { + mxt_proc_t25_messages(data, message); } else if (report_id >= data->T15_reportid_min && report_id <= data->T15_reportid_max) { mxt_proc_t15_messages(data, message); @@ -1613,6 +1638,84 @@ static int mxt_t6_command(struct mxt_data *data, u16 cmd_offset, return 0; } +static int mxt_t25_command(struct mxt_data *data, u8 cmd, bool wait) +{ + u16 reg; + int timeout_counter = 0; + int ret; + u8 val[2]; + + reg = data->T25_address; + val[0] = 0x3; + val[1] = cmd; + + data->t25_status = true; + ret = __mxt_write_reg(data->client, reg, sizeof(val), val); + if (ret) { + data->t25_status = false; + return ret; + } + + if (!wait) + return 0; + + do { + msleep(MXT_WAKEUP_TIME); + ret = __mxt_read_reg(data->client, reg + 1, 1, &val[1]); + if (ret) + return ret; + } while ((val[1] != 0) && (timeout_counter++ <= 100)); + + if (timeout_counter > 100) { + dev_err(&data->client->dev, "Command failed!\n"); + data->t25_status = false; + return -EIO; + } + return 0; +} + +/* Firmware Version is returned as Major.Minor.Build */ +static ssize_t mxt_t25_selftest_show(struct device *dev, struct + device_attribute *attr, char *buf) +{ + struct mxt_data *data = dev_get_drvdata(dev); + ssize_t offset = 0; + + if (data->t25_status) + return -EAGAIN; + + if (data->t25_msg[0] == 0xFE) + offset += scnprintf(buf, PAGE_SIZE, "PASS\n"); + else + offset += scnprintf(buf, PAGE_SIZE, "FAILED\n"); + + offset += scnprintf(buf + offset, PAGE_SIZE, "%x %x %x %x %x %x\n", + data->t25_msg[0], + data->t25_msg[1], + data->t25_msg[2], + data->t25_msg[3], + data->t25_msg[4], + data->t25_msg[5]); + return offset; +} + +static ssize_t mxt_t25_selftest_store(struct device *dev, struct + device_attribute *attr, const char *buf, + size_t count) +{ + struct mxt_data *data = dev_get_drvdata(dev); + u32 cmd; + + if (sscanf(buf, "%x", &cmd) == 1) { + if (mxt_t25_command(data, (u8)cmd, 1) == 0) + return count; + + dev_dbg(dev, "mxt_t25_cmd_store write cmd %x error\n", cmd); + return -EINVAL; + } + return 0; +} + static int mxt_acquire_irq(struct mxt_data *data) { int error; @@ -2091,6 +2194,8 @@ static void mxt_free_object_table(struct mxt_data *data) data->T15_reportid_max = 0; data->T18_address = 0; data->T19_reportid = 0; + data->T25_address = 0; + data->T25_reportid = 0; data->T42_reportid_min = 0; data->T42_reportid_max = 0; data->T44_address = 0; @@ -2178,6 +2283,10 @@ static int mxt_parse_object_table(struct mxt_data *data, case MXT_SPT_COMMSCONFIG_T18: data->T18_address = object->start_address; break; + case MXT_SPT_SELFTEST_T25: + data->T25_address = object->start_address; + data->T25_reportid = min_id; + break; case MXT_PROCI_TOUCHSUPPRESSION_T42: data->T42_reportid_min = min_id; data->T42_reportid_max = max_id; @@ -3764,6 +3873,7 @@ static DEVICE_ATTR(debug_enable, S_IWUSR | S_IRUSR, mxt_debug_enable_show, static DEVICE_ATTR(debug_v2_enable, S_IWUSR | S_IRUSR, NULL, mxt_debug_v2_enable_store); static DEVICE_ATTR(debug_notify, S_IRUGO, mxt_debug_notify_show, NULL); +static DEVICE_ATTR(t25, 0600, mxt_t25_selftest_show, mxt_t25_selftest_store); static struct attribute *mxt_attrs[] = { &dev_attr_fw_version.attr, @@ -3774,6 +3884,7 @@ static struct attribute *mxt_attrs[] = { &dev_attr_debug_enable.attr, &dev_attr_debug_v2_enable.attr, &dev_attr_debug_notify.attr, + &dev_attr_t25.attr, NULL };