From patchwork Mon Aug 28 18:37:21 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heiner Kallweit X-Patchwork-Id: 806713 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; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Ij7gaI6W"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xh0qv0K72z9ryT for ; Tue, 29 Aug 2017 04:37:31 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751192AbdH1Sha (ORCPT ); Mon, 28 Aug 2017 14:37:30 -0400 Received: from mail-wr0-f195.google.com ([209.85.128.195]:36022 "EHLO mail-wr0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751184AbdH1Sh3 (ORCPT ); Mon, 28 Aug 2017 14:37:29 -0400 Received: by mail-wr0-f195.google.com with SMTP id 40so666111wrv.3 for ; Mon, 28 Aug 2017 11:37:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=to:cc:from:subject:message-id:date:user-agent:mime-version :content-transfer-encoding; bh=O07Td1Tz+ngc1jgWA516bQDpkDLS6eHT8bOchFZ6Af4=; b=Ij7gaI6W6GwZFz5fS15yanCZexMNdS1OmzHRHeoXjJZa0uI7xJtOlt20zTnZqqKJtZ tBxvQBGZH3+g39JmpDNQURx3FKR3ZQmv9fAWTKcINQhkDlo/7Zg93eiYTqclhhBWOFR0 FkomfgJOVXiQOOH83YRcVcMjKhv1P0cPEWP+LoXm9CJpjQ4favfJHadE0Z5u6HX8A80w e7YlXOXyiqJyckFMfDmkkUCdAPDxMM0ooIK3bekR6wiG3m6qmB5YrgwDZIjbYGha+Rpr s4SUYYtudPw5py4hqM149xMPVpLGUug06+wETDwcMnz9Q5GhDRPtHpl8Fh0cu8qtjNIt hEBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:to:cc:from:subject:message-id:date:user-agent :mime-version:content-transfer-encoding; bh=O07Td1Tz+ngc1jgWA516bQDpkDLS6eHT8bOchFZ6Af4=; b=ucf4ZqU25AebNFFm5aqwY8NxgifoOzQ86Z0AZaw+qGJxs/C1oNtynKXIceO9IpSMF5 WVbCXVvJFxVnUHomhcl4lPDn+ud8q//NF6TTlypKm2oG34uW17spw6/PGthLrvpT9DlD MGi9M1X9R7JEkeBZGuvyqaCAOGWEGBniD4rj9ysP8EH6SIopFpzRirosFfnisMiOjTNX 3itLoq9jM8GoHgD/Jji2bOCsAku9RgnvJcFNePoB3leF4SQiMSbIwooFRPtfGnR+Eanz vYIyrvWSddPXJfcCAmTLvdTpEzMwFGENQmzzymyH12A9kdWVrAIQ0EzXx2dr5e5R6Yff tN+A== X-Gm-Message-State: AHYfb5i2jAX1xrVn8pAvEdSJY/B1s3NRgn+tsf8F0+p1pCvnZ8OgF/tY wozCmue9rZWqzW/7 X-Received: by 10.223.183.7 with SMTP id l7mr988762wre.270.1503945447948; Mon, 28 Aug 2017 11:37:27 -0700 (PDT) Received: from ?IPv6:2003:ea:8bc7:5e00:d03d:3b20:7ef4:d434? (p200300EA8BC75E00D03D3B207EF4D434.dip0.t-ipconnect.de. [2003:ea:8bc7:5e00:d03d:3b20:7ef4:d434]) by smtp.googlemail.com with ESMTPSA id g51sm1989102wrg.49.2017.08.28.11.37.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 28 Aug 2017 11:37:27 -0700 (PDT) To: Alexandre Belloni Cc: linux-rtc@vger.kernel.org From: Heiner Kallweit Subject: [PATCH] rtc: ds1307: improve weekday handling Message-ID: <57598a86-21c7-b354-2840-309563440435@gmail.com> Date: Mon, 28 Aug 2017 20:37:21 +0200 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.3.0 MIME-Version: 1.0 Sender: linux-rtc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rtc@vger.kernel.org mcp794xx as one chip supported by this driver needs the weekday for alarm matching. RTC core ignores the weekday so we can't rely on the values we receive in member tm_wday of struct rtc_time. Therefore calculate the weekday from date/time when setting the time and setting the alarm time for mcp794xx. When having this in place we don't have to check the weekday at each driver load. After a chip reset date/time and weekday may be out of sync but in this case date/time need to be set anyway. Signed-off-by: Heiner Kallweit --- drivers/rtc/rtc-ds1307.c | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 9d680d36..83b8c997 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -437,6 +437,18 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t) return rtc_valid_tm(t); } +/* + * Certain chips need the weekday for alarm matching and tm->t_wday + * may be not or not properly populated + */ +static int ds1307_get_weekday(struct rtc_time *tm) +{ + time64_t secs64 = rtc_tm_to_time64(tm); + int days = div_s64(secs64, 24 * 60 * 60); + + return (days + 4) % 7 + 1; +} + static int ds1307_set_time(struct device *dev, struct rtc_time *t) { struct ds1307 *ds1307 = dev_get_drvdata(dev); @@ -465,7 +477,7 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) regs[DS1307_REG_SECS] = bin2bcd(t->tm_sec); regs[DS1307_REG_MIN] = bin2bcd(t->tm_min); regs[DS1307_REG_HOUR] = bin2bcd(t->tm_hour); - regs[DS1307_REG_WDAY] = bin2bcd(t->tm_wday + 1); + regs[DS1307_REG_WDAY] = ds1307_get_weekday(t); regs[DS1307_REG_MDAY] = bin2bcd(t->tm_mday); regs[DS1307_REG_MONTH] = bin2bcd(t->tm_mon + 1); @@ -902,7 +914,7 @@ static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t) regs[3] = bin2bcd(t->time.tm_sec); regs[4] = bin2bcd(t->time.tm_min); regs[5] = bin2bcd(t->time.tm_hour); - regs[6] = bin2bcd(t->time.tm_wday + 1); + regs[6] = ds1307_get_weekday(&t->time); regs[7] = bin2bcd(t->time.tm_mday); regs[8] = bin2bcd(t->time.tm_mon + 1); @@ -1355,14 +1367,12 @@ static int ds1307_probe(struct i2c_client *client, { struct ds1307 *ds1307; int err = -ENODEV; - int tmp, wday; + int tmp; const struct chip_desc *chip; bool want_irq; bool ds1307_can_wakeup_device = false; unsigned char regs[8]; struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev); - struct rtc_time tm; - unsigned long timestamp; u8 trickle_charger_setup = 0; ds1307 = devm_kzalloc(&client->dev, sizeof(struct ds1307), GFP_KERNEL); @@ -1642,25 +1652,6 @@ static int ds1307_probe(struct i2c_client *client, bin2bcd(tmp)); } - /* - * Some IPs have weekday reset value = 0x1 which might not correct - * hence compute the wday using the current date/month/year values - */ - ds1307_get_time(ds1307->dev, &tm); - wday = tm.tm_wday; - timestamp = rtc_tm_to_time64(&tm); - rtc_time64_to_tm(timestamp, &tm); - - /* - * Check if reset wday is different from the computed wday - * If different then set the wday which we computed using - * timestamp - */ - if (wday != tm.tm_wday) - regmap_update_bits(ds1307->regmap, MCP794XX_REG_WEEKDAY, - MCP794XX_REG_WEEKDAY_WDAY_MASK, - tm.tm_wday + 1); - if (want_irq || ds1307_can_wakeup_device) { device_set_wakeup_capable(ds1307->dev, true); set_bit(HAS_ALARM, &ds1307->flags);