xref: /freebsd/sys/arm64/nvidia/tegra210/max77620_rtc.c (revision cab6a39d7b343596a5823e65c0f7b426551ec22d)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright 2020 Michal Meloun <mmel@FreeBSD.org>
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30 
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/bus.h>
34 #include <sys/clock.h>
35 #include <sys/kernel.h>
36 #include <sys/module.h>
37 #include <sys/rman.h>
38 #include <sys/sx.h>
39 
40 #include <dev/iicbus/iiconf.h>
41 #include <dev/iicbus/iicbus.h>
42 #include <dev/ofw/ofw_bus.h>
43 
44 #include "clock_if.h"
45 #include "max77620.h"
46 #define	MAX77620_RTC_INT	0x00
47 #define	MAX77620_RTC_INTM	0x01
48 #define	MAX77620_RTC_CONTROLM	0x02
49 #define	MAX77620_RTC_CONTROL	0x03
50 #define  RTC_CONTROL_MODE_24		(1 << 1)
51 #define  RTC_CONTROL_BCD_EN		(1 << 0)
52 
53 #define	MAX77620_RTC_UPDATE0	0x04
54 #define	 RTC_UPDATE0_RTC_RBUDR		(1 << 4)
55 #define	 RTC_UPDATE0_RTC_UDR		(1 << 0)
56 
57 #define	MAX77620_WTSR_SMPL_CNTL	0x06
58 #define	MAX77620_RTC_SEC	0x07
59 #define	MAX77620_RTC_MIN	0x08
60 #define	MAX77620_RTC_HOUR	0x09
61 #define	MAX77620_RTC_WEEKDAY	0x0A
62 #define	MAX77620_RTC_MONTH	0x0B
63 #define	MAX77620_RTC_YEAR	0x0C
64 #define	MAX77620_RTC_DATE	0x0D
65 #define	MAX77620_ALARM1_SEC	0x0E
66 #define	MAX77620_ALARM1_MIN	0x0F
67 #define	MAX77620_ALARM1_HOUR	0x10
68 #define	MAX77620_ALARM1_WEEKDAY	0x11
69 #define	MAX77620_ALARM1_MONTH	0x12
70 #define	MAX77620_ALARM1_YEAR	0x13
71 #define	MAX77620_ALARM1_DATE	0x14
72 #define	MAX77620_ALARM2_SEC	0x15
73 #define	MAX77620_ALARM2_MIN	0x16
74 #define	MAX77620_ALARM2_HOUR	0x17
75 #define	MAX77620_ALARM2_WEEKDAY	0x18
76 #define	MAX77620_ALARM2_MONTH	0x19
77 #define	MAX77620_ALARM2_YEAR	0x1A
78 #define	MAX77620_ALARM2_DATE	0x1B
79 
80 #define	MAX77620_RTC_START_YEAR	2000
81 #define MAX77620_RTC_I2C_ADDR	0x68
82 
83 #define	LOCK(_sc)		sx_xlock(&(_sc)->lock)
84 #define	UNLOCK(_sc)		sx_xunlock(&(_sc)->lock)
85 #define	LOCK_INIT(_sc)		sx_init(&(_sc)->lock, "max77620_rtc")
86 #define	LOCK_DESTROY(_sc)	sx_destroy(&(_sc)->lock);
87 
88 struct max77620_rtc_softc {
89 	device_t			dev;
90 	struct sx			lock;
91 	int				bus_addr;
92 };
93 
94 /*
95  * Raw register access function.
96  */
97 static int
98 max77620_rtc_read(struct max77620_rtc_softc *sc, uint8_t reg, uint8_t *val)
99 {
100 	uint8_t addr;
101 	int rv;
102 	struct iic_msg msgs[2] = {
103 		{0, IIC_M_WR, 1, &addr},
104 		{0, IIC_M_RD, 1, val},
105 	};
106 
107 	msgs[0].slave = sc->bus_addr;
108 	msgs[1].slave = sc->bus_addr;
109 	addr = reg;
110 
111 	rv = iicbus_transfer(sc->dev, msgs, 2);
112 	if (rv != 0) {
113 		device_printf(sc->dev,
114 		    "Error when reading reg 0x%02X, rv: %d\n", reg,  rv);
115 		return (EIO);
116 	}
117 
118 	return (0);
119 }
120 
121 static int
122 max77620_rtc_read_buf(struct max77620_rtc_softc *sc, uint8_t reg,
123     uint8_t *buf, size_t size)
124 {
125 	uint8_t addr;
126 	int rv;
127 	struct iic_msg msgs[2] = {
128 		{0, IIC_M_WR, 1, &addr},
129 		{0, IIC_M_RD, size, buf},
130 	};
131 
132 	msgs[0].slave = sc->bus_addr;
133 	msgs[1].slave = sc->bus_addr;
134 	addr = reg;
135 
136 	rv = iicbus_transfer(sc->dev, msgs, 2);
137 	if (rv != 0) {
138 		device_printf(sc->dev,
139 		    "Error when reading reg 0x%02X, rv: %d\n", reg,  rv);
140 		return (EIO);
141 	}
142 
143 	return (0);
144 }
145 
146 static int
147 max77620_rtc_write(struct max77620_rtc_softc *sc, uint8_t reg, uint8_t val)
148 {
149 	uint8_t data[2];
150 	int rv;
151 
152 	struct iic_msg msgs[1] = {
153 		{0, IIC_M_WR, 2, data},
154 	};
155 
156 	msgs[0].slave = sc->bus_addr;
157 	data[0] = reg;
158 	data[1] = val;
159 
160 	rv = iicbus_transfer(sc->dev, msgs, 1);
161 	if (rv != 0) {
162 		device_printf(sc->dev,
163 		    "Error when writing reg 0x%02X, rv: %d\n", reg, rv);
164 		return (EIO);
165 	}
166 	return (0);
167 }
168 
169 static int
170 max77620_rtc_write_buf(struct max77620_rtc_softc *sc, uint8_t reg, uint8_t *buf,
171     size_t size)
172 {
173 	uint8_t data[1];
174 	int rv;
175 	struct iic_msg msgs[2] = {
176 		{0, IIC_M_WR, 1, data},
177 		{0, IIC_M_WR | IIC_M_NOSTART, size, buf},
178 	};
179 
180 	msgs[0].slave = sc->bus_addr;
181 	msgs[1].slave = sc->bus_addr;
182 	data[0] = reg;
183 
184 	rv = iicbus_transfer(sc->dev, msgs, 2);
185 	if (rv != 0) {
186 		device_printf(sc->dev,
187 		    "Error when writing reg 0x%02X, rv: %d\n", reg, rv);
188 		return (EIO);
189 	}
190 	return (0);
191 }
192 
193 static int
194 max77620_rtc_modify(struct max77620_rtc_softc *sc, uint8_t reg, uint8_t clear,
195     uint8_t set)
196 {
197 	uint8_t val;
198 	int rv;
199 
200 	rv = max77620_rtc_read(sc, reg, &val);
201 	if (rv != 0)
202 		return (rv);
203 
204 	val &= ~clear;
205 	val |= set;
206 
207 	rv = max77620_rtc_write(sc, reg, val);
208 	if (rv != 0)
209 		return (rv);
210 
211 	return (0);
212 }
213 
214 static int
215 max77620_rtc_update(struct max77620_rtc_softc *sc, bool for_read)
216 {
217 	uint8_t reg;
218 	int rv;
219 
220 	reg = for_read ? RTC_UPDATE0_RTC_RBUDR: RTC_UPDATE0_RTC_UDR;
221 	rv = max77620_rtc_modify(sc, MAX77620_RTC_UPDATE0, reg, reg);
222 	if (rv != 0)
223 		return (rv);
224 
225 	DELAY(16000);
226 	return (rv);
227 }
228 
229 static int
230 max77620_rtc_gettime(device_t dev, struct timespec *ts)
231 {
232 	struct max77620_rtc_softc *sc;
233 	struct clocktime ct;
234 	uint8_t buf[7];
235 	int rv;
236 
237 	sc = device_get_softc(dev);
238 
239 	LOCK(sc);
240 	rv = max77620_rtc_update(sc, true);
241 	if (rv != 0) {
242 		UNLOCK(sc);
243 		device_printf(sc->dev, "Failed to strobe RTC data\n");
244 		return (rv);
245 	}
246 
247 	rv = max77620_rtc_read_buf(sc, MAX77620_RTC_SEC, buf, nitems(buf));
248 	UNLOCK(sc);
249 	if (rv != 0) {
250 		device_printf(sc->dev, "Failed to read RTC data\n");
251 		return (rv);
252 	}
253 	ct.nsec = 0;
254 	ct.sec  = bcd2bin(buf[0] & 0x7F);
255 	ct.min  = bcd2bin(buf[1] & 0x7F);
256 	ct.hour = bcd2bin(buf[2] & 0x3F);
257 	ct.dow  = ffs(buf[3] & 07);
258 	ct.mon  = bcd2bin(buf[4] & 0x1F);
259 	ct.year = bcd2bin(buf[5] & 0x7F) + MAX77620_RTC_START_YEAR;
260 	ct.day  = bcd2bin(buf[6] & 0x3F);
261 
262 	return (clock_ct_to_ts(&ct, ts));
263 }
264 
265 static int
266 max77620_rtc_settime(device_t dev, struct timespec *ts)
267 {
268 	struct max77620_rtc_softc *sc;
269 	struct clocktime ct;
270 	uint8_t buf[7];
271 	int rv;
272 
273 	sc = device_get_softc(dev);
274 	clock_ts_to_ct(ts, &ct);
275 
276 	if (ct.year < MAX77620_RTC_START_YEAR)
277 		return (EINVAL);
278 
279 	buf[0] = bin2bcd(ct.sec);
280 	buf[1] = bin2bcd(ct.min);
281 	buf[2] = bin2bcd(ct.hour);
282 	buf[3] = 1 << ct.dow;
283 	buf[4] = bin2bcd(ct.mon);
284 	buf[5] = bin2bcd(ct.year - MAX77620_RTC_START_YEAR);
285 	buf[6] = bin2bcd(ct.day);
286 
287 	LOCK(sc);
288 	rv = max77620_rtc_write_buf(sc, MAX77620_RTC_SEC, buf, nitems(buf));
289 	if (rv != 0) {
290 		UNLOCK(sc);
291 		device_printf(sc->dev, "Failed to write RTC data\n");
292 		return (rv);
293 	}
294 	rv = max77620_rtc_update(sc, false);
295 	UNLOCK(sc);
296 	if (rv != 0) {
297 		device_printf(sc->dev, "Failed to update RTC data\n");
298 		return (rv);
299 	}
300 
301 	return (0);
302 }
303 
304 static int
305 max77620_rtc_probe(device_t dev)
306 {
307 	struct iicbus_ivar *dinfo;
308 
309 	dinfo = device_get_ivars(dev);
310 	if (dinfo == NULL)
311 		return (ENXIO);
312 	if (dinfo->addr != MAX77620_RTC_I2C_ADDR << 1)
313 		return (ENXIO);
314 
315 	device_set_desc(dev, "MAX77620 RTC");
316 	return (BUS_PROBE_DEFAULT);
317 }
318 
319 static int
320 max77620_rtc_attach(device_t dev)
321 {
322 	struct max77620_rtc_softc *sc;
323 	uint8_t reg;
324 	int rv;
325 
326 	sc = device_get_softc(dev);
327 	sc->dev = dev;
328 	sc->bus_addr = iicbus_get_addr(dev);
329 
330 	LOCK_INIT(sc);
331 
332 	reg = RTC_CONTROL_MODE_24 | RTC_CONTROL_BCD_EN;
333 	rv = max77620_rtc_modify(sc, MAX77620_RTC_CONTROLM, reg, reg);
334 	if (rv != 0) {
335 		device_printf(sc->dev, "Failed to configure RTC\n");
336 		goto fail;
337 	}
338 
339 	rv = max77620_rtc_modify(sc, MAX77620_RTC_CONTROL, reg, reg);
340 	if (rv != 0) {
341 		device_printf(sc->dev, "Failed to configure RTC\n");
342 		goto fail;
343 	}
344 	rv = max77620_rtc_update(sc, false);
345 	if (rv != 0) {
346 		device_printf(sc->dev, "Failed to update RTC data\n");
347 		return (rv);
348 	}
349 
350 	clock_register(sc->dev, 1000000);
351 
352 	return (bus_generic_attach(dev));
353 
354 fail:
355 	LOCK_DESTROY(sc);
356 	return (rv);
357 }
358 
359 /*
360  * The secondary address of MAX77620 (RTC function) is not in DTB,
361  * add it manualy
362  */
363 static int
364 max77620_rtc_detach(device_t dev)
365 {
366 	struct max77620_softc *sc;
367 
368 	sc = device_get_softc(dev);
369 	LOCK_DESTROY(sc);
370 
371 	return (bus_generic_detach(dev));
372 }
373 
374 int
375 max77620_rtc_create(struct max77620_softc *sc, phandle_t node)
376 {
377 	device_t parent, child;
378 	struct iicbus_ivar *dinfo;
379 
380 	parent = device_get_parent(sc->dev);
381 	child = BUS_ADD_CHILD(parent, 0, NULL, -1);
382 	if (child == 0)	{
383 		device_printf(sc->dev, "Cannot add MAX77620 RTC device.\n");
384 		return (ENXIO);
385 	}
386 	dinfo = device_get_ivars(child);
387 	if (dinfo == NULL)	{
388 		device_printf(sc->dev,
389 		    "Cannot set I2Caddress for MAX77620 RTC.\n");
390 		return (ENXIO);
391 	}
392 	dinfo->addr = MAX77620_RTC_I2C_ADDR << 1;
393 	return (0);
394 }
395 
396 static device_method_t max77620_rtc_methods[] = {
397 	/* Device interface */
398 	DEVMETHOD(device_probe,		max77620_rtc_probe),
399 	DEVMETHOD(device_attach,	max77620_rtc_attach),
400 	DEVMETHOD(device_detach,	max77620_rtc_detach),
401 
402 	/* RTC interface */
403 	DEVMETHOD(clock_gettime,	max77620_rtc_gettime),
404 	DEVMETHOD(clock_settime,	max77620_rtc_settime),
405 
406 	DEVMETHOD_END
407 };
408 
409 static devclass_t max77620_rtc_devclass;
410 static DEFINE_CLASS_0(rtc, max77620_rtc_driver, max77620_rtc_methods,
411     sizeof(struct max77620_rtc_softc));
412 EARLY_DRIVER_MODULE(max77620rtc_, iicbus, max77620_rtc_driver,
413     max77620_rtc_devclass, NULL, NULL, 74);
414