The branch main has been updated by manu:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=328077bb8ff1a55d20ca7f8fdbb898e8c07bb057

commit 328077bb8ff1a55d20ca7f8fdbb898e8c07bb057
Author:     Emmanuel Vadot <[email protected]>
AuthorDate: 2021-11-11 19:41:52 +0000
Commit:     Emmanuel Vadot <[email protected]>
CommitDate: 2021-11-14 11:31:18 +0000

    pmic: rockchip: Split the rtc part in its own file
    
    Even if for now all the RTC-related register are at the same offset don't
    use some hardcoded values for them but set them based on the PMIC type.
    
    No functional changes intended.
---
 sys/conf/files.arm64                     |   1 +
 sys/dev/iicbus/pmic/rockchip/rk805.c     | 204 ++++++-------------------------
 sys/dev/iicbus/pmic/rockchip/rk8xx.h     | 109 +++++++++++++++++
 sys/dev/iicbus/pmic/rockchip/rk8xx_rtc.c | 142 +++++++++++++++++++++
 4 files changed, 289 insertions(+), 167 deletions(-)

diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64
index 1f344d0273b8..a3c325070469 100644
--- a/sys/conf/files.arm64
+++ b/sys/conf/files.arm64
@@ -541,6 +541,7 @@ arm64/rockchip/rk_dwc3.c                    optional fdt 
rk_dwc3 soc_rockchip_rk3399
 arm64/rockchip/rk_i2c.c                                optional fdt rk_i2c 
soc_rockchip_rk3328 | fdt rk_i2c soc_rockchip_rk3399
 arm64/rockchip/rk_i2s.c                                optional fdt sound 
soc_rockchip_rk3328 | fdt sound soc_rockchip_rk3399
 dev/iicbus/pmic/rockchip/rk805.c               optional fdt rk805 
soc_rockchip_rk3328 | fdt rk805 soc_rockchip_rk3399
+dev/iicbus/pmic/rockchip/rk8xx_rtc.c           optional fdt rk805 
soc_rockchip_rk3328 | fdt rk805 soc_rockchip_rk3399
 arm64/rockchip/rk_grf.c                                optional fdt 
soc_rockchip_rk3328 | fdt soc_rockchip_rk3399
 arm64/rockchip/rk_pinctrl.c                    optional fdt rk_pinctrl 
soc_rockchip_rk3328 | fdt rk_pinctrl soc_rockchip_rk3399
 arm64/rockchip/rk_gpio.c                       optional fdt rk_gpio 
soc_rockchip_rk3328 | fdt rk_gpio soc_rockchip_rk3399
diff --git a/sys/dev/iicbus/pmic/rockchip/rk805.c 
b/sys/dev/iicbus/pmic/rockchip/rk805.c
index 76c8462e694e..ab4006ad63f9 100644
--- a/sys/dev/iicbus/pmic/rockchip/rk805.c
+++ b/sys/dev/iicbus/pmic/rockchip/rk805.c
@@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
 
 #include <dev/iicbus/pmic/rockchip/rk805reg.h>
 #include <dev/iicbus/pmic/rockchip/rk808reg.h>
+#include <dev/iicbus/pmic/rockchip/rk8xx.h>
 
 #include "clock_if.h"
 #include "regdev_if.h"
@@ -59,55 +60,12 @@ MALLOC_DEFINE(M_RK805_REG, "RK805 regulator", "RK805 power 
regulator");
 /* #define     dprintf(sc, format, arg...)     device_printf(sc->base_dev, 
"%s: " format, __func__, arg) */
 #define        dprintf(sc, format, arg...)
 
-enum rk_pmic_type {
-       RK805 = 1,
-       RK808,
-};
-
 static struct ofw_compat_data compat_data[] = {
        {"rockchip,rk805", RK805},
        {"rockchip,rk808", RK808},
        {NULL,             0}
 };
 
-struct rk8xx_regdef {
-       intptr_t                id;
-       char                    *name;
-       uint8_t                 enable_reg;
-       uint8_t                 enable_mask;
-       uint8_t                 voltage_reg;
-       uint8_t                 voltage_mask;
-       int                     voltage_min;
-       int                     voltage_max;
-       int                     voltage_step;
-       int                     voltage_nstep;
-};
-
-struct rk8xx_reg_sc {
-       struct regnode          *regnode;
-       device_t                base_dev;
-       struct rk8xx_regdef     *def;
-       phandle_t               xref;
-       struct regnode_std_param *param;
-};
-
-struct reg_list {
-       TAILQ_ENTRY(reg_list)   next;
-       struct rk8xx_reg_sc     *reg;
-};
-
-struct rk8xx_softc {
-       device_t                dev;
-       struct mtx              mtx;
-       struct resource *       res[1];
-       void *                  intrcookie;
-       struct intr_config_hook intr_hook;
-       enum rk_pmic_type       type;
-
-       TAILQ_HEAD(, reg_list)          regs;
-       int                     nregs;
-};
-
 static int rk8xx_regnode_status(struct regnode *regnode, int *status);
 static int rk8xx_regnode_set_voltage(struct regnode *regnode, int min_uvolt,
     int max_uvolt, int *udelay);
@@ -352,7 +310,7 @@ static struct rk8xx_regdef rk808_regdefs[] = {
        },
 };
 
