{"id":803634,"url":"http://patchwork.ozlabs.org/api/1.2/patches/803634/?format=json","web_url":"http://patchwork.ozlabs.org/project/rtc-linux/patch/20170820013632.18375-3-afaerber@suse.de/","project":{"id":9,"url":"http://patchwork.ozlabs.org/api/1.2/projects/9/?format=json","name":"Linux RTC development","link_name":"rtc-linux","list_id":"linux-rtc.vger.kernel.org","list_email":"linux-rtc@vger.kernel.org","web_url":"","scm_url":"","webscm_url":"","list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20170820013632.18375-3-afaerber@suse.de>","list_archive_url":null,"date":"2017-08-20T01:36:30","name":"[RFC,2/3] rtc: Add Realtek RTD1295","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"46245adfbdcb87e735ec67734b4ac20ce4d93fb3","submitter":{"id":9542,"url":"http://patchwork.ozlabs.org/api/1.2/people/9542/?format=json","name":"Andreas Färber","email":"afaerber@suse.de"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/rtc-linux/patch/20170820013632.18375-3-afaerber@suse.de/mbox/","series":[],"comments":"http://patchwork.ozlabs.org/api/patches/803634/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/803634/checks/","tags":{},"related":[],"headers":{"Return-Path":"<linux-rtc-owner@vger.kernel.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@bilbo.ozlabs.org","Authentication-Results":"ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=linux-rtc-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xZfbP46Qvz9sNv\n\tfor <incoming@patchwork.ozlabs.org>;\n\tSun, 20 Aug 2017 11:38:09 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1752539AbdHTBhe (ORCPT <rfc822;incoming@patchwork.ozlabs.org>);\n\tSat, 19 Aug 2017 21:37:34 -0400","from mx2.suse.de ([195.135.220.15]:33183 \"EHLO mx1.suse.de\"\n\trhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP\n\tid S1752509AbdHTBhc (ORCPT <rfc822;linux-rtc@vger.kernel.org>);\n\tSat, 19 Aug 2017 21:37:32 -0400","from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254])\n\tby mx1.suse.de (Postfix) with ESMTP id 0684FABED;\n\tSun, 20 Aug 2017 01:37:31 +0000 (UTC)"],"X-Virus-Scanned":"by amavisd-new at test-mx.suse.de","From":"=?UTF-8?q?Andreas=20F=C3=A4rber?= <afaerber@suse.de>","To":"Alessandro Zummo <a.zummo@towertech.it>,\n\tAlexandre Belloni <alexandre.belloni@free-electrons.com>,\n\tlinux-rtc@vger.kernel.org, linux-arm-kernel@lists.infradead.org","Cc":"linux-kernel@vger.kernel.org, Roc He <hepeng@zidoo.tv>,\n\t=?UTF-8?q?=E8=92=8B=E4=B8=BD=E7=90=B4?= <jiang.liqin@geniatech.com>, \n\t=?UTF-8?q?Andreas=20F=C3=A4rber?= <afaerber@suse.de>","Subject":"[RFC 2/3] rtc: Add Realtek RTD1295","Date":"Sun, 20 Aug 2017 03:36:30 +0200","Message-Id":"<20170820013632.18375-3-afaerber@suse.de>","X-Mailer":"git-send-email 2.12.3","In-Reply-To":"<20170820013632.18375-1-afaerber@suse.de>","References":"<20170820013632.18375-1-afaerber@suse.de>","MIME-Version":"1.0","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","Sender":"linux-rtc-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<linux-rtc.vger.kernel.org>","X-Mailing-List":"linux-rtc@vger.kernel.org"},"content":"Based on QNAP's mach-rtk119x/driver/rtk_rtc_drv.c code.\n\nSigned-off-by: Andreas Färber <afaerber@suse.de>\n---\n drivers/rtc/Kconfig       |   8 +++\n drivers/rtc/Makefile      |   1 +\n drivers/rtc/rtc-rtd119x.c | 175 ++++++++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 184 insertions(+)\n create mode 100644 drivers/rtc/rtc-rtd119x.c","diff":"diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig\nindex 72419ac2c52a..882828b1b351 100644\n--- a/drivers/rtc/Kconfig\n+++ b/drivers/rtc/Kconfig\n@@ -1765,6 +1765,14 @@ config RTC_DRV_CPCAP\n \t   Say y here for CPCAP rtc found on some Motorola phones\n \t   and tablets such as Droid 4.\n \n+config RTC_DRV_RTD119X\n+\tbool \"Realtek RTD129x RTC\"\n+\tdepends on ARCH_REALTEK || COMPILE_TEST\n+\tdefault ARCH_REALTEK\n+\thelp\n+\t  If you say yes here, you get support for the RTD1295 SoC\n+\t  Real Time Clock.\n+\n comment \"HID Sensor RTC drivers\"\n \n config RTC_DRV_HID_SENSOR_TIME\ndiff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile\nindex acd366b41c85..55a0a5ca45b0 100644\n--- a/drivers/rtc/Makefile\n+++ b/drivers/rtc/Makefile\n@@ -131,6 +131,7 @@ obj-$(CONFIG_RTC_DRV_RP5C01)\t+= rtc-rp5c01.o\n obj-$(CONFIG_RTC_DRV_RS5C313)\t+= rtc-rs5c313.o\n obj-$(CONFIG_RTC_DRV_RS5C348)\t+= rtc-rs5c348.o\n obj-$(CONFIG_RTC_DRV_RS5C372)\t+= rtc-rs5c372.o\n+obj-$(CONFIG_RTC_DRV_RTD119X)\t+= rtc-rtd119x.o\n obj-$(CONFIG_RTC_DRV_RV3029C2)\t+= rtc-rv3029c2.o\n obj-$(CONFIG_RTC_DRV_RV8803)\t+= rtc-rv8803.o\n obj-$(CONFIG_RTC_DRV_RX4581)\t+= rtc-rx4581.o\ndiff --git a/drivers/rtc/rtc-rtd119x.c b/drivers/rtc/rtc-rtd119x.c\nnew file mode 100644\nindex 000000000000..b532e127b56e\n--- /dev/null\n+++ b/drivers/rtc/rtc-rtd119x.c\n@@ -0,0 +1,175 @@\n+/*\n+ * Realtek RTD129x RTC\n+ *\n+ * Copyright (c) 2017 Andreas Färber\n+ *\n+ * SPDX-License-Identifier: GPL-2.0+\n+ */\n+\n+#include <linux/clk.h>\n+#include <linux/io.h>\n+#include <linux/module.h>\n+#include <linux/of.h>\n+#include <linux/of_address.h>\n+#include <linux/platform_device.h>\n+#include <linux/rtc.h>\n+\n+#define RTD_RTCSEC\t\t0x00\n+#define RTD_RTCMIN\t\t0x04\n+#define RTD_RTCHR\t\t0x08\n+#define RTD_RTCDATE_LOW\t\t0x0c\n+#define RTD_RTCDATE_HIGH\t0x10\n+#define RTD_RTCACR\t\t0x28\n+#define RTD_RTCEN\t\t0x2c\n+\n+struct rtd119x_rtc {\n+\tvoid __iomem *base;\n+\tstruct clk *clk;\n+\tstruct rtc_device *rtcdev;\n+\tunsigned base_year;\n+};\n+\n+static void rtd119x_rtc_set_enabled(struct device *dev, bool enable)\n+{\n+\tstruct rtd119x_rtc *data = dev_get_drvdata(dev);\n+\tu32 val;\n+\n+\tval = readl_relaxed(data->base + RTD_RTCEN);\n+\tdev_info(dev, \"%s: rtcen = 0x%08x\\n\", __func__, val);\n+\tif (enable) {\n+\t\tif ((val & 0xff) == 0x5a)\n+\t\t\treturn;\n+\t\twritel_relaxed(0x5a, data->base + RTD_RTCEN);\n+\t} else {\n+\t\twritel_relaxed(0, data->base + RTD_RTCEN);\n+\t}\n+}\n+\n+static int rtd119x_rtc_read_time(struct device *dev, struct rtc_time *tm)\n+{\n+\tstruct rtd119x_rtc *data = dev_get_drvdata(dev);\n+\ttime64_t t;\n+\tu32 day;\n+\n+\tday = readl_relaxed(data->base + RTD_RTCDATE_LOW);\n+\tday |= readl_relaxed(data->base + RTD_RTCDATE_HIGH) << 8;\n+\tt = mktime64(data->base_year, 1, 1, 0, 0, 0);\n+\tt += day * 24 * 60 * 60;\n+\trtc_time64_to_tm(t, tm);\n+\ttm->tm_sec  = readl_relaxed(data->base + RTD_RTCSEC) >> 1;\n+\ttm->tm_min  = readl_relaxed(data->base + RTD_RTCMIN);\n+\ttm->tm_hour = readl_relaxed(data->base + RTD_RTCHR);\n+\n+\treturn rtc_valid_tm(tm);\n+}\n+\n+static int rtd119x_rtc_set_time(struct device *dev, struct rtc_time *tm)\n+{\n+\tstruct rtd119x_rtc *data = dev_get_drvdata(dev);\n+\ttime64_t time_base, new_time, time_delta;\n+\tunsigned long day;\n+\n+\tif (tm->tm_year < data->base_year)\n+\t\treturn -EINVAL;\n+\n+\ttime_base = mktime64(data->base_year, 1, 1, 0, 0, 0);\n+\tnew_time = rtc_tm_to_time64(tm);\n+\ttime_delta = new_time - time_base;\n+\tday = time_delta / (24 * 60 * 60);\n+\tif (day > 0x7fff)\n+\t\treturn -EINVAL;\n+\n+\trtd119x_rtc_set_enabled(dev, false);\n+\n+\twritel_relaxed(tm->tm_sec,  data->base + RTD_RTCSEC);\n+\twritel_relaxed(tm->tm_min,  data->base + RTD_RTCMIN);\n+\twritel_relaxed(tm->tm_hour, data->base + RTD_RTCHR);\n+\twritel_relaxed(day & 0xff, data->base + RTD_RTCDATE_LOW);\n+\twritel_relaxed((day >> 8) & 0x7f, data->base + RTD_RTCDATE_HIGH);\n+\n+\trtd119x_rtc_set_enabled(dev, true);\n+\n+\treturn 0;\n+}\n+\n+static int rtd119x_rtc_open(struct device *dev)\n+{\n+\tstruct rtd119x_rtc *data = dev_get_drvdata(dev);\n+\tu32 val;\n+\tint ret;\n+\n+\tret = clk_prepare_enable(data->clk);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tval = readl_relaxed(data->base + RTD_RTCACR);\n+\tdev_info(dev, \"rtcacr = 0x%08x\\n\", val);\n+\tif (!(val & BIT(7))) {\n+\t}\n+\n+\trtd119x_rtc_set_enabled(dev, true);\n+\n+\treturn 0;\n+}\n+\n+static void rtd119x_rtc_release(struct device *dev)\n+{\n+\tstruct rtd119x_rtc *data = dev_get_drvdata(dev);\n+\n+\trtd119x_rtc_set_enabled(dev, false);\n+\n+\tclk_disable_unprepare(data->clk);\n+}\n+\n+static const struct rtc_class_ops rtd119x_rtc_ops = {\n+\t.open\t\t= rtd119x_rtc_open,\n+\t.release\t= rtd119x_rtc_release,\n+\t.read_time\t= rtd119x_rtc_read_time,\n+\t.set_time\t= rtd119x_rtc_set_time,\n+};\n+\n+static const struct of_device_id rtd119x_rtc_dt_ids[] = {\n+\t { .compatible = \"realtek,rtd1295-rtc\" },\n+\t { }\n+};\n+\n+static int rtd119x_rtc_probe(struct platform_device *pdev)\n+{\n+\tstruct rtd119x_rtc *data;\n+\tstruct resource *res;\n+\n+\tdata = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);\n+\tif (!data)\n+\t\treturn -ENOMEM;\n+\n+\tplatform_set_drvdata(pdev, data);\n+\tdata->base_year = 2014;\n+\n+\tres = platform_get_resource(pdev, IORESOURCE_MEM, 0);\n+\tdata->base = devm_ioremap_resource(&pdev->dev, res);\n+\tif (IS_ERR(data->base))\n+\t\treturn PTR_ERR(data->base);\n+\n+\tdata->clk = of_clk_get(pdev->dev.of_node, 0);\n+\tif (IS_ERR(data->clk))\n+\t\treturn PTR_ERR(data->clk);\n+\n+\tdata->rtcdev = devm_rtc_device_register(&pdev->dev, \"rtc\",\n+\t\t\t\t&rtd119x_rtc_ops, THIS_MODULE);\n+\tif (IS_ERR(data->rtcdev)) {\n+\t\tdev_err(&pdev->dev, \"failed to register rtc device\");\n+\t\tclk_put(data->clk);\n+\t\treturn PTR_ERR(data->rtcdev);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static struct platform_driver rtd119x_rtc_driver = {\n+\t.probe = rtd119x_rtc_probe,\n+\t.driver = {\n+\t\t.name = \"rtd1295-rtc\",\n+\t\t.of_match_table\t= rtd119x_rtc_dt_ids,\n+\t},\n+};\n+builtin_platform_driver(rtd119x_rtc_driver);\n","prefixes":["RFC","2/3"]}