From patchwork Tue Aug 13 15:35:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bruno Thomsen X-Patchwork-Id: 1146414 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-rtc-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="B5DYkpsc"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 467Gyr35S9z9sN1 for ; Wed, 14 Aug 2019 01:36:20 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726637AbfHMPgS (ORCPT ); Tue, 13 Aug 2019 11:36:18 -0400 Received: from mail-wr1-f67.google.com ([209.85.221.67]:38938 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726086AbfHMPgS (ORCPT ); Tue, 13 Aug 2019 11:36:18 -0400 Received: by mail-wr1-f67.google.com with SMTP id t16so18048757wra.6; Tue, 13 Aug 2019 08:36:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=3NjKQ6bH7M7yJLbzjNkN2jx2rsf9cC0ZyK9exN5M9fc=; b=B5DYkpscXQ+An0BUridFKo+Ww8pwrfetP9wB6FvcuEnF0lWBrcVCMjapkrfcMhrQzh AGMpBJ+EYQqC5kkgDzhuXPNLb7nM7xmJUk1b2/S72DBKLPwj2FG8MxibuckmaVnOBNE8 3HglQbzBAtUOFAX1qYavqkeqSDDSriHbu3BGFFeUmRaCWIJV6KhlE+lAu1uhI0FzT0gY lak51C1fN5Z4iF5N10UoWOQc1doApL3KmwQI3FdAZclafD8XLfPdSqbY3XQQxFsNms7E O/RSVjyZRbO3i0Unn8yiiCHI1Wk+YXR2lmoqcVdhXFBRdMV/OhYatwtxDMHs0LILNBvH xjcA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=3NjKQ6bH7M7yJLbzjNkN2jx2rsf9cC0ZyK9exN5M9fc=; b=UyKt9IjGVExazbfvavoyAQnchny3jqYhR1aq/6W6IEc4tM/z1bo9ZrtYE+mwq2Dpjv 8c+xOaexQOSsOoefxYkoYvr5ZrLqLUaiaZvEI0xTS1FwDzkgoO0VFaLXEh609U8qrvjX vL2QULtTgp4h82NE2g4SNec2q+QAfPDF+RwbDZoLFTGVQmQK5PfT2tUzAGecjyr0qG/P CnofJGljxoNfVTt+CgDezHqDuHU692CogsqzR5rAYM7RwMCLhLt8AU+NxKJ8+vMG4+DE S2eTK+HtmT5QSiu7FhOlwO2sXh0HzV8mR2i2TFFlhFnTZ6lj3/LeGDggTMurK0B4fE8w 2QtQ== X-Gm-Message-State: APjAAAXPii/aDBxJEUgjoo04M+bsicsJqQ1JHJCxhynYhyTcLj3ExewO TUVAfhBlZpfgigIZUS73JySSK2upE1OiAA== X-Google-Smtp-Source: APXvYqymKR1IAdIWFCEFj6HBkPYK9BDaxjsH0Xm2qhL1hEQycFFFwqfSpxYYyYRpPndXwqNSwPGgQA== X-Received: by 2002:a5d:604d:: with SMTP id j13mr32026234wrt.244.1565710576306; Tue, 13 Aug 2019 08:36:16 -0700 (PDT) Received: from localhost.localdomain (3e6b1cc1.rev.stofanet.dk. [62.107.28.193]) by smtp.googlemail.com with ESMTPSA id j16sm64744819wrp.62.2019.08.13.08.36.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Aug 2019 08:36:15 -0700 (PDT) From: Bruno Thomsen To: linux-rtc@vger.kernel.org, linux-watchdog@vger.kernel.org Cc: alexandre.belloni@bootlin.com, a.zummo@towertech.it, wim@linux-watchdog.org, linux@roeck-us.net, u.kleine-koenig@pengutronix.de, sean.nyekjaer@prevas.dk, bth@kamstrup.com, bruno.thomsen@gmail.com Subject: [PATCH v2 1/5] rtc: pcf2127: convert to devm_rtc_allocate_device Date: Tue, 13 Aug 2019 17:35:56 +0200 Message-Id: <20190813153600.12406-2-bruno.thomsen@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190813153600.12406-1-bruno.thomsen@gmail.com> References: <20190813153600.12406-1-bruno.thomsen@gmail.com> MIME-Version: 1.0 Sender: linux-rtc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rtc@vger.kernel.org This allows further improvement of the driver. Signed-off-by: Bruno Thomsen --- drivers/rtc/rtc-pcf2127.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index 8632f58fed43..58eb96506e4b 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -237,11 +237,12 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap, dev_set_drvdata(dev, pcf2127); - pcf2127->rtc = devm_rtc_device_register(dev, name, &pcf2127_rtc_ops, - THIS_MODULE); + pcf2127->rtc = devm_rtc_allocate_device(dev); if (IS_ERR(pcf2127->rtc)) return PTR_ERR(pcf2127->rtc); + pcf2127->rtc->ops = &pcf2127_rtc_ops; + if (has_nvmem) { struct nvmem_config nvmem_cfg = { .priv = pcf2127, @@ -253,7 +254,7 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap, ret = rtc_nvmem_register(pcf2127->rtc, &nvmem_cfg); } - return ret; + return rtc_register_device(pcf2127->rtc); } #ifdef CONFIG_OF From patchwork Tue Aug 13 15:35:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bruno Thomsen X-Patchwork-Id: 1146415 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-rtc-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="h48NKyr3"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 467Gys3KvGz9sND for ; Wed, 14 Aug 2019 01:36:21 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729175AbfHMPgV (ORCPT ); Tue, 13 Aug 2019 11:36:21 -0400 Received: from mail-wm1-f65.google.com ([209.85.128.65]:38112 "EHLO mail-wm1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726086AbfHMPgV (ORCPT ); Tue, 13 Aug 2019 11:36:21 -0400 Received: by mail-wm1-f65.google.com with SMTP id m125so1847255wmm.3; Tue, 13 Aug 2019 08:36:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=1yJ4ftAjCov31C2AvIIal4auvs/ATcW3oCboKgN7svY=; b=h48NKyr3OtkI0cZqjtqor4Rsov5DNwovosH2Czaj/Z1GlqjKUTyxvsaaj1WBkr6B4x 7YCs3yi1xn9riGZK4IffSRcqz3Kyr1ubm85w3SttuQ9EHHJtRYG1CTgvCVZVzeRHRLJN ih47K0pVVz5Gei+1rf7UQwrS4sN5idj85VNMPIAmNpAWmK0fP2FS3+rz5bA2ZYLsEYas xWwYexoZ9MMqal9t6weIcq5SGNjTFgnptgkXuy9HhOkpyij4Td3anazsjp+mHmRBqL51 D74NcfEp+TfoGOb8vryMNSBtUa+mVN053vIrjjhOC8XopFvs9me2kjvQs+D5gRmITalO LRrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=1yJ4ftAjCov31C2AvIIal4auvs/ATcW3oCboKgN7svY=; b=d+ygAvL0/NNVXQZz1r+6ahDAkc6C0BccnO2VX1VB2bKEQ26CGH/LWv1F9ynvSd+bmz C6BiTWcJSKix9gcBuHrZ9JMBqGgGczcOKZH2d6vbYUOTn5phHm0eb4bwYuG3G9oNShlW hvOiptbl4nx8rz7TxbkvA45JEPSsHReX7iVvBjupbo6kLAypBTMhGiqojfQleWTGp6u+ 7a6Ho2QMJ0EjdS3igjSh0QD79k1Upw9WwY68Z8imlCw51G8RjMM1mkTcd2gLF5NGC4BI 1PqBvPtfvxyEKRDjPrX3G3WpkLtiZUePIFpZ4Bc46miMbi9JW5/FJPlrMOqIbZHye9/j XGDw== X-Gm-Message-State: APjAAAW19/oMT51w4PiIA35/ix0Vq2yNGg7/SzJ6kHnyJNFOKO+xTuRD uh1XZhS5lm7qKbNcfUMXBLMAdwryomG/Lw== X-Google-Smtp-Source: APXvYqyjp9RWWkDCnvs8FkHAQKTNt1lH1twQodclh8Evns3iBpSeybw4/C3Z9S1Amr7S5N1YbiAXNg== X-Received: by 2002:a1c:7611:: with SMTP id r17mr3763035wmc.117.1565710577912; Tue, 13 Aug 2019 08:36:17 -0700 (PDT) Received: from localhost.localdomain (3e6b1cc1.rev.stofanet.dk. [62.107.28.193]) by smtp.googlemail.com with ESMTPSA id j16sm64744819wrp.62.2019.08.13.08.36.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Aug 2019 08:36:17 -0700 (PDT) From: Bruno Thomsen To: linux-rtc@vger.kernel.org, linux-watchdog@vger.kernel.org Cc: alexandre.belloni@bootlin.com, a.zummo@towertech.it, wim@linux-watchdog.org, linux@roeck-us.net, u.kleine-koenig@pengutronix.de, sean.nyekjaer@prevas.dk, bth@kamstrup.com, bruno.thomsen@gmail.com Subject: [PATCH v2 2/5] rtc: pcf2127: cleanup register and bit defines Date: Tue, 13 Aug 2019 17:35:57 +0200 Message-Id: <20190813153600.12406-3-bruno.thomsen@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190813153600.12406-1-bruno.thomsen@gmail.com> References: <20190813153600.12406-1-bruno.thomsen@gmail.com> MIME-Version: 1.0 Sender: linux-rtc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rtc@vger.kernel.org Cleanup of defines to follow kernel coding style and increase code readability by using same register and bit define style. Change PCF2127_REG_RAM_{addr_MSB,wrt_cmd,rd_cmd} to upper case as kernel coding guide section 12 'Macros, Enums and RTL' states "Names of macros defining constants and labels in enums are capitalized". Improve readability of RAM register comment by making whole sentences. Remove parentheses from register defines as they are only used for expressions and not constants. As there are no clear style for name of registers and bits in the kernel drivers, I suggest the following for at least this driver, but hopefully also other RTC drivers. Register name should follow this convention: [chip]_REG_[reg name] 0xXX Bit name should follow this convention, so it clearly states which chip register it's part of: [chip]_BIT_[reg name]_[bit name] BIT(X) Additionally I suggest bit defines are always placed right below its corresponding register define and using an extra tab indentation for the BIT(X) part. This will visualt make it easy to see that bit defines are part of the complete register definition. Rename PCF2127_OSF to PCF2127_BIT_SC_OSF and move it right below PCF2127_REG_SC. This will improve readability of bit checks as it's easy to verify that it uses the correct register. Move end of line comments above register defines as it's more like a heading for 1 register define and up to 8 bit defines or a collection of registers that are close related like timestamp split across 6 registers. Signed-off-by: Bruno Thomsen --- drivers/rtc/rtc-pcf2127.c | 59 ++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index 58eb96506e4b..cd8def79b379 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -19,26 +19,32 @@ #include #include -#define PCF2127_REG_CTRL1 (0x00) /* Control Register 1 */ -#define PCF2127_REG_CTRL2 (0x01) /* Control Register 2 */ - -#define PCF2127_REG_CTRL3 (0x02) /* Control Register 3 */ -#define PCF2127_REG_CTRL3_BLF BIT(2) - -#define PCF2127_REG_SC (0x03) /* datetime */ -#define PCF2127_REG_MN (0x04) -#define PCF2127_REG_HR (0x05) -#define PCF2127_REG_DM (0x06) -#define PCF2127_REG_DW (0x07) -#define PCF2127_REG_MO (0x08) -#define PCF2127_REG_YR (0x09) - -/* the pcf2127 has 512 bytes nvmem, pcf2129 doesn't */ -#define PCF2127_REG_RAM_addr_MSB 0x1a -#define PCF2127_REG_RAM_wrt_cmd 0x1c -#define PCF2127_REG_RAM_rd_cmd 0x1d +/* Control register 1 */ +#define PCF2127_REG_CTRL1 0x00 +/* Control register 2 */ +#define PCF2127_REG_CTRL2 0x01 +/* Control register 3 */ +#define PCF2127_REG_CTRL3 0x02 +#define PCF2127_BIT_CTRL3_BLF BIT(2) +/* Time and date registers */ +#define PCF2127_REG_SC 0x03 +#define PCF2127_BIT_SC_OSF BIT(7) +#define PCF2127_REG_MN 0x04 +#define PCF2127_REG_HR 0x05 +#define PCF2127_REG_DM 0x06 +#define PCF2127_REG_DW 0x07 +#define PCF2127_REG_MO 0x08 +#define PCF2127_REG_YR 0x09 +/* + * RAM registers + * PCF2127 has 512 bytes general-purpose static RAM (SRAM) that is + * battery backed and can survive a power outage. + * PCF2129 doesn't have this feature. + */ +#define PCF2127_REG_RAM_ADDR_MSB 0x1A +#define PCF2127_REG_RAM_WRT_CMD 0x1C +#define PCF2127_REG_RAM_RD_CMD 0x1D -#define PCF2127_OSF BIT(7) /* Oscillator Fail flag */ struct pcf2127 { struct rtc_device *rtc; @@ -73,11 +79,12 @@ static int pcf2127_rtc_read_time(struct device *dev, struct rtc_time *tm) return ret; } - if (buf[PCF2127_REG_CTRL3] & PCF2127_REG_CTRL3_BLF) + if (buf[PCF2127_REG_CTRL3] & PCF2127_BIT_CTRL3_BLF) dev_info(dev, "low voltage detected, check/replace RTC battery.\n"); - if (buf[PCF2127_REG_SC] & PCF2127_OSF) { + /* Clock integrity is not guaranteed when OSF flag is set. */ + if (buf[PCF2127_REG_SC] & PCF2127_BIT_SC_OSF) { /* * no need clear the flag here, * it will be cleared once the new date is saved @@ -166,7 +173,7 @@ static int pcf2127_rtc_ioctl(struct device *dev, if (ret) return ret; - touser = touser & PCF2127_REG_CTRL3_BLF ? 1 : 0; + touser = touser & PCF2127_BIT_CTRL3_BLF ? 1 : 0; if (copy_to_user((void __user *)arg, &touser, sizeof(int))) return -EFAULT; @@ -192,12 +199,12 @@ static int pcf2127_nvmem_read(void *priv, unsigned int offset, int ret; unsigned char offsetbuf[] = { offset >> 8, offset }; - ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_addr_MSB, + ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_ADDR_MSB, offsetbuf, 2); if (ret) return ret; - ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_RAM_rd_cmd, + ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_RAM_RD_CMD, val, bytes); return ret ?: bytes; @@ -210,12 +217,12 @@ static int pcf2127_nvmem_write(void *priv, unsigned int offset, int ret; unsigned char offsetbuf[] = { offset >> 8, offset }; - ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_addr_MSB, + ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_ADDR_MSB, offsetbuf, 2); if (ret) return ret; - ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_wrt_cmd, + ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_WRT_CMD, val, bytes); return ret ?: bytes; From patchwork Tue Aug 13 15:35:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bruno Thomsen X-Patchwork-Id: 1146416 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-rtc-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="c2l2CXJx"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 467Gyt3Q1Gz9sN1 for ; Wed, 14 Aug 2019 01:36:22 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729182AbfHMPgW (ORCPT ); Tue, 13 Aug 2019 11:36:22 -0400 Received: from mail-wm1-f66.google.com ([209.85.128.66]:53753 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728526AbfHMPgW (ORCPT ); Tue, 13 Aug 2019 11:36:22 -0400 Received: by mail-wm1-f66.google.com with SMTP id 10so1931004wmp.3; Tue, 13 Aug 2019 08:36:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=PfJght1t4wRVtt6zBPMGaeEsIVMsuY2LkXUxfSL3G0c=; b=c2l2CXJx0VRZ5Li/09osRG8P/CznNctd5JvvKoPk/OsA/x3NQh+itIuEGx+Byk+ov0 9M24Kd0ch9J2EaO3qva1lbft4eSn3z2cfHg/bKjTHt2A4tuMaI7uZ/SZpISr0PLlY3sD S8nVBg8alAzfh7yvXd5fWyWFcyjLdR48T+RVoh3LVJuFfifTFbYrBbNbxO5f3N0oCd9I 1rwJZAnpr8AIvd+Ss8tej+uJu6TFHdlK/qhTU+Pbr8mOLfY2pzVzpXwgXUdCLdGFZSFx TVMMSSkNPmeJAPA215BvJjLa7aZOlAd33RuezVQ+sHjx1Hs6U4bURLgiOUMzDez2OfY+ sZQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=PfJght1t4wRVtt6zBPMGaeEsIVMsuY2LkXUxfSL3G0c=; b=JkjKGDxfiKycS88WqnM1YoKbefgsM8r50oaMFt6R6Kg4d/pJH9Y+4zvgfhg4H8/ufb 2aW7ikjek4eI5Vsi9BWH75O6ifvOx1HDiMSZAooJPUlqu9NmJGUsvW7bMbk4Q+85mLdb LxKH1FXkli6FA4UQdANcYjehQ8AvUipmlOgH89ErFkfxWglS4BFFnIuitwAi7zNIhRXl aDYlXbdp5UxOQCq/hIdp3pS2B2GG9EfRjLZLDoYzXxdp56Hrb5WjUqEGuW96eXr9MLkp PejTDY6p/Ye7lCKbb7fvBb8y3cyJfzqXONzO4Ezvk6PrqDgGy4bKIuWKFXzhrgp3fSTB MsvQ== X-Gm-Message-State: APjAAAVnd94CcnAJEG/uT/8adMZtwFYh6d7wkobrN9qYs0URfdOkmaax AdZfcWVQo2bmQk+pmC6vyqWweO9UzIZHKQ== X-Google-Smtp-Source: APXvYqztG8XbO0ESbaQQ7+RG0vdTywVCBLvg6lD+682s5M2Sb+99CH+k9z2nGWrHEq/K7n6r4E9z6g== X-Received: by 2002:a7b:c310:: with SMTP id k16mr3601397wmj.133.1565710578968; Tue, 13 Aug 2019 08:36:18 -0700 (PDT) Received: from localhost.localdomain (3e6b1cc1.rev.stofanet.dk. [62.107.28.193]) by smtp.googlemail.com with ESMTPSA id j16sm64744819wrp.62.2019.08.13.08.36.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Aug 2019 08:36:18 -0700 (PDT) From: Bruno Thomsen To: linux-rtc@vger.kernel.org, linux-watchdog@vger.kernel.org Cc: alexandre.belloni@bootlin.com, a.zummo@towertech.it, wim@linux-watchdog.org, linux@roeck-us.net, u.kleine-koenig@pengutronix.de, sean.nyekjaer@prevas.dk, bth@kamstrup.com, bruno.thomsen@gmail.com Subject: [PATCH v2 3/5] rtc: pcf2127: bugfix: read rtc disables watchdog Date: Tue, 13 Aug 2019 17:35:58 +0200 Message-Id: <20190813153600.12406-4-bruno.thomsen@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190813153600.12406-1-bruno.thomsen@gmail.com> References: <20190813153600.12406-1-bruno.thomsen@gmail.com> MIME-Version: 1.0 Sender: linux-rtc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rtc@vger.kernel.org The previous fix listed bulk read of registers as root cause of accendential disabling of watchdog, since the watchdog counter register (WD_VAL) was zeroed. Fixes: 3769a375ab83 rtc: pcf2127: bulk read only date and time registers. Tested with the same PCF2127 chip as Sean reveled root cause of WD_VAL register value zeroing was caused by reading CTRL2 register which is one of the watchdog feature control registers. So the solution is to not read the first two control registers (CTRL1 and CTRL2) in pcf2127_rtc_read_time as they are not needed anyway. Size of local buf variable is kept to allow easy usage of register defines to improve readability of code. Debug trace line was updated after CTRL1 and CTRL2 are no longer read from the chip. Also replaced magic numbers in buf access with register defines. Signed-off-by: Bruno Thomsen --- drivers/rtc/rtc-pcf2127.c | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index cd8def79b379..ee4921e4a47c 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -60,20 +60,14 @@ static int pcf2127_rtc_read_time(struct device *dev, struct rtc_time *tm) struct pcf2127 *pcf2127 = dev_get_drvdata(dev); unsigned char buf[10]; int ret; - int i; - for (i = 0; i <= PCF2127_REG_CTRL3; i++) { - ret = regmap_read(pcf2127->regmap, PCF2127_REG_CTRL1 + i, - (unsigned int *)(buf + i)); - if (ret) { - dev_err(dev, "%s: read error\n", __func__); - return ret; - } - } - - ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_SC, - (buf + PCF2127_REG_SC), - ARRAY_SIZE(buf) - PCF2127_REG_SC); + /* + * Avoid reading CTRL2 register as it causes WD_VAL register + * value to reset to 0 which means watchdog is stopped. + */ + ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_CTRL3, + (buf + PCF2127_REG_CTRL3), + ARRAY_SIZE(buf) - PCF2127_REG_CTRL3); if (ret) { dev_err(dev, "%s: read error\n", __func__); return ret; @@ -95,14 +89,12 @@ static int pcf2127_rtc_read_time(struct device *dev, struct rtc_time *tm) } dev_dbg(dev, - "%s: raw data is cr1=%02x, cr2=%02x, cr3=%02x, " - "sec=%02x, min=%02x, hr=%02x, " + "%s: raw data is cr3=%02x, sec=%02x, min=%02x, hr=%02x, " "mday=%02x, wday=%02x, mon=%02x, year=%02x\n", - __func__, - buf[0], buf[1], buf[2], - buf[3], buf[4], buf[5], - buf[6], buf[7], buf[8], buf[9]); - + __func__, buf[PCF2127_REG_CTRL3], buf[PCF2127_REG_SC], + buf[PCF2127_REG_MN], buf[PCF2127_REG_HR], + buf[PCF2127_REG_DM], buf[PCF2127_REG_DW], + buf[PCF2127_REG_MO], buf[PCF2127_REG_YR]); tm->tm_sec = bcd2bin(buf[PCF2127_REG_SC] & 0x7F); tm->tm_min = bcd2bin(buf[PCF2127_REG_MN] & 0x7F); From patchwork Tue Aug 13 15:35:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bruno Thomsen X-Patchwork-Id: 1146417 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-rtc-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Of9NqMW+"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 467Gyw1p11z9sN1 for ; Wed, 14 Aug 2019 01:36:24 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728526AbfHMPgY (ORCPT ); Tue, 13 Aug 2019 11:36:24 -0400 Received: from mail-wr1-f66.google.com ([209.85.221.66]:32944 "EHLO mail-wr1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729154AbfHMPgX (ORCPT ); Tue, 13 Aug 2019 11:36:23 -0400 Received: by mail-wr1-f66.google.com with SMTP id n9so108285558wru.0; Tue, 13 Aug 2019 08:36:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=rVE9oHutogN6ejoLoys/sfwB1R/4ybXWMhaAGVTGT4Y=; b=Of9NqMW+v9I7qsij6dbM1LW69CyVABHyd2GmLOxuY5NZPjXe53mPrsUEr5gIAgBvDe zqa9MspJkRlwlUWatzYU0KOp4yrkBZpg7eFPIAk+QXiO/iWXFyTt10GPOAUoV+W75iJP lb8PiA+HyUNg+z1GomnnzL7mo7LuvGqDNL92qFq7WsqzefWy1EfDWBMq0WyPLofGbx8y TPgheXZuXHFIPvX8uZfvBXmxXMwt+tT/ktk4JPqoz1eDGCqmulGqSrlMtJGN9VVY0EOV bbBFZCtYHwPZstirJ78ngrfSUZ+iJg/GaLJp+D0xFvRch7H/dq449Ww0rbH6sNtDM45q JVyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=rVE9oHutogN6ejoLoys/sfwB1R/4ybXWMhaAGVTGT4Y=; b=os3MfVTYHW50OlDnsw0lILFEDjoFbkCb79iyF0GjgK5Uk9tQLq06/ZfrRSyvpu5NIT ErzAlal8fvk9nUSBaNn2afNnp9uIwQOGuQkdqBawMC0FUNE5AZo7JCuE0SCkxYoZxn0y 4vS8U1NgaFgzK6cNj9yKgy/7djlzdqIl8scNe8uhNDgLul2jH4s5FYNJSsQZ/YapuVC9 8Kbv87o7SSd97j7BQ37cGkWupXtSW5/+nCFXtfvooKcUWz1AJKBFQR7ZGrtDpNj0flS8 UamYLxczxKLbnocYd8OMT3quHR+jiE1SausB4awIBfNXEoI0VclW2SQL/KxAkKnW7eUA OH5Q== X-Gm-Message-State: APjAAAUIBoTLvCd4HordOHJ8C3BH9HZe3hVKGUn6w9238QLjoxXZLyQk lyuwzrMTIexphgxrzGv1xJCP0o6NCUPn8g== X-Google-Smtp-Source: APXvYqz+8q6OSu4KtGFmtL6zJL2oTfd1Q6qVFMGsU0hYqeG+ip8dqJw65YeZCzRIxEVHma8VlovG9g== X-Received: by 2002:adf:c70e:: with SMTP id k14mr49290454wrg.201.1565710580179; Tue, 13 Aug 2019 08:36:20 -0700 (PDT) Received: from localhost.localdomain (3e6b1cc1.rev.stofanet.dk. [62.107.28.193]) by smtp.googlemail.com with ESMTPSA id j16sm64744819wrp.62.2019.08.13.08.36.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Aug 2019 08:36:19 -0700 (PDT) From: Bruno Thomsen To: linux-rtc@vger.kernel.org, linux-watchdog@vger.kernel.org Cc: alexandre.belloni@bootlin.com, a.zummo@towertech.it, wim@linux-watchdog.org, linux@roeck-us.net, u.kleine-koenig@pengutronix.de, sean.nyekjaer@prevas.dk, bth@kamstrup.com, bruno.thomsen@gmail.com Subject: [PATCH v2 4/5] rtc: pcf2127: add watchdog feature support Date: Tue, 13 Aug 2019 17:35:59 +0200 Message-Id: <20190813153600.12406-5-bruno.thomsen@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190813153600.12406-1-bruno.thomsen@gmail.com> References: <20190813153600.12406-1-bruno.thomsen@gmail.com> MIME-Version: 1.0 Sender: linux-rtc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rtc@vger.kernel.org Add partial support for the watchdog functionality of both PCF2127 and PCF2129 chips. The programmable watchdog timer is currently using a fixed clock source of 1Hz. This result in a selectable range of 1-255 seconds, which covers most embedded Linux use-cases. Clock sources of 4096Hz, 64Hz and 1/60Hz is mostly useful in MCU use-cases. Countdown timer not available when using watchdog feature. Signed-off-by: Bruno Thomsen --- drivers/rtc/Kconfig | 7 ++- drivers/rtc/rtc-pcf2127.c | 127 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+), 1 deletion(-) diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index e72f65b61176..a3bb58a08879 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -876,7 +876,12 @@ config RTC_DRV_PCF2127 depends on RTC_I2C_AND_SPI help If you say yes here you get support for the NXP PCF2127/29 RTC - chips. + chips with integrated quartz crystal for industrial applications. + Both chips also have watchdog timer and tamper switch detection + features. + + PCF2127 has an additional feature of 512 bytes battery backed + memory that's accessible using nvmem interface. This driver can also be built as a module. If so, the module will be called rtc-pcf2127. diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index ee4921e4a47c..700db7dd3eef 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -5,6 +5,9 @@ * * Author: Renaud Cerrato * + * Watchdog and tamper functions + * Author: Bruno Thomsen + * * based on the other drivers in this same directory. * * Datasheet: http://cache.nxp.com/documents/data_sheet/PCF2127.pdf @@ -18,6 +21,7 @@ #include #include #include +#include /* Control register 1 */ #define PCF2127_REG_CTRL1 0x00 @@ -35,6 +39,13 @@ #define PCF2127_REG_DW 0x07 #define PCF2127_REG_MO 0x08 #define PCF2127_REG_YR 0x09 +/* Watchdog registers */ +#define PCF2127_REG_WD_CTL 0x10 +#define PCF2127_BIT_WD_CTL_TF0 BIT(0) +#define PCF2127_BIT_WD_CTL_TF1 BIT(1) +#define PCF2127_BIT_WD_CTL_CD0 BIT(6) +#define PCF2127_BIT_WD_CTL_CD1 BIT(7) +#define PCF2127_REG_WD_VAL 0x11 /* * RAM registers * PCF2127 has 512 bytes general-purpose static RAM (SRAM) that is @@ -45,9 +56,15 @@ #define PCF2127_REG_RAM_WRT_CMD 0x1C #define PCF2127_REG_RAM_RD_CMD 0x1D +/* Watchdog timer value constants */ +#define PCF2127_WD_VAL_STOP 0 +#define PCF2127_WD_VAL_MIN 2 +#define PCF2127_WD_VAL_MAX 255 +#define PCF2127_WD_VAL_DEFAULT 60 struct pcf2127 { struct rtc_device *rtc; + struct watchdog_device wdd; struct regmap *regmap; }; @@ -220,6 +237,81 @@ static int pcf2127_nvmem_write(void *priv, unsigned int offset, return ret ?: bytes; } +/* watchdog driver */ + +static int pcf2127_wdt_ping(struct watchdog_device *wdd) +{ + struct pcf2127 *pcf2127 = watchdog_get_drvdata(wdd); + + return regmap_write(pcf2127->regmap, PCF2127_REG_WD_VAL, wdd->timeout); +} + +/* + * Restart watchdog timer if feature is active. + * + * Note: Reading CTRL2 register causes watchdog to stop which is unfortunate, + * since register also contain control/status flags for other features. + * Always call this function after reading CTRL2 register. + */ +static int pcf2127_wdt_active_ping(struct watchdog_device *wdd) +{ + int ret = 0; + + if (watchdog_active(wdd)) { + ret = pcf2127_wdt_ping(wdd); + if (ret) + dev_err(wdd->parent, + "%s: watchdog restart failed, ret=%d\n", + __func__, ret); + } + + return ret; +} + +static int pcf2127_wdt_start(struct watchdog_device *wdd) +{ + dev_info(wdd->parent, "watchdog enabled\n"); + + return pcf2127_wdt_ping(wdd); +} + +static int pcf2127_wdt_stop(struct watchdog_device *wdd) +{ + struct pcf2127 *pcf2127 = watchdog_get_drvdata(wdd); + + dev_info(wdd->parent, "watchdog disabled\n"); + + return regmap_write(pcf2127->regmap, PCF2127_REG_WD_VAL, + PCF2127_WD_VAL_STOP); +} + +static int pcf2127_wdt_set_timeout(struct watchdog_device *wdd, + unsigned int new_timeout) +{ + int ret = 0; + + dev_info(wdd->parent, "new watchdog timeout: %is (old: %is)\n", + new_timeout, wdd->timeout); + + wdd->timeout = new_timeout; + ret = pcf2127_wdt_active_ping(wdd); + + return ret; +} + +static const struct watchdog_info pcf2127_wdt_info = { + .identity = "NXP PCF2127/PCF2129 Watchdog", + .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, +}; + +static const struct watchdog_ops pcf2127_watchdog_ops = { + .owner = THIS_MODULE, + .start = pcf2127_wdt_start, + .stop = pcf2127_wdt_stop, + .ping = pcf2127_wdt_ping, + .set_timeout = pcf2127_wdt_set_timeout, +}; + static int pcf2127_probe(struct device *dev, struct regmap *regmap, const char *name, bool has_nvmem) { @@ -242,6 +334,16 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap, pcf2127->rtc->ops = &pcf2127_rtc_ops; + pcf2127->wdd.parent = dev; + pcf2127->wdd.info = &pcf2127_wdt_info; + pcf2127->wdd.ops = &pcf2127_watchdog_ops; + pcf2127->wdd.min_timeout = PCF2127_WD_VAL_MIN; + pcf2127->wdd.max_timeout = PCF2127_WD_VAL_MAX; + pcf2127->wdd.timeout = PCF2127_WD_VAL_DEFAULT; + pcf2127->wdd.min_hw_heartbeat_ms = 500; + + watchdog_set_drvdata(&pcf2127->wdd, pcf2127); + if (has_nvmem) { struct nvmem_config nvmem_cfg = { .priv = pcf2127, @@ -253,6 +355,31 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap, ret = rtc_nvmem_register(pcf2127->rtc, &nvmem_cfg); } + /* + * Watchdog timer enabled and reset pin /RST activated when timed out. + * Select 1Hz clock source for watchdog timer. + * Timer is not started until WD_VAL is loaded with a valid value. + * Note: Countdown timer disabled and not available. + */ + ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_WD_CTL, + PCF2127_BIT_WD_CTL_CD1 | + PCF2127_BIT_WD_CTL_CD0 | + PCF2127_BIT_WD_CTL_TF1 | + PCF2127_BIT_WD_CTL_TF0, + PCF2127_BIT_WD_CTL_CD1 | + PCF2127_BIT_WD_CTL_CD0 | + PCF2127_BIT_WD_CTL_TF1); + if (ret) { + dev_err(dev, "%s: watchdog config (wd_ctl) failed\n", __func__); + return ret; + } + + ret = devm_watchdog_register_device(dev, &pcf2127->wdd); + if (ret) { + dev_err(dev, "%s: watchdog registering failed\n", __func__); + return ret; + } + return rtc_register_device(pcf2127->rtc); } From patchwork Tue Aug 13 15:36:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bruno Thomsen X-Patchwork-Id: 1146418 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-rtc-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="dXrTFfGD"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 467Gyw6fx5z9sND for ; Wed, 14 Aug 2019 01:36:24 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729185AbfHMPgY (ORCPT ); Tue, 13 Aug 2019 11:36:24 -0400 Received: from mail-wm1-f66.google.com ([209.85.128.66]:56160 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726086AbfHMPgY (ORCPT ); Tue, 13 Aug 2019 11:36:24 -0400 Received: by mail-wm1-f66.google.com with SMTP id f72so1927848wmf.5; Tue, 13 Aug 2019 08:36:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=UYV2yjdUYLPyUUdL20ioXIarD+5iPfqzSdJEEsg/kSI=; b=dXrTFfGDEkVvxDLwnacKoRgFeO7iuOEGHSexsSLhzL87S62xvMVIlNgFdj2jLCtmoz 8rNlN3wBepZQl996Dzee9AFSQ6wjcPcbk4onMVOzZ7HMKy86tgmEoukdQKpYi4Tlgngz L81K8p9gDV4Fzk6MtFPMqR2kJBNpJDBVJIXdUBZvbzFs1ib0pPF9szX/zU5g6C0cyabs DmmL3JBqhQuFkUtA8V+xatuOX9w17RryioUertgo+ZhsHEiUc0vHrAOK9QMcd1kVw7++ kMXzGhBsmoUOhnNV6MCuf7SXpvZaHTiZQFmc5oA9UGh2Um6OQ3HrpwSnK5u/KIHWLsuu qSKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UYV2yjdUYLPyUUdL20ioXIarD+5iPfqzSdJEEsg/kSI=; b=MPcAIVJ6JlwHBlY2xOxA6ZhlFC2xnlz/i76SOMiQUr5oN1F8aFlVZ41GHZfOFydCK0 EiqRjKsmx6wLVjYVxHIKL33U/+tqj2K8f6jOux0KIU5cNw3cgKkkklitiUq9uOjt+mRy lGKwMsYR19ra/pal+Q8qf1m55j04GQrFyoxEHLKMmHKmrgB6vBGZutdcvV5pfEr1KkR2 g1icREcZRjoWesxUvEyZgkNyiLr+xPWFSCNdQAx3jh9XjOAzRQ87vbovdYY6yQvS6+Q0 MPiFXXAn0cDuC+rP80KwnJlFq081xEUe0fp9117NmANwZYdEypdqSVYLelU9FaMwYnM9 6JpQ== X-Gm-Message-State: APjAAAXbJGXu8xOFMDrAQzhbbFOyMiA/YLQQ1CfgOH7s6Gmn9gxu7bwX LyZjr8E5b5fzqP5Kh+cVEdDi8xY/uPHI0g== X-Google-Smtp-Source: APXvYqye+cN7G8L2AW3E185LkxkEutFsU3SLaFLHeuJ+QDWUmNVkzrfTmzbWE+qRdEReZNFW+Q2EzQ== X-Received: by 2002:a05:600c:2486:: with SMTP id 6mr4023714wms.80.1565710581232; Tue, 13 Aug 2019 08:36:21 -0700 (PDT) Received: from localhost.localdomain (3e6b1cc1.rev.stofanet.dk. [62.107.28.193]) by smtp.googlemail.com with ESMTPSA id j16sm64744819wrp.62.2019.08.13.08.36.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Aug 2019 08:36:20 -0700 (PDT) From: Bruno Thomsen To: linux-rtc@vger.kernel.org, linux-watchdog@vger.kernel.org Cc: alexandre.belloni@bootlin.com, a.zummo@towertech.it, wim@linux-watchdog.org, linux@roeck-us.net, u.kleine-koenig@pengutronix.de, sean.nyekjaer@prevas.dk, bth@kamstrup.com, bruno.thomsen@gmail.com Subject: [PATCH v2 5/5] rtc: pcf2127: add tamper detection support Date: Tue, 13 Aug 2019 17:36:00 +0200 Message-Id: <20190813153600.12406-6-bruno.thomsen@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190813153600.12406-1-bruno.thomsen@gmail.com> References: <20190813153600.12406-1-bruno.thomsen@gmail.com> MIME-Version: 1.0 Sender: linux-rtc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rtc@vger.kernel.org Add support for integrated tamper detection function in both PCF2127 and PCF2129 chips. This patch implements the feature by adding an additional timestamp0 file to sysfs device path. This file contains seconds since epoch, if an event occurred, or is empty, if none occurred. Interface should match ISL1208 and RV3028 RTC drivers. Signed-off-by: Bruno Thomsen --- drivers/rtc/rtc-pcf2127.c | 160 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index 700db7dd3eef..9a5c042cf267 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -25,11 +25,18 @@ /* Control register 1 */ #define PCF2127_REG_CTRL1 0x00 +#define PCF2127_BIT_CTRL1_TSF1 BIT(4) /* Control register 2 */ #define PCF2127_REG_CTRL2 0x01 +#define PCF2127_BIT_CTRL2_TSIE BIT(2) +#define PCF2127_BIT_CTRL2_TSF2 BIT(5) /* Control register 3 */ #define PCF2127_REG_CTRL3 0x02 +#define PCF2127_BIT_CTRL3_BLIE BIT(0) +#define PCF2127_BIT_CTRL3_BIE BIT(1) #define PCF2127_BIT_CTRL3_BLF BIT(2) +#define PCF2127_BIT_CTRL3_BF BIT(3) +#define PCF2127_BIT_CTRL3_BTSE BIT(4) /* Time and date registers */ #define PCF2127_REG_SC 0x03 #define PCF2127_BIT_SC_OSF BIT(7) @@ -46,6 +53,16 @@ #define PCF2127_BIT_WD_CTL_CD0 BIT(6) #define PCF2127_BIT_WD_CTL_CD1 BIT(7) #define PCF2127_REG_WD_VAL 0x11 +/* Tamper timestamp registers */ +#define PCF2127_REG_TS_CTRL 0x12 +#define PCF2127_BIT_TS_CTRL_TSOFF BIT(6) +#define PCF2127_BIT_TS_CTRL_TSM BIT(7) +#define PCF2127_REG_TS_SC 0x13 +#define PCF2127_REG_TS_MN 0x14 +#define PCF2127_REG_TS_HR 0x15 +#define PCF2127_REG_TS_DM 0x16 +#define PCF2127_REG_TS_MO 0x17 +#define PCF2127_REG_TS_YR 0x18 /* * RAM registers * PCF2127 has 512 bytes general-purpose static RAM (SRAM) that is @@ -312,6 +329,97 @@ static const struct watchdog_ops pcf2127_watchdog_ops = { .set_timeout = pcf2127_wdt_set_timeout, }; +/* sysfs interface */ + +static ssize_t timestamp0_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct pcf2127 *pcf2127 = dev_get_drvdata(dev->parent); + int ret; + + ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL1, + PCF2127_BIT_CTRL1_TSF1, 0); + if (ret) { + dev_err(dev, "%s: update ctrl1 ret=%d\n", __func__, ret); + return ret; + } + + ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL2, + PCF2127_BIT_CTRL2_TSF2, 0); + if (ret) { + dev_err(dev, "%s: update ctrl2 ret=%d\n", __func__, ret); + return ret; + } + + ret = pcf2127_wdt_active_ping(&pcf2127->wdd); + if (ret) + return ret; + + return count; +}; + +static ssize_t timestamp0_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct pcf2127 *pcf2127 = dev_get_drvdata(dev->parent); + struct rtc_time tm; + int ret; + unsigned char data[25]; + + ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_CTRL1, data, + sizeof(data)); + if (ret) { + dev_err(dev, "%s: read error ret=%d\n", __func__, ret); + return ret; + } + + dev_dbg(dev, + "%s: raw data is cr1=%02x, cr2=%02x, cr3=%02x, ts_sc=%02x, " + "ts_mn=%02x, ts_hr=%02x, ts_dm=%02x, ts_mo=%02x, ts_yr=%02x\n", + __func__, data[PCF2127_REG_CTRL1], data[PCF2127_REG_CTRL2], + data[PCF2127_REG_CTRL3], data[PCF2127_REG_TS_SC], + data[PCF2127_REG_TS_MN], data[PCF2127_REG_TS_HR], + data[PCF2127_REG_TS_DM], data[PCF2127_REG_TS_MO], + data[PCF2127_REG_TS_YR]); + + ret = pcf2127_wdt_active_ping(&pcf2127->wdd); + if (ret) + return ret; + + if (!(data[PCF2127_REG_CTRL1] & PCF2127_BIT_CTRL1_TSF1) && + !(data[PCF2127_REG_CTRL2] & PCF2127_BIT_CTRL2_TSF2)) + return 0; + + tm.tm_sec = bcd2bin(data[PCF2127_REG_TS_SC] & 0x7F); + tm.tm_min = bcd2bin(data[PCF2127_REG_TS_MN] & 0x7F); + tm.tm_hour = bcd2bin(data[PCF2127_REG_TS_HR] & 0x3F); + tm.tm_mday = bcd2bin(data[PCF2127_REG_TS_DM] & 0x3F); + /* TS_MO register (month) value range: 1-12 */ + tm.tm_mon = bcd2bin(data[PCF2127_REG_TS_MO] & 0x1F) - 1; + tm.tm_year = bcd2bin(data[PCF2127_REG_TS_YR]); + if (tm.tm_year < 70) + tm.tm_year += 100; /* assume we are in 1970...2069 */ + + ret = rtc_valid_tm(&tm); + if (ret) + return ret; + + return sprintf(buf, "%llu\n", + (unsigned long long)rtc_tm_to_time64(&tm)); +}; + +static DEVICE_ATTR_RW(timestamp0); + +static struct attribute *pcf2127_attrs[] = { + &dev_attr_timestamp0.attr, + NULL +}; + +static const struct attribute_group pcf2127_attr_group = { + .attrs = pcf2127_attrs, +}; + static int pcf2127_probe(struct device *dev, struct regmap *regmap, const char *name, bool has_nvmem) { @@ -380,6 +488,58 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap, return ret; } + /* + * Disable battery low/switch-over timestamp and interrupts. + * Clear battery interrupt flags which can block new trigger events. + * Note: This is the default chip behaviour but added to ensure + * correct tamper timestamp and interrupt function. + */ + ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL3, + PCF2127_BIT_CTRL3_BTSE | + PCF2127_BIT_CTRL3_BF | + PCF2127_BIT_CTRL3_BIE | + PCF2127_BIT_CTRL3_BLIE, 0); + if (ret) { + dev_err(dev, "%s: interrupt config (ctrl3) failed\n", + __func__); + return ret; + } + + /* + * Enable timestamp function and store timestamp of first trigger + * event until TSF1 and TFS2 interrupt flags are cleared. + */ + ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_TS_CTRL, + PCF2127_BIT_TS_CTRL_TSOFF | + PCF2127_BIT_TS_CTRL_TSM, + PCF2127_BIT_TS_CTRL_TSM); + if (ret) { + dev_err(dev, "%s: tamper detection config (ts_ctrl) failed\n", + __func__); + return ret; + } + + /* + * Enable interrupt generation when TSF1 or TSF2 timestamp flags + * are set. Interrupt signal is an open-drain output and can be + * left floating if unused. + */ + ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL2, + PCF2127_BIT_CTRL2_TSIE, + PCF2127_BIT_CTRL2_TSIE); + if (ret) { + dev_err(dev, "%s: tamper detection config (ctrl2) failed\n", + __func__); + return ret; + } + + ret = rtc_add_group(pcf2127->rtc, &pcf2127_attr_group); + if (ret) { + dev_err(dev, "%s: tamper sysfs registering failed\n", + __func__); + return ret; + } + return rtc_register_device(pcf2127->rtc); }