git: 328077bb8ff1 - main - pmic: rockchip: Split the rtc part in its own file
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 14 Nov 2021 12:34:23 UTC
The branch main has been updated by manu:
URL: https://cgit.FreeBSD.org/src/commit/?id=328077bb8ff1a55d20ca7f8fdbb898e8c07bb057
commit 328077bb8ff1a55d20ca7f8fdbb898e8c07bb057
Author: Emmanuel Vadot <manu@FreeBSD.org>
AuthorDate: 2021-11-11 19:41:52 +0000
Commit: Emmanuel Vadot <manu@FreeBSD.org>
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 <manu@FreeBSD.org>
+ *
+ * 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 <manu@FreeBSD.org>
+ * Copyright (c) 2021 Peter Jeremy <peterj@FreeBSD.org>
+ *
+ * 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);
+}