1/*	$NetBSD: bq4802reg.h,v 1.1 2026/02/01 11:45:10 jdc Exp $	*/
2
3/*-
4 * Copyright (c) 2026 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Julian Coleman.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32
33/*
34 * Registers and register values taken from the Texas Instruments
35 * bq4802Y/bq4802LY data sheet 2002.
36 */
37
38#define	BQ4802_SEC		0x00	/* Seconds */
39#define	BQ4802_SEC_ALM		0x01	/* Seconds alarm */
40#define	BQ4802_MIN		0x02	/* Minutes */
41#define	BQ4802_MIN_ALM		0x03	/* Minutes alarm */
42#define	BQ4802_HOUR		0x04	/* Hours */
43#define	BQ4802_HOUR_ALM		0x05	/* Hours alarm */
44#define	BQ4802_DAY		0x06	/* Day */
45#define	BQ4802_DAY_ALM		0x07	/* Day alarm */
46#define	BQ4802_WDAY		0x08	/* Day of week */
47#define	BQ4802_MONTH		0x09	/* Month */
48#define	BQ4802_YEAR		0x0a	/* Year */
49#define	BQ4802_RATES		0x0b	/* Rates */
50#define	BQ4802_ENABLES		0x0c	/* Enables */
51#define	BQ4802_FLAGS		0x0d	/* Flags */
52#define	BQ4802_CTRL		0x0e	/* Control */
53#define	BQ4802_CENT		0x0f	/* Century */
54
55/* Seconds and Seconds alarm (00-59) */
56#define	BQ4802_SECS_1		0x0f	/* 1-second digit */
57#define	BQ4802_SECS_10		0x70	/* 10-second digit */
58#define	BQ4802_SECS_ALM0	0x40	/* seconds alarm mask 0 */
59#define	BQ4802_SECS_ALM1	0x80	/* seconds alarm mask 1 */
60
61/* Minutes and Minutes alarm (00-59) */
62#define	BQ4802_MINS_1		0x0f	/* 1-minute digit */
63#define	BQ4802_MINS_10		0x70	/* 10-minute digit */
64#define	BQ4802_MINS_ALM0	0x40	/* minutes alarm mask 0 */
65#define	BQ4802_MINS_ALM1	0x80	/* minutes alarm mask 1 */
66
67/* Hours and Hours alarm (01-24 or 01-12 AM / 81-92 PM) */
68#define	BQ4802_HOURS_1		0x0f	/* 1-hour digit */
69#define	BQ4802_HOURS_10		0x30	/* 10-hour digit */
70#define	BQ4802_HOURS_AM		0x00	/* AM/PM bit */
71#define	BQ4802_HOURS_PM		0x80	/* AM/PM bit */
72#define	BQ4802_HOURS_ALM0	0x40	/* hours alarm mask 0 */
73#define	BQ4802_HOURS_ALM1	0x80	/* hours alarm mask 1 */
74
75/* Days and Days alarm (01-31) */
76#define	BQ4802_DAYS_1		0x0f	/* 1-day digit */
77#define	BQ4802_DAYS_10		0x30	/* 10-day digit */
78#define	BQ4802_DAYS_ALM0	0x40	/* days alarm mask 0 */
79#define	BQ4802_DAYS_ALM1	0x80	/* days alarm mask 1 */
80
81/* Day of week (01-07) */
82#define	BQ4802_WDAYS_1		0x07	/* day of week digit */
83
84/* Month (01-12) */
85#define	BQ4802_MONTHS_1		0x0f	/* 1-month digit */
86#define	BQ4802_MONTHS_10	0x30	/* 10-month digit */
87
88/* Year (00-99) */
89#define	BQ4802_YEARS_1		0x0f	/* 1-year digit */
90#define	BQ4802_YEARS_10		0xf0	/* 10-year digit */
91
92/* Century (00-99) */
93#define	BQ4802_CENTS_1		0x0f	/* 1-century digit */
94#define	BQ4802_CENTS_10		0xf0	/* 10-century digit */
95
96/* Rates */
97#define	BQ4802_RATE_RS0	0x01	/* RS0 */
98#define	BQ4802_RATE_RS1	0x02	/* RS1 */
99#define	BQ4802_RATE_RS2	0x04	/* RS2 */
100#define	BQ4802_RATE_RS3	0x08	/* RS3 */
101#define	BQ4802_RATE_WD0	0x10	/* WD0 */
102#define	BQ4802_RATE_WD1	0x20	/* WD1 */
103#define	BQ4802_RATE_WD2	0x40	/* WD2 */
104
105/* Enables */
106#define	BQ4802_EN_ABE	0x01	/* Alarm enable in battery-backup mode */
107#define	BQ4802_EN_PWRIE	0x02	/* Power-fail interrupt enable */
108#define	BQ4802_EN_PIE	0x04	/* Periodic interrupt enable */
109#define	BQ4802_EN_AIE	0x08	/* Alarm interrupt enable */
110
111/* Flags */
112#define	BQ4802_FLG_BVF	0x01	/* Battery-valid flag */
113#define	BQ4802_FLG_PWRF	0x02	/* Power-fail interrupt flag */
114#define	BQ4802_FLG_PF	0x04	/* Periodic interrupt flag */
115#define	BQ4802_FLG_AF	0x08	/* Alarm interrupt flag */
116
117/* Control */
118#define	BQ4802_CTRL_DSE	0x01	/* Daylight savings enable */
119#define	BQ4802_CTRL_24	0x02	/* 1 for 24-hour, 0 for 12-hour */
120#define	BQ4802_CTRL_STP	0x04	/* Stop when in battery-backup mode */
121#define	BQ4802_CTRL_UTI	0x08	/* Update transfer inhibit */
122
123/* Max number of registers we need to read/write for the TOD. */
124#define	BQ4802_NREGS	0x10
125typedef uint8_t bq4802_regs[BQ4802_NREGS];	/* sparse */
126static int bq4802_tods[BQ4802_NREGS] =		/* TOD registers */
127    { 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1 };
128
129/* Register read and write functions -- machine-dependent. */
130uint8_t bq4802_read(void *, uint8_t);
131void bq4802_write(void *, uint8_t, uint8_t);
132
133/*
134 * Get all of the TOD registers.
135 * Called at splclock(), and with the RTC set up.
136 */
137#define	BQ4802_GETTOD(sc, regs)						\
138	do {								\
139		int i;							\
140		uint8_t ctrl;						\
141									\
142		/* disable register updates */				\
143		ctrl = bq4802_read(sc, BQ4802_CTRL);			\
144		bq4802_write(sc, BQ4802_CTRL, ctrl | BQ4802_CTRL_UTI);	\
145									\
146		/* read the TOD registers */				\
147		for (i = 0; i < BQ4802_NREGS; i++) 			\
148			if (bq4802_tods[i])				\
149				(*regs)[i] = bq4802_read(sc, i);	\
150									\
151		/* re-enable register updates */			\
152		bq4802_write(sc, BQ4802_CTRL, ctrl);			\
153	} while (0);
154
155/*
156 * Set all of the TOD registers.
157 * Called at splclock(), and with the RTC set up.
158 */
159#define	BQ4802_SETTOD(sc, regs)						\
160	do {								\
161		int i;							\
162		uint8_t ctrl;						\
163									\
164		/* disable register updates */				\
165		ctrl = bq4802_read(sc, BQ4802_CTRL);			\
166		bq4802_write(sc, BQ4802_CTRL, ctrl | BQ4802_CTRL_UTI);	\
167									\
168		/* write the TOD registers */				\
169		for (i = 0; i < BQ4802_NREGS; i++) 			\
170			if (bq4802_tods[i])				\
171				bq4802_write(sc, i, (*regs)[i]);	\
172									\
173		/* re-enable register updates */			\
174		bq4802_write(sc, BQ4802_CTRL, ctrl);			\
175	} while (0);
176