1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright 2020 Michal Meloun <[email protected]>
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
max77620_rtc_read(struct max77620_rtc_softc * sc,uint8_t reg,uint8_t * val)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
max77620_rtc_read_buf(struct max77620_rtc_softc * sc,uint8_t reg,uint8_t * buf,size_t size)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
max77620_rtc_write(struct max77620_rtc_softc * sc,uint8_t reg,uint8_t val)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
max77620_rtc_write_buf(struct max77620_rtc_softc * sc,uint8_t reg,uint8_t * buf,size_t size)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
max77620_rtc_modify(struct max77620_rtc_softc * sc,uint8_t reg,uint8_t clear,uint8_t set)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
max77620_rtc_update(struct max77620_rtc_softc * sc,bool for_read)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
max77620_rtc_gettime(device_t dev,struct timespec * ts)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
max77620_rtc_settime(device_t dev,struct timespec * ts)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
max77620_rtc_probe(device_t dev)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
max77620_rtc_attach(device_t dev)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
max77620_rtc_detach(device_t dev)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
max77620_rtc_create(struct max77620_softc * sc,phandle_t node)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