Commit eadc4e40 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'rtc-5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux

Pull RTC updates from Alexandre Belloni:
 "The VL_READ and VL_CLR ioctls have been reworked to be more useful.
  This will not break userspace as there are very few users and they are
  using the integer value as a boolean.

  Apart from that, two drivers were reworked and a few fixes here and
  there for a net reduction of number of lines.

  Summary:

  Subsystem:
   - the VL_READ and VL_CLR ioctls are now documented and their behavior
     is unified across all the drivers.
   - RTC_I2C_AND_SPI Kconfig option rework to avoid selecting both
     REGMAP_I2C and REGMAP_SPI unecessarily.

  Drivers:
   - at91rm9200: remove deprecated procfs, add sam9x60, sama5d4 and
     sama5d2 compatibles.
   - cmos: solve lost interrupts issue on MS Surface 3
   - hym8563: return proper errno when time is invalid
   - rv3029: many fixes, nvram support"

* tag 'rtc-5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (63 commits)
  dt-bindings: rtc: at91rm9200: document clocks property
  rtc: i2c/spi: Avoid inclusion of REGMAP support when not needed
  rtc: Kconfig: select REGMAP_I2C when necessary
  rtc: Kconfig: properly indent sd3078 entry
  rtc: cmos: Refactor code by using the new dmi_get_bios_year() helper
  rtc: cmos: Use predefined value for RTC IRQ on legacy x86
  rtc: cmos: Stop using shared IRQ
  rtc: tps6586x: Use IRQ_NOAUTOEN flag
  rtc: at91rm9200: use FIELD_PREP/FIELD_GET
  rtc: at91rm9200: avoid time readout in at91_rtc_setalarm
  rtc: at91rm9200: move register definitions to C file
  rtc: at91rm9200: add sama5d4 and sama5d2 compatibles
  dt-bindings: rtc: at91rm9200: convert bindings to json-schema
  rtc: at91rm9200: remove procfs information
  dt-bindings: atmel, at91rm9200-rtc: add microchip, sam9x60-rtc
  rtc: pcf8563: Use BIT
  rtc: moxart: Convert to SPDX identifier
  rtc: ds1343: Remove unused struct spi_device in struct ds1343_priv
  rtc: rx8025: Remove struct i2c_client from struct rx8025_data
  rtc: hym8563: Read the valid flag directly instead of caching it
  ...