-static int
+int
 rk8xx_read(device_t dev, uint8_t reg, uint8_t *data, uint8_t size)
 {
        int err;
@@ -361,7 +319,7 @@ rk8xx_read(device_t dev, uint8_t reg, uint8_t *data, 
uint8_t size)
        return (err);
 }
 
-static int
+int
 rk8xx_write(device_t dev, uint8_t reg, uint8_t *data, uint8_t size)
 {
 
@@ -748,128 +706,6 @@ rk8xx_start(void *pdev)
        config_intrhook_disestablish(&sc->intr_hook);
 }
 
-static int
-rk8xx_gettime(device_t dev, struct timespec *ts)
-{
-       struct bcd_clocktime bct;
-       uint8_t data[7];
-       uint8_t ctrl;
-       int error;
-
-       /* Latch the RTC value into the shadow registers and set 24hr mode */
-       error = rk8xx_read(dev, RK805_RTC_CTRL, &ctrl, 1);
-       if (error != 0)
-               return (error);
-
-       ctrl |= RK805_RTC_READSEL;
-       ctrl &= ~(RK805_RTC_AMPM_MODE | RK805_RTC_GET_TIME);
-       error = rk8xx_write(dev, RK805_RTC_CTRL, &ctrl, 1);
-       if (error != 0)
-               return (error);
-       ctrl |= RK805_RTC_GET_TIME;
-       error = rk8xx_write(dev, RK805_RTC_CTRL, &ctrl, 1);
-       if (error != 0)
-               return (error);
-       ctrl &= ~RK805_RTC_GET_TIME;
-       error = rk8xx_write(dev, RK805_RTC_CTRL, &ctrl, 1);
-       if (error != 0)
-               return (error);
-
-       /* This works as long as RK805_RTC_SECS = 0 */
-       error = rk8xx_read(dev, RK805_RTC_SECS, data, 7);
-       if (error != 0)
-               return (error);
-
-       /*
-        * If the reported year is earlier than 2019, assume the clock is unset.
-        * This is both later than the reset value for the RK805 and RK808 as
-        * well as being prior to the current time.
-        */
-       if (data[RK805_RTC_YEARS] < 0x19)
-               return (EINVAL);
-
-       memset(&bct, 0, sizeof(bct));
-       bct.year = data[RK805_RTC_YEARS];
-       bct.mon = data[RK805_RTC_MONTHS] & RK805_RTC_MONTHS_MASK;
-       bct.day = data[RK805_RTC_DAYS] & RK805_RTC_DAYS_MASK;
-       bct.hour = data[RK805_RTC_HOURS] & RK805_RTC_HOURS_MASK;
-       bct.min = data[RK805_RTC_MINUTES] & RK805_RTC_MINUTES_MASK;
-       bct.sec = data[RK805_RTC_SECS] & RK805_RTC_SECS_MASK;
-       bct.dow = data[RK805_RTC_WEEKS] & RK805_RTC_WEEKS_MASK;
-       /* The day of week is reported as 1-7 with 1 = Monday */
-       if (bct.dow == 7)
-               bct.dow = 0;
-       bct.ispm = 0;
-
-       if (bootverbose)
-               device_printf(dev, "Read RTC: %02x-%02x-%02x %02x:%02x:%02x\n",
-                   bct.year, bct.mon, bct.day, bct.hour, bct.min, bct.sec);
-
-       return (clock_bcd_to_ts(&bct, ts, false));
-}
-
-static int
-rk8xx_settime(device_t dev, struct timespec *ts)
-{
-       struct bcd_clocktime bct;
-       uint8_t data[7];
-       int error;
-       uint8_t ctrl;
-
-       clock_ts_to_bcd(ts, &bct, false);
-
-       /* This works as long as RK805_RTC_SECS = 0 */
-       data[RK805_RTC_YEARS] = bct.year;
-       data[RK805_RTC_MONTHS] = bct.mon;
-       data[RK805_RTC_DAYS] = bct.day;
-       data[RK805_RTC_HOURS] = bct.hour;
-       data[RK805_RTC_MINUTES] = bct.min;
-       data[RK805_RTC_SECS] = bct.sec;
-       data[RK805_RTC_WEEKS] = bct.dow;
-       /* The day of week is reported as 1-7 with 1 = Monday */
-       if (data[RK805_RTC_WEEKS] == 0)
-               data[RK805_RTC_WEEKS] = 7;
-
-       error = rk8xx_read(dev, RK805_RTC_CTRL, &ctrl, 1);
-       if (error != 0)
-               return (error);
-
-       ctrl |= RK805_RTC_CTRL_STOP;
-       ctrl &= ~RK805_RTC_AMPM_MODE;
-       error = rk8xx_write(dev, RK805_RTC_CTRL, &ctrl, 1);
-       if (error != 0)
-               return (error);
-
-       error = rk8xx_write(dev, RK805_RTC_SECS, data, 7);
-       ctrl &= ~RK805_RTC_CTRL_STOP;
-       rk8xx_write(dev, RK805_RTC_CTRL, &ctrl, 1);
-
-       return (error);
-}
-
-static void
-rk805_poweroff(void *arg, int howto)
-{
-       device_t dev = arg;
-       int error;
-       uint8_t val;
-
-       if ((howto & RB_POWEROFF) == 0)
-               return;
-
-       device_printf(dev, "Powering off...\n");
-       error = rk805_read(dev, RK805_DEV_CTRL, &val, 1);
-       if (error == 0) {
-               val |= RK805_DEV_CTRL_OFF;
-               error = rk805_write(dev, RK805_DEV_CTRL, &val, 1);
-
-               /* Wait a bit for the command to take effect. */
-               if (error == 0)
-                       DELAY(100);
-       }
-       device_printf(dev, "Power off failed\n");
-}
-
 static int
 rk8xx_attach(device_t dev)
 {
@@ -896,10 +732,44 @@ rk8xx_attach(device_t dev)
        case RK805:
                regdefs = rk805_regdefs;
                sc->nregs = nitems(rk805_regdefs);
+               sc->rtc_regs.secs = RK805_RTC_SECS;
+               sc->rtc_regs.secs_mask = RK805_RTC_SECS_MASK;
+               sc->rtc_regs.minutes = RK805_RTC_MINUTES;
+               sc->rtc_regs.minutes_mask = RK805_RTC_MINUTES_MASK;
+               sc->rtc_regs.hours = RK805_RTC_HOURS;
+               sc->rtc_regs.hours_mask = RK805_RTC_HOURS_MASK;
+               sc->rtc_regs.days = RK805_RTC_DAYS;
+               sc->rtc_regs.days_mask = RK805_RTC_DAYS_MASK;
+               sc->rtc_regs.months = RK805_RTC_MONTHS;
+               sc->rtc_regs.months_mask = RK805_RTC_MONTHS_MASK;
+               sc->rtc_regs.years = RK805_RTC_YEARS;
+               sc->rtc_regs.weeks = RK805_RTC_WEEKS_MASK;
+               sc->rtc_regs.ctrl = RK805_RTC_CTRL;
+               sc->rtc_regs.ctrl_stop_mask = RK805_RTC_CTRL_STOP;
+               sc->rtc_regs.ctrl_ampm_mask = RK805_RTC_AMPM_MODE;
+               sc->rtc_regs.ctrl_gettime_mask = RK805_RTC_GET_TIME;
+               sc->rtc_regs.ctrl_readsel_mask = RK805_RTC_READSEL;
                break;
        case RK808:
                regdefs = rk808_regdefs;
                sc->nregs = nitems(rk808_regdefs);
+               sc->rtc_regs.secs = RK808_RTC_SECS;
+               sc->rtc_regs.secs_mask = RK808_RTC_SECS_MASK;
+               sc->rtc_regs.minutes = RK808_RTC_MINUTES;
+               sc->rtc_regs.minutes_mask = RK808_RTC_MINUTES_MASK;
+               sc->rtc_regs.hours = RK808_RTC_HOURS;
+               sc->rtc_regs.hours_mask = RK808_RTC_HOURS_MASK;
+               sc->rtc_regs.days = RK808_RTC_DAYS;
+               sc->rtc_regs.days_mask = RK808_RTC_DAYS_MASK;
+               sc->rtc_regs.months = RK808_RTC_MONTHS;
+               sc->rtc_regs.months_mask = RK808_RTC_MONTHS_MASK;
+               sc->rtc_regs.years = RK808_RTC_YEARS;
+               sc->rtc_regs.weeks = RK808_RTC_WEEKS_MASK;
+               sc->rtc_regs.ctrl = RK808_RTC_CTRL;
+               sc->rtc_regs.ctrl_stop_mask = RK808_RTC_CTRL_STOP;
+               sc->rtc_regs.ctrl_ampm_mask = RK808_RTC_AMPM_MODE;
+               sc->rtc_regs.ctrl_gettime_mask = RK808_RTC_GET_TIME;
+               sc->rtc_regs.ctrl_readsel_mask = RK808_RTC_READSEL;
                break;
        default:
                device_printf(dev, "Unknown type %d\n", sc->type);
diff --git a/sys/dev/iicbus/pmic/rockchip/rk8xx.h 
b/sys/dev/iicbus/pmic/rockchip/rk8xx.h
new file mode 100644
index 000000000000..4351f8fe254c
--- /dev/null
+++ b/sys/dev/iicbus/pmic/rockchip/rk8xx.h
@@ -0,0 +1,109 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2021 Emmanuel Vadot <[email protected]>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _RK8XX_H_
+#define        _RK8XX_H_
+
+#include <sys/kernel.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+enum rk_pmic_type {
+       RK805 = 1,
+       RK808,
+};
+
+struct rk8xx_regdef {
+       intptr_t                id;
+       char                    *name;
+       uint8_t                 enable_reg;
+       uint8_t                 enable_mask;
+       uint8_t                 voltage_reg;
+       uint8_t                 voltage_mask;
+       int                     voltage_min;
+       int                     voltage_max;
+       int                     voltage_step;
+       int                     voltage_nstep;
+};
+
+struct rk8xx_reg_sc {
+       struct regnode          *regnode;
+       device_t                base_dev;
+       struct rk8xx_regdef     *def;
+       phandle_t               xref;
+       struct regnode_std_param *param;
+};
+
+struct reg_list {
+       TAILQ_ENTRY(reg_list)   next;
+       struct rk8xx_reg_sc     *reg;
+};
+
+struct rk8xx_rtc_reg {
+       uint8_t secs;
+       uint8_t secs_mask;
+       uint8_t minutes;
+       uint8_t minutes_mask;
+       uint8_t hours;
+       uint8_t hours_mask;
+       uint8_t days;
+       uint8_t days_mask;
+       uint8_t months;
+       uint8_t months_mask;
+       uint8_t years;
+       uint8_t weeks;
+       uint8_t weeks_mask;
+       uint8_t ctrl;
+       uint8_t ctrl_stop_mask;
+       uint8_t ctrl_ampm_mask;
+       uint8_t ctrl_gettime_mask;
+       uint8_t ctrl_readsel_mask;
+};
+
+struct rk8xx_softc {
+       device_t                dev;
+       struct mtx              mtx;
+       struct resource *       res[1];
+       void *                  intrcookie;
+       struct intr_config_hook intr_hook;
+       enum rk_pmic_type       type;
+
+       TAILQ_HEAD(, reg_list)          regs;
+       int                     nregs;
+
+       struct rk8xx_rtc_reg    rtc_regs;
+};
+
+int rk8xx_read(device_t dev, uint8_t reg, uint8_t *data, uint8_t size);
+int rk8xx_write(device_t dev, uint8_t reg, uint8_t *data, uint8_t size);
+
+/* rk8xx_rtc.c */
+int rk8xx_gettime(device_t dev, struct timespec *ts);
+int rk8xx_settime(device_t dev, struct timespec *ts);
+
+#endif /* _RK8XX_H_ */
diff --git a/sys/dev/iicbus/pmic/rockchip/rk8xx_rtc.c 
b/sys/dev/iicbus/pmic/rockchip/rk8xx_rtc.c
new file mode 100644
index 000000000000..2f755d16b164
--- /dev/null
+++ b/sys/dev/iicbus/pmic/rockchip/rk8xx_rtc.c
@@ -0,0 +1,142 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2021 Emmanuel Vadot <[email protected]>
+ * Copyright (c) 2021 Peter Jeremy <[email protected]>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/systm.h>
+#include <sys/clock.h>
+
+#include <dev/iicbus/pmic/rockchip/rk8xx.h>
+
+int
+rk8xx_gettime(device_t dev, struct timespec *ts)
+{
+       struct rk8xx_softc *sc;
+       struct bcd_clocktime bct;
+       uint8_t data[7];
+       uint8_t ctrl;
+       int error;
+
+       sc = device_get_softc(dev);
+
+       /* Latch the RTC value into the shadow registers and set 24hr mode */
+       error = rk8xx_read(dev, sc->rtc_regs.ctrl, &ctrl, 1);
+       if (error != 0)
+               return (error);
+
+       ctrl |= sc->rtc_regs.ctrl_readsel_mask;
+       ctrl &= ~(sc->rtc_regs.ctrl_ampm_mask | sc->rtc_regs.ctrl_gettime_mask);
+       error = rk8xx_write(dev, sc->rtc_regs.ctrl, &ctrl, 1);
+       if (error != 0)
+               return (error);
+       ctrl |= sc->rtc_regs.ctrl_gettime_mask;
+       error = rk8xx_write(dev, sc->rtc_regs.ctrl, &ctrl, 1);
+       if (error != 0)
+               return (error);
+       ctrl &= ~sc->rtc_regs.ctrl_gettime_mask;
+       error = rk8xx_write(dev, sc->rtc_regs.ctrl, &ctrl, 1);
+       if (error != 0)
+               return (error);
+
+       /* This works as long as sc->rtc_regs.secs = 0 */
+       error = rk8xx_read(dev, sc->rtc_regs.secs, data, 7);
+       if (error != 0)
+               return (error);
+
+       /*
+        * If the reported year is earlier than 2019, assume the clock is unset.
+        * This is both later than the reset value for the RK805 and RK808 as
+        * well as being prior to the current time.
+        */
+       if (data[sc->rtc_regs.years] < 0x19)
+               return (EINVAL);
+
+       memset(&bct, 0, sizeof(bct));
+       bct.year = data[sc->rtc_regs.years];
+       bct.mon = data[sc->rtc_regs.months] & sc->rtc_regs.months_mask;
+       bct.day = data[sc->rtc_regs.days] & sc->rtc_regs.days_mask;
+       bct.hour = data[sc->rtc_regs.hours] & sc->rtc_regs.hours_mask;
+       bct.min = data[sc->rtc_regs.minutes] & sc->rtc_regs.minutes_mask;
+       bct.sec = data[sc->rtc_regs.secs] & sc->rtc_regs.secs_mask;
+       bct.dow = data[sc->rtc_regs.weeks] & sc->rtc_regs.weeks_mask;
+       /* The day of week is reported as 1-7 with 1 = Monday */
+       if (bct.dow == 7)
+               bct.dow = 0;
+       bct.ispm = 0;
+
+       if (bootverbose)
+               device_printf(dev, "Read RTC: %02x-%02x-%02x %02x:%02x:%02x\n",
+                   bct.year, bct.mon, bct.day, bct.hour, bct.min, bct.sec);
+
+       return (clock_bcd_to_ts(&bct, ts, false));
+}
+
+int
+rk8xx_settime(device_t dev, struct timespec *ts)
+{
+       struct rk8xx_softc *sc;
+       struct bcd_clocktime bct;
+       uint8_t data[7];
+       int error;
+       uint8_t ctrl;
+
+       sc = device_get_softc(dev);
+
+       clock_ts_to_bcd(ts, &bct, false);
+
+       /* This works as long as RK805_RTC_SECS = 0 */
+       data[sc->rtc_regs.years] = bct.year;
+       data[sc->rtc_regs.months] = bct.mon;
+       data[sc->rtc_regs.days] = bct.day;
+       data[sc->rtc_regs.hours] = bct.hour;
+       data[sc->rtc_regs.minutes] = bct.min;
+       data[sc->rtc_regs.secs] = bct.sec;
+       data[sc->rtc_regs.weeks] = bct.dow;
+       /* The day of week is reported as 1-7 with 1 = Monday */
+       if (data[sc->rtc_regs.weeks] == 0)
+               data[sc->rtc_regs.weeks] = 7;
+
+       error = rk8xx_read(dev, sc->rtc_regs.ctrl, &ctrl, 1);
+       if (error != 0)
+               return (error);
+
+       ctrl |= sc->rtc_regs.ctrl_stop_mask;
+       ctrl &= ~sc->rtc_regs.ctrl_ampm_mask;
+       error = rk8xx_write(dev, sc->rtc_regs.ctrl, &ctrl, 1);
+       if (error != 0)
+               return (error);
+
+       error = rk8xx_write(dev, sc->rtc_regs.secs, data, 7);
+       ctrl &= ~sc->rtc_regs.ctrl_stop_mask;
+       rk8xx_write(dev, sc->rtc_regs.ctrl, &ctrl, 1);
+
+       return (error);
+}

Reply via email to