diff options
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/Kconfig | 8 | ||||
-rw-r--r-- | drivers/rtc/Makefile | 2 | ||||
-rw-r--r-- | drivers/rtc/class.c | 14 | ||||
-rw-r--r-- | drivers/rtc/rtc-abracon.c | 20 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1307.c | 15 | ||||
-rw-r--r-- | drivers/rtc/rtc-imxdi.c | 25 | ||||
-rw-r--r-- | drivers/rtc/rtc-jz4740.c | 12 | ||||
-rw-r--r-- | drivers/rtc/rtc-lib.c | 7 | ||||
-rw-r--r-- | drivers/rtc/rtc-pcf85363.c | 166 |
9 files changed, 201 insertions, 68 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 9d2c6e614b..98e58da89b 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only # # RTC class/drivers configuration # @@ -36,6 +37,13 @@ config RTC_DRV_DS1307 config RTC_DRV_ABRACON tristate "Abracon RTCs" +config RTC_DRV_PCF85363 + tristate "NXP PCF85363" + depends on I2C + select REGMAP_I2C + help + If you say yes here you get support for the PCF85363 RTC chip. + endif # I2C config RTC_DRV_IMXDI diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 1308beff38..ec9775b691 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only # # Makefile for RTC class/drivers. # @@ -11,3 +12,4 @@ obj-$(CONFIG_RTC_DRV_ABRACON) += rtc-abracon.o obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o +obj-$(CONFIG_RTC_DRV_PCF85363) += rtc-pcf85363.o diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 5b58271c07..3edb294ed7 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * RTC barebox subsystem, base class * * Copyright (C) 2014 Antony Pavlov <antonynpavlov@gmail.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <linux/err.h> @@ -61,7 +51,7 @@ EXPORT_SYMBOL(rtc_set_time); int rtc_register(struct rtc_device *rtcdev) { - struct device_d *dev = &rtcdev->class_dev; + struct device *dev = &rtcdev->class_dev; if (!rtcdev->ops) return -EINVAL; diff --git a/drivers/rtc/rtc-abracon.c b/drivers/rtc/rtc-abracon.c index 571909bf71..d43b1b4021 100644 --- a/drivers/rtc/rtc-abracon.c +++ b/drivers/rtc/rtc-abracon.c @@ -1,13 +1,4 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; version 2. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - */ +// SPDX-License-Identifier: GPL-2.0-only #include <common.h> #include <driver.h> @@ -89,11 +80,10 @@ static const struct rtc_class_ops ds13xx_rtc_ops = { .set_time = abracon_set_time, }; -static int abracon_probe(struct device_d *dev) +static int abracon_probe(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct abracon *abracon; - int ret; abracon = xzalloc(sizeof(*abracon)); @@ -102,9 +92,7 @@ static int abracon_probe(struct device_d *dev) abracon->rtc.ops = &ds13xx_rtc_ops; abracon->rtc.dev = dev; - ret = rtc_register(&abracon->rtc); - - return ret; + return rtc_register(&abracon->rtc); }; static struct platform_device_id abracon_id[] = { @@ -112,7 +100,7 @@ static struct platform_device_id abracon_id[] = { { } }; -static struct driver_d abracon_driver = { +static struct driver abracon_driver = { .name = "rtc-abracon", .probe = abracon_probe, .id_table = abracon_id, diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index f1feee4689..e1a8e214d2 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * rtc-ds1307.c - RTC driver for some mostly-compatible I2C chips. * @@ -7,10 +8,6 @@ * Copyright (C) 2006 David Brownell * Copyright (C) 2009 Matthias Fuchs (rx8025 support) * Copyright (C) 2012 Bertrand Achard (nvram access fixes) - * - * 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. */ #include <common.h> @@ -196,7 +193,7 @@ static inline struct ds1307 *to_ds1307_priv(struct rtc_device *rtcdev) static int ds1307_get_time(struct rtc_device *rtcdev, struct rtc_time *t) { - struct device_d *dev = rtcdev->dev; + struct device *dev = rtcdev->dev; struct ds1307 *ds1307 = to_ds1307_priv(rtcdev); int tmp; @@ -234,7 +231,7 @@ static int ds1307_get_time(struct rtc_device *rtcdev, struct rtc_time *t) static int ds1307_set_time(struct rtc_device *rtcdev, struct rtc_time *t) { - struct device_d *dev = rtcdev->dev; + struct device *dev = rtcdev->dev; struct ds1307 *ds1307 = to_ds1307_priv(rtcdev); int result; int tmp; @@ -283,7 +280,7 @@ static const struct rtc_class_ops ds13xx_rtc_ops = { .set_time = ds1307_set_time, }; -static int ds1307_probe(struct device_d *dev) +static int ds1307_probe(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct ds1307 *ds1307; @@ -291,7 +288,7 @@ static int ds1307_probe(struct device_d *dev) int tmp; unsigned char *buf; unsigned long driver_data; - const struct device_node *np = dev->device_node; + const struct device_node *np = dev->of_node; ds1307 = xzalloc(sizeof(struct ds1307)); @@ -484,7 +481,7 @@ exit: return err; } -static struct driver_d ds1307_driver = { +static struct driver ds1307_driver = { .name = "rtc-ds1307", .probe = ds1307_probe, .id_table = ds1307_id, diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index 82ed6d5007..e9d68c6739 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c @@ -1,17 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. * Copyright 2010 Orex Computed Radiography */ -/* - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - /* based on rtc-mc13892.c */ /* @@ -110,7 +102,7 @@ * @dsr: copy of the DSR register */ struct imxdi_dev { - struct device_d *dev; + struct device *dev; struct rtc_device rtc; void __iomem *ioaddr; struct clk *clk; @@ -537,20 +529,16 @@ static int nvstore_read(void *ctx, unsigned reg, void *val, size_t bytes) return 0; } -static struct nvmem_bus nvstore_nvmem_bus = { - .write = nvstore_write, - .read = nvstore_read, -}; - static struct nvmem_config nvstore_nvmem_config = { .name = "nvstore", .stride = 4, .word_size = 4, .size = 4, - .bus = &nvstore_nvmem_bus, + .reg_write = nvstore_write, + .reg_read = nvstore_read, }; -static int __init dryice_rtc_probe(struct device_d *dev) +static int __init dryice_rtc_probe(struct device *dev) { struct resource *res; struct imxdi_dev *imxdi; @@ -611,8 +599,9 @@ static __maybe_unused const struct of_device_id dryice_dt_ids[] = { { .compatible = "fsl,imx25-rtc" }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, dryice_dt_ids); -static struct driver_d dryice_rtc_driver = { +static struct driver dryice_rtc_driver = { .name = "imx-di-rtc", .probe = dryice_rtc_probe, .of_compatible = DRV_OF_COMPAT(dryice_dt_ids), diff --git a/drivers/rtc/rtc-jz4740.c b/drivers/rtc/rtc-jz4740.c index 95885357d9..aa79cb2ac5 100644 --- a/drivers/rtc/rtc-jz4740.c +++ b/drivers/rtc/rtc-jz4740.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * JZ4740 SoC RTC driver * @@ -5,12 +6,6 @@ * * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> * Copyright (C) 2010, Paul Cercueil <paul@crapouillou.net> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * */ #include <common.h> @@ -111,7 +106,7 @@ static struct rtc_class_ops jz4740_rtc_ops = { .set_time = jz4740_rtc_set_time, }; -static int jz4740_rtc_probe(struct device_d *dev) +static int jz4740_rtc_probe(struct device *dev) { struct resource *iores; int ret; @@ -158,8 +153,9 @@ static __maybe_unused struct of_device_id jz4740_rtc_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, jz4740_rtc_dt_ids); -static struct driver_d jz4740_rtc_driver = { +static struct driver jz4740_rtc_driver = { .name = "jz4740-rtc", .probe = jz4740_rtc_probe, .of_compatible = DRV_OF_COMPAT(jz4740_rtc_dt_ids), diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c index 4a2d34fcfd..3709d46cbe 100644 --- a/drivers/rtc/rtc-lib.c +++ b/drivers/rtc/rtc-lib.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * rtc and date/time utility functions * @@ -7,11 +8,7 @@ * Author: Alessandro Zummo <a.zummo@towertech.it> * * based on arch/arm/common/rtctime.c and other bits - * - * 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. -*/ + */ #include <rtc.h> #include <linux/rtc.h> diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c new file mode 100644 index 0000000000..bcc251e138 --- /dev/null +++ b/drivers/rtc/rtc-pcf85363.c @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * drivers/rtc/rtc-pcf85363.c + * + * Driver for NXP PCF85363 real-time clock. + * + * Copyright (C) 2017 Eric Nelson + * + * This code is ported from linux-5.12 + * by Antony Pavlov <antonynpavlov@gmail.com> + */ + +#include <common.h> +#include <driver.h> +#include <xfuncs.h> +#include <malloc.h> +#include <errno.h> +#include <i2c/i2c.h> +#include <linux/regmap.h> +#include <rtc.h> +#include <linux/rtc.h> +#include <linux/bcd.h> + +/* + * 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 + +/* + * control registers + */ +#define CTRL_STOP_EN 0x2e + +#define STOP_EN_STOP BIT(0) + +#define RESET_CPR 0xa4 + +struct pcf85363 { + struct rtc_device rtc; + struct regmap *regmap; +}; + +static inline struct pcf85363 *to_pcf85363_priv(struct rtc_device *rtcdev) +{ + return container_of(rtcdev, struct pcf85363, rtc); +} + +static int pcf85363_rtc_read_time(struct rtc_device *rtcdev, + struct rtc_time *tm) +{ + struct device *dev = rtcdev->dev; + struct pcf85363 *pcf85363 = to_pcf85363_priv(rtcdev); + 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 rtc_device *rtcdev, struct rtc_time *tm) +{ + struct pcf85363 *pcf85363 = to_pcf85363_priv(rtcdev); + unsigned char tmp[11]; + unsigned char *buf = &tmp[2]; + int ret; + + tmp[0] = STOP_EN_STOP; + tmp[1] = RESET_CPR; + + 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); + + ret = regmap_bulk_write(pcf85363->regmap, CTRL_STOP_EN, + tmp, 2); + if (ret) + return ret; + + ret = regmap_bulk_write(pcf85363->regmap, DT_100THS, + buf, sizeof(tmp) - 2); + if (ret) + return ret; + + return regmap_write(pcf85363->regmap, CTRL_STOP_EN, 0); +} + +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 pcf85363_regmap_i2c_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0x7f, +}; + +static int pcf85363_probe(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct pcf85363 *pcf85363; + struct regmap *regmap; + + regmap = regmap_init_i2c(client, + &pcf85363_regmap_i2c_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + pcf85363 = xzalloc(sizeof(struct pcf85363)); + + pcf85363->regmap = regmap; + + i2c_set_clientdata(client, pcf85363); + + pcf85363->rtc.ops = &rtc_ops; + pcf85363->rtc.dev = dev; + + return rtc_register(&pcf85363->rtc); +} + +static struct platform_device_id dev_ids[] = { + { .name = "pcf85363" }, + { /* sentinel */ } +}; + +static struct driver pcf85363_driver = { + .name = "pcf85363", + .probe = pcf85363_probe, + .id_table = dev_ids, +}; +device_i2c_driver(pcf85363_driver); + +MODULE_AUTHOR("Eric Nelson"); +MODULE_DESCRIPTION("pcf85363 I2C RTC driver"); +MODULE_LICENSE("GPL"); |