xref: /freebsd/sys/dev/iicbus/rtc/nxprtc.c (revision 2f16049c985a364e2bd2b256f5bef9af17e10c62)
1*2f16049cSEmmanuel Vadot /*-
2*2f16049cSEmmanuel Vadot  * SPDX-License-Identifier: BSD-2-Clause
3*2f16049cSEmmanuel Vadot  *
4*2f16049cSEmmanuel Vadot  * Copyright (c) 2017 Ian Lepore <ian@freebsd.org>
5*2f16049cSEmmanuel Vadot  *
6*2f16049cSEmmanuel Vadot  * Redistribution and use in source and binary forms, with or without
7*2f16049cSEmmanuel Vadot  * modification, are permitted provided that the following conditions
8*2f16049cSEmmanuel Vadot  * are met:
9*2f16049cSEmmanuel Vadot  * 1. Redistributions of source code must retain the above copyright
10*2f16049cSEmmanuel Vadot  *    notice, this list of conditions and the following disclaimer.
11*2f16049cSEmmanuel Vadot  * 2. Redistributions in binary form must reproduce the above copyright
12*2f16049cSEmmanuel Vadot  *    notice, this list of conditions and the following disclaimer in the
13*2f16049cSEmmanuel Vadot  *    documentation and/or other materials provided with the distribution.
14*2f16049cSEmmanuel Vadot  *
15*2f16049cSEmmanuel Vadot  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16*2f16049cSEmmanuel Vadot  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17*2f16049cSEmmanuel Vadot  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18*2f16049cSEmmanuel Vadot  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19*2f16049cSEmmanuel Vadot  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20*2f16049cSEmmanuel Vadot  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21*2f16049cSEmmanuel Vadot  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22*2f16049cSEmmanuel Vadot  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23*2f16049cSEmmanuel Vadot  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24*2f16049cSEmmanuel Vadot  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25*2f16049cSEmmanuel Vadot  * SUCH DAMAGE.
26*2f16049cSEmmanuel Vadot  */
27*2f16049cSEmmanuel Vadot 
28*2f16049cSEmmanuel Vadot #include <sys/cdefs.h>
29*2f16049cSEmmanuel Vadot /*
30*2f16049cSEmmanuel Vadot  * Driver for NXP real-time clock/calendar chips:
31*2f16049cSEmmanuel Vadot  *  - PCF8563 = low power, countdown timer
32*2f16049cSEmmanuel Vadot  *  - PCA8565 = like PCF8563, automotive temperature range
33*2f16049cSEmmanuel Vadot  *  - PCF8523 = low power, countdown timer, oscillator freq tuning, 2 timers
34*2f16049cSEmmanuel Vadot  *  - PCF2127 = like PCF8523, industrial, tcxo, tamper/ts, i2c & spi, 512B ram
35*2f16049cSEmmanuel Vadot  *  - PCA2129 = like PCF8523, automotive, tcxo, tamper/ts, i2c & spi, (note 1)
36*2f16049cSEmmanuel Vadot  *  - PCF2129 = like PCF8523, industrial, tcxo, tamper/ts, i2c & spi, (note 1)
37*2f16049cSEmmanuel Vadot  *
38*2f16049cSEmmanuel Vadot  *  Most chips have a countdown timer, ostensibly intended to generate periodic
39*2f16049cSEmmanuel Vadot  *  interrupt signals on an output pin.  The timer is driven from the same
40*2f16049cSEmmanuel Vadot  *  divider chain that clocks the time of day registers, and they start counting
41*2f16049cSEmmanuel Vadot  *  in sync when the STOP bit is cleared after the time and timer registers are
42*2f16049cSEmmanuel Vadot  *  set.  The timer register can also be read on the fly, so we use it to count
43*2f16049cSEmmanuel Vadot  *  fractional seconds and get a resolution of ~15ms.
44*2f16049cSEmmanuel Vadot  *
45*2f16049cSEmmanuel Vadot  *  [1] Note that the datasheets for the PCx2129 chips state that they have only
46*2f16049cSEmmanuel Vadot  *  a watchdog timer, not a countdown timer.  Empirical testing shows that the
47*2f16049cSEmmanuel Vadot  *  countdown timer is actually there and it works fine, except that it can't
48*2f16049cSEmmanuel Vadot  *  trigger an interrupt or toggle an output pin like it can on other chips.  We
49*2f16049cSEmmanuel Vadot  *  don't care about interrupts and output pins, we just read the timer register
50*2f16049cSEmmanuel Vadot  *  to get better resolution.
51*2f16049cSEmmanuel Vadot  */
52*2f16049cSEmmanuel Vadot 
53*2f16049cSEmmanuel Vadot #include "opt_platform.h"
54*2f16049cSEmmanuel Vadot 
55*2f16049cSEmmanuel Vadot #include <sys/param.h>
56*2f16049cSEmmanuel Vadot #include <sys/systm.h>
57*2f16049cSEmmanuel Vadot #include <sys/bus.h>
58*2f16049cSEmmanuel Vadot #include <sys/clock.h>
59*2f16049cSEmmanuel Vadot #include <sys/kernel.h>
60*2f16049cSEmmanuel Vadot #include <sys/libkern.h>
61*2f16049cSEmmanuel Vadot #include <sys/module.h>
62*2f16049cSEmmanuel Vadot #include <sys/sysctl.h>
63*2f16049cSEmmanuel Vadot 
64*2f16049cSEmmanuel Vadot #include <dev/iicbus/iicbus.h>
65*2f16049cSEmmanuel Vadot #include <dev/iicbus/iiconf.h>
66*2f16049cSEmmanuel Vadot #ifdef FDT
67*2f16049cSEmmanuel Vadot #include <dev/ofw/openfirm.h>
68*2f16049cSEmmanuel Vadot #include <dev/ofw/ofw_bus.h>
69*2f16049cSEmmanuel Vadot #include <dev/ofw/ofw_bus_subr.h>
70*2f16049cSEmmanuel Vadot #endif
71*2f16049cSEmmanuel Vadot 
72*2f16049cSEmmanuel Vadot #include "clock_if.h"
73*2f16049cSEmmanuel Vadot #include "iicbus_if.h"
74*2f16049cSEmmanuel Vadot 
75*2f16049cSEmmanuel Vadot /*
76*2f16049cSEmmanuel Vadot  * I2C address 1010 001x : PCA2129 PCF2127 PCF2129 PCF8563 PCF8565
77*2f16049cSEmmanuel Vadot  * I2C address 1101 000x : PCF8523
78*2f16049cSEmmanuel Vadot  */
79*2f16049cSEmmanuel Vadot #define	PCF8563_ADDR		0xa2
80*2f16049cSEmmanuel Vadot #define	PCF8523_ADDR		0xd0
81*2f16049cSEmmanuel Vadot 
82*2f16049cSEmmanuel Vadot /*
83*2f16049cSEmmanuel Vadot  * Registers, bits within them, and masks that are common to all chip types.
84*2f16049cSEmmanuel Vadot  */
85*2f16049cSEmmanuel Vadot #define	PCF85xx_R_CS1		0x00	/* CS1 and CS2 control regs are in */
86*2f16049cSEmmanuel Vadot #define	PCF85xx_R_CS2		0x01	/* the same location on all chips. */
87*2f16049cSEmmanuel Vadot 
88*2f16049cSEmmanuel Vadot #define	PCF85xx_B_CS1_STOP	0x20	/* Stop time incrementing bit */
89*2f16049cSEmmanuel Vadot #define	PCF85xx_B_SECOND_OS	0x80	/* Oscillator Stopped bit */
90*2f16049cSEmmanuel Vadot 
91*2f16049cSEmmanuel Vadot #define	PCF85xx_M_SECOND	0x7f	/* Masks for all BCD time regs... */
92*2f16049cSEmmanuel Vadot #define	PCF85xx_M_MINUTE	0x7f
93*2f16049cSEmmanuel Vadot #define	PCF85xx_M_12HOUR	0x1f
94*2f16049cSEmmanuel Vadot #define	PCF85xx_M_24HOUR	0x3f
95*2f16049cSEmmanuel Vadot #define	PCF85xx_M_DAY		0x3f
96*2f16049cSEmmanuel Vadot #define	PCF85xx_M_MONTH		0x1f
97*2f16049cSEmmanuel Vadot #define	PCF85xx_M_YEAR		0xff
98*2f16049cSEmmanuel Vadot 
99*2f16049cSEmmanuel Vadot /*
100*2f16049cSEmmanuel Vadot  * PCF2127-specific registers, bits, and masks.
101*2f16049cSEmmanuel Vadot  */
102*2f16049cSEmmanuel Vadot #define	PCF2127_R_TMR_CTL	0x10	/* Timer/watchdog control */
103*2f16049cSEmmanuel Vadot 
104*2f16049cSEmmanuel Vadot #define	PCF2127_M_TMR_CTRL	0xe3	/* Mask off undef bits */
105*2f16049cSEmmanuel Vadot 
106*2f16049cSEmmanuel Vadot #define	PCF2127_B_TMR_CD	0x40	/* Run in countdown mode */
107*2f16049cSEmmanuel Vadot #define	PCF2127_B_TMR_64HZ	0x01	/* Timer frequency 64Hz */
108*2f16049cSEmmanuel Vadot 
109*2f16049cSEmmanuel Vadot #define	PCF2127_R_TS_CTL	0x12	/* Timestamp control */
110*2f16049cSEmmanuel Vadot #define	PCF2127_B_TSOFF		0x40	/* Turn off timestamp function */
111*2f16049cSEmmanuel Vadot 
112*2f16049cSEmmanuel Vadot #define	PCF2127_R_AGING_OFFSET	0x19	/* Frequency aging offset in PPM */
113*2f16049cSEmmanuel Vadot 
114*2f16049cSEmmanuel Vadot /*
115*2f16049cSEmmanuel Vadot  * PCA/PCF2129-specific registers, bits, and masks.
116*2f16049cSEmmanuel Vadot  */
117*2f16049cSEmmanuel Vadot #define	PCF2129_B_CS1_12HR	0x04	/* Use 12-hour (AM/PM) mode bit */
118*2f16049cSEmmanuel Vadot #define	PCF2129_B_CLKOUT_OTPR	0x20	/* OTP refresh command */
119*2f16049cSEmmanuel Vadot #define	PCF2129_B_CLKOUT_HIGHZ	0x07	/* Clock Out Freq = disable */
120*2f16049cSEmmanuel Vadot 
121*2f16049cSEmmanuel Vadot /*
122*2f16049cSEmmanuel Vadot  * PCF8523-specific registers, bits, and masks.
123*2f16049cSEmmanuel Vadot  */
124*2f16049cSEmmanuel Vadot #define	PCF8523_R_CS3		0x02	/* Control and status reg 3 */
125*2f16049cSEmmanuel Vadot #define	PCF8523_R_SECOND	0x03	/* Seconds */
126*2f16049cSEmmanuel Vadot #define	PCF8523_R_TMR_CLKOUT	0x0F	/* Timer and clockout control */
127*2f16049cSEmmanuel Vadot #define	PCF8523_R_TMR_A_FREQ	0x10	/* Timer A frequency control */
128*2f16049cSEmmanuel Vadot #define	PCF8523_R_TMR_A_COUNT	0x11	/* Timer A count */
129*2f16049cSEmmanuel Vadot 
130*2f16049cSEmmanuel Vadot #define	PCF8523_M_TMR_A_FREQ	0x07	/* Mask off undef bits */
131*2f16049cSEmmanuel Vadot 
132*2f16049cSEmmanuel Vadot #define	PCF8523_B_HOUR_PM	0x20	/* PM bit */
133*2f16049cSEmmanuel Vadot #define	PCF8523_B_CS1_SOFTRESET	0x58	/* Initiate Soft Reset bits */
134*2f16049cSEmmanuel Vadot #define	PCF8523_B_CS1_12HR	0x08	/* Use 12-hour (AM/PM) mode bit */
135*2f16049cSEmmanuel Vadot #define	PCF8523_B_CLKOUT_TACD	0x02	/* TimerA runs in CountDown mode */
136*2f16049cSEmmanuel Vadot #define	PCF8523_B_CLKOUT_HIGHZ	0x38	/* Clock Out Freq = disable */
137*2f16049cSEmmanuel Vadot #define	PCF8523_B_TMR_A_64HZ	0x01	/* Timer A freq 64Hz */
138*2f16049cSEmmanuel Vadot 
139*2f16049cSEmmanuel Vadot #define	PCF8523_M_CS3_PM	0xE0	/* Power mode mask */
140*2f16049cSEmmanuel Vadot #define	PCF8523_B_CS3_PM_NOBAT	0xE0	/* PM bits: no battery usage */
141*2f16049cSEmmanuel Vadot #define	PCF8523_B_CS3_PM_STD	0x00	/* PM bits: standard */
142*2f16049cSEmmanuel Vadot #define	PCF8523_B_CS3_PM_DSNBM	0xa0	/* PM bits: direct switch, no bat mon */
143*2f16049cSEmmanuel Vadot #define	PCF8523_B_CS3_BLF	0x04	/* Battery Low Flag bit */
144*2f16049cSEmmanuel Vadot 
145*2f16049cSEmmanuel Vadot /*
146*2f16049cSEmmanuel Vadot  * PCF8563-specific registers, bits, and masks.
147*2f16049cSEmmanuel Vadot  */
148*2f16049cSEmmanuel Vadot #define	PCF8563_R_SECOND	0x02	/* Seconds */
149*2f16049cSEmmanuel Vadot 
150*2f16049cSEmmanuel Vadot #define	PCF8563_R_CLKOUT	0x0d	/* Clock output control */
151*2f16049cSEmmanuel Vadot 
152*2f16049cSEmmanuel Vadot #define	PCF8563_R_TMR_CTRL	0x0e	/* Timer control */
153*2f16049cSEmmanuel Vadot #define	PCF8563_R_TMR_COUNT	0x0f	/* Timer count */
154*2f16049cSEmmanuel Vadot 
155*2f16049cSEmmanuel Vadot #define	PCF8563_M_TMR_CTRL	0x93	/* Mask off undef bits */
156*2f16049cSEmmanuel Vadot 
157*2f16049cSEmmanuel Vadot #define	PCF8563_B_TMR_ENABLE	0x80	/* Enable countdown timer */
158*2f16049cSEmmanuel Vadot #define	PCF8563_B_TMR_64HZ	0x01	/* Timer frequency 64Hz */
159*2f16049cSEmmanuel Vadot 
160*2f16049cSEmmanuel Vadot #define	PCF8563_B_MONTH_C	0x80	/* Century bit */
161*2f16049cSEmmanuel Vadot 
162*2f16049cSEmmanuel Vadot /*
163*2f16049cSEmmanuel Vadot  * We use the countdown timer for fractional seconds.  We program it for 64 Hz,
164*2f16049cSEmmanuel Vadot  * the fastest available rate that doesn't roll over in less than a second.
165*2f16049cSEmmanuel Vadot  */
166*2f16049cSEmmanuel Vadot #define	TMR_TICKS_SEC		64
167*2f16049cSEmmanuel Vadot #define	TMR_TICKS_HALFSEC	32
168*2f16049cSEmmanuel Vadot 
169*2f16049cSEmmanuel Vadot /*
170*2f16049cSEmmanuel Vadot  * The chip types we support.
171*2f16049cSEmmanuel Vadot  */
172*2f16049cSEmmanuel Vadot enum {
173*2f16049cSEmmanuel Vadot 	TYPE_NONE,
174*2f16049cSEmmanuel Vadot 	TYPE_PCA2129,
175*2f16049cSEmmanuel Vadot 	TYPE_PCA8565,
176*2f16049cSEmmanuel Vadot 	TYPE_PCF2127,
177*2f16049cSEmmanuel Vadot 	TYPE_PCF2129,
178*2f16049cSEmmanuel Vadot 	TYPE_PCF8523,
179*2f16049cSEmmanuel Vadot 	TYPE_PCF8563,
180*2f16049cSEmmanuel Vadot 
181*2f16049cSEmmanuel Vadot 	TYPE_COUNT
182*2f16049cSEmmanuel Vadot };
183*2f16049cSEmmanuel Vadot static const char *desc_strings[] = {
184*2f16049cSEmmanuel Vadot 	"",
185*2f16049cSEmmanuel Vadot 	"NXP PCA2129 RTC",
186*2f16049cSEmmanuel Vadot 	"NXP PCA8565 RTC",
187*2f16049cSEmmanuel Vadot 	"NXP PCF2127 RTC",
188*2f16049cSEmmanuel Vadot 	"NXP PCF2129 RTC",
189*2f16049cSEmmanuel Vadot 	"NXP PCF8523 RTC",
190*2f16049cSEmmanuel Vadot 	"NXP PCF8563 RTC",
191*2f16049cSEmmanuel Vadot };
192*2f16049cSEmmanuel Vadot CTASSERT(nitems(desc_strings) == TYPE_COUNT);
193*2f16049cSEmmanuel Vadot 
194*2f16049cSEmmanuel Vadot /*
195*2f16049cSEmmanuel Vadot  * The time registers in the order they are laid out in hardware.
196*2f16049cSEmmanuel Vadot  */
197*2f16049cSEmmanuel Vadot struct time_regs {
198*2f16049cSEmmanuel Vadot 	uint8_t sec, min, hour, day, wday, month, year;
199*2f16049cSEmmanuel Vadot };
200*2f16049cSEmmanuel Vadot 
201*2f16049cSEmmanuel Vadot struct nxprtc_softc {
202*2f16049cSEmmanuel Vadot 	device_t	dev;
203*2f16049cSEmmanuel Vadot 	device_t	busdev;
204*2f16049cSEmmanuel Vadot 	struct intr_config_hook
205*2f16049cSEmmanuel Vadot 			config_hook;
206*2f16049cSEmmanuel Vadot 	u_int		flags;		/* SC_F_* flags */
207*2f16049cSEmmanuel Vadot 	u_int		chiptype;	/* Type of PCF85xx chip */
208*2f16049cSEmmanuel Vadot 	time_t		bat_time;	/* Next time to check battery */
209*2f16049cSEmmanuel Vadot 	int		freqadj;	/* Current freq adj in PPM */
210*2f16049cSEmmanuel Vadot 	uint8_t		secaddr;	/* Address of seconds register */
211*2f16049cSEmmanuel Vadot 	uint8_t		tmcaddr;	/* Address of timer count register */
212*2f16049cSEmmanuel Vadot 	bool		use_timer;	/* Use timer for fractional sec */
213*2f16049cSEmmanuel Vadot 	bool		use_ampm;	/* Chip is set to use am/pm mode */
214*2f16049cSEmmanuel Vadot 	bool		is212x;		/* Chip type is 2127 or 2129 */
215*2f16049cSEmmanuel Vadot };
216*2f16049cSEmmanuel Vadot 
217*2f16049cSEmmanuel Vadot #define	SC_F_CPOL	(1 << 0)	/* Century bit means 19xx */
218*2f16049cSEmmanuel Vadot 
219*2f16049cSEmmanuel Vadot /*
220*2f16049cSEmmanuel Vadot  * When doing i2c IO, indicate that we need to wait for exclusive bus ownership,
221*2f16049cSEmmanuel Vadot  * but that we should not wait if we already own the bus.  This lets us put
222*2f16049cSEmmanuel Vadot  * iicbus_acquire_bus() calls with a non-recursive wait at the entry of our API
223*2f16049cSEmmanuel Vadot  * functions to ensure that only one client at a time accesses the hardware for
224*2f16049cSEmmanuel Vadot  * the entire series of operations it takes to read or write the clock.
225*2f16049cSEmmanuel Vadot  */
226*2f16049cSEmmanuel Vadot #define	WAITFLAGS	(IIC_WAIT | IIC_RECURSIVE)
227*2f16049cSEmmanuel Vadot 
228*2f16049cSEmmanuel Vadot /*
229*2f16049cSEmmanuel Vadot  * We use the compat_data table to look up hint strings in the non-FDT case, so
230*2f16049cSEmmanuel Vadot  * define the struct locally when we don't get it from ofw_bus_subr.h.
231*2f16049cSEmmanuel Vadot  */
232*2f16049cSEmmanuel Vadot #ifdef FDT
233*2f16049cSEmmanuel Vadot typedef struct ofw_compat_data nxprtc_compat_data;
234*2f16049cSEmmanuel Vadot #else
235*2f16049cSEmmanuel Vadot typedef struct {
236*2f16049cSEmmanuel Vadot 	const char *ocd_str;
237*2f16049cSEmmanuel Vadot 	uintptr_t  ocd_data;
238*2f16049cSEmmanuel Vadot } nxprtc_compat_data;
239*2f16049cSEmmanuel Vadot #endif
240*2f16049cSEmmanuel Vadot 
241*2f16049cSEmmanuel Vadot static nxprtc_compat_data compat_data[] = {
242*2f16049cSEmmanuel Vadot 	{"nxp,pca2129",     TYPE_PCA2129},
243*2f16049cSEmmanuel Vadot 	{"nxp,pca8565",     TYPE_PCA8565},
244*2f16049cSEmmanuel Vadot 	{"nxp,pcf2127",     TYPE_PCF2127},
245*2f16049cSEmmanuel Vadot 	{"nxp,pcf2129",     TYPE_PCF2129},
246*2f16049cSEmmanuel Vadot 	{"nxp,pcf8523",     TYPE_PCF8523},
247*2f16049cSEmmanuel Vadot 	{"nxp,pcf8563",     TYPE_PCF8563},
248*2f16049cSEmmanuel Vadot 
249*2f16049cSEmmanuel Vadot 	/* Undocumented compat strings known to exist in the wild... */
250*2f16049cSEmmanuel Vadot 	{"pcf8563",         TYPE_PCF8563},
251*2f16049cSEmmanuel Vadot 	{"phg,pcf8563",     TYPE_PCF8563},
252*2f16049cSEmmanuel Vadot 	{"philips,pcf8563", TYPE_PCF8563},
253*2f16049cSEmmanuel Vadot 
254*2f16049cSEmmanuel Vadot 	{NULL,              TYPE_NONE},
255*2f16049cSEmmanuel Vadot };
256*2f16049cSEmmanuel Vadot 
257*2f16049cSEmmanuel Vadot static int
nxprtc_readfrom(device_t slavedev,uint8_t regaddr,void * buffer,uint16_t buflen,int waithow)258*2f16049cSEmmanuel Vadot nxprtc_readfrom(device_t slavedev, uint8_t regaddr, void *buffer,
259*2f16049cSEmmanuel Vadot     uint16_t buflen, int waithow)
260*2f16049cSEmmanuel Vadot {
261*2f16049cSEmmanuel Vadot 	struct iic_msg msg;
262*2f16049cSEmmanuel Vadot 	int err;
263*2f16049cSEmmanuel Vadot 	uint8_t slaveaddr;
264*2f16049cSEmmanuel Vadot 
265*2f16049cSEmmanuel Vadot 	/*
266*2f16049cSEmmanuel Vadot 	 * Two transfers back to back with a stop and start between them; first we
267*2f16049cSEmmanuel Vadot 	 * write the address-within-device, then we read from the device.  This
268*2f16049cSEmmanuel Vadot 	 * is used instead of the standard iicdev_readfrom() because some of the
269*2f16049cSEmmanuel Vadot 	 * chips we service don't support i2c repeat-start operations (grrrrr)
270*2f16049cSEmmanuel Vadot 	 * so we do two completely separate transfers with a full stop between.
271*2f16049cSEmmanuel Vadot 	 */
272*2f16049cSEmmanuel Vadot 	slaveaddr = iicbus_get_addr(slavedev);
273*2f16049cSEmmanuel Vadot 
274*2f16049cSEmmanuel Vadot 	msg.slave = slaveaddr;
275*2f16049cSEmmanuel Vadot 	msg.flags = IIC_M_WR;
276*2f16049cSEmmanuel Vadot 	msg.len   = 1;
277*2f16049cSEmmanuel Vadot 	msg.buf   = &regaddr;
278*2f16049cSEmmanuel Vadot 
279*2f16049cSEmmanuel Vadot 	if ((err = iicbus_transfer_excl(slavedev, &msg, 1, waithow)) != 0)
280*2f16049cSEmmanuel Vadot 		return (err);
281*2f16049cSEmmanuel Vadot 
282*2f16049cSEmmanuel Vadot 	msg.slave = slaveaddr;
283*2f16049cSEmmanuel Vadot 	msg.flags = IIC_M_RD;
284*2f16049cSEmmanuel Vadot 	msg.len   = buflen;
285*2f16049cSEmmanuel Vadot 	msg.buf   = buffer;
286*2f16049cSEmmanuel Vadot 
287*2f16049cSEmmanuel Vadot 	return (iicbus_transfer_excl(slavedev, &msg, 1, waithow));
288*2f16049cSEmmanuel Vadot }
289*2f16049cSEmmanuel Vadot 
290*2f16049cSEmmanuel Vadot static int
read_reg(struct nxprtc_softc * sc,uint8_t reg,uint8_t * val)291*2f16049cSEmmanuel Vadot read_reg(struct nxprtc_softc *sc, uint8_t reg, uint8_t *val)
292*2f16049cSEmmanuel Vadot {
293*2f16049cSEmmanuel Vadot 
294*2f16049cSEmmanuel Vadot 	return (nxprtc_readfrom(sc->dev, reg, val, sizeof(*val), WAITFLAGS));
295*2f16049cSEmmanuel Vadot }
296*2f16049cSEmmanuel Vadot 
297*2f16049cSEmmanuel Vadot static int
write_reg(struct nxprtc_softc * sc,uint8_t reg,uint8_t val)298*2f16049cSEmmanuel Vadot write_reg(struct nxprtc_softc *sc, uint8_t reg, uint8_t val)
299*2f16049cSEmmanuel Vadot {
300*2f16049cSEmmanuel Vadot 
301*2f16049cSEmmanuel Vadot 	return (iicdev_writeto(sc->dev, reg, &val, sizeof(val), WAITFLAGS));
302*2f16049cSEmmanuel Vadot }
303*2f16049cSEmmanuel Vadot 
304*2f16049cSEmmanuel Vadot static int
read_timeregs(struct nxprtc_softc * sc,struct time_regs * tregs,uint8_t * tmr)305*2f16049cSEmmanuel Vadot read_timeregs(struct nxprtc_softc *sc, struct time_regs *tregs, uint8_t *tmr)
306*2f16049cSEmmanuel Vadot {
307*2f16049cSEmmanuel Vadot 	int err;
308*2f16049cSEmmanuel Vadot 	uint8_t sec, tmr1, tmr2;
309*2f16049cSEmmanuel Vadot 
310*2f16049cSEmmanuel Vadot 	/*
311*2f16049cSEmmanuel Vadot 	 * The datasheet says loop to read the same timer value twice because it
312*2f16049cSEmmanuel Vadot 	 * does not freeze while reading.  To that we add our own logic that
313*2f16049cSEmmanuel Vadot 	 * the seconds register must be the same before and after reading the
314*2f16049cSEmmanuel Vadot 	 * timer, ensuring the fractional part is from the same second as tregs.
315*2f16049cSEmmanuel Vadot 	 */
316*2f16049cSEmmanuel Vadot 	do {
317*2f16049cSEmmanuel Vadot 		if (sc->use_timer) {
318*2f16049cSEmmanuel Vadot 			if ((err = read_reg(sc, sc->secaddr, &sec)) != 0)
319*2f16049cSEmmanuel Vadot 				break;
320*2f16049cSEmmanuel Vadot 			if ((err = read_reg(sc, sc->tmcaddr, &tmr1)) != 0)
321*2f16049cSEmmanuel Vadot 				break;
322*2f16049cSEmmanuel Vadot 			if ((err = read_reg(sc, sc->tmcaddr, &tmr2)) != 0)
323*2f16049cSEmmanuel Vadot 				break;
324*2f16049cSEmmanuel Vadot 			if (tmr1 != tmr2)
325*2f16049cSEmmanuel Vadot 				continue;
326*2f16049cSEmmanuel Vadot 		}
327*2f16049cSEmmanuel Vadot 		if ((err = nxprtc_readfrom(sc->dev, sc->secaddr, tregs,
328*2f16049cSEmmanuel Vadot 		    sizeof(*tregs), WAITFLAGS)) != 0)
329*2f16049cSEmmanuel Vadot 			break;
330*2f16049cSEmmanuel Vadot 	} while (sc->use_timer && tregs->sec != sec);
331*2f16049cSEmmanuel Vadot 
332*2f16049cSEmmanuel Vadot 	/*
333*2f16049cSEmmanuel Vadot 	 * If the timer value is greater than our hz rate (or is zero),
334*2f16049cSEmmanuel Vadot 	 * something is wrong.  Maybe some other OS used the timer differently?
335*2f16049cSEmmanuel Vadot 	 * Just set it to zero.  Likewise if we're not using the timer.  After
336*2f16049cSEmmanuel Vadot 	 * the offset calc below, the zero turns into 32, the mid-second point,
337*2f16049cSEmmanuel Vadot 	 * which in effect performs 4/5 rounding, which is just the right thing
338*2f16049cSEmmanuel Vadot 	 * to do if we don't have fine-grained time.
339*2f16049cSEmmanuel Vadot 	 */
340*2f16049cSEmmanuel Vadot 	if (!sc->use_timer || tmr1 > TMR_TICKS_SEC)
341*2f16049cSEmmanuel Vadot 		tmr1 = 0;
342*2f16049cSEmmanuel Vadot 
343*2f16049cSEmmanuel Vadot 	/*
344*2f16049cSEmmanuel Vadot 	 * Turn the downcounter into an upcounter.  The timer starts counting at
345*2f16049cSEmmanuel Vadot 	 * and rolls over at mid-second, so add half a second worth of ticks to
346*2f16049cSEmmanuel Vadot 	 * get its zero point back in sync with the tregs.sec rollover.
347*2f16049cSEmmanuel Vadot 	 */
348*2f16049cSEmmanuel Vadot 	*tmr = (TMR_TICKS_SEC - tmr1 + TMR_TICKS_HALFSEC) % TMR_TICKS_SEC;
349*2f16049cSEmmanuel Vadot 
350*2f16049cSEmmanuel Vadot 	return (err);
351*2f16049cSEmmanuel Vadot }
352*2f16049cSEmmanuel Vadot 
353*2f16049cSEmmanuel Vadot static int
write_timeregs(struct nxprtc_softc * sc,struct time_regs * tregs)354*2f16049cSEmmanuel Vadot write_timeregs(struct nxprtc_softc *sc, struct time_regs *tregs)
355*2f16049cSEmmanuel Vadot {
356*2f16049cSEmmanuel Vadot 
357*2f16049cSEmmanuel Vadot 	return (iicdev_writeto(sc->dev, sc->secaddr, tregs,
358*2f16049cSEmmanuel Vadot 	    sizeof(*tregs), WAITFLAGS));
359*2f16049cSEmmanuel Vadot }
360*2f16049cSEmmanuel Vadot 
361*2f16049cSEmmanuel Vadot static int
freqadj_sysctl(SYSCTL_HANDLER_ARGS)362*2f16049cSEmmanuel Vadot freqadj_sysctl(SYSCTL_HANDLER_ARGS)
363*2f16049cSEmmanuel Vadot {
364*2f16049cSEmmanuel Vadot 	struct nxprtc_softc *sc;
365*2f16049cSEmmanuel Vadot 	int err, freqppm, newppm;
366*2f16049cSEmmanuel Vadot 
367*2f16049cSEmmanuel Vadot 	sc = arg1;
368*2f16049cSEmmanuel Vadot 
369*2f16049cSEmmanuel Vadot 	/* PPM range [-7,8] maps to reg value range [0,15] */
370*2f16049cSEmmanuel Vadot 	freqppm = newppm = 8 - sc->freqadj;
371*2f16049cSEmmanuel Vadot 
372*2f16049cSEmmanuel Vadot 	err = sysctl_handle_int(oidp, &newppm, 0, req);
373*2f16049cSEmmanuel Vadot 	if (err != 0 || req->newptr == NULL)
374*2f16049cSEmmanuel Vadot 		return (err);
375*2f16049cSEmmanuel Vadot 	if (freqppm != newppm) {
376*2f16049cSEmmanuel Vadot 		if (newppm < -7 || newppm > 8)
377*2f16049cSEmmanuel Vadot 			return (EINVAL);
378*2f16049cSEmmanuel Vadot 		sc->freqadj = 8 - newppm;
379*2f16049cSEmmanuel Vadot 		err = write_reg(sc, PCF2127_R_AGING_OFFSET, sc->freqadj);
380*2f16049cSEmmanuel Vadot 	}
381*2f16049cSEmmanuel Vadot 
382*2f16049cSEmmanuel Vadot 	return (err);
383*2f16049cSEmmanuel Vadot }
384*2f16049cSEmmanuel Vadot 
385*2f16049cSEmmanuel Vadot static int
pcf8523_battery_check(struct nxprtc_softc * sc)386*2f16049cSEmmanuel Vadot pcf8523_battery_check(struct nxprtc_softc *sc)
387*2f16049cSEmmanuel Vadot {
388*2f16049cSEmmanuel Vadot 	struct timespec ts;
389*2f16049cSEmmanuel Vadot 	int err;
390*2f16049cSEmmanuel Vadot 	uint8_t cs3;
391*2f16049cSEmmanuel Vadot 
392*2f16049cSEmmanuel Vadot 	/* We check the battery when starting up, and then only once a day. */
393*2f16049cSEmmanuel Vadot 	getnanouptime(&ts);
394*2f16049cSEmmanuel Vadot 	if (ts.tv_sec < sc->bat_time)
395*2f16049cSEmmanuel Vadot 		return (0);
396*2f16049cSEmmanuel Vadot 	sc->bat_time = ts.tv_sec + (60 * 60 * 24);
397*2f16049cSEmmanuel Vadot 
398*2f16049cSEmmanuel Vadot 	/*
399*2f16049cSEmmanuel Vadot 	 * The 8523, 2127, and 2129 chips have a "power manager" which includes
400*2f16049cSEmmanuel Vadot 	 * an optional battery voltage monitor and several choices for power
401*2f16049cSEmmanuel Vadot 	 * switching modes.  The battery monitor uses a lot of current and it
402*2f16049cSEmmanuel Vadot 	 * remains active when running from battery, making it the "drain my
403*2f16049cSEmmanuel Vadot 	 * battery twice as fast" mode.  So, we run the chip in direct-switching
404*2f16049cSEmmanuel Vadot 	 * mode with the battery monitor disabled, reducing the current draw
405*2f16049cSEmmanuel Vadot 	 * when running on battery from 1930nA to 880nA.  While it's not clear
406*2f16049cSEmmanuel Vadot 	 * from the datasheets, empirical testing shows that both disabling the
407*2f16049cSEmmanuel Vadot 	 * battery monitor and using direct-switch mode are required to get the
408*2f16049cSEmmanuel Vadot 	 * full power savings.
409*2f16049cSEmmanuel Vadot 	 *
410*2f16049cSEmmanuel Vadot 	 * There isn't any need to continuously monitor the battery voltage, so
411*2f16049cSEmmanuel Vadot 	 * this function is used to periodically enable the monitor, check the
412*2f16049cSEmmanuel Vadot 	 * voltage, then return to the low-power monitor-disabled mode.
413*2f16049cSEmmanuel Vadot 	 */
414*2f16049cSEmmanuel Vadot 	err = write_reg(sc, PCF8523_R_CS3, PCF8523_B_CS3_PM_STD);
415*2f16049cSEmmanuel Vadot 	if (err != 0) {
416*2f16049cSEmmanuel Vadot 		device_printf(sc->dev, "cannot write CS3 reg\n");
417*2f16049cSEmmanuel Vadot 		return (err);
418*2f16049cSEmmanuel Vadot 	}
419*2f16049cSEmmanuel Vadot 	pause_sbt("nxpbat", mstosbt(100), 0, 0);
420*2f16049cSEmmanuel Vadot 	if ((err = read_reg(sc, PCF8523_R_CS3, &cs3)) != 0) {
421*2f16049cSEmmanuel Vadot 		device_printf(sc->dev, "cannot read CS3 reg\n");
422*2f16049cSEmmanuel Vadot 		return (err);
423*2f16049cSEmmanuel Vadot 	}
424*2f16049cSEmmanuel Vadot 	err = write_reg(sc, PCF8523_R_CS3, PCF8523_B_CS3_PM_DSNBM);
425*2f16049cSEmmanuel Vadot 	if (err != 0) {
426*2f16049cSEmmanuel Vadot 		device_printf(sc->dev, "cannot write CS3 reg\n");
427*2f16049cSEmmanuel Vadot 		return (err);
428*2f16049cSEmmanuel Vadot 	}
429*2f16049cSEmmanuel Vadot 
430*2f16049cSEmmanuel Vadot 	if (cs3 & PCF8523_B_CS3_BLF)
431*2f16049cSEmmanuel Vadot 		device_printf(sc->dev, "WARNING: RTC battery is low\n");
432*2f16049cSEmmanuel Vadot 
433*2f16049cSEmmanuel Vadot 	return (0);
434*2f16049cSEmmanuel Vadot }
435*2f16049cSEmmanuel Vadot 
436*2f16049cSEmmanuel Vadot static int
pcf8523_start(struct nxprtc_softc * sc)437*2f16049cSEmmanuel Vadot pcf8523_start(struct nxprtc_softc *sc)
438*2f16049cSEmmanuel Vadot {
439*2f16049cSEmmanuel Vadot 	struct sysctl_ctx_list *ctx;
440*2f16049cSEmmanuel Vadot 	struct sysctl_oid_list *tree;
441*2f16049cSEmmanuel Vadot 	struct csr {
442*2f16049cSEmmanuel Vadot 		uint8_t	cs1;
443*2f16049cSEmmanuel Vadot 		uint8_t	cs2;
444*2f16049cSEmmanuel Vadot 		uint8_t cs3;
445*2f16049cSEmmanuel Vadot 		uint8_t sec;
446*2f16049cSEmmanuel Vadot 	} csr;
447*2f16049cSEmmanuel Vadot 	int err;
448*2f16049cSEmmanuel Vadot 	uint8_t clkout, freqadj;
449*2f16049cSEmmanuel Vadot 
450*2f16049cSEmmanuel Vadot 	/* Read the control and status registers. */
451*2f16049cSEmmanuel Vadot 	if ((err = nxprtc_readfrom(sc->dev, PCF85xx_R_CS1, &csr,
452*2f16049cSEmmanuel Vadot 	    sizeof(csr), WAITFLAGS)) != 0){
453*2f16049cSEmmanuel Vadot 		device_printf(sc->dev, "cannot read RTC control regs\n");
454*2f16049cSEmmanuel Vadot 		return (err);
455*2f16049cSEmmanuel Vadot 	}
456*2f16049cSEmmanuel Vadot 
457*2f16049cSEmmanuel Vadot 	/*
458*2f16049cSEmmanuel Vadot 	 * Do a full init if...
459*2f16049cSEmmanuel Vadot 	 *  - The chip power manager is in battery-disable mode.
460*2f16049cSEmmanuel Vadot 	 *  - The OS (oscillator stopped) bit is set (all power was lost).
461*2f16049cSEmmanuel Vadot 	 *  - The clock-increment STOP flag is set (this is just insane).
462*2f16049cSEmmanuel Vadot 	 */
463*2f16049cSEmmanuel Vadot 	if ((csr.cs3 & PCF8523_M_CS3_PM) == PCF8523_B_CS3_PM_NOBAT ||
464*2f16049cSEmmanuel Vadot 	    (csr.cs1 & PCF85xx_B_CS1_STOP) || (csr.sec & PCF85xx_B_SECOND_OS)) {
465*2f16049cSEmmanuel Vadot 		device_printf(sc->dev,
466*2f16049cSEmmanuel Vadot 		    "WARNING: RTC battery failed; time is invalid\n");
467*2f16049cSEmmanuel Vadot 
468*2f16049cSEmmanuel Vadot 		/*
469*2f16049cSEmmanuel Vadot 		 * For 212x series...
470*2f16049cSEmmanuel Vadot 		 * - Turn off the POR-Override bit (used for mfg test only),
471*2f16049cSEmmanuel Vadot 		 *   by writing zero to cs 1 (all other bits power on as zero).
472*2f16049cSEmmanuel Vadot 		 * - Turn off the timestamp option to save the power used to
473*2f16049cSEmmanuel Vadot 		 *   monitor that input pin.
474*2f16049cSEmmanuel Vadot 		 * - Trigger OTP refresh by forcing the OTPR bit to zero then
475*2f16049cSEmmanuel Vadot 		 *   back to 1, then wait 100ms for the refresh.
476*2f16049cSEmmanuel Vadot 		 */
477*2f16049cSEmmanuel Vadot 		if (sc->is212x) {
478*2f16049cSEmmanuel Vadot 			err = write_reg(sc, PCF85xx_R_CS1, 0);
479*2f16049cSEmmanuel Vadot 			if (err != 0) {
480*2f16049cSEmmanuel Vadot 				device_printf(sc->dev,
481*2f16049cSEmmanuel Vadot 				    "cannot write CS1 reg\n");
482*2f16049cSEmmanuel Vadot 				return (err);
483*2f16049cSEmmanuel Vadot 			}
484*2f16049cSEmmanuel Vadot 
485*2f16049cSEmmanuel Vadot 			err = write_reg(sc, PCF2127_R_TS_CTL, PCF2127_B_TSOFF);
486*2f16049cSEmmanuel Vadot 			if (err != 0) {
487*2f16049cSEmmanuel Vadot 				device_printf(sc->dev,
488*2f16049cSEmmanuel Vadot 				    "cannot write timestamp control\n");
489*2f16049cSEmmanuel Vadot 				return (err);
490*2f16049cSEmmanuel Vadot 			}
491*2f16049cSEmmanuel Vadot 
492*2f16049cSEmmanuel Vadot 			clkout = PCF2129_B_CLKOUT_HIGHZ;
493*2f16049cSEmmanuel Vadot 			err = write_reg(sc, PCF8523_R_TMR_CLKOUT, clkout);
494*2f16049cSEmmanuel Vadot 			if (err == 0)
495*2f16049cSEmmanuel Vadot 				err = write_reg(sc, PCF8523_R_TMR_CLKOUT,
496*2f16049cSEmmanuel Vadot 				    clkout | PCF2129_B_CLKOUT_OTPR);
497*2f16049cSEmmanuel Vadot 			if (err != 0) {
498*2f16049cSEmmanuel Vadot 				device_printf(sc->dev,
499*2f16049cSEmmanuel Vadot 				    "cannot write CLKOUT control\n");
500*2f16049cSEmmanuel Vadot 				return (err);
501*2f16049cSEmmanuel Vadot 			}
502*2f16049cSEmmanuel Vadot 			pause_sbt("nxpotp", mstosbt(100), mstosbt(10), 0);
503*2f16049cSEmmanuel Vadot 		} else
504*2f16049cSEmmanuel Vadot 			clkout = PCF8523_B_CLKOUT_HIGHZ;
505*2f16049cSEmmanuel Vadot 
506*2f16049cSEmmanuel Vadot 		/* All chips: set clock output pin to high-z to save power */
507*2f16049cSEmmanuel Vadot 		if ((err = write_reg(sc, PCF8523_R_TMR_CLKOUT, clkout)) != 0) {
508*2f16049cSEmmanuel Vadot 			device_printf(sc->dev, "cannot write CLKOUT control\n");
509*2f16049cSEmmanuel Vadot 			return (err);
510*2f16049cSEmmanuel Vadot 		}
511*2f16049cSEmmanuel Vadot 	}
512*2f16049cSEmmanuel Vadot 
513*2f16049cSEmmanuel Vadot 	/*
514*2f16049cSEmmanuel Vadot 	 * Check the battery voltage and report if it's low.  This also has the
515*2f16049cSEmmanuel Vadot 	 * side effect of (re-)initializing the power manager to low-power mode
516*2f16049cSEmmanuel Vadot 	 * when we come up after a power fail.
517*2f16049cSEmmanuel Vadot 	 */
518*2f16049cSEmmanuel Vadot 	pcf8523_battery_check(sc);
519*2f16049cSEmmanuel Vadot 
520*2f16049cSEmmanuel Vadot 	/*
521*2f16049cSEmmanuel Vadot 	 * Remember whether we're running in AM/PM mode.  The chip default is
522*2f16049cSEmmanuel Vadot 	 * 24-hour mode, but if we're co-existing with some other OS that
523*2f16049cSEmmanuel Vadot 	 * prefers AM/PM we can run that way too.
524*2f16049cSEmmanuel Vadot 	 *
525*2f16049cSEmmanuel Vadot 	 * Also, for 212x chips, retrieve the current frequency aging offset,
526*2f16049cSEmmanuel Vadot 	 * and set up the sysctl handler for reading/setting it.
527*2f16049cSEmmanuel Vadot 	 */
528*2f16049cSEmmanuel Vadot 	if (sc->is212x) {
529*2f16049cSEmmanuel Vadot 		if (csr.cs1 & PCF2129_B_CS1_12HR)
530*2f16049cSEmmanuel Vadot 			sc->use_ampm = true;
531*2f16049cSEmmanuel Vadot 
532*2f16049cSEmmanuel Vadot 		err = read_reg(sc, PCF2127_R_AGING_OFFSET, &freqadj);
533*2f16049cSEmmanuel Vadot 		if (err != 0) {
534*2f16049cSEmmanuel Vadot 			device_printf(sc->dev,
535*2f16049cSEmmanuel Vadot 			    "cannot read AGINGOFFSET register\n");
536*2f16049cSEmmanuel Vadot 			return (err);
537*2f16049cSEmmanuel Vadot 		}
538*2f16049cSEmmanuel Vadot 		sc->freqadj = (int8_t)freqadj;
539*2f16049cSEmmanuel Vadot 
540*2f16049cSEmmanuel Vadot 		ctx = device_get_sysctl_ctx(sc->dev);
541*2f16049cSEmmanuel Vadot 		tree = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev));
542*2f16049cSEmmanuel Vadot 
543*2f16049cSEmmanuel Vadot 		SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "freqadj",
544*2f16049cSEmmanuel Vadot 		    CTLFLAG_RWTUN | CTLTYPE_INT | CTLFLAG_MPSAFE, sc, 0,
545*2f16049cSEmmanuel Vadot 		    freqadj_sysctl, "I", "Frequency adjust in PPM, range [-7,+8]");
546*2f16049cSEmmanuel Vadot 	} else {
547*2f16049cSEmmanuel Vadot 		if (csr.cs1 & PCF8523_B_CS1_12HR)
548*2f16049cSEmmanuel Vadot 			sc->use_ampm = true;
549*2f16049cSEmmanuel Vadot 	}
550*2f16049cSEmmanuel Vadot 
551*2f16049cSEmmanuel Vadot 	return (0);
552*2f16049cSEmmanuel Vadot }
553*2f16049cSEmmanuel Vadot static int
pcf8523_start_timer(struct nxprtc_softc * sc)554*2f16049cSEmmanuel Vadot pcf8523_start_timer(struct nxprtc_softc *sc)
555*2f16049cSEmmanuel Vadot {
556*2f16049cSEmmanuel Vadot 	int err;
557*2f16049cSEmmanuel Vadot 	uint8_t clkout, stdclk, stdfreq, tmrfreq;
558*2f16049cSEmmanuel Vadot 
559*2f16049cSEmmanuel Vadot 	/*
560*2f16049cSEmmanuel Vadot 	 * Read the timer control and frequency regs.  If they don't have the
561*2f16049cSEmmanuel Vadot 	 * values we normally program into them then the timer count doesn't
562*2f16049cSEmmanuel Vadot 	 * contain a valid fractional second, so zero it to prevent using a bad
563*2f16049cSEmmanuel Vadot 	 * value.  Then program the normal timer values so that on the first
564*2f16049cSEmmanuel Vadot 	 * settime call we'll begin to use fractional time.
565*2f16049cSEmmanuel Vadot 	 */
566*2f16049cSEmmanuel Vadot 	if ((err = read_reg(sc, PCF8523_R_TMR_A_FREQ, &tmrfreq)) != 0)
567*2f16049cSEmmanuel Vadot 		return (err);
568*2f16049cSEmmanuel Vadot 	if ((err = read_reg(sc, PCF8523_R_TMR_CLKOUT, &clkout)) != 0)
569*2f16049cSEmmanuel Vadot 		return (err);
570*2f16049cSEmmanuel Vadot 
571*2f16049cSEmmanuel Vadot 	stdfreq = PCF8523_B_TMR_A_64HZ;
572*2f16049cSEmmanuel Vadot 	stdclk = PCF8523_B_CLKOUT_TACD | PCF8523_B_CLKOUT_HIGHZ;
573*2f16049cSEmmanuel Vadot 
574*2f16049cSEmmanuel Vadot 	if (clkout != stdclk || (tmrfreq & PCF8523_M_TMR_A_FREQ) != stdfreq) {
575*2f16049cSEmmanuel Vadot 		if ((err = write_reg(sc, sc->tmcaddr, 0)) != 0)
576*2f16049cSEmmanuel Vadot 			return (err);
577*2f16049cSEmmanuel Vadot 		if ((err = write_reg(sc, PCF8523_R_TMR_A_FREQ, stdfreq)) != 0)
578*2f16049cSEmmanuel Vadot 			return (err);
579*2f16049cSEmmanuel Vadot 		if ((err = write_reg(sc, PCF8523_R_TMR_CLKOUT, stdclk)) != 0)
580*2f16049cSEmmanuel Vadot 			return (err);
581*2f16049cSEmmanuel Vadot 	}
582*2f16049cSEmmanuel Vadot 	return (0);
583*2f16049cSEmmanuel Vadot }
584*2f16049cSEmmanuel Vadot 
585*2f16049cSEmmanuel Vadot static int
pcf2127_start_timer(struct nxprtc_softc * sc)586*2f16049cSEmmanuel Vadot pcf2127_start_timer(struct nxprtc_softc *sc)
587*2f16049cSEmmanuel Vadot {
588*2f16049cSEmmanuel Vadot 	int err;
589*2f16049cSEmmanuel Vadot 	uint8_t stdctl, tmrctl;
590*2f16049cSEmmanuel Vadot 
591*2f16049cSEmmanuel Vadot 	/*
592*2f16049cSEmmanuel Vadot 	 * Set up timer if it's not already in the mode we normally run it.  See
593*2f16049cSEmmanuel Vadot 	 * the comment in pcf8523_start_timer() for more details.
594*2f16049cSEmmanuel Vadot 	 *
595*2f16049cSEmmanuel Vadot 	 * Note that the PCF2129 datasheet says it has no countdown timer, but
596*2f16049cSEmmanuel Vadot 	 * empirical testing shows that it works just fine for our purposes.
597*2f16049cSEmmanuel Vadot 	 */
598*2f16049cSEmmanuel Vadot 	if ((err = read_reg(sc, PCF2127_R_TMR_CTL, &tmrctl)) != 0)
599*2f16049cSEmmanuel Vadot 		return (err);
600*2f16049cSEmmanuel Vadot 
601*2f16049cSEmmanuel Vadot 	stdctl = PCF2127_B_TMR_CD | PCF8523_B_TMR_A_64HZ;
602*2f16049cSEmmanuel Vadot 
603*2f16049cSEmmanuel Vadot 	if ((tmrctl & PCF2127_M_TMR_CTRL) != stdctl) {
604*2f16049cSEmmanuel Vadot 		if ((err = write_reg(sc, sc->tmcaddr, 0)) != 0)
605*2f16049cSEmmanuel Vadot 			return (err);
606*2f16049cSEmmanuel Vadot 		if ((err = write_reg(sc, PCF2127_R_TMR_CTL, stdctl)) != 0)
607*2f16049cSEmmanuel Vadot 			return (err);
608*2f16049cSEmmanuel Vadot 	}
609*2f16049cSEmmanuel Vadot 	return (0);
610*2f16049cSEmmanuel Vadot }
611*2f16049cSEmmanuel Vadot 
612*2f16049cSEmmanuel Vadot static int
pcf8563_start(struct nxprtc_softc * sc)613*2f16049cSEmmanuel Vadot pcf8563_start(struct nxprtc_softc *sc)
614*2f16049cSEmmanuel Vadot {
615*2f16049cSEmmanuel Vadot 	struct csr {
616*2f16049cSEmmanuel Vadot 		uint8_t	cs1;
617*2f16049cSEmmanuel Vadot 		uint8_t	cs2;
618*2f16049cSEmmanuel Vadot 		uint8_t sec;
619*2f16049cSEmmanuel Vadot 	} csr;
620*2f16049cSEmmanuel Vadot 	int err;
621*2f16049cSEmmanuel Vadot 
622*2f16049cSEmmanuel Vadot 	/* Read the control and status registers. */
623*2f16049cSEmmanuel Vadot 	if ((err = nxprtc_readfrom(sc->dev, PCF85xx_R_CS1, &csr,
624*2f16049cSEmmanuel Vadot 	    sizeof(csr), WAITFLAGS)) != 0){
625*2f16049cSEmmanuel Vadot 		device_printf(sc->dev, "cannot read RTC control regs\n");
626*2f16049cSEmmanuel Vadot 		return (err);
627*2f16049cSEmmanuel Vadot 	}
628*2f16049cSEmmanuel Vadot 
629*2f16049cSEmmanuel Vadot 	/*
630*2f16049cSEmmanuel Vadot 	 * Do a full init if...
631*2f16049cSEmmanuel Vadot 	 *  - The OS (oscillator stopped) bit is set (all power was lost).  This
632*2f16049cSEmmanuel Vadot 	 *    bit is called VL (Voltage Low) in the 8563 datasheet.
633*2f16049cSEmmanuel Vadot 	 *  - The clock-increment STOP flag is set (this is just insane).
634*2f16049cSEmmanuel Vadot 	 */
635*2f16049cSEmmanuel Vadot 	if ((csr.cs1 & PCF85xx_B_CS1_STOP) || (csr.sec & PCF85xx_B_SECOND_OS)) {
636*2f16049cSEmmanuel Vadot 		device_printf(sc->dev,
637*2f16049cSEmmanuel Vadot 		    "WARNING: RTC battery failed; time is invalid\n");
638*2f16049cSEmmanuel Vadot 		/*
639*2f16049cSEmmanuel Vadot 		 * - Turn off the POR-Override bit (used for mfg test only), by
640*2f16049cSEmmanuel Vadot 		 *   writing zero to cs 1 (all other bits power on as zero).
641*2f16049cSEmmanuel Vadot 		 * - Turn off the clock output pin (to save battery power), by
642*2f16049cSEmmanuel Vadot 		 *   writing zero to the clkout control reg.
643*2f16049cSEmmanuel Vadot 		 */
644*2f16049cSEmmanuel Vadot 		if ((err = write_reg(sc, PCF85xx_R_CS1, 0)) != 0) {
645*2f16049cSEmmanuel Vadot 			device_printf(sc->dev, "cannot write CS1 reg\n");
646*2f16049cSEmmanuel Vadot 			return (err);
647*2f16049cSEmmanuel Vadot 		}
648*2f16049cSEmmanuel Vadot 
649*2f16049cSEmmanuel Vadot 		if ((err = write_reg(sc, PCF8563_R_CLKOUT, 0)) != 0) {
650*2f16049cSEmmanuel Vadot 			device_printf(sc->dev, "cannot write CS1 reg\n");
651*2f16049cSEmmanuel Vadot 			return (err);
652*2f16049cSEmmanuel Vadot 		}
653*2f16049cSEmmanuel Vadot 	}
654*2f16049cSEmmanuel Vadot 
655*2f16049cSEmmanuel Vadot 	return (0);
656*2f16049cSEmmanuel Vadot }
657*2f16049cSEmmanuel Vadot 
658*2f16049cSEmmanuel Vadot static int
pcf8563_start_timer(struct nxprtc_softc * sc)659*2f16049cSEmmanuel Vadot pcf8563_start_timer(struct nxprtc_softc *sc)
660*2f16049cSEmmanuel Vadot {
661*2f16049cSEmmanuel Vadot 	int err;
662*2f16049cSEmmanuel Vadot 	uint8_t stdctl, tmrctl;
663*2f16049cSEmmanuel Vadot 
664*2f16049cSEmmanuel Vadot 	/* See comment in pcf8523_start_timer().  */
665*2f16049cSEmmanuel Vadot 	if ((err = read_reg(sc, PCF8563_R_TMR_CTRL, &tmrctl)) != 0)
666*2f16049cSEmmanuel Vadot 		return (err);
667*2f16049cSEmmanuel Vadot 
668*2f16049cSEmmanuel Vadot 	stdctl = PCF8563_B_TMR_ENABLE | PCF8563_B_TMR_64HZ;
669*2f16049cSEmmanuel Vadot 
670*2f16049cSEmmanuel Vadot 	if ((tmrctl & PCF8563_M_TMR_CTRL) != stdctl) {
671*2f16049cSEmmanuel Vadot 		if ((err = write_reg(sc, sc->tmcaddr, 0)) != 0)
672*2f16049cSEmmanuel Vadot 			return (err);
673*2f16049cSEmmanuel Vadot 		if ((err = write_reg(sc, PCF8563_R_TMR_CTRL, stdctl)) != 0)
674*2f16049cSEmmanuel Vadot 			return (err);
675*2f16049cSEmmanuel Vadot 	}
676*2f16049cSEmmanuel Vadot 	return (0);
677*2f16049cSEmmanuel Vadot }
678*2f16049cSEmmanuel Vadot 
679*2f16049cSEmmanuel Vadot static void
nxprtc_start(void * dev)680*2f16049cSEmmanuel Vadot nxprtc_start(void *dev)
681*2f16049cSEmmanuel Vadot {
682*2f16049cSEmmanuel Vadot 	struct nxprtc_softc *sc;
683*2f16049cSEmmanuel Vadot 	int clockflags, resolution;
684*2f16049cSEmmanuel Vadot 
685*2f16049cSEmmanuel Vadot 	sc = device_get_softc((device_t)dev);
686*2f16049cSEmmanuel Vadot 	config_intrhook_disestablish(&sc->config_hook);
687*2f16049cSEmmanuel Vadot 
688*2f16049cSEmmanuel Vadot 	/* First do chip-specific inits. */
689*2f16049cSEmmanuel Vadot 	switch (sc->chiptype) {
690*2f16049cSEmmanuel Vadot 	case TYPE_PCA2129:
691*2f16049cSEmmanuel Vadot 	case TYPE_PCF2129:
692*2f16049cSEmmanuel Vadot 	case TYPE_PCF2127:
693*2f16049cSEmmanuel Vadot 		sc->is212x = true;
694*2f16049cSEmmanuel Vadot 		if (pcf8523_start(sc) != 0)
695*2f16049cSEmmanuel Vadot 			return;
696*2f16049cSEmmanuel Vadot 		if (pcf2127_start_timer(sc) != 0) {
697*2f16049cSEmmanuel Vadot 			device_printf(sc->dev, "cannot set up timer\n");
698*2f16049cSEmmanuel Vadot 			return;
699*2f16049cSEmmanuel Vadot 		}
700*2f16049cSEmmanuel Vadot 		break;
701*2f16049cSEmmanuel Vadot 	case TYPE_PCF8523:
702*2f16049cSEmmanuel Vadot 		if (pcf8523_start(sc) != 0)
703*2f16049cSEmmanuel Vadot 			return;
704*2f16049cSEmmanuel Vadot 		if (pcf8523_start_timer(sc) != 0) {
705*2f16049cSEmmanuel Vadot 			device_printf(sc->dev, "cannot set up timer\n");
706*2f16049cSEmmanuel Vadot 			return;
707*2f16049cSEmmanuel Vadot 		}
708*2f16049cSEmmanuel Vadot 		break;
709*2f16049cSEmmanuel Vadot 	case TYPE_PCA8565:
710*2f16049cSEmmanuel Vadot 	case TYPE_PCF8563:
711*2f16049cSEmmanuel Vadot 		if (pcf8563_start(sc) != 0)
712*2f16049cSEmmanuel Vadot 			return;
713*2f16049cSEmmanuel Vadot 		if (pcf8563_start_timer(sc) != 0) {
714*2f16049cSEmmanuel Vadot 			device_printf(sc->dev, "cannot set up timer\n");
715*2f16049cSEmmanuel Vadot 			return;
716*2f16049cSEmmanuel Vadot 		}
717*2f16049cSEmmanuel Vadot 		break;
718*2f16049cSEmmanuel Vadot 	default:
719*2f16049cSEmmanuel Vadot 		device_printf(sc->dev, "missing init code for this chiptype\n");
720*2f16049cSEmmanuel Vadot 		return;
721*2f16049cSEmmanuel Vadot 	}
722*2f16049cSEmmanuel Vadot 
723*2f16049cSEmmanuel Vadot 	/*
724*2f16049cSEmmanuel Vadot 	 * Everything looks good if we make it to here; register as an RTC.  If
725*2f16049cSEmmanuel Vadot 	 * we're using the timer to count fractional seconds, our resolution is
726*2f16049cSEmmanuel Vadot 	 * 1e6/64, about 15.6ms.  Without the timer we still align the RTC clock
727*2f16049cSEmmanuel Vadot 	 * when setting it so our error is an average .5s when reading it.
728*2f16049cSEmmanuel Vadot 	 * Schedule our clock_settime() method to be called at a .495ms offset
729*2f16049cSEmmanuel Vadot 	 * into the second, because the clock hardware resets the divider chain
730*2f16049cSEmmanuel Vadot 	 * to the mid-second point when you set the time and it takes about 5ms
731*2f16049cSEmmanuel Vadot 	 * of i2c bus activity to set the clock.
732*2f16049cSEmmanuel Vadot 	 */
733*2f16049cSEmmanuel Vadot 	resolution = sc->use_timer ? 1000000 / TMR_TICKS_SEC : 1000000 / 2;
734*2f16049cSEmmanuel Vadot 	clockflags = CLOCKF_GETTIME_NO_ADJ | CLOCKF_SETTIME_NO_TS;
735*2f16049cSEmmanuel Vadot 	clock_register_flags(sc->dev, resolution, clockflags);
736*2f16049cSEmmanuel Vadot 	clock_schedule(sc->dev, 495000000);
737*2f16049cSEmmanuel Vadot }
738*2f16049cSEmmanuel Vadot 
739*2f16049cSEmmanuel Vadot static int
nxprtc_gettime(device_t dev,struct timespec * ts)740*2f16049cSEmmanuel Vadot nxprtc_gettime(device_t dev, struct timespec *ts)
741*2f16049cSEmmanuel Vadot {
742*2f16049cSEmmanuel Vadot 	struct bcd_clocktime bct;
743*2f16049cSEmmanuel Vadot 	struct time_regs tregs;
744*2f16049cSEmmanuel Vadot 	struct nxprtc_softc *sc;
745*2f16049cSEmmanuel Vadot 	int err;
746*2f16049cSEmmanuel Vadot 	uint8_t cs1, hourmask, tmrcount;
747*2f16049cSEmmanuel Vadot 
748*2f16049cSEmmanuel Vadot 	sc = device_get_softc(dev);
749*2f16049cSEmmanuel Vadot 
750*2f16049cSEmmanuel Vadot 	/*
751*2f16049cSEmmanuel Vadot 	 * Read the time, but before using it, validate that the oscillator-
752*2f16049cSEmmanuel Vadot 	 * stopped/power-fail bit is not set, and that the time-increment STOP
753*2f16049cSEmmanuel Vadot 	 * bit is not set in the control reg.  The latter can happen if there
754*2f16049cSEmmanuel Vadot 	 * was an error when setting the time.
755*2f16049cSEmmanuel Vadot 	 */
756*2f16049cSEmmanuel Vadot 	if ((err = iicbus_request_bus(sc->busdev, sc->dev, IIC_WAIT)) == 0) {
757*2f16049cSEmmanuel Vadot 		if ((err = read_timeregs(sc, &tregs, &tmrcount)) == 0) {
758*2f16049cSEmmanuel Vadot 			err = read_reg(sc, PCF85xx_R_CS1, &cs1);
759*2f16049cSEmmanuel Vadot 		}
760*2f16049cSEmmanuel Vadot 		iicbus_release_bus(sc->busdev, sc->dev);
761*2f16049cSEmmanuel Vadot 	}
762*2f16049cSEmmanuel Vadot 	if (err != 0)
763*2f16049cSEmmanuel Vadot 		return (err);
764*2f16049cSEmmanuel Vadot 
765*2f16049cSEmmanuel Vadot 	if ((tregs.sec & PCF85xx_B_SECOND_OS) || (cs1 & PCF85xx_B_CS1_STOP)) {
766*2f16049cSEmmanuel Vadot 		device_printf(dev, "RTC clock not running\n");
767*2f16049cSEmmanuel Vadot 		return (EINVAL); /* hardware is good, time is not. */
768*2f16049cSEmmanuel Vadot 	}
769*2f16049cSEmmanuel Vadot 
770*2f16049cSEmmanuel Vadot 	if (sc->use_ampm)
771*2f16049cSEmmanuel Vadot 		hourmask = PCF85xx_M_12HOUR;
772*2f16049cSEmmanuel Vadot 	else
773*2f16049cSEmmanuel Vadot 		hourmask = PCF85xx_M_24HOUR;
774*2f16049cSEmmanuel Vadot 
775*2f16049cSEmmanuel Vadot 	bct.nsec = ((uint64_t)tmrcount * 1000000000) / TMR_TICKS_SEC;
776*2f16049cSEmmanuel Vadot 	bct.ispm = (tregs.hour & PCF8523_B_HOUR_PM) != 0;
777*2f16049cSEmmanuel Vadot 	bct.sec  = tregs.sec   & PCF85xx_M_SECOND;
778*2f16049cSEmmanuel Vadot 	bct.min  = tregs.min   & PCF85xx_M_MINUTE;
779*2f16049cSEmmanuel Vadot 	bct.hour = tregs.hour  & hourmask;
780*2f16049cSEmmanuel Vadot 	bct.day  = tregs.day   & PCF85xx_M_DAY;
781*2f16049cSEmmanuel Vadot 	bct.mon  = tregs.month & PCF85xx_M_MONTH;
782*2f16049cSEmmanuel Vadot 	bct.year = tregs.year  & PCF85xx_M_YEAR;
783*2f16049cSEmmanuel Vadot 
784*2f16049cSEmmanuel Vadot 	/*
785*2f16049cSEmmanuel Vadot 	 * Old PCF8563 datasheets recommended that the C bit be 1 for 19xx and 0
786*2f16049cSEmmanuel Vadot 	 * for 20xx; newer datasheets don't recommend that.  We don't care,
787*2f16049cSEmmanuel Vadot 	 * but we may co-exist with other OSes sharing the hardware. Determine
788*2f16049cSEmmanuel Vadot 	 * existing polarity on a read so that we can preserve it on a write.
789*2f16049cSEmmanuel Vadot 	 */
790*2f16049cSEmmanuel Vadot 	if (sc->chiptype == TYPE_PCF8563) {
791*2f16049cSEmmanuel Vadot 		if (tregs.month & PCF8563_B_MONTH_C) {
792*2f16049cSEmmanuel Vadot 			if (bct.year < 0x70)
793*2f16049cSEmmanuel Vadot 				sc->flags |= SC_F_CPOL;
794*2f16049cSEmmanuel Vadot 		} else if (bct.year >= 0x70)
795*2f16049cSEmmanuel Vadot 				sc->flags |= SC_F_CPOL;
796*2f16049cSEmmanuel Vadot 	}
797*2f16049cSEmmanuel Vadot 
798*2f16049cSEmmanuel Vadot 	clock_dbgprint_bcd(sc->dev, CLOCK_DBG_READ, &bct);
799*2f16049cSEmmanuel Vadot 	err = clock_bcd_to_ts(&bct, ts, sc->use_ampm);
800*2f16049cSEmmanuel Vadot 	ts->tv_sec += utc_offset();
801*2f16049cSEmmanuel Vadot 
802*2f16049cSEmmanuel Vadot 	return (err);
803*2f16049cSEmmanuel Vadot }
804*2f16049cSEmmanuel Vadot 
805*2f16049cSEmmanuel Vadot static int
nxprtc_settime(device_t dev,struct timespec * ts)806*2f16049cSEmmanuel Vadot nxprtc_settime(device_t dev, struct timespec *ts)
807*2f16049cSEmmanuel Vadot {
808*2f16049cSEmmanuel Vadot 	struct bcd_clocktime bct;
809*2f16049cSEmmanuel Vadot 	struct time_regs tregs;
810*2f16049cSEmmanuel Vadot 	struct nxprtc_softc *sc;
811*2f16049cSEmmanuel Vadot 	int err;
812*2f16049cSEmmanuel Vadot 	uint8_t cflag, cs1;
813*2f16049cSEmmanuel Vadot 
814*2f16049cSEmmanuel Vadot 	sc = device_get_softc(dev);
815*2f16049cSEmmanuel Vadot 
816*2f16049cSEmmanuel Vadot 	/*
817*2f16049cSEmmanuel Vadot 	 * We stop the clock, set the time, then restart the clock.  Half a
818*2f16049cSEmmanuel Vadot 	 * second after restarting the clock it ticks over to the next second.
819*2f16049cSEmmanuel Vadot 	 * So to align the RTC, we schedule this function to be called when
820*2f16049cSEmmanuel Vadot 	 * system time is roughly halfway (.495) through the current second.
821*2f16049cSEmmanuel Vadot 	 *
822*2f16049cSEmmanuel Vadot 	 * Reserve use of the i2c bus and stop the RTC clock.  Note that if
823*2f16049cSEmmanuel Vadot 	 * anything goes wrong from this point on, we leave the clock stopped,
824*2f16049cSEmmanuel Vadot 	 * because we don't really know what state it's in.
825*2f16049cSEmmanuel Vadot 	 */
826*2f16049cSEmmanuel Vadot 	if ((err = iicbus_request_bus(sc->busdev, sc->dev, IIC_WAIT)) != 0)
827*2f16049cSEmmanuel Vadot 		return (err);
828*2f16049cSEmmanuel Vadot 	if ((err = read_reg(sc, PCF85xx_R_CS1, &cs1)) != 0)
829*2f16049cSEmmanuel Vadot 		goto errout;
830*2f16049cSEmmanuel Vadot 	cs1 |= PCF85xx_B_CS1_STOP;
831*2f16049cSEmmanuel Vadot 	if ((err = write_reg(sc, PCF85xx_R_CS1, cs1)) != 0)
832*2f16049cSEmmanuel Vadot 		goto errout;
833*2f16049cSEmmanuel Vadot 
834*2f16049cSEmmanuel Vadot 	/* Grab a fresh post-sleep idea of what time it is. */
835*2f16049cSEmmanuel Vadot 	getnanotime(ts);
836*2f16049cSEmmanuel Vadot 	ts->tv_sec -= utc_offset();
837*2f16049cSEmmanuel Vadot 	ts->tv_nsec = 0;
838*2f16049cSEmmanuel Vadot 	clock_ts_to_bcd(ts, &bct, sc->use_ampm);
839*2f16049cSEmmanuel Vadot 	clock_dbgprint_bcd(sc->dev, CLOCK_DBG_WRITE, &bct);
840*2f16049cSEmmanuel Vadot 
841*2f16049cSEmmanuel Vadot 	/* On 8563 set the century based on the polarity seen when reading. */
842*2f16049cSEmmanuel Vadot 	cflag = 0;
843*2f16049cSEmmanuel Vadot 	if (sc->chiptype == TYPE_PCF8563) {
844*2f16049cSEmmanuel Vadot 		if ((sc->flags & SC_F_CPOL) != 0) {
845*2f16049cSEmmanuel Vadot 			if (bct.year >= 0x2000)
846*2f16049cSEmmanuel Vadot 				cflag = PCF8563_B_MONTH_C;
847*2f16049cSEmmanuel Vadot 		} else if (bct.year < 0x2000)
848*2f16049cSEmmanuel Vadot 				cflag = PCF8563_B_MONTH_C;
849*2f16049cSEmmanuel Vadot 	}
850*2f16049cSEmmanuel Vadot 
851*2f16049cSEmmanuel Vadot 	tregs.sec   = bct.sec;
852*2f16049cSEmmanuel Vadot 	tregs.min   = bct.min;
853*2f16049cSEmmanuel Vadot 	tregs.hour  = bct.hour | (bct.ispm ? PCF8523_B_HOUR_PM : 0);
854*2f16049cSEmmanuel Vadot 	tregs.day   = bct.day;
855*2f16049cSEmmanuel Vadot 	tregs.month = bct.mon;
856*2f16049cSEmmanuel Vadot 	tregs.year  = (bct.year & 0xff) | cflag;
857*2f16049cSEmmanuel Vadot 	tregs.wday  = bct.dow;
858*2f16049cSEmmanuel Vadot 
859*2f16049cSEmmanuel Vadot 	/*
860*2f16049cSEmmanuel Vadot 	 * Set the time, reset the timer count register, then start the clocks.
861*2f16049cSEmmanuel Vadot 	 */
862*2f16049cSEmmanuel Vadot 	if ((err = write_timeregs(sc, &tregs)) != 0)
863*2f16049cSEmmanuel Vadot 		goto errout;
864*2f16049cSEmmanuel Vadot 
865*2f16049cSEmmanuel Vadot 	if ((err = write_reg(sc, sc->tmcaddr, TMR_TICKS_SEC)) != 0)
866*2f16049cSEmmanuel Vadot 		return (err);
867*2f16049cSEmmanuel Vadot 
868*2f16049cSEmmanuel Vadot 	cs1 &= ~PCF85xx_B_CS1_STOP;
869*2f16049cSEmmanuel Vadot 	err = write_reg(sc, PCF85xx_R_CS1, cs1);
870*2f16049cSEmmanuel Vadot 
871*2f16049cSEmmanuel Vadot 	/*
872*2f16049cSEmmanuel Vadot 	 * Check for battery-low.  The actual check is throttled to only occur
873*2f16049cSEmmanuel Vadot 	 * once a day, mostly to avoid spamming the user with frequent warnings.
874*2f16049cSEmmanuel Vadot 	 */
875*2f16049cSEmmanuel Vadot 	pcf8523_battery_check(sc);
876*2f16049cSEmmanuel Vadot 
877*2f16049cSEmmanuel Vadot errout:
878*2f16049cSEmmanuel Vadot 
879*2f16049cSEmmanuel Vadot 	iicbus_release_bus(sc->busdev, sc->dev);
880*2f16049cSEmmanuel Vadot 
881*2f16049cSEmmanuel Vadot 	if (err != 0)
882*2f16049cSEmmanuel Vadot 		device_printf(dev, "cannot write RTC time\n");
883*2f16049cSEmmanuel Vadot 
884*2f16049cSEmmanuel Vadot 	return (err);
885*2f16049cSEmmanuel Vadot }
886*2f16049cSEmmanuel Vadot 
887*2f16049cSEmmanuel Vadot static int
nxprtc_get_chiptype(device_t dev)888*2f16049cSEmmanuel Vadot nxprtc_get_chiptype(device_t dev)
889*2f16049cSEmmanuel Vadot {
890*2f16049cSEmmanuel Vadot #ifdef FDT
891*2f16049cSEmmanuel Vadot 
892*2f16049cSEmmanuel Vadot 	return (ofw_bus_search_compatible(dev, compat_data)->ocd_data);
893*2f16049cSEmmanuel Vadot #else
894*2f16049cSEmmanuel Vadot 	nxprtc_compat_data *cdata;
895*2f16049cSEmmanuel Vadot 	const char *htype;
896*2f16049cSEmmanuel Vadot 	int chiptype;
897*2f16049cSEmmanuel Vadot 
898*2f16049cSEmmanuel Vadot 	/*
899*2f16049cSEmmanuel Vadot 	 * If given a chiptype hint string, loop through the ofw compat data
900*2f16049cSEmmanuel Vadot 	 * comparing the hinted chip type to the compat strings.  The table end
901*2f16049cSEmmanuel Vadot 	 * marker ocd_data is TYPE_NONE.
902*2f16049cSEmmanuel Vadot 	 */
903*2f16049cSEmmanuel Vadot 	if (resource_string_value(device_get_name(dev),
904*2f16049cSEmmanuel Vadot 	    device_get_unit(dev), "compatible", &htype) == 0) {
905*2f16049cSEmmanuel Vadot 		for (cdata = compat_data; cdata->ocd_str != NULL; ++cdata) {
906*2f16049cSEmmanuel Vadot 			if (strcmp(htype, cdata->ocd_str) == 0)
907*2f16049cSEmmanuel Vadot 				break;
908*2f16049cSEmmanuel Vadot 		}
909*2f16049cSEmmanuel Vadot 		chiptype = cdata->ocd_data;
910*2f16049cSEmmanuel Vadot 	} else
911*2f16049cSEmmanuel Vadot 		chiptype = TYPE_NONE;
912*2f16049cSEmmanuel Vadot 
913*2f16049cSEmmanuel Vadot 	/*
914*2f16049cSEmmanuel Vadot 	 * On non-FDT systems the historical behavior of this driver was to
915*2f16049cSEmmanuel Vadot 	 * assume a PCF8563; keep doing that for compatibility.
916*2f16049cSEmmanuel Vadot 	 */
917*2f16049cSEmmanuel Vadot 	if (chiptype == TYPE_NONE)
918*2f16049cSEmmanuel Vadot 		return (TYPE_PCF8563);
919*2f16049cSEmmanuel Vadot 	else
920*2f16049cSEmmanuel Vadot 		return (chiptype);
921*2f16049cSEmmanuel Vadot #endif
922*2f16049cSEmmanuel Vadot }
923*2f16049cSEmmanuel Vadot 
924*2f16049cSEmmanuel Vadot static int
nxprtc_probe(device_t dev)925*2f16049cSEmmanuel Vadot nxprtc_probe(device_t dev)
926*2f16049cSEmmanuel Vadot {
927*2f16049cSEmmanuel Vadot 	int chiptype, rv;
928*2f16049cSEmmanuel Vadot 
929*2f16049cSEmmanuel Vadot #ifdef FDT
930*2f16049cSEmmanuel Vadot 	if (!ofw_bus_status_okay(dev))
931*2f16049cSEmmanuel Vadot 		return (ENXIO);
932*2f16049cSEmmanuel Vadot 	rv = BUS_PROBE_GENERIC;
933*2f16049cSEmmanuel Vadot #else
934*2f16049cSEmmanuel Vadot 	rv = BUS_PROBE_NOWILDCARD;
935*2f16049cSEmmanuel Vadot #endif
936*2f16049cSEmmanuel Vadot 	if ((chiptype = nxprtc_get_chiptype(dev)) == TYPE_NONE)
937*2f16049cSEmmanuel Vadot 		return (ENXIO);
938*2f16049cSEmmanuel Vadot 
939*2f16049cSEmmanuel Vadot 	device_set_desc(dev, desc_strings[chiptype]);
940*2f16049cSEmmanuel Vadot 	return (rv);
941*2f16049cSEmmanuel Vadot }
942*2f16049cSEmmanuel Vadot 
943*2f16049cSEmmanuel Vadot static int
nxprtc_attach(device_t dev)944*2f16049cSEmmanuel Vadot nxprtc_attach(device_t dev)
945*2f16049cSEmmanuel Vadot {
946*2f16049cSEmmanuel Vadot 	struct nxprtc_softc *sc;
947*2f16049cSEmmanuel Vadot 
948*2f16049cSEmmanuel Vadot 	sc = device_get_softc(dev);
949*2f16049cSEmmanuel Vadot 	sc->dev = dev;
950*2f16049cSEmmanuel Vadot 	sc->busdev = device_get_parent(dev);
951*2f16049cSEmmanuel Vadot 
952*2f16049cSEmmanuel Vadot 	/* We need to know what kind of chip we're driving. */
953*2f16049cSEmmanuel Vadot 	sc->chiptype = nxprtc_get_chiptype(dev);
954*2f16049cSEmmanuel Vadot 
955*2f16049cSEmmanuel Vadot 	/* The features and some register addresses vary by chip type. */
956*2f16049cSEmmanuel Vadot 	switch (sc->chiptype) {
957*2f16049cSEmmanuel Vadot 	case TYPE_PCA2129:
958*2f16049cSEmmanuel Vadot 	case TYPE_PCF2129:
959*2f16049cSEmmanuel Vadot 	case TYPE_PCF2127:
960*2f16049cSEmmanuel Vadot 	case TYPE_PCF8523:
961*2f16049cSEmmanuel Vadot 		sc->secaddr = PCF8523_R_SECOND;
962*2f16049cSEmmanuel Vadot 		sc->tmcaddr = PCF8523_R_TMR_A_COUNT;
963*2f16049cSEmmanuel Vadot 		sc->use_timer = true;
964*2f16049cSEmmanuel Vadot 		break;
965*2f16049cSEmmanuel Vadot 	case TYPE_PCA8565:
966*2f16049cSEmmanuel Vadot 	case TYPE_PCF8563:
967*2f16049cSEmmanuel Vadot 		sc->secaddr = PCF8563_R_SECOND;
968*2f16049cSEmmanuel Vadot 		sc->tmcaddr = PCF8563_R_TMR_COUNT;
969*2f16049cSEmmanuel Vadot 		sc->use_timer = true;
970*2f16049cSEmmanuel Vadot 		break;
971*2f16049cSEmmanuel Vadot 	default:
972*2f16049cSEmmanuel Vadot 		device_printf(dev, "impossible: cannot determine chip type\n");
973*2f16049cSEmmanuel Vadot 		return (ENXIO);
974*2f16049cSEmmanuel Vadot 	}
975*2f16049cSEmmanuel Vadot 
976*2f16049cSEmmanuel Vadot 	/*
977*2f16049cSEmmanuel Vadot 	 * We have to wait until interrupts are enabled.  Sometimes I2C read
978*2f16049cSEmmanuel Vadot 	 * and write only works when the interrupts are available.
979*2f16049cSEmmanuel Vadot 	 */
980*2f16049cSEmmanuel Vadot 	sc->config_hook.ich_func = nxprtc_start;
981*2f16049cSEmmanuel Vadot 	sc->config_hook.ich_arg = dev;
982*2f16049cSEmmanuel Vadot 	if (config_intrhook_establish(&sc->config_hook) != 0)
983*2f16049cSEmmanuel Vadot 		return (ENOMEM);
984*2f16049cSEmmanuel Vadot 
985*2f16049cSEmmanuel Vadot 	return (0);
986*2f16049cSEmmanuel Vadot }
987*2f16049cSEmmanuel Vadot 
988*2f16049cSEmmanuel Vadot static int
nxprtc_detach(device_t dev)989*2f16049cSEmmanuel Vadot nxprtc_detach(device_t dev)
990*2f16049cSEmmanuel Vadot {
991*2f16049cSEmmanuel Vadot 
992*2f16049cSEmmanuel Vadot 	clock_unregister(dev);
993*2f16049cSEmmanuel Vadot 	return (0);
994*2f16049cSEmmanuel Vadot }
995*2f16049cSEmmanuel Vadot 
996*2f16049cSEmmanuel Vadot static device_method_t nxprtc_methods[] = {
997*2f16049cSEmmanuel Vadot 	DEVMETHOD(device_probe,		nxprtc_probe),
998*2f16049cSEmmanuel Vadot 	DEVMETHOD(device_attach,	nxprtc_attach),
999*2f16049cSEmmanuel Vadot 	DEVMETHOD(device_detach,	nxprtc_detach),
1000*2f16049cSEmmanuel Vadot 
1001*2f16049cSEmmanuel Vadot 	DEVMETHOD(clock_gettime,	nxprtc_gettime),
1002*2f16049cSEmmanuel Vadot 	DEVMETHOD(clock_settime,	nxprtc_settime),
1003*2f16049cSEmmanuel Vadot 
1004*2f16049cSEmmanuel Vadot 	DEVMETHOD_END
1005*2f16049cSEmmanuel Vadot };
1006*2f16049cSEmmanuel Vadot 
1007*2f16049cSEmmanuel Vadot static driver_t nxprtc_driver = {
1008*2f16049cSEmmanuel Vadot 	"nxprtc",
1009*2f16049cSEmmanuel Vadot 	nxprtc_methods,
1010*2f16049cSEmmanuel Vadot 	sizeof(struct nxprtc_softc),
1011*2f16049cSEmmanuel Vadot };
1012*2f16049cSEmmanuel Vadot 
1013*2f16049cSEmmanuel Vadot DRIVER_MODULE(nxprtc, iicbus, nxprtc_driver, NULL, NULL);
1014*2f16049cSEmmanuel Vadot MODULE_VERSION(nxprtc, 1);
1015*2f16049cSEmmanuel Vadot MODULE_DEPEND(nxprtc, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
1016*2f16049cSEmmanuel Vadot IICBUS_FDT_PNP_INFO(compat_data);
1017