1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
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/param.h>
29 #include <sys/systm.h>
30 #include <sys/bus.h>
31 #include <sys/clock.h>
32 #include <sys/kernel.h>
33 #include <sys/module.h>
34 #include <sys/rman.h>
35 #include <sys/sx.h>
36
37 #include <dev/iicbus/iiconf.h>
38 #include <dev/iicbus/iicbus.h>
39 #include <dev/ofw/ofw_bus.h>
40 #include <dev/ofw/ofw_bus_subr.h>
41
42 #include "clock_if.h"
43 #include "ofw_iicbus_if.h"
44 #include "max77620.h"
45
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 char max77620_rtc_compat[] = "maxim,max77620_rtc";
95
96 /*
97 * Raw register access function.
98 */
99 static int
max77620_rtc_read(struct max77620_rtc_softc * sc,uint8_t reg,uint8_t * val)100 max77620_rtc_read(struct max77620_rtc_softc *sc, uint8_t reg, uint8_t *val)
101 {
102 uint8_t addr;
103 int rv;
104 struct iic_msg msgs[2] = {
105 {0, IIC_M_WR, 1, &addr},
106 {0, IIC_M_RD, 1, val},
107 };
108
109 msgs[0].slave = sc->bus_addr;
110 msgs[1].slave = sc->bus_addr;
111 addr = reg;
112
113 rv = iicbus_transfer(sc->dev, msgs, 2);
114 if (rv != 0) {
115 device_printf(sc->dev,
116 "Error when reading reg 0x%02X, rv: %d\n", reg, rv);
117 return (EIO);
118 }
119
120 return (0);
121 }
122
123 static int
max77620_rtc_read_buf(struct max77620_rtc_softc * sc,uint8_t reg,uint8_t * buf,size_t size)124 max77620_rtc_read_buf(struct max77620_rtc_softc *sc, uint8_t reg,
125 uint8_t *buf, size_t size)
126 {
127 uint8_t addr;
128 int rv;
129 struct iic_msg msgs[2] = {
130 {0, IIC_M_WR, 1, &addr},
131 {0, IIC_M_RD, size, buf},
132 };
133
134 msgs[0].slave = sc->bus_addr;
135 msgs[1].slave = sc->bus_addr;
136 addr = reg;
137
138 rv = iicbus_transfer(sc->dev, msgs, 2);
139 if (rv != 0) {
140 device_printf(sc->dev,
141 "Error when reading reg 0x%02X, rv: %d\n", reg, rv);
142 return (EIO);
143 }
144
145 return (0);
146 }
147
148 static int
max77620_rtc_write(struct max77620_rtc_softc * sc,uint8_t reg,uint8_t val)149 max77620_rtc_write(struct max77620_rtc_softc *sc, uint8_t reg, uint8_t val)
150 {
151 uint8_t data[2];
152 int rv;
153
154 struct iic_msg msgs[1] = {
155 {0, IIC_M_WR, 2, data},
156 };
157
158 msgs[0].slave = sc->bus_addr;
159 data[0] = reg;
160 data[1] = val;
161
162 rv = iicbus_transfer(sc->dev, msgs, 1);
163 if (rv != 0) {
164 device_printf(sc->dev,
165 "Error when writing reg 0x%02X, rv: %d\n", reg, rv);
166 return (EIO);
167 }
168 return (0);
169 }
170
171 static int
max77620_rtc_write_buf(struct max77620_rtc_softc * sc,uint8_t reg,uint8_t * buf,size_t size)172 max77620_rtc_write_buf(struct max77620_rtc_softc *sc, uint8_t reg, uint8_t *buf,
173 size_t size)
174 {
175 uint8_t data[1];
176 int rv;
177 struct iic_msg msgs[2] = {
178 {0, IIC_M_WR, 1, data},
179 {0, IIC_M_WR | IIC_M_NOSTART, size, buf},
180 };
181
182 msgs[0].slave = sc->bus_addr;
183 msgs[1].slave = sc->bus_addr;
184 data[0] = reg;
185
186 rv = iicbus_transfer(sc->dev, msgs, 2);
187 if (rv != 0) {
188 device_printf(sc->dev,
189 "Error when writing reg 0x%02X, rv: %d\n", reg, rv);
190 return (EIO);
191 }
192 return (0);
193 }
194
195 static int
max77620_rtc_modify(struct max77620_rtc_softc * sc,uint8_t reg,uint8_t clear,uint8_t set)196 max77620_rtc_modify(struct max77620_rtc_softc *sc, uint8_t reg, uint8_t clear,
197 uint8_t set)
198 {
199 uint8_t val;
200 int rv;
201
202 rv = max77620_rtc_read(sc, reg, &val);
203 if (rv != 0)
204 return (rv);
205
206 val &= ~clear;
207 val |= set;
208
209 rv = max77620_rtc_write(sc, reg, val);
210 if (rv != 0)
211 return (rv);
212
213 return (0);
214 }
215
216 static int
max77620_rtc_update(struct max77620_rtc_softc * sc,bool for_read)217 max77620_rtc_update(struct max77620_rtc_softc *sc, bool for_read)
218 {
219 uint8_t reg;
220 int rv;
221
222 reg = for_read ? RTC_UPDATE0_RTC_RBUDR: RTC_UPDATE0_RTC_UDR;
223 rv = max77620_rtc_modify(sc, MAX77620_RTC_UPDATE0, reg, reg);
224 if (rv != 0)
225 return (rv);
226
227 DELAY(16000);
228 return (rv);
229 }
230
231 static int
max77620_rtc_gettime(device_t dev,struct timespec * ts)232 max77620_rtc_gettime(device_t dev, struct timespec *ts)
233 {
234 struct max77620_rtc_softc *sc;
235 struct clocktime ct;
236 uint8_t buf[7];
237 int rv;
238
239 sc = device_get_softc(dev);
240
241 LOCK(sc);
242 rv = max77620_rtc_update(sc, true);
243 if (rv != 0) {
244 UNLOCK(sc);
245 device_printf(sc->dev, "Failed to strobe RTC data\n");
246 return (rv);
247 }
248
249 rv = max77620_rtc_read_buf(sc, MAX77620_RTC_SEC, buf, nitems(buf));
250 UNLOCK(sc);
251 if (rv != 0) {
252 device_printf(sc->dev, "Failed to read RTC data\n");
253 return (rv);
254 }
255 ct.nsec = 0;
256 ct.sec = bcd2bin(buf[0] & 0x7F);
257 ct.min = bcd2bin(buf[1] & 0x7F);
258 ct.hour = bcd2bin(buf[2] & 0x3F);
259 ct.dow = ffs(buf[3] & 07);
260 ct.mon = bcd2bin(buf[4] & 0x1F);
261 ct.year = bcd2bin(buf[5] & 0x7F) + MAX77620_RTC_START_YEAR;
262 ct.day = bcd2bin(buf[6] & 0x3F);
263
264 return (clock_ct_to_ts(&ct, ts));
265 }
266
267 static int
max77620_rtc_settime(device_t dev,struct timespec * ts)268 max77620_rtc_settime(device_t dev, struct timespec *ts)
269 {
270 struct max77620_rtc_softc *sc;
271 struct clocktime ct;
272 uint8_t buf[7];
273 int rv;
274
275 sc = device_get_softc(dev);
276 clock_ts_to_ct(ts, &ct);
277
278 if (ct.year < MAX77620_RTC_START_YEAR)
279 return (EINVAL);
280
281 buf[0] = bin2bcd(ct.sec);
282 buf[1] = bin2bcd(ct.min);
283 buf[2] = bin2bcd(ct.hour);
284 buf[3] = 1 << ct.dow;
285 buf[4] = bin2bcd(ct.mon);
286 buf[5] = bin2bcd(ct.year - MAX77620_RTC_START_YEAR);
287 buf[6] = bin2bcd(ct.day);
288
289 LOCK(sc);
290 rv = max77620_rtc_write_buf(sc, MAX77620_RTC_SEC, buf, nitems(buf));
291 if (rv != 0) {
292 UNLOCK(sc);
293 device_printf(sc->dev, "Failed to write RTC data\n");
294 return (rv);
295 }
296 rv = max77620_rtc_update(sc, false);
297 UNLOCK(sc);
298 if (rv != 0) {
299 device_printf(sc->dev, "Failed to update RTC data\n");
300 return (rv);
301 }
302
303 return (0);
304 }
305
306 static int
max77620_rtc_probe(device_t dev)307 max77620_rtc_probe(device_t dev)
308 {
309 const char *compat;
310
311 /*
312 * TODO:
313 * ofw_bus_is_compatible() should use compat string from devinfo cache
314 * maximum size of OFW property should be defined in public header
315 */
316 if ((compat = ofw_bus_get_compat(dev)) == NULL)
317 return (ENXIO);
318 if (strncasecmp(compat, max77620_rtc_compat, 255) != 0)
319 return (ENXIO);
320
321 device_set_desc(dev, "MAX77620 RTC");
322 return (BUS_PROBE_DEFAULT);
323 }
324
325 static int
max77620_rtc_attach(device_t dev)326 max77620_rtc_attach(device_t dev)
327 {
328 struct max77620_rtc_softc *sc;
329 uint8_t reg;
330 int rv;
331
332 sc = device_get_softc(dev);
333 sc->dev = dev;
334 sc->bus_addr = iicbus_get_addr(dev);
335
336 LOCK_INIT(sc);
337
338 reg = RTC_CONTROL_MODE_24 | RTC_CONTROL_BCD_EN;
339 rv = max77620_rtc_modify(sc, MAX77620_RTC_CONTROLM, reg, reg);
340 if (rv != 0) {
341 device_printf(sc->dev, "Failed to configure RTC\n");
342 goto fail;
343 }
344
345 rv = max77620_rtc_modify(sc, MAX77620_RTC_CONTROL, reg, reg);
346 if (rv != 0) {
347 device_printf(sc->dev, "Failed to configure RTC\n");
348 goto fail;
349 }
350 rv = max77620_rtc_update(sc, false);
351 if (rv != 0) {
352 device_printf(sc->dev, "Failed to update RTC data\n");
353 return (rv);
354 }
355
356 clock_register(sc->dev, 1000000);
357
358 bus_attach_children(dev);
359 return (0);
360
361 fail:
362 LOCK_DESTROY(sc);
363 return (rv);
364 }
365
366 static int
max77620_rtc_detach(device_t dev)367 max77620_rtc_detach(device_t dev)
368 {
369 struct max77620_softc *sc;
370 int error;
371
372 error = bus_generic_detach(dev);
373 if (error != 0)
374 return (error);
375
376 sc = device_get_softc(dev);
377 LOCK_DESTROY(sc);
378
379 return (0);
380 }
381
382 /*
383 * The secondary address of MAX77620 (RTC function) is not in DT,
384 * add it manualy as subdevice
385 */
386 int
max77620_rtc_create(struct max77620_softc * sc,phandle_t node)387 max77620_rtc_create(struct max77620_softc *sc, phandle_t node)
388 {
389 device_t parent, child;
390 int rv;
391
392 parent = device_get_parent(sc->dev);
393
394 child = BUS_ADD_CHILD(parent, 0, NULL, DEVICE_UNIT_ANY);
395 if (child == NULL) {
396 device_printf(sc->dev, "Cannot create MAX77620 RTC device.\n");
397 return (ENXIO);
398 }
399
400 rv = OFW_IICBUS_SET_DEVINFO(parent, child, -1, "rtc@68",
401 max77620_rtc_compat, MAX77620_RTC_I2C_ADDR << 1);
402 if (rv != 0) {
403 device_printf(sc->dev, "Cannot setup MAX77620 RTC device.\n");
404 return (ENXIO);
405 }
406
407 return (0);
408 }
409
410 static device_method_t max77620_rtc_methods[] = {
411 /* Device interface */
412 DEVMETHOD(device_probe, max77620_rtc_probe),
413 DEVMETHOD(device_attach, max77620_rtc_attach),
414 DEVMETHOD(device_detach, max77620_rtc_detach),
415
416 /* RTC interface */
417 DEVMETHOD(clock_gettime, max77620_rtc_gettime),
418 DEVMETHOD(clock_settime, max77620_rtc_settime),
419
420 DEVMETHOD_END
421 };
422
423 static DEFINE_CLASS_0(rtc, max77620_rtc_driver, max77620_rtc_methods,
424 sizeof(struct max77620_rtc_softc));
425 EARLY_DRIVER_MODULE(max77620rtc_, iicbus, max77620_rtc_driver, NULL, NULL, 74);
426