From patchwork Tue Jul 16 08:15:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Biju Das X-Patchwork-Id: 11045497 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 60638112C for ; Tue, 16 Jul 2019 08:20:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4F0B026E4A for ; Tue, 16 Jul 2019 08:20:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4377928429; Tue, 16 Jul 2019 08:20:54 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9186D26E4A for ; Tue, 16 Jul 2019 08:20:53 +0000 (UTC) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 25DCECC1; Tue, 16 Jul 2019 08:20:53 +0000 (UTC) X-Original-To: cip-dev@lists.cip-project.org Delivered-To: cip-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 41D44CC2 for ; Tue, 16 Jul 2019 08:20:51 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relmlie6.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by smtp1.linuxfoundation.org (Postfix) with ESMTP id 163568A2 for ; Tue, 16 Jul 2019 08:20:49 +0000 (UTC) X-IronPort-AV: E=Sophos;i="5.62,497,1554735600"; d="scan'208";a="21311523" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie6.idc.renesas.com with ESMTP; 16 Jul 2019 17:20:49 +0900 Received: from be1yocto.ree.adwin.renesas.com (unknown [172.29.43.62]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 9F2AC41B7371; Tue, 16 Jul 2019 17:20:48 +0900 (JST) From: Biju Das To: cip-dev@lists.cip-project.org Date: Tue, 16 Jul 2019 09:15:12 +0100 Message-Id: <1563264921-42973-2-git-send-email-biju.das@bp.renesas.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1563264921-42973-1-git-send-email-biju.das@bp.renesas.com> References: <1563264921-42973-1-git-send-email-biju.das@bp.renesas.com> Cc: Biju Das Subject: [cip-dev] [PATCH 4.4.y-cip 01/10] rtc: add support for NXP PCF85363 real-time clock X-BeenThere: cip-dev@lists.cip-project.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: cip-dev-bounces@lists.cip-project.org Errors-To: cip-dev-bounces@lists.cip-project.org X-Virus-Scanned: ClamAV using ClamSMTP From: Eric Nelson commit a9687aa2764dd2669602bd19dc636cbeef5293d5 upstream. Note that alarms are not currently implemented. 64 bytes of nvmem is supported and exposed in sysfs (# is the instance number, starting with 0): /sys/bus/nvmem/devices/pcf85363-#/nvmem Signed-off-by: Eric Nelson Reviewed-by: Fabio Estevam Tested-by: Alexandre Belloni Acked-by: Rob Herring Signed-off-by: Alexandre Belloni Signed-off-by: Biju Das [Removed rtc nvmem support. Added I2C ID table to rtc-pcf85363.c Updated Kconfig description for rtc-pcf85363] --- Documentation/devicetree/bindings/rtc/pcf85363.txt | 17 ++ drivers/rtc/Kconfig | 9 + drivers/rtc/Makefile | 1 + drivers/rtc/rtc-pcf85363.c | 197 +++++++++++++++++++++ 4 files changed, 224 insertions(+) create mode 100644 Documentation/devicetree/bindings/rtc/pcf85363.txt create mode 100644 drivers/rtc/rtc-pcf85363.c diff --git a/Documentation/devicetree/bindings/rtc/pcf85363.txt b/Documentation/devicetree/bindings/rtc/pcf85363.txt new file mode 100644 index 0000000..76fdabc --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/pcf85363.txt @@ -0,0 +1,17 @@ +NXP PCF85363 Real Time Clock +============================ + +Required properties: +- compatible: Should contain "nxp,pcf85363". +- reg: I2C address for chip. + +Optional properties: +- interrupts: IRQ line for the RTC (not implemented). + +Example: + +pcf85363: pcf85363@51 { + compatible = "nxp,pcf85363"; + reg = <0x51>; +}; + diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 2a52424..8f2fed5 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -419,6 +419,15 @@ config RTC_DRV_PCF8523 This driver can also be built as a module. If so, the module will be called rtc-pcf8523. +config RTC_DRV_PCF85363 + tristate "NXP PCF85363" + select REGMAP_I2C + help + If you say yes here you get support for the PCF85363 RTC chip. + + This driver can also be built as a module. If so, the module + will be called rtc-pcf85363. + config RTC_DRV_PCF8563 tristate "Philips PCF8563/Epson RTC8564" help diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 231f764..8419d5b 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -109,6 +109,7 @@ obj-$(CONFIG_RTC_DRV_PCF2123) += rtc-pcf2123.o obj-$(CONFIG_RTC_DRV_PCF2127) += rtc-pcf2127.o obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o obj-$(CONFIG_RTC_DRV_PCF85063) += rtc-pcf85063.o +obj-$(CONFIG_RTC_DRV_PCF85363) += rtc-pcf85363.o obj-$(CONFIG_RTC_DRV_PCF8523) += rtc-pcf8523.o obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c new file mode 100644 index 0000000..54fc1a7 --- /dev/null +++ b/drivers/rtc/rtc-pcf85363.c @@ -0,0 +1,197 @@ +/* + * drivers/rtc/rtc-pcf85363.c + * + * Driver for NXP PCF85363 real-time clock. + * + * Copyright (C) 2017 Eric Nelson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Based loosely on rtc-8583 by Russell King, Wolfram Sang and Juergen Beisert + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Date/Time registers + */ +#define DT_100THS 0x00 +#define DT_SECS 0x01 +#define DT_MINUTES 0x02 +#define DT_HOURS 0x03 +#define DT_DAYS 0x04 +#define DT_WEEKDAYS 0x05 +#define DT_MONTHS 0x06 +#define DT_YEARS 0x07 + +/* + * Alarm registers + */ +#define DT_SECOND_ALM1 0x08 +#define DT_MINUTE_ALM1 0x09 +#define DT_HOUR_ALM1 0x0a +#define DT_DAY_ALM1 0x0b +#define DT_MONTH_ALM1 0x0c +#define DT_MINUTE_ALM2 0x0d +#define DT_HOUR_ALM2 0x0e +#define DT_WEEKDAY_ALM2 0x0f +#define DT_ALARM_EN 0x10 + +/* + * Time stamp registers + */ +#define DT_TIMESTAMP1 0x11 +#define DT_TIMESTAMP2 0x17 +#define DT_TIMESTAMP3 0x1d +#define DT_TS_MODE 0x23 + +/* + * control registers + */ +#define CTRL_OFFSET 0x24 +#define CTRL_OSCILLATOR 0x25 +#define CTRL_BATTERY 0x26 +#define CTRL_PIN_IO 0x27 +#define CTRL_FUNCTION 0x28 +#define CTRL_INTA_EN 0x29 +#define CTRL_INTB_EN 0x2a +#define CTRL_FLAGS 0x2b +#define CTRL_RAMBYTE 0x2c +#define CTRL_WDOG 0x2d +#define CTRL_STOP_EN 0x2e +#define CTRL_RESETS 0x2f +#define CTRL_RAM 0x40 + +#define NVRAM_SIZE 0x40 + +static struct i2c_driver pcf85363_driver; + +struct pcf85363 { + struct device *dev; + struct rtc_device *rtc; + struct regmap *regmap; +}; + +static int pcf85363_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct pcf85363 *pcf85363 = dev_get_drvdata(dev); + unsigned char buf[DT_YEARS + 1]; + int ret, len = sizeof(buf); + + /* read the RTC date and time registers all at once */ + ret = regmap_bulk_read(pcf85363->regmap, DT_100THS, buf, len); + if (ret) { + dev_err(dev, "%s: error %d\n", __func__, ret); + return ret; + } + + tm->tm_year = bcd2bin(buf[DT_YEARS]); + /* adjust for 1900 base of rtc_time */ + tm->tm_year += 100; + + tm->tm_wday = buf[DT_WEEKDAYS] & 7; + buf[DT_SECS] &= 0x7F; + tm->tm_sec = bcd2bin(buf[DT_SECS]); + buf[DT_MINUTES] &= 0x7F; + tm->tm_min = bcd2bin(buf[DT_MINUTES]); + tm->tm_hour = bcd2bin(buf[DT_HOURS]); + tm->tm_mday = bcd2bin(buf[DT_DAYS]); + tm->tm_mon = bcd2bin(buf[DT_MONTHS]) - 1; + + return 0; +} + +static int pcf85363_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct pcf85363 *pcf85363 = dev_get_drvdata(dev); + unsigned char buf[DT_YEARS + 1]; + int len = sizeof(buf); + + buf[DT_100THS] = 0; + buf[DT_SECS] = bin2bcd(tm->tm_sec); + buf[DT_MINUTES] = bin2bcd(tm->tm_min); + buf[DT_HOURS] = bin2bcd(tm->tm_hour); + buf[DT_DAYS] = bin2bcd(tm->tm_mday); + buf[DT_WEEKDAYS] = tm->tm_wday; + buf[DT_MONTHS] = bin2bcd(tm->tm_mon + 1); + buf[DT_YEARS] = bin2bcd(tm->tm_year % 100); + + return regmap_bulk_write(pcf85363->regmap, DT_100THS, + buf, len); +} + +static const struct rtc_class_ops rtc_ops = { + .read_time = pcf85363_rtc_read_time, + .set_time = pcf85363_rtc_set_time, +}; + +static const struct regmap_config regmap_config = { + .reg_bits = 8, + .val_bits = 8, +}; + +static int pcf85363_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct pcf85363 *pcf85363; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return -ENODEV; + + pcf85363 = devm_kzalloc(&client->dev, sizeof(struct pcf85363), + GFP_KERNEL); + if (!pcf85363) + return -ENOMEM; + + pcf85363->regmap = devm_regmap_init_i2c(client, ®map_config); + if (IS_ERR(pcf85363->regmap)) { + dev_err(&client->dev, "regmap allocation failed\n"); + return PTR_ERR(pcf85363->regmap); + } + + pcf85363->dev = &client->dev; + i2c_set_clientdata(client, pcf85363); + + pcf85363->rtc = devm_rtc_device_register(pcf85363->dev, + pcf85363_driver.driver.name, + &rtc_ops, THIS_MODULE); + + return PTR_ERR_OR_ZERO(pcf85363->rtc); +} + +static const struct i2c_device_id pcf85363_id[] = { + { "pcf85363", 0 }, + { } +}; + +static const struct of_device_id dev_ids[] = { + { .compatible = "nxp,pcf85363" }, + {} +}; +MODULE_DEVICE_TABLE(of, dev_ids); + +static struct i2c_driver pcf85363_driver = { + .driver = { + .name = "pcf85363", + .of_match_table = of_match_ptr(dev_ids), + }, + .probe = pcf85363_probe, + .id_table = pcf85363_id, +}; + +module_i2c_driver(pcf85363_driver); + +MODULE_AUTHOR("Eric Nelson"); +MODULE_DESCRIPTION("pcf85363 I2C RTC driver"); +MODULE_LICENSE("GPL");