From patchwork Fri Nov 5 00:40:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Modilaynen X-Patchwork-Id: 1551178 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=axis.com header.i=@axis.com header.a=rsa-sha256 header.s=axis-central1 header.b=i01lGdl8; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-rtc-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4HlhWZ6T67z9sf8 for ; Fri, 5 Nov 2021 11:40:58 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229971AbhKEAnf (ORCPT ); Thu, 4 Nov 2021 20:43:35 -0400 Received: from smtp1.axis.com ([195.60.68.17]:9290 "EHLO smtp1.axis.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229587AbhKEAnf (ORCPT ); Thu, 4 Nov 2021 20:43:35 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axis.com; q=dns/txt; s=axis-central1; t=1636072857; x=1667608857; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=GjYacMkXqPa7BY/QUGUd7Cu5vTMkFLoJdOBo70fFGAg=; b=i01lGdl8iJZG1tdXDENeI33ZPdqzekc107SLf312ar65YE13gO3J8DTO 1wxUqXIVrqW9xYwZDy6Ka2rYHZbHeZgbHWtFGksebh7mhHJyMIYbcKfyb uFlAu743z18hjwcHnSnMbnNb7t9L63Z+SFgL9M5ZPBDBxE2iP2wUu87yf URugCrolvalmUa6rJ5CYO0pMawMFdKple7F0XcqC6YE1+Xltt5euCxzp8 XeaYZn1RpJUgd0sNCDyaXfcUWuH2Pr4VlOOnCGJcG78ualMUr/kIxEy0k aU46+VuaRHmNI4xzdaEgjRn4bo/0runoB1BwU3yiytR/IAG+YeMlGEjcD A==; From: Pavel Modilaynen To: , CC: , , , Pavel Modilaynen Subject: [PATCH] rtc: rs5c372: Add support of RTC_VL_READ ioctl Date: Fri, 5 Nov 2021 01:40:49 +0100 Message-ID: <20211105004049.5486-1-pavel.modilaynen@axis.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-rtc@vger.kernel.org From: Pavel Modilaynen Read, cache and expose with RTC_VL_READ ioctl low voltage detection flag. It is supported on all devices except RS5C372A/B, for which osciallation halt detection bit is interpreted as low voltage condition. Add RTC_VL_CLEAR ioctl to clear the cached value. Signed-off-by: Pavel Modilaynen --- drivers/rtc/rtc-rs5c372.c | 46 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index 80980414890c..68d2ed9670c4 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c @@ -126,6 +126,7 @@ struct rs5c372 { unsigned smbus:1; char buf[17]; char *regs; + int voltage_low; }; static int rs5c_get_regs(struct rs5c372 *rs5c) @@ -216,22 +217,40 @@ static int rs5c372_rtc_read_time(struct device *dev, struct rtc_time *tm) if (status < 0) return status; + /* check the warning bits */ switch (rs5c->type) { case rtc_r2025sd: case rtc_r2221tl: if ((rs5c->type == rtc_r2025sd && !(ctrl2 & R2x2x_CTRL2_XSTP)) || (rs5c->type == rtc_r2221tl && (ctrl2 & R2x2x_CTRL2_XSTP))) { dev_warn(&client->dev, "rtc oscillator interruption detected. Please reset the rtc clock.\n"); + /* keep it as indicator of low/dead battery */ + rs5c->voltage_low = 1; return -EINVAL; } break; default: if (ctrl2 & RS5C_CTRL2_XSTP) { dev_warn(&client->dev, "rtc oscillator interruption detected. Please reset the rtc clock.\n"); + /* keep it as indicator of low/dead battery */ + rs5c->voltage_low = 1; return -EINVAL; } } + + switch (rs5c->type) { + case rtc_rs5c372a: + case rtc_rs5c372b: + break; + default: + if (ctrl2 & R2x2x_CTRL2_VDET) { + rs5c->voltage_low = 1; + dev_warn(&client->dev, "low voltage detected\n"); + } + break; + } + tm->tm_sec = bcd2bin(rs5c->regs[RS5C372_REG_SECS] & 0x7f); tm->tm_min = bcd2bin(rs5c->regs[RS5C372_REG_MINS] & 0x7f); tm->tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C372_REG_HOURS]); @@ -485,6 +504,32 @@ static int rs5c372_rtc_proc(struct device *dev, struct seq_file *seq) #define rs5c372_rtc_proc NULL #endif +#ifdef CONFIG_RTC_INTF_DEV +static int rs5c372_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) +{ + struct rs5c372 *rs5c = i2c_get_clientdata(to_i2c_client(dev)); + + dev_dbg(dev, "%s: cmd=%x\n", __func__, cmd); + + switch (cmd) { + case RTC_VL_READ: + if (rs5c->voltage_low) + dev_info(dev, "low voltage detected, date/time is not reliable.\n"); + + return put_user(rs5c->voltage_low, (unsigned int __user *)arg); + case RTC_VL_CLR: + /* Clear the cached value. */ + rs5c->voltage_low = 0; + return 0; + default: + return -ENOIOCTLCMD; + } + return 0; +} +#else +#define rs5c372_ioctl NULL +#endif + static const struct rtc_class_ops rs5c372_rtc_ops = { .proc = rs5c372_rtc_proc, .read_time = rs5c372_rtc_read_time, @@ -492,6 +537,7 @@ static const struct rtc_class_ops rs5c372_rtc_ops = { .read_alarm = rs5c_read_alarm, .set_alarm = rs5c_set_alarm, .alarm_irq_enable = rs5c_rtc_alarm_irq_enable, + .ioctl = rs5c372_ioctl, }; #if IS_ENABLED(CONFIG_RTC_INTF_SYSFS)