parents 322bf2d3 f4571924
......@@ -18,6 +18,7 @@ Aleksey Gorelov <aleksey_gorelov@phoenix.com>
Aleksandar Markovic <aleksandar.markovic@mips.com> <aleksandar.markovic@imgtec.com>
Alex Shi <alex.shi@linux.alibaba.com> <alex.shi@intel.com>
Alex Shi <alex.shi@linux.alibaba.com> <alex.shi@linaro.org>
Alexandre Belloni <alexandre.belloni@bootlin.com> <alexandre.belloni@free-electrons.com>
Alexei Starovoitov <ast@kernel.org> <ast@plumgrid.com>
Alexei Starovoitov <ast@kernel.org> <alexei.starovoitov@gmail.com>
Alexei Starovoitov <ast@kernel.org> <ast@fb.com>
......
......@@ -33,6 +33,14 @@ Description:
Requires a separate RTC_PIE_ON call to enable the periodic
interrupts.
* RTC_VL_READ: Read the voltage inputs status of the RTC when
supported. The value is a bit field of RTC_VL_*, giving the
status of the main and backup voltages.
* RTC_VL_CLEAR: Clear the voltage status of the RTC. Some RTCs
need user interaction when the backup power provider is
replaced or charged to be able to clear the status.
The ioctl() calls supported by the older /dev/rtc interface are
also supported by the newer RTC class framework. However,
because the chips and systems are not standardized, some PC/AT
......
Atmel AT91RM9200 Real Time Clock
Required properties:
- compatible: should be: "atmel,at91rm9200-rtc" or "atmel,at91sam9x5-rtc"
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: rtc alarm/event interrupt
- clocks: phandle to input clock.
Example:
rtc@fffffe00 {
compatible = "atmel,at91rm9200-rtc";
reg = <0xfffffe00 0x100>;
interrupts = <1 4 7>;
clocks = <&clk32k>;
};
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/rtc/atmel,at91rm9200-rtc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Atmel AT91 RTC Device Tree Bindings
allOf:
- $ref: "rtc.yaml#"
maintainers:
- Alexandre Belloni <alexandre.belloni@bootlin.com>
properties:
compatible:
enum:
- atmel,at91rm9200-rtc
- atmel,at91sam9x5-rtc
- atmel,sama5d4-rtc
- atmel,sama5d2-rtc
- microchip,sam9x60-rtc
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
maxItems: 1
required:
- compatible
- reg
- interrupts
- clocks
additionalProperties: false
examples:
- |
rtc@fffffe00 {
compatible = "atmel,at91rm9200-rtc";
reg = <0xfffffe00 0x100>;
interrupts = <1 4 7>;
clocks = <&clk32k>;
};
...
......@@ -240,6 +240,7 @@ config RTC_DRV_AS3722
config RTC_DRV_DS1307
tristate "Dallas/Maxim DS1307/37/38/39/40/41, ST M41T00, EPSON RX-8025, ISL12057"
select REGMAP_I2C
help
If you say yes here you get support for various compatible RTC
chips (often with battery backup) connected with I2C. This driver
......@@ -622,6 +623,7 @@ config RTC_DRV_RX8010
config RTC_DRV_RX8581
tristate "Epson RX-8571/RX-8581"
select REGMAP_I2C
help
If you say yes here you will get support for the Epson RX-8571/
RX-8581.
......@@ -649,6 +651,7 @@ config RTC_DRV_EM3027
config RTC_DRV_RV3028
tristate "Micro Crystal RV3028"
select REGMAP_I2C
help
If you say yes here you get support for the Micro Crystal
RV3028.
......@@ -678,6 +681,7 @@ config RTC_DRV_S5M
config RTC_DRV_SD3078
tristate "ZXW Shenzhen whwave SD3078"
select REGMAP_I2C
help
If you say yes here you get support for the ZXW Shenzhen whwave
SD3078 RTC chips.
......@@ -849,14 +853,14 @@ config RTC_I2C_AND_SPI
default m if I2C=m
default y if I2C=y
default y if SPI_MASTER=y
select REGMAP_I2C if I2C
select REGMAP_SPI if SPI_MASTER
comment "SPI and I2C RTC drivers"
config RTC_DRV_DS3232
tristate "Dallas/Maxim DS3232/DS3234"
depends on RTC_I2C_AND_SPI
select REGMAP_I2C if I2C
select REGMAP_SPI if SPI_MASTER
help
If you say yes here you get support for Dallas Semiconductor
DS3232 and DS3234 real-time clock chips. If an interrupt is associated
......@@ -876,6 +880,8 @@ config RTC_DRV_DS3232_HWMON
config RTC_DRV_PCF2127
tristate "NXP PCF2127"
depends on RTC_I2C_AND_SPI
select REGMAP_I2C if I2C
select REGMAP_SPI if SPI_MASTER
select WATCHDOG_CORE if WATCHDOG
help
If you say yes here you get support for the NXP PCF2127/29 RTC
......@@ -892,6 +898,8 @@ config RTC_DRV_PCF2127
config RTC_DRV_RV3029C2
tristate "Micro Crystal RV3029/3049"
depends on RTC_I2C_AND_SPI
select REGMAP_I2C if I2C
select REGMAP_SPI if SPI_MASTER
help
If you say yes here you get support for the Micro Crystal
RV3029 and RV3049 RTC chips.
......
......@@ -523,12 +523,9 @@ static int abx80x_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
if (status < 0)
return status;
tmp = !!(status & ABX8XX_STATUS_BLF);
tmp = status & ABX8XX_STATUS_BLF ? RTC_VL_BACKUP_LOW : 0;
if (copy_to_user((void __user *)arg, &tmp, sizeof(int)))
return -EFAULT;
return 0;
return put_user(tmp, (unsigned int __user *)arg);
case RTC_VL_CLR:
status = i2c_smbus_read_byte_data(client, ABX8XX_REG_STATUS);
......
......@@ -264,6 +264,9 @@ static int asm9260_rtc_probe(struct platform_device *pdev)
return PTR_ERR(priv->iobase);
priv->clk = devm_clk_get(dev, "ahb");
if (IS_ERR(priv->clk))
return PTR_ERR(priv->clk);
ret = clk_prepare_enable(priv->clk);
if (ret) {
dev_err(dev, "Failed to enable clk!\n");
......
......@@ -14,6 +14,7 @@
*/
#include <linux/bcd.h>
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/interrupt.h>
......@@ -30,7 +31,51 @@
#include <linux/time.h>
#include <linux/uaccess.h>
#include "rtc-at91rm9200.h"
#define AT91_RTC_CR 0x00 /* Control Register */
#define AT91_RTC_UPDTIM BIT(0) /* Update Request Time Register */
#define AT91_RTC_UPDCAL BIT(1) /* Update Request Calendar Register */
#define AT91_RTC_MR 0x04 /* Mode Register */
#define AT91_RTC_TIMR 0x08 /* Time Register */
#define AT91_RTC_SEC GENMASK(6, 0) /* Current Second */
#define AT91_RTC_MIN GENMASK(14, 8) /* Current Minute */
#define AT91_RTC_HOUR GENMASK(21, 16) /* Current Hour */
#define AT91_RTC_AMPM BIT(22) /* Ante Meridiem Post Meridiem Indicator */
#define AT91_RTC_CALR 0x0c /* Calendar Register */
#define AT91_RTC_CENT GENMASK(6, 0) /* Current Century */
#define AT91_RTC_YEAR GENMASK(15, 8) /* Current Year */
#define AT91_RTC_MONTH GENMASK(20, 16) /* Current Month */
#define AT91_RTC_DAY GENMASK(23, 21) /* Current Day */
#define AT91_RTC_DATE GENMASK(29, 24) /* Current Date */
#define AT91_RTC_TIMALR 0x10 /* Time Alarm Register */
#define AT91_RTC_SECEN BIT(7) /* Second Alarm Enable */
#define AT91_RTC_MINEN BIT(15) /* Minute Alarm Enable */
#define AT91_RTC_HOUREN BIT(23) /* Hour Alarm Enable */
#define AT91_RTC_CALALR 0x14 /* Calendar Alarm Register */
#define AT91_RTC_MTHEN BIT(23) /* Month Alarm Enable */
#define AT91_RTC_DATEEN BIT(31) /* Date Alarm Enable */
#define AT91_RTC_SR 0x18 /* Status Register */
#define AT91_RTC_ACKUPD BIT(0) /* Acknowledge for Update */
#define AT91_RTC_ALARM BIT(1) /* Alarm Flag */
#define AT91_RTC_SECEV BIT(2) /* Second Event */
#define AT91_RTC_TIMEV BIT(3) /* Time Event */
#define AT91_RTC_CALEV BIT(4) /* Calendar Event */
#define AT91_RTC_SCCR 0x1c /* Status Clear Command Register */
#define AT91_RTC_IER 0x20 /* Interrupt Enable Register */
#define AT91_RTC_IDR 0x24 /* Interrupt Disable Register */
#define AT91_RTC_IMR 0x28 /* Interrupt Mask Register */
#define AT91_RTC_VER 0x2c /* Valid Entry Register */
#define AT91_RTC_NVTIM BIT(0) /* Non valid Time */
#define AT91_RTC_NVCAL BIT(1) /* Non valid Calendar */
#define AT91_RTC_NVTIMALR BIT(2) /* Non valid Time Alarm */
#define AT91_RTC_NVCALALR BIT(3) /* Non valid Calendar Alarm */
#define at91_rtc_read(field) \
readl_relaxed(at91_rtc_regs + field)
......@@ -117,20 +162,20 @@ static void at91_rtc_decodetime(unsigned int timereg, unsigned int calreg,
} while ((time != at91_rtc_read(timereg)) ||
(date != at91_rtc_read(calreg)));
tm->tm_sec = bcd2bin((time & AT91_RTC_SEC) >> 0);
tm->tm_min = bcd2bin((time & AT91_RTC_MIN) >> 8);
tm->tm_hour = bcd2bin((time & AT91_RTC_HOUR) >> 16);
tm->tm_sec = bcd2bin(FIELD_GET(AT91_RTC_SEC, time));
tm->tm_min = bcd2bin(FIELD_GET(AT91_RTC_MIN, time));
tm->tm_hour = bcd2bin(FIELD_GET(AT91_RTC_HOUR, time));
/*
* The Calendar Alarm register does not have a field for
* the year - so these will return an invalid value.
*/
tm->tm_year = bcd2bin(date & AT91_RTC_CENT) * 100; /* century */
tm->tm_year += bcd2bin((date & AT91_RTC_YEAR) >> 8); /* year */
tm->tm_year += bcd2bin(FIELD_GET(AT91_RTC_YEAR, date)); /* year */
tm->tm_wday = bcd2bin((date & AT91_RTC_DAY) >> 21) - 1; /* day of the week [0-6], Sunday=0 */
tm->tm_mon = bcd2bin((date & AT91_RTC_MONTH) >> 16) - 1;
tm->tm_mday = bcd2bin((date & AT91_RTC_DATE) >> 24);
tm->tm_wday = bcd2bin(FIELD_GET(AT91_RTC_DAY, date)) - 1; /* day of the week [0-6], Sunday=0 */
tm->tm_mon = bcd2bin(FIELD_GET(AT91_RTC_MONTH, date)) - 1;
tm->tm_mday = bcd2bin(FIELD_GET(AT91_RTC_DATE, date));
}
/*
......@@ -167,16 +212,17 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm)
at91_rtc_write_idr(AT91_RTC_ACKUPD);
at91_rtc_write(AT91_RTC_TIMR,
bin2bcd(tm->tm_sec) << 0
| bin2bcd(tm->tm_min) << 8
| bin2bcd(tm->tm_hour) << 16);
FIELD_PREP(AT91_RTC_SEC, bin2bcd(tm->tm_sec))
| FIELD_PREP(AT91_RTC_MIN, bin2bcd(tm->tm_min))
| FIELD_PREP(AT91_RTC_HOUR, bin2bcd(tm->tm_hour)));
at91_rtc_write(AT91_RTC_CALR,
bin2bcd((tm->tm_year + 1900) / 100) /* century */
| bin2bcd(tm->tm_year % 100) << 8 /* year */
| bin2bcd(tm->tm_mon + 1) << 16 /* tm_mon starts at zero */
| bin2bcd(tm->tm_wday + 1) << 21 /* day of the week [0-6], Sunday=0 */
| bin2bcd(tm->tm_mday) << 24);
FIELD_PREP(AT91_RTC_CENT,
bin2bcd((tm->tm_year + 1900) / 100))
| FIELD_PREP(AT91_RTC_YEAR, bin2bcd(tm->tm_year % 100))
| FIELD_PREP(AT91_RTC_MONTH, bin2bcd(tm->tm_mon + 1))
| FIELD_PREP(AT91_RTC_DAY, bin2bcd(tm->tm_wday + 1))
| FIELD_PREP(AT91_RTC_DATE, bin2bcd(tm->tm_mday)));
/* Restart Time/Calendar */
cr = at91_rtc_read(AT91_RTC_CR);
......@@ -211,25 +257,17 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
*/
static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct rtc_time tm;
at91_rtc_decodetime(AT91_RTC_TIMR, AT91_RTC_CALR, &tm);
tm.tm_mon = alrm->time.tm_mon;
tm.tm_mday = alrm->time.tm_mday;
tm.tm_hour = alrm->time.tm_hour;
tm.tm_min = alrm->time.tm_min;
tm.tm_sec = alrm->time.tm_sec;
struct rtc_time tm = alrm->time;
at91_rtc_write_idr(AT91_RTC_ALARM);
at91_rtc_write(AT91_RTC_TIMALR,
bin2bcd(tm.tm_sec) << 0
| bin2bcd(tm.tm_min) << 8
| bin2bcd(tm.tm_hour) << 16
FIELD_PREP(AT91_RTC_SEC, bin2bcd(alrm->time.tm_sec))
| FIELD_PREP(AT91_RTC_MIN, bin2bcd(alrm->time.tm_min))
| FIELD_PREP(AT91_RTC_HOUR, bin2bcd(alrm->time.tm_hour))
| AT91_RTC_HOUREN | AT91_RTC_MINEN | AT91_RTC_SECEN);
at91_rtc_write(AT91_RTC_CALALR,
bin2bcd(tm.tm_mon + 1) << 16 /* tm_mon starts at zero */
| bin2bcd(tm.tm_mday) << 24
FIELD_PREP(AT91_RTC_MONTH, bin2bcd(alrm->time.tm_mon + 1))
| FIELD_PREP(AT91_RTC_DATE, bin2bcd(alrm->time.tm_mday))
| AT91_RTC_DATEEN | AT91_RTC_MTHEN);
if (alrm->enabled) {
......@@ -254,20 +292,6 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
return 0;
}
/*
* Provide additional RTC information in /proc/driver/rtc
*/
static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
{
unsigned long imr = at91_rtc_read_imr();
seq_printf(seq, "update_IRQ\t: %s\n",
(imr & AT91_RTC_ACKUPD) ? "yes" : "no");
seq_printf(seq, "periodic_IRQ\t: %s\n",
(imr & AT91_RTC_SECEV) ? "yes" : "no");
return 0;
}
/*
* IRQ handler for the RTC
......@@ -326,6 +350,12 @@ static const struct of_device_id at91_rtc_dt_ids[] = {
}, {
.compatible = "atmel,at91sam9x5-rtc",
.data = &at91sam9x5_config,
}, {
.compatible = "atmel,sama5d4-rtc",
.data = &at91rm9200_config,
}, {
.compatible = "atmel,sama5d2-rtc",
.data = &at91rm9200_config,
}, {
/* sentinel */
}
......@@ -337,7 +367,6 @@ static const struct rtc_class_ops at91_rtc_ops = {
.set_time = at91_rtc_settime,
.read_alarm = at91_rtc_readalarm,
.set_alarm = at91_rtc_setalarm,
.proc = at91_rtc_proc,
.alarm_irq_enable = at91_rtc_alarm_irq_enable,
};
......
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* arch/arm/mach-at91/include/mach/at91_rtc.h
*
* Copyright (C) 2005 Ivan Kokshaysky
* Copyright (C) SAN People
*
* Real Time Clock (RTC) - System peripheral registers.
* Based on AT91RM9200 datasheet revision E.
*/
#ifndef AT91_RTC_H
#define AT91_RTC_H
#define AT91_RTC_CR 0x00 /* Control Register */
#define AT91_RTC_UPDTIM (1 << 0) /* Update Request Time Register */
#define AT91_RTC_UPDCAL (1 << 1) /* Update Request Calendar Register */
#define AT91_RTC_TIMEVSEL (3 << 8) /* Time Event Selection */
#define AT91_RTC_TIMEVSEL_MINUTE (0 << 8)
#define AT91_RTC_TIMEVSEL_HOUR (1 << 8)
#define AT91_RTC_TIMEVSEL_DAY24 (2 << 8)
#define AT91_RTC_TIMEVSEL_DAY12 (3 << 8)
#define AT91_RTC_CALEVSEL (3 << 16) /* Calendar Event Selection */
#define AT91_RTC_CALEVSEL_WEEK (0 << 16)
#define AT91_RTC_CALEVSEL_MONTH (1 << 16)
#define AT91_RTC_CALEVSEL_YEAR (2 << 16)
#define AT91_RTC_MR 0x04 /* Mode Register */
#define AT91_RTC_HRMOD (1 << 0) /* 12/24 Hour Mode */
#define AT91_RTC_TIMR 0x08 /* Time Register */
#define AT91_RTC_SEC (0x7f << 0) /* Current Second */
#define AT91_RTC_MIN (0x7f << 8) /* Current Minute */
#define AT91_RTC_HOUR (0x3f << 16) /* Current Hour */
#define AT91_RTC_AMPM (1 << 22) /* Ante Meridiem Post Meridiem Indicator */
#define AT91_RTC_CALR 0x0c /* Calendar Register */
#define AT91_RTC_CENT (0x7f << 0) /* Current Century */
#define AT91_RTC_YEAR (0xff << 8) /* Current Year */
#define AT91_RTC_MONTH (0x1f << 16) /* Current Month */
#define AT91_RTC_DAY (7 << 21) /* Current Day */
#define AT91_RTC_DATE (0x3f << 24) /* Current Date */
#define AT91_RTC_TIMALR 0x10 /* Time Alarm Register */
#define AT91_RTC_SECEN (1 << 7) /* Second Alarm Enable */
#define AT91_RTC_MINEN (1 << 15) /* Minute Alarm Enable */
#define AT91_RTC_HOUREN (1 << 23) /* Hour Alarm Enable */
#define AT91_RTC_CALALR 0x14 /* Calendar Alarm Register */
#define AT91_RTC_MTHEN (1 << 23) /* Month Alarm Enable */
#define AT91_RTC_DATEEN (1 << 31) /* Date Alarm Enable */
#define AT91_RTC_SR 0x18 /* Status Register */
#define AT91_RTC_ACKUPD (1 << 0) /* Acknowledge for Update */
#define AT91_RTC_ALARM (1 << 1) /* Alarm Flag */
#define AT91_RTC_SECEV (1 << 2) /* Second Event */
#define AT91_RTC_TIMEV (1 << 3) /* Time Event */
#define AT91_RTC_CALEV (1 << 4) /* Calendar Event */
#define AT91_RTC_SCCR 0x1c /* Status Clear Command Register */
#define AT91_RTC_IER 0x20 /* Interrupt Enable Register */
#define AT91_RTC_IDR 0x24 /* Interrupt Disable Register */
#define AT91_RTC_IMR 0x28 /* Interrupt Mask Register */
#define AT91_RTC_VER 0x2c /* Valid Entry Register */
#define AT91_RTC_NVTIM (1 << 0) /* Non valid Time */
#define AT91_RTC_NVCAL (1 << 1) /* Non valid Calendar */
#define AT91_RTC_NVTIMALR (1 << 2) /* Non valid Time Alarm */
#define AT91_RTC_NVCALALR (1 << 3) /* Non valid Calendar Alarm */
#endif
......@@ -850,7 +850,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
rtc_cmos_int_handler = cmos_interrupt;
retval = request_irq(rtc_irq, rtc_cmos_int_handler,
IRQF_SHARED, dev_name(&cmos_rtc.rtc->dev),
0, dev_name(&cmos_rtc.rtc->dev),
cmos_rtc.rtc);
if (retval < 0) {
dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq);
......@@ -1197,8 +1197,6 @@ static void rtc_wake_off(struct device *dev)
/* Enable use_acpi_alarm mode for Intel platforms no earlier than 2015 */
static void use_acpi_alarm_quirks(void)
{
int year;
if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
return;
......@@ -1208,7 +1206,9 @@ static void use_acpi_alarm_quirks(void)
if (!is_hpet_enabled())
return;
if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year >= 2015)
if (dmi_get_bios_year() < 2015)
return;
use_acpi_alarm = true;
}
#else
......@@ -1305,7 +1305,7 @@ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
* hardcode it on systems with a legacy PIC.
*/
if (nr_legacy_irqs())
irq = 8;
irq = RTC_IRQ;
#endif
return cmos_do_probe(&pnp->dev,
pnp_get_resource(pnp, IORESOURCE_IO, 0), irq);
......
......@@ -75,7 +75,6 @@ static const struct spi_device_id ds1343_id[] = {
MODULE_DEVICE_TABLE(spi, ds1343_id);
struct ds1343_priv {
struct spi_device *spi;
struct rtc_device *rtc;
struct regmap *map;
int irq;
......@@ -362,12 +361,13 @@ static int ds1343_probe(struct spi_device *spi)
if (!priv)
return -ENOMEM;
priv->spi = spi;
/* RTC DS1347 works in spi mode 3 and
* its chip select is active high
* its chip select is active high. Active high should be defined as
* "inverse polarity" as GPIO-based chip selects can be logically
* active high but inverted by the GPIO library.
*/
spi->mode = SPI_MODE_3 | SPI_CS_HIGH;
spi->mode |= SPI_MODE_3;
spi->mode ^= SPI_CS_HIGH;
spi->bits_per_word = 8;
res = spi_setup(spi);
if (res)
......
......@@ -78,7 +78,6 @@
struct hym8563 {
struct i2c_client *client;
struct rtc_device *rtc;
bool valid;
#ifdef CONFIG_COMMON_CLK
struct clk_hw clkout_hw;
#endif
......@@ -91,19 +90,19 @@ struct hym8563 {
static int hym8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct i2c_client *client = to_i2c_client(dev);
struct hym8563 *hym8563 = i2c_get_clientdata(client);
u8 buf[7];
int ret;
if (!hym8563->valid) {
dev_warn(&client->dev, "no valid clock/calendar values available\n");
return -EPERM;
}
ret = i2c_smbus_read_i2c_block_data(client, HYM8563_SEC, 7, buf);
if (ret < 0)
return ret;
if (buf[0] & HYM8563_SEC_VL) {
dev_warn(&client->dev,
"no valid clock/calendar values available\n");
return -EINVAL;
}
tm->tm_sec = bcd2bin(buf[0] & HYM8563_SEC_MASK);
tm->tm_min = bcd2bin(buf[1] & HYM8563_MIN_MASK);
tm->tm_hour = bcd2bin(buf[2] & HYM8563_HOUR_MASK);
......@@ -118,7 +117,6 @@ static int hym8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int hym8563_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct i2c_client *client = to_i2c_client(dev);
struct hym8563 *hym8563 = i2c_get_clientdata(client);
u8 buf[7];
int ret;
......@@ -157,8 +155,6 @@ static int hym8563_rtc_set_time(struct device *dev, struct rtc_time *tm)
if (ret < 0)
return ret;
hym8563->valid = true;
return 0;
}
......@@ -556,9 +552,8 @@ static int hym8563_probe(struct i2c_client *client,
if (ret < 0)
return ret;
hym8563->valid = !(ret & HYM8563_SEC_VL);
dev_dbg(&client->dev, "rtc information is %s\n",
hym8563->valid ? "valid" : "invalid");
(ret & HYM8563_SEC_VL) ? "invalid" : "valid");
hym8563->rtc = devm_rtc_device_register(&client->dev, client->name,
&hym8563_rtc_ops, THIS_MODULE);
......
// SPDX-License-Identifier: GPL-2.0
/*
* MOXA ART RTC driver.
*
......@@ -7,10 +8,6 @@
*
* Based on code from
* Moxa Technology Co., Ltd. <www.moxa.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/init.h>
......
......@@ -297,15 +297,7 @@ static int mtk_rtc_probe(struct platform_device *pdev)
rtc->rtc_dev->ops = &mtk_rtc_ops;
ret = rtc_register_device(rtc->rtc_dev);
if (ret)
goto out_free_irq;
return 0;
out_free_irq:
free_irq(rtc->irq, rtc);
return ret;
return rtc_register_device(rtc->rtc_dev);
}
#ifdef CONFIG_PM_SLEEP
......
......@@ -616,7 +616,7 @@ static int rtc_pinconf_get(struct pinctrl_dev *pctldev,
break;
default:
return -ENOTSUPP;
};
}
*config = pinconf_to_config_packed(param, arg);
......
......@@ -199,11 +199,9 @@ static int pcf2127_rtc_ioctl(struct device *dev,
if (ret)
return ret;
touser = touser & PCF2127_BIT_CTRL3_BLF ? 1 : 0;
touser = touser & PCF2127_BIT_CTRL3_BLF ? RTC_VL_BACKUP_LOW : 0;
if (copy_to_user((void __user *)arg, &touser, sizeof(int)))
return -EFAULT;
return 0;
return put_user(touser, (unsigned int __user *)arg);
default:
return -ENOIOCTLCMD;
}
......
......@@ -289,21 +289,9 @@ static int pcf85063_ioctl(struct device *dev, unsigned int cmd,
if (ret < 0)
return ret;
if (status & PCF85063_REG_SC_OS)
dev_warn(&pcf85063->rtc->dev, "Voltage low, data loss detected.\n");
status = status & PCF85063_REG_SC_OS ? RTC_VL_DATA_INVALID : 0;
status &= PCF85063_REG_SC_OS;
if (copy_to_user((void __user *)arg, &status, sizeof(int)))
return -EFAULT;
return 0;
case RTC_VL_CLR:
ret = regmap_update_bits(pcf85063->regmap, PCF85063_REG_SC,
PCF85063_REG_SC_OS, 0);
return ret;
return put_user(status, (unsigned int __user *)arg);
default:
return -ENOIOCTLCMD;
......
......@@ -282,11 +282,11 @@ static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd,
ret = pcf8523_voltage_low(client);
if (ret < 0)
return ret;
if (ret)
ret = RTC_VL_BACKUP_LOW;
if (copy_to_user((void __user *)arg, &ret, sizeof(int)))
return -EFAULT;
return put_user(ret, (unsigned int __user *)arg);
return 0;
default:
return -ENOIOCTLCMD;
}
......
......@@ -22,8 +22,8 @@
#define PCF8563_REG_ST1 0x00 /* status */
#define PCF8563_REG_ST2 0x01
#define PCF8563_BIT_AIE (1 << 1)
#define PCF8563_BIT_AF (1 << 3)
#define PCF8563_BIT_AIE BIT(1)
#define PCF8563_BIT_AF BIT(3)
#define PCF8563_BITS_ST2_N (7 << 5)
#define PCF8563_REG_SC 0x02 /* datetime */
......@@ -76,7 +76,6 @@ struct pcf8563 {
* 1970...2069.
*/
int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */
int voltage_low; /* incicates if a low_voltage was detected */
struct i2c_client *client;
#ifdef CONFIG_COMMON_CLK
......@@ -208,7 +207,6 @@ static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
return err;
if (buf[PCF8563_REG_SC] & PCF8563_SC_LV) {
pcf8563->voltage_low = 1;
dev_err(&client->dev,
"low voltage detected, date/time is not reliable.\n");
return -EINVAL;
......@@ -276,43 +274,23 @@ static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm)
9 - PCF8563_REG_SC, buf + PCF8563_REG_SC);
}
#ifdef CONFIG_RTC_INTF_DEV
static int pcf8563_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
struct pcf8563 *pcf8563 = i2c_get_clientdata(to_i2c_client(dev));
struct rtc_time tm;
struct i2c_client *client = to_i2c_client(dev);
int ret;
switch (cmd) {
case RTC_VL_READ:
if (pcf8563->voltage_low)
dev_info(dev, "low voltage detected, date/time is not reliable.\n");
if (copy_to_user((void __user *)arg, &pcf8563->voltage_low,
sizeof(int)))
return -EFAULT;
return 0;
case RTC_VL_CLR:
/*
* Clear the VL bit in the seconds register in case
* the time has not been set already (which would
* have cleared it). This does not really matter
* because of the cached voltage_low value but do it
* anyway for consistency.
*/
if (pcf8563_rtc_read_time(dev, &tm))
pcf8563_rtc_set_time(dev, &tm);
/* Clear the cached value. */
pcf8563->voltage_low = 0;
ret = i2c_smbus_read_byte_data(client, PCF8563_REG_SC);
if (ret < 0)
return ret;
return 0;
return put_user(ret & PCF8563_SC_LV ? RTC_VL_DATA_INVALID : 0,
(unsigned int __user *)arg);
default:
return -ENOIOCTLCMD;
}
}
#else
#define pcf8563_rtc_ioctl NULL
#endif
static int pcf8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm)
{
......
......@@ -428,21 +428,8 @@ static int rv3028_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
if (ret < 0)
return ret;
if (status & RV3028_STATUS_PORF)
dev_warn(&rv3028->rtc->dev, "Voltage low, data loss detected.\n");
status &= RV3028_STATUS_PORF;
if (copy_to_user((void __user *)arg, &status, sizeof(int)))
return -EFAULT;
return 0;
case RTC_VL_CLR:
ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS,
RV3028_STATUS_PORF, 0);
return ret;
status = status & RV3028_STATUS_PORF ? RTC_VL_DATA_INVALID : 0;
return put_user(status, (unsigned int __user *)arg);
default:
return -ENOIOCTLCMD;
......
......@@ -109,10 +109,8 @@
#define RV3029_CONTROL_E2P_TOV_MASK 0x3F /* XTAL turnover temp mask */
/* user ram section */
#define RV3029_USR1_RAM_PAGE 0x38
#define RV3029_USR1_SECTION_LEN 0x04
#define RV3029_USR2_RAM_PAGE 0x3C
#define RV3029_USR2_SECTION_LEN 0x04
#define RV3029_RAM_PAGE 0x38
#define RV3029_RAM_SECTION_LEN 8
struct rv3029_data {
struct device *dev;
......@@ -121,77 +119,13 @@ struct rv3029_data {
int irq;
};
static int rv3029_read_regs(struct device *dev, u8 reg, u8 *buf,
unsigned int len)
{
struct rv3029_data *rv3029 = dev_get_drvdata(dev);
if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
(reg + len > RV3029_USR1_RAM_PAGE + 8))
return -EINVAL;
return regmap_bulk_read(rv3029->regmap, reg, buf, len);
}
static int rv3029_write_regs(struct device *dev, u8 reg, u8 const buf[],
unsigned int len)
{
struct rv3029_data *rv3029 = dev_get_drvdata(dev);
if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
(reg + len > RV3029_USR1_RAM_PAGE + 8))
return -EINVAL;
return regmap_bulk_write(rv3029->regmap, reg, buf, len);
}
static int rv3029_update_bits(struct device *dev, u8 reg, u8 mask, u8 set)
{
u8 buf;
int ret;
ret = rv3029_read_regs(dev, reg, &buf, 1);
if (ret < 0)
return ret;
buf &= ~mask;
buf |= set & mask;
ret = rv3029_write_regs(dev, reg, &buf, 1);
if (ret < 0)
return ret;
return 0;
}
static int rv3029_get_sr(struct device *dev, u8 *buf)
{
int ret = rv3029_read_regs(dev, RV3029_STATUS, buf, 1);
if (ret < 0)
return -EIO;
dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
return 0;
}
static int rv3029_set_sr(struct device *dev, u8 val)
{
u8 buf[1];
int sr;
buf[0] = val;
sr = rv3029_write_regs(dev, RV3029_STATUS, buf, 1);
dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
if (sr < 0)
return -EIO;
return 0;
}
static int rv3029_eeprom_busywait(struct device *dev)
static int rv3029_eeprom_busywait(struct rv3029_data *rv3029)
{
unsigned int sr;
int i, ret;
u8 sr;
for (i = 100; i > 0; i--) {
ret = rv3029_get_sr(dev, &sr);
ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr);
if (ret < 0)
break;
if (!(sr & RV3029_STATUS_EEBUSY))
......@@ -199,126 +133,128 @@ static int rv3029_eeprom_busywait(struct device *dev)
usleep_range(1000, 10000);
}
if (i <= 0) {
dev_err(dev, "EEPROM busy wait timeout.\n");
dev_err(rv3029->dev, "EEPROM busy wait timeout.\n");
return -ETIMEDOUT;
}
return ret;
}
static int rv3029_eeprom_exit(struct device *dev)
static int rv3029_eeprom_exit(struct rv3029_data *rv3029)
{
/* Re-enable eeprom refresh */
return rv3029_update_bits(dev, RV3029_ONOFF_CTRL,
return regmap_update_bits(rv3029->regmap, RV3029_ONOFF_CTRL,
RV3029_ONOFF_CTRL_EERE,
RV3029_ONOFF_CTRL_EERE);
}
static int rv3029_eeprom_enter(struct device *dev)
static int rv3029_eeprom_enter(struct rv3029_data *rv3029)
{
unsigned int sr;
int ret;
u8 sr;
/* Check whether we are in the allowed voltage range. */
ret = rv3029_get_sr(dev, &sr);
ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr);
if (ret < 0)
return ret;
if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
if (sr & RV3029_STATUS_VLOW2)
return -ENODEV;
if (sr & RV3029_STATUS_VLOW1) {
/* We clear the bits and retry once just in case
* we had a brown out in early startup.
*/
sr &= ~RV3029_STATUS_VLOW1;
sr &= ~RV3029_STATUS_VLOW2;
ret = rv3029_set_sr(dev, sr);
ret = regmap_update_bits(rv3029->regmap, RV3029_STATUS,
RV3029_STATUS_VLOW1, 0);
if (ret < 0)
return ret;
usleep_range(1000, 10000);
ret = rv3029_get_sr(dev, &sr);
ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr);
if (ret < 0)
return ret;
if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
dev_err(dev,
if (sr & RV3029_STATUS_VLOW1) {
dev_err(rv3029->dev,
"Supply voltage is too low to safely access the EEPROM.\n");
return -ENODEV;
}
}
/* Disable eeprom refresh. */
ret = rv3029_update_bits(dev, RV3029_ONOFF_CTRL, RV3029_ONOFF_CTRL_EERE,
0);
ret = regmap_update_bits(rv3029->regmap, RV3029_ONOFF_CTRL,
RV3029_ONOFF_CTRL_EERE, 0);
if (ret < 0)
return ret;
/* Wait for any previous eeprom accesses to finish. */
ret = rv3029_eeprom_busywait(dev);
ret = rv3029_eeprom_busywait(rv3029);
if (ret < 0)
rv3029_eeprom_exit(dev);
rv3029_eeprom_exit(rv3029);
return ret;
}
static int rv3029_eeprom_read(struct device *dev, u8 reg,
static int rv3029_eeprom_read(struct rv3029_data *rv3029, u8 reg,
u8 buf[], size_t len)
{
int ret, err;
err = rv3029_eeprom_enter(dev);
err = rv3029_eeprom_enter(rv3029);
if (err < 0)
return err;
ret = rv3029_read_regs(dev, reg, buf, len);
ret = regmap_bulk_read(rv3029->regmap, reg, buf, len);
err = rv3029_eeprom_exit(dev);
err = rv3029_eeprom_exit(rv3029);
if (err < 0)
return err;
return ret;
}
static int rv3029_eeprom_write(struct device *dev, u8 reg,
static int rv3029_eeprom_write(struct rv3029_data *rv3029, u8 reg,
u8 const buf[], size_t len)
{
unsigned int tmp;
int ret, err;
size_t i;
u8 tmp;
err = rv3029_eeprom_enter(dev);
err = rv3029_eeprom_enter(rv3029);
if (err < 0)
return err;
for (i = 0; i < len; i++, reg++) {
ret = rv3029_read_regs(dev, reg, &tmp, 1);
ret = regmap_read(rv3029->regmap, reg, &tmp);
if (ret < 0)
break;
if (tmp != buf[i]) {
ret = rv3029_write_regs(dev, reg, &buf[i], 1);
tmp = buf[i];
ret = regmap_write(rv3029->regmap, reg, tmp);
if (ret < 0)
break;
}
ret = rv3029_eeprom_busywait(dev);
ret = rv3029_eeprom_busywait(rv3029);
if (ret < 0)
break;
}
err = rv3029_eeprom_exit(dev);
err = rv3029_eeprom_exit(rv3029);
if (err < 0)
return err;
return ret;
}
static int rv3029_eeprom_update_bits(struct device *dev,
static int rv3029_eeprom_update_bits(struct rv3029_data *rv3029,
u8 reg, u8 mask, u8 set)
{
u8 buf;
int ret;
ret = rv3029_eeprom_read(dev, reg, &buf, 1);
ret = rv3029_eeprom_read(rv3029, reg, &buf, 1);
if (ret < 0)
return ret;
buf &= ~mask;
buf |= set & mask;
ret = rv3029_eeprom_write(dev, reg, &buf, 1);
ret = rv3029_eeprom_write(rv3029, reg, &buf, 1);
if (ret < 0)
return ret;
......@@ -330,20 +266,20 @@ static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
struct device *dev = dev_id;
struct rv3029_data *rv3029 = dev_get_drvdata(dev);
struct mutex *lock = &rv3029->rtc->ops_lock;
unsigned int flags, controls;
unsigned long events = 0;
u8 flags, controls;
int ret;
mutex_lock(lock);
ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
ret = regmap_read(rv3029->regmap, RV3029_IRQ_CTRL, &controls);
if (ret) {
dev_warn(dev, "Read IRQ Control Register error %d\n", ret);
mutex_unlock(lock);
return IRQ_NONE;
}
ret = rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
ret = regmap_read(rv3029->regmap, RV3029_IRQ_FLAGS, &flags);
if (ret) {
dev_warn(dev, "Read IRQ Flags Register error %d\n", ret);
mutex_unlock(lock);
......@@ -358,8 +294,8 @@ static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
if (events) {
rtc_update_irq(rv3029->rtc, 1, events);
rv3029_write_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
regmap_write(rv3029->regmap, RV3029_IRQ_FLAGS, flags);
regmap_write(rv3029->regmap, RV3029_IRQ_CTRL, controls);
}
mutex_unlock(lock);
......@@ -368,22 +304,22 @@ static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
{
u8 buf[1];
struct rv3029_data *rv3029 = dev_get_drvdata(dev);
unsigned int sr;
int ret;
u8 regs[RV3029_WATCH_SECTION_LEN] = { 0, };
ret = rv3029_get_sr(dev, buf);
if (ret < 0) {
dev_err(dev, "%s: reading SR failed\n", __func__);
return -EIO;
}
ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr);
if (ret < 0)
return ret;
ret = rv3029_read_regs(dev, RV3029_W_SEC, regs,
if (sr & (RV3029_STATUS_VLOW2 | RV3029_STATUS_PON))
return -EINVAL;
ret = regmap_bulk_read(rv3029->regmap, RV3029_W_SEC, regs,
RV3029_WATCH_SECTION_LEN);
if (ret < 0) {
dev_err(dev, "%s: reading RTC section failed\n", __func__);
if (ret < 0)
return ret;
}
tm->tm_sec = bcd2bin(regs[RV3029_W_SEC - RV3029_W_SEC]);
tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES - RV3029_W_SEC]);
......@@ -411,34 +347,24 @@ static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
struct rv3029_data *rv3029 = dev_get_drvdata(dev);
struct rtc_time *const tm = &alarm->time;
unsigned int controls, flags;
int ret;
u8 regs[8], controls, flags;
ret = rv3029_get_sr(dev, regs);
if (ret < 0) {
dev_err(dev, "%s: reading SR failed\n", __func__);
return -EIO;
}
u8 regs[8];
ret = rv3029_read_regs(dev, RV3029_A_SC, regs,
ret = regmap_bulk_read(rv3029->regmap, RV3029_A_SC, regs,
RV3029_ALARM_SECTION_LEN);
if (ret < 0) {
dev_err(dev, "%s: reading alarm section failed\n", __func__);
if (ret < 0)
return ret;
}
ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
if (ret) {
dev_err(dev, "Read IRQ Control Register error %d\n", ret);
ret = regmap_read(rv3029->regmap, RV3029_IRQ_CTRL, &controls);
if (ret)
return ret;
}
ret = rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
if (ret < 0) {
dev_err(dev, "Read IRQ Flags Register error %d\n", ret);
ret = regmap_read(rv3029->regmap, RV3029_IRQ_FLAGS, &flags);
if (ret < 0)
return ret;
}
tm->tm_sec = bcd2bin(regs[RV3029_A_SC - RV3029_A_SC] & 0x7f);
tm->tm_min = bcd2bin(regs[RV3029_A_MN - RV3029_A_SC] & 0x7f);
......@@ -456,50 +382,20 @@ static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
static int rv3029_alarm_irq_enable(struct device *dev, unsigned int enable)
{
int ret;
u8 controls;
ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
if (ret < 0) {
dev_warn(dev, "Read IRQ Control Register error %d\n", ret);
return ret;
}
/* enable/disable AIE irq */
if (enable)
controls |= RV3029_IRQ_CTRL_AIE;
else
controls &= ~RV3029_IRQ_CTRL_AIE;
ret = rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
if (ret < 0) {
dev_err(dev, "can't update INT reg\n");
return ret;
}
struct rv3029_data *rv3029 = dev_get_drvdata(dev);
return 0;
return regmap_update_bits(rv3029->regmap, RV3029_IRQ_CTRL,
RV3029_IRQ_CTRL_AIE,
enable ? RV3029_IRQ_CTRL_AIE : 0);
}
static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
struct rv3029_data *rv3029 = dev_get_drvdata(dev);
struct rtc_time *const tm = &alarm->time;
int ret;
u8 regs[8];
/*
* The clock has an 8 bit wide bcd-coded register (they never learn)
* for the year. tm_year is an offset from 1900 and we are interested
* in the 2000-2099 range, so any value less than 100 is invalid.
*/
if (tm->tm_year < 100)
return -EINVAL;
ret = rv3029_get_sr(dev, regs);
if (ret < 0) {
dev_err(dev, "%s: reading SR failed\n", __func__);
return -EIO;
}
/* Activate all the alarms with AE_x bit */
regs[RV3029_A_SC - RV3029_A_SC] = bin2bcd(tm->tm_sec) | RV3029_A_AE_X;
regs[RV3029_A_MN - RV3029_A_SC] = bin2bcd(tm->tm_min) | RV3029_A_AE_X;
......@@ -515,39 +411,20 @@ static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
| RV3029_A_AE_X;
/* Write the alarm */
ret = rv3029_write_regs(dev, RV3029_A_SC, regs,
ret = regmap_bulk_write(rv3029->regmap, RV3029_A_SC, regs,
RV3029_ALARM_SECTION_LEN);
if (ret < 0)
return ret;
if (alarm->enabled) {
/* enable AIE irq */
ret = rv3029_alarm_irq_enable(dev, 1);
if (ret)
return ret;
} else {
/* disable AIE irq */
ret = rv3029_alarm_irq_enable(dev, 0);
if (ret)
return ret;
}
return 0;
return rv3029_alarm_irq_enable(dev, alarm->enabled);
}
static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
{
struct rv3029_data *rv3029 = dev_get_drvdata(dev);
u8 regs[8];
int ret;
/*
* The clock has an 8 bit wide bcd-coded register (they never learn)
* for the year. tm_year is an offset from 1900 and we are interested
* in the 2000-2099 range, so any value less than 100 is invalid.
*/
if (tm->tm_year < 100)
return -EINVAL;
regs[RV3029_W_SEC - RV3029_W_SEC] = bin2bcd(tm->tm_sec);
regs[RV3029_W_MINUTES - RV3029_W_SEC] = bin2bcd(tm->tm_min);
regs[RV3029_W_HOURS - RV3029_W_SEC] = bin2bcd(tm->tm_hour);
......@@ -556,24 +433,55 @@ static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
regs[RV3029_W_DAYS - RV3029_W_SEC] = bin2bcd(tm->tm_wday + 1) & 0x7;
regs[RV3029_W_YEARS - RV3029_W_SEC] = bin2bcd(tm->tm_year - 100);
ret = rv3029_write_regs(dev, RV3029_W_SEC, regs,
ret = regmap_bulk_write(rv3029->regmap, RV3029_W_SEC, regs,
RV3029_WATCH_SECTION_LEN);
if (ret < 0)
return ret;
ret = rv3029_get_sr(dev, regs);
if (ret < 0) {
dev_err(dev, "%s: reading SR failed\n", __func__);
return ret;
}
/* clear PON bit */
ret = rv3029_set_sr(dev, (regs[0] & ~RV3029_STATUS_PON));
if (ret < 0) {
dev_err(dev, "%s: reading SR failed\n", __func__);
/* clear PON and VLOW2 bits */
return regmap_update_bits(rv3029->regmap, RV3029_STATUS,
RV3029_STATUS_PON | RV3029_STATUS_VLOW2, 0);
}
static int rv3029_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
struct rv3029_data *rv3029 = dev_get_drvdata(dev);
unsigned long vl = 0;
int sr, ret = 0;
switch (cmd) {
case RTC_VL_READ:
ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr);
if (ret < 0)
return ret;
if (sr & RV3029_STATUS_VLOW1)
vl = RTC_VL_ACCURACY_LOW;
if (sr & (RV3029_STATUS_VLOW2 | RV3029_STATUS_PON))
vl |= RTC_VL_DATA_INVALID;
return put_user(vl, (unsigned int __user *)arg);
case RTC_VL_CLR:
return regmap_update_bits(rv3029->regmap, RV3029_STATUS,
RV3029_STATUS_VLOW1, 0);
default:
return -ENOIOCTLCMD;
}
}
return 0;
static int rv3029_nvram_write(void *priv, unsigned int offset, void *val,
size_t bytes)
{
return regmap_bulk_write(priv, RV3029_RAM_PAGE + offset, val, bytes);
}
static int rv3029_nvram_read(void *priv, unsigned int offset, void *val,
size_t bytes)
{
return regmap_bulk_read(priv, RV3029_RAM_PAGE + offset, val, bytes);
}
static const struct rv3029_trickle_tab_elem {
......@@ -635,6 +543,7 @@ static const struct rv3029_trickle_tab_elem {
static void rv3029_trickle_config(struct device *dev)
{
struct rv3029_data *rv3029 = dev_get_drvdata(dev);
struct device_node *of_node = dev->of_node;
const struct rv3029_trickle_tab_elem *elem;
int i, err;
......@@ -661,7 +570,7 @@ static void rv3029_trickle_config(struct device *dev)
"Trickle charger enabled at %d ohms resistance.\n",
elem->r);
}
err = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
err = rv3029_eeprom_update_bits(rv3029, RV3029_CONTROL_E2P_EECTRL,
RV3029_TRICKLE_MASK,
trickle_set_bits);
if (err < 0)
......@@ -670,12 +579,12 @@ static void rv3029_trickle_config(struct device *dev)
#ifdef CONFIG_RTC_DRV_RV3029_HWMON
static int rv3029_read_temp(struct device *dev, int *temp_mC)
static int rv3029_read_temp(struct rv3029_data *rv3029, int *temp_mC)
{
unsigned int temp;
int ret;
u8 temp;
ret = rv3029_read_regs(dev, RV3029_TEMP_PAGE, &temp, 1);
ret = regmap_read(rv3029->regmap, RV3029_TEMP_PAGE, &temp);
if (ret < 0)
return ret;
......@@ -688,9 +597,10 @@ static ssize_t rv3029_hwmon_show_temp(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct rv3029_data *rv3029 = dev_get_drvdata(dev);
int ret, temp_mC;
ret = rv3029_read_temp(dev, &temp_mC);
ret = rv3029_read_temp(rv3029, &temp_mC);
if (ret < 0)
return ret;
......@@ -702,9 +612,10 @@ static ssize_t rv3029_hwmon_set_update_interval(struct device *dev,
const char *buf,
size_t count)
{
struct rv3029_data *rv3029 = dev_get_drvdata(dev);
unsigned int th_set_bits = 0;
unsigned long interval_ms;
int ret;
u8 th_set_bits = 0;
ret = kstrtoul(buf, 10, &interval_ms);
if (ret < 0)
......@@ -715,7 +626,7 @@ static ssize_t rv3029_hwmon_set_update_interval(struct device *dev,
if (interval_ms >= 16000)
th_set_bits |= RV3029_EECTRL_THP;
}
ret = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
ret = rv3029_eeprom_update_bits(rv3029, RV3029_CONTROL_E2P_EECTRL,
RV3029_EECTRL_THE | RV3029_EECTRL_THP,
th_set_bits);
if (ret < 0)
......@@ -728,10 +639,11 @@ static ssize_t rv3029_hwmon_show_update_interval(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct rv3029_data *rv3029 = dev_get_drvdata(dev);
int ret, interval_ms;
u8 eectrl;
ret = rv3029_eeprom_read(dev, RV3029_CONTROL_E2P_EECTRL,
ret = rv3029_eeprom_read(rv3029, RV3029_CONTROL_E2P_EECTRL,
&eectrl, 1);
if (ret < 0)
return ret;
......@@ -785,14 +697,23 @@ static void rv3029_hwmon_register(struct device *dev, const char *name)
static struct rtc_class_ops rv3029_rtc_ops = {
.read_time = rv3029_read_time,
.set_time = rv3029_set_time,
.ioctl = rv3029_ioctl,
};
static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
const char *name)
{
struct rv3029_data *rv3029;
struct nvmem_config nvmem_cfg = {
.name = "rv3029_nvram",
.word_size = 1,
.stride = 1,
.size = RV3029_RAM_SECTION_LEN,
.type = NVMEM_TYPE_BATTERY_BACKED,
.reg_read = rv3029_nvram_read,
.reg_write = rv3029_nvram_write,
};
int rc = 0;
u8 buf[1];
rv3029 = devm_kzalloc(dev, sizeof(*rv3029), GFP_KERNEL);
if (!rv3029)
......@@ -803,21 +724,12 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
rv3029->dev = dev;
dev_set_drvdata(dev, rv3029);
rc = rv3029_get_sr(dev, buf);
if (rc < 0) {
dev_err(dev, "reading status failed\n");
return rc;
}
rv3029_trickle_config(dev);
rv3029_hwmon_register(dev, name);
rv3029->rtc = devm_rtc_device_register(dev, name, &rv3029_rtc_ops,
THIS_MODULE);
if (IS_ERR(rv3029->rtc)) {
dev_err(dev, "unable to register the class device\n");
rv3029->rtc = devm_rtc_allocate_device(dev);
if (IS_ERR(rv3029->rtc))
return PTR_ERR(rv3029->rtc);
}
if (rv3029->irq > 0) {
rc = devm_request_threaded_irq(dev, rv3029->irq,
......@@ -834,20 +746,48 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
}
}
rv3029->rtc->ops = &rv3029_rtc_ops;
rv3029->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
rv3029->rtc->range_max = RTC_TIMESTAMP_END_2079;
rc = rtc_register_device(rv3029->rtc);
if (rc)
return rc;
nvmem_cfg.priv = rv3029->regmap;
rtc_nvmem_register(rv3029->rtc, &nvmem_cfg);
return 0;
}
static const struct regmap_range rv3029_holes_range[] = {
regmap_reg_range(0x05, 0x07),
regmap_reg_range(0x0f, 0x0f),
regmap_reg_range(0x17, 0x17),
regmap_reg_range(0x1a, 0x1f),
regmap_reg_range(0x21, 0x27),
regmap_reg_range(0x34, 0x37),
};
static const struct regmap_access_table rv3029_regs = {
.no_ranges = rv3029_holes_range,
.n_no_ranges = ARRAY_SIZE(rv3029_holes_range),
};
static const struct regmap_config config = {
.reg_bits = 8,
.val_bits = 8,
.rd_table = &rv3029_regs,
.wr_table = &rv3029_regs,
.max_register = 0x3f,
};
#if IS_ENABLED(CONFIG_I2C)
static int rv3029_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct regmap *regmap;
static const struct regmap_config config = {
.reg_bits = 8,
.val_bits = 8,
};
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK |
I2C_FUNC_SMBUS_BYTE)) {
dev_err(&client->dev, "Adapter does not support SMBUS_I2C_BLOCK or SMBUS_I2C_BYTE\n");
......@@ -855,11 +795,8 @@ static int rv3029_i2c_probe(struct i2c_client *client,
}
regmap = devm_regmap_init_i2c(client, &config);
if (IS_ERR(regmap)) {
dev_err(&client->dev, "%s: regmap allocation failed: %ld\n",
__func__, PTR_ERR(regmap));
if (IS_ERR(regmap))
return PTR_ERR(regmap);
}
return rv3029_probe(&client->dev, regmap, client->irq, client->name);
}
......@@ -873,24 +810,20 @@ MODULE_DEVICE_TABLE(i2c, rv3029_id);
static const struct of_device_id rv3029_of_match[] = {
{ .compatible = "microcrystal,rv3029" },
/* Backward compatibility only, do not use compatibles below: */
{ .compatible = "rv3029" },
{ .compatible = "rv3029c2" },
{ .compatible = "mc,rv3029c2" },
{ }
};
MODULE_DEVICE_TABLE(of, rv3029_of_match);
static struct i2c_driver rv3029_driver = {
.driver = {
.name = "rtc-rv3029c2",
.name = "rv3029",
.of_match_table = of_match_ptr(rv3029_of_match),
},
.probe = rv3029_i2c_probe,
.id_table = rv3029_id,
};
static int rv3029_register_driver(void)
static int __init rv3029_register_driver(void)
{
return i2c_add_driver(&rv3029_driver);
}
......@@ -902,7 +835,7 @@ static void rv3029_unregister_driver(void)
#else
static int rv3029_register_driver(void)
static int __init rv3029_register_driver(void)
{
return 0;
}
......@@ -917,18 +850,11 @@ static void rv3029_unregister_driver(void)
static int rv3049_probe(struct spi_device *spi)
{
static const struct regmap_config config = {
.reg_bits = 8,
.val_bits = 8,
};
struct regmap *regmap;
regmap = devm_regmap_init_spi(spi, &config);
if (IS_ERR(regmap)) {
dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n",
__func__, PTR_ERR(regmap));
if (IS_ERR(regmap))
return PTR_ERR(regmap);
}
return rv3029_probe(&spi->dev, regmap, spi->irq, "rv3049");
}
......@@ -940,24 +866,24 @@ static struct spi_driver rv3049_driver = {
.probe = rv3049_probe,
};
static int rv3049_register_driver(void)
static int __init rv3049_register_driver(void)
{
return spi_register_driver(&rv3049_driver);
}
static void rv3049_unregister_driver(void)
static void __exit rv3049_unregister_driver(void)
{
spi_unregister_driver(&rv3049_driver);
}
#else
static int rv3049_register_driver(void)
static int __init rv3049_register_driver(void)
{
return 0;
}
static void rv3049_unregister_driver(void)
static void __exit rv3049_unregister_driver(void)
{
}
......@@ -968,16 +894,12 @@ static int __init rv30x9_init(void)
int ret;
ret = rv3029_register_driver();
if (ret) {
pr_err("Failed to register rv3029 driver: %d\n", ret);
if (ret)
return ret;
}
ret = rv3049_register_driver();
if (ret) {
pr_err("Failed to register rv3049 driver: %d\n", ret);
if (ret)
rv3029_unregister_driver();
}
return ret;
}
......
......@@ -411,6 +411,7 @@ static int rv8803_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
struct i2c_client *client = to_i2c_client(dev);
struct rv8803_data *rv8803 = dev_get_drvdata(dev);
unsigned int vl = 0;
int flags, ret = 0;
switch (cmd) {
......@@ -419,18 +420,15 @@ static int rv8803_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
if (flags < 0)
return flags;
if (flags & RV8803_FLAG_V1F)
if (flags & RV8803_FLAG_V1F) {
dev_warn(&client->dev, "Voltage low, temperature compensation stopped.\n");
vl = RTC_VL_ACCURACY_LOW;
}
if (flags & RV8803_FLAG_V2F)
dev_warn(&client->dev, "Voltage low, data loss detected.\n");
vl |= RTC_VL_DATA_INVALID;
flags &= RV8803_FLAG_V1F | RV8803_FLAG_V2F;
if (copy_to_user((void __user *)arg, &flags, sizeof(int)))
return -EFAULT;
return 0;
return put_user(vl, (unsigned int __user *)arg);
case RTC_VL_CLR:
mutex_lock(&rv8803->flags_lock);
......@@ -440,7 +438,7 @@ static int rv8803_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
return flags;
}
flags &= ~(RV8803_FLAG_V1F | RV8803_FLAG_V2F);
flags &= ~RV8803_FLAG_V1F;
ret = rv8803_write_reg(client, RV8803_FLAG, flags);
mutex_unlock(&rv8803->flags_lock);
if (ret)
......
......@@ -389,9 +389,8 @@ static int rx8010_alarm_irq_enable(struct device *dev,
static int rx8010_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
struct i2c_client *client = to_i2c_client(dev);
struct rx8010_data *rx8010 = dev_get_drvdata(dev);
int ret, tmp;
int tmp;
int flagreg;
switch (cmd) {
......@@ -400,24 +399,8 @@ static int rx8010_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
if (flagreg < 0)
return flagreg;
tmp = !!(flagreg & RX8010_FLAG_VLF);
if (copy_to_user((void __user *)arg, &tmp, sizeof(int)))
return -EFAULT;
return 0;
case RTC_VL_CLR:
flagreg = i2c_smbus_read_byte_data(rx8010->client, RX8010_FLAG);
if (flagreg < 0) {
return flagreg;
}
flagreg &= ~RX8010_FLAG_VLF;
ret = i2c_smbus_write_byte_data(client, RX8010_FLAG, flagreg);
if (ret < 0)
return ret;
return 0;
tmp = flagreg & RX8010_FLAG_VLF ? RTC_VL_DATA_INVALID : 0;
return put_user(tmp, (unsigned int __user *)arg);
default:
return -ENOIOCTLCMD;
......@@ -482,7 +465,7 @@ static int rx8010_probe(struct i2c_client *client,
rx8010->rtc->max_user_freq = 1;
return err;
return 0;
}
static struct i2c_driver rx8010_driver = {
......
......@@ -67,7 +67,6 @@ static const struct i2c_device_id rx8025_id[] = {
MODULE_DEVICE_TABLE(i2c, rx8025_id);
struct rx8025_data {
struct i2c_client *client;
struct rtc_device *rtc;
u8 ctrl1;
};
......@@ -103,10 +102,10 @@ static s32 rx8025_write_regs(const struct i2c_client *client,
static int rx8025_check_validity(struct device *dev)
{
struct rx8025_data *rx8025 = dev_get_drvdata(dev);
struct i2c_client *client = to_i2c_client(dev);
int ctrl2;
ctrl2 = rx8025_read_reg(rx8025->client, RX8025_REG_CTRL2);
ctrl2 = rx8025_read_reg(client, RX8025_REG_CTRL2);
if (ctrl2 < 0)
return ctrl2;
......@@ -178,6 +177,7 @@ static irqreturn_t rx8025_handle_irq(int irq, void *dev_id)
static int rx8025_get_time(struct device *dev, struct rtc_time *dt)
{
struct i2c_client *client = to_i2c_client(dev);
struct rx8025_data *rx8025 = dev_get_drvdata(dev);
u8 date[7];
int err;
......@@ -186,7 +186,7 @@ static int rx8025_get_time(struct device *dev, struct rtc_time *dt)
if (err)
return err;
err = rx8025_read_regs(rx8025->client, RX8025_REG_SEC, 7, date);
err = rx8025_read_regs(client, RX8025_REG_SEC, 7, date);
if (err)
return err;
......@@ -211,6 +211,7 @@ static int rx8025_get_time(struct device *dev, struct rtc_time *dt)
static int rx8025_set_time(struct device *dev, struct rtc_time *dt)
{
struct i2c_client *client = to_i2c_client(dev);
struct rx8025_data *rx8025 = dev_get_drvdata(dev);
u8 date[7];
int ret;
......@@ -237,11 +238,11 @@ static int rx8025_set_time(struct device *dev, struct rtc_time *dt)
dev_dbg(dev, "%s: write %7ph\n", __func__, date);
ret = rx8025_write_regs(rx8025->client, RX8025_REG_SEC, 7, date);
ret = rx8025_write_regs(client, RX8025_REG_SEC, 7, date);
if (ret < 0)
return ret;
return rx8025_reset_validity(rx8025->client);
return rx8025_reset_validity(client);
}
static int rx8025_init_client(struct i2c_client *client)
......@@ -251,7 +252,7 @@ static int rx8025_init_client(struct i2c_client *client)
int need_clear = 0;
int err;
err = rx8025_read_regs(rx8025->client, RX8025_REG_CTRL1, 2, ctrl);
err = rx8025_read_regs(client, RX8025_REG_CTRL1, 2, ctrl);
if (err)
goto out;
......@@ -280,8 +281,8 @@ static int rx8025_init_client(struct i2c_client *client)
/* Alarm support */
static int rx8025_read_alarm(struct device *dev, struct rtc_wkalrm *t)
{
struct i2c_client *client = to_i2c_client(dev);
struct rx8025_data *rx8025 = dev_get_drvdata(dev);
struct i2c_client *client = rx8025->client;
u8 ald[2];
int ctrl2, err;
......@@ -347,18 +348,18 @@ static int rx8025_set_alarm(struct device *dev, struct rtc_wkalrm *t)
if (rx8025->ctrl1 & RX8025_BIT_CTRL1_DALE) {
rx8025->ctrl1 &= ~RX8025_BIT_CTRL1_DALE;
err = rx8025_write_reg(rx8025->client, RX8025_REG_CTRL1,
err = rx8025_write_reg(client, RX8025_REG_CTRL1,
rx8025->ctrl1);
if (err)
return err;
}
err = rx8025_write_regs(rx8025->client, RX8025_REG_ALDMIN, 2, ald);
err = rx8025_write_regs(client, RX8025_REG_ALDMIN, 2, ald);
if (err)
return err;
if (t->enabled) {
rx8025->ctrl1 |= RX8025_BIT_CTRL1_DALE;
err = rx8025_write_reg(rx8025->client, RX8025_REG_CTRL1,
err = rx8025_write_reg(client, RX8025_REG_CTRL1,
rx8025->ctrl1);
if (err)
return err;
......@@ -369,6 +370,7 @@ static int rx8025_set_alarm(struct device *dev, struct rtc_wkalrm *t)
static int rx8025_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
struct i2c_client *client = to_i2c_client(dev);
struct rx8025_data *rx8025 = dev_get_drvdata(dev);
u8 ctrl1;
int err;
......@@ -381,7 +383,7 @@ static int rx8025_alarm_irq_enable(struct device *dev, unsigned int enabled)
if (ctrl1 != rx8025->ctrl1) {
rx8025->ctrl1 = ctrl1;
err = rx8025_write_reg(rx8025->client, RX8025_REG_CTRL1,
err = rx8025_write_reg(client, RX8025_REG_CTRL1,
rx8025->ctrl1);
if (err)
return err;
......@@ -516,7 +518,6 @@ static int rx8025_probe(struct i2c_client *client,
if (!rx8025)
return -ENOMEM;
rx8025->client = client;
i2c_set_clientdata(client, rx8025);
err = rx8025_init_client(client);
......
......@@ -897,8 +897,11 @@ static int stm32_rtc_resume(struct device *dev)
}
ret = stm32_rtc_wait_sync(rtc);
if (ret < 0)
if (ret < 0) {
if (rtc->data->has_pclk)
clk_disable_unprepare(rtc->pclk);
return ret;
}
if (device_may_wakeup(dev))
return disable_irq_wake(rtc->irq_alarm);
......
......@@ -23,6 +23,7 @@
#include <linux/device.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/mfd/tps6586x.h>
#include <linux/module.h>
......@@ -267,6 +268,8 @@ static int tps6586x_rtc_probe(struct platform_device *pdev)
rtc->rtc->start_secs = mktime64(2009, 1, 1, 0, 0, 0);
rtc->rtc->set_start_time = true;
irq_set_status_flags(rtc->irq, IRQ_NOAUTOEN);
ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL,
tps6586x_rtc_irq,
IRQF_ONESHOT,
......@@ -276,7 +279,6 @@ static int tps6586x_rtc_probe(struct platform_device *pdev)
rtc->irq, ret);
goto fail_rtc_register;
}
disable_irq(rtc->irq);
ret = rtc_register_device(rtc->rtc);
if (ret)
......
......@@ -94,7 +94,7 @@ static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm)
* RTC has updated the CURRENT_TIME with the time written into
* SET_TIME_WRITE register.
*/
rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_CUR_TM), tm);
read_time = readl(xrtcdev->reg_base + RTC_CUR_TM);
} else {
/*
* Time written in SET_TIME_WRITE has not yet updated into
......@@ -104,8 +104,8 @@ static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm)
* reading.
*/
read_time = readl(xrtcdev->reg_base + RTC_SET_TM_RD) - 1;
rtc_time64_to_tm(read_time, tm);
}
rtc_time64_to_tm(read_time, tm);
return 0;
}
......
......@@ -167,6 +167,7 @@ struct rtc_device {
#define RTC_TIMESTAMP_BEGIN_1900 -2208988800LL /* 1900-01-01 00:00:00 */
#define RTC_TIMESTAMP_BEGIN_2000 946684800LL /* 2000-01-01 00:00:00 */
#define RTC_TIMESTAMP_END_2063 2966371199LL /* 2063-12-31 23:59:59 */
#define RTC_TIMESTAMP_END_2079 3471292799LL /* 2079-12-31 23:59:59 */
#define RTC_TIMESTAMP_END_2099 4102444799LL /* 2099-12-31 23:59:59 */
#define RTC_TIMESTAMP_END_2199 7258118399LL /* 2199-12-31 23:59:59 */
#define RTC_TIMESTAMP_END_9999 253402300799LL /* 9999-12-31 23:59:59 */
......
......@@ -92,7 +92,12 @@ struct rtc_pll_info {
#define RTC_PLL_GET _IOR('p', 0x11, struct rtc_pll_info) /* Get PLL correction */
#define RTC_PLL_SET _IOW('p', 0x12, struct rtc_pll_info) /* Set PLL correction */
#define RTC_VL_READ _IOR('p', 0x13, int) /* Voltage low detector */
#define RTC_VL_DATA_INVALID BIT(0) /* Voltage too low, RTC data is invalid */
#define RTC_VL_BACKUP_LOW BIT(1) /* Backup voltage is low */
#define RTC_VL_BACKUP_EMPTY BIT(2) /* Backup empty or not present */
#define RTC_VL_ACCURACY_LOW BIT(3) /* Voltage is low, RTC accuracy is reduced */
#define RTC_VL_READ _IOR('p', 0x13, unsigned int) /* Voltage low detection */
#define RTC_VL_CLR _IO('p', 0x14) /* Clear voltage low information */
/* interrupt flags */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment