]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/iicbus/ds3231.c
Add a detach() method.
[FreeBSD/FreeBSD.git] / sys / dev / iicbus / ds3231.c
1 /*-
2  * Copyright (c) 2014-2015 Luiz Otavio O Souza <loos@FreeBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29
30 /*
31  * Driver for Maxim DS3231[N] real-time clock/calendar.
32  */
33
34 #include "opt_platform.h"
35
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/bus.h>
39 #include <sys/clock.h>
40 #include <sys/kernel.h>
41 #include <sys/module.h>
42 #include <sys/sysctl.h>
43
44 #include <dev/iicbus/iicbus.h>
45 #include <dev/iicbus/iiconf.h>
46 #ifdef FDT
47 #include <dev/ofw/openfirm.h>
48 #include <dev/ofw/ofw_bus.h>
49 #include <dev/ofw/ofw_bus_subr.h>
50 #endif
51
52 #include <dev/iicbus/ds3231reg.h>
53
54 #include "clock_if.h"
55 #include "iicbus_if.h"
56
57 struct ds3231_softc {
58         device_t        sc_dev;
59         int             sc_last_c;
60         int             sc_year0;
61         struct intr_config_hook enum_hook;
62         uint16_t        sc_addr;        /* DS3231 slave address. */
63         uint8_t         sc_ctrl;
64         uint8_t         sc_status;
65 };
66
67 static void ds3231_start(void *);
68
69 static int
70 ds3231_read1(device_t dev, uint8_t reg, uint8_t *data)
71 {
72
73         return (iicdev_readfrom(dev, reg, data, 1, IIC_INTRWAIT));
74 }
75
76 static int
77 ds3231_write1(device_t dev, uint8_t reg, uint8_t data)
78 {
79
80         return (iicdev_writeto(dev, reg, &data, 1, IIC_INTRWAIT));
81 }
82
83 static int
84 ds3231_ctrl_read(struct ds3231_softc *sc)
85 {
86         int error;
87
88         error = ds3231_read1(sc->sc_dev, DS3231_CONTROL, &sc->sc_ctrl);
89         if (error) {
90                 device_printf(sc->sc_dev, "cannot read from RTC.\n");
91                 return (error);
92         }
93         return (0);
94 }
95
96 static int
97 ds3231_ctrl_write(struct ds3231_softc *sc)
98 {
99         int error;
100         uint8_t data;
101
102         /* Always enable the oscillator.  Always disable both alarms. */
103         data = sc->sc_ctrl & ~DS3231_CTRL_MASK;
104         error = ds3231_write1(sc->sc_dev, DS3231_CONTROL, data);
105         if (error != 0)
106                 device_printf(sc->sc_dev, "cannot write to RTC.\n");
107
108         return (error);
109 }
110
111 static int
112 ds3231_status_read(struct ds3231_softc *sc)
113 {
114         int error;
115
116         error = ds3231_read1(sc->sc_dev, DS3231_STATUS, &sc->sc_status);
117         if (error) {
118                 device_printf(sc->sc_dev, "cannot read from RTC.\n");
119                 return (error);
120         }
121
122         return (0);
123 }
124
125 static int
126 ds3231_status_write(struct ds3231_softc *sc, int clear_a1, int clear_a2)
127 {
128         int error;
129         uint8_t data;
130
131         data = sc->sc_status;
132         if (clear_a1 == 0)
133                 data |= DS3231_STATUS_A1F;
134         if (clear_a2 == 0)
135                 data |= DS3231_STATUS_A2F;
136         error = ds3231_write1(sc->sc_dev, DS3231_STATUS, data);
137         if (error != 0)
138                 device_printf(sc->sc_dev, "cannot write to RTC.\n");
139
140         return (error);
141 }
142
143 static int
144 ds3231_set_24hrs_mode(struct ds3231_softc *sc)
145 {
146         int error;
147         uint8_t hour;
148
149         error = ds3231_read1(sc->sc_dev, DS3231_HOUR, &hour);
150         if (error) {
151                 device_printf(sc->sc_dev, "cannot read from RTC.\n");
152                 return (error);
153         }
154         hour &= ~DS3231_C_MASK;
155         error = ds3231_write1(sc->sc_dev, DS3231_HOUR, hour);
156         if (error != 0)
157                 device_printf(sc->sc_dev, "cannot write to RTC.\n");
158
159         return (error);
160 }
161
162 static int
163 ds3231_temp_read(struct ds3231_softc *sc, int *temp)
164 {
165         int error, neg, t;
166         uint8_t buf8[2];
167         uint16_t buf;
168
169         error = iicdev_readfrom(sc->sc_dev, DS3231_TEMP, buf8, sizeof(buf8),
170             IIC_INTRWAIT);
171         if (error != 0)
172                 return (error);
173         buf = (buf8[0] << 8) | (buf8[1] & 0xff);
174         neg = 0;
175         if (buf & DS3231_NEG_BIT) {
176                 buf = ~(buf & DS3231_TEMP_MASK) + 1;
177                 neg = 1;
178         }
179         *temp = ((int16_t)buf >> 8) * 10;
180         t = 0;
181         if (buf & DS3231_0250C)
182                 t += 250;
183         if (buf & DS3231_0500C)
184                 t += 500;
185         t /= 100;
186         *temp += t;
187         if (neg)
188                 *temp = -(*temp);
189         *temp += TZ_ZEROC;
190
191         return (0);
192 }
193
194 static int
195 ds3231_temp_sysctl(SYSCTL_HANDLER_ARGS)
196 {
197         int error, temp;
198         struct ds3231_softc *sc;
199
200         sc = (struct ds3231_softc *)arg1;
201         if (ds3231_temp_read(sc, &temp) != 0)
202                 return (EIO);
203         error = sysctl_handle_int(oidp, &temp, 0, req);
204
205         return (error);
206 }
207
208 static int
209 ds3231_conv_sysctl(SYSCTL_HANDLER_ARGS)
210 {
211         int error, conv, newc;
212         struct ds3231_softc *sc;
213
214         sc = (struct ds3231_softc *)arg1;
215         error = ds3231_ctrl_read(sc);
216         if (error != 0)
217                 return (error);
218         newc = conv = (sc->sc_ctrl & DS3231_CTRL_CONV) ? 1 : 0;
219         error = sysctl_handle_int(oidp, &newc, 0, req);
220         if (error != 0 || req->newptr == NULL)
221                 return (error);
222         if (conv == 0 && newc != 0) {
223                 error = ds3231_status_read(sc);
224                 if (error != 0)
225                         return (error);
226                 if (sc->sc_status & DS3231_STATUS_BUSY)
227                         return (0);
228                 sc->sc_ctrl |= DS3231_CTRL_CONV;
229                 error = ds3231_ctrl_write(sc);
230                 if (error != 0)
231                         return (error);
232         }
233
234         return (error);
235 }
236
237 static int
238 ds3231_bbsqw_sysctl(SYSCTL_HANDLER_ARGS)
239 {
240         int bbsqw, error, newb;
241         struct ds3231_softc *sc;
242
243         sc = (struct ds3231_softc *)arg1;
244         error = ds3231_ctrl_read(sc);
245         if (error != 0)
246                 return (error);
247         bbsqw = newb = (sc->sc_ctrl & DS3231_CTRL_BBSQW) ? 1 : 0;
248         error = sysctl_handle_int(oidp, &newb, 0, req);
249         if (error != 0 || req->newptr == NULL)
250                 return (error);
251         if (bbsqw != newb) {
252                 sc->sc_ctrl &= ~DS3231_CTRL_BBSQW;
253                 if (newb)
254                         sc->sc_ctrl |= DS3231_CTRL_BBSQW;
255                 error = ds3231_ctrl_write(sc);
256                 if (error != 0)
257                         return (error);
258         }
259
260         return (error);
261 }
262
263 static int
264 ds3231_sqw_freq_sysctl(SYSCTL_HANDLER_ARGS)
265 {
266         int ds3231_sqw_freq[] = { 1, 1024, 4096, 8192 };
267         int error, freq, i, newf, tmp;
268         struct ds3231_softc *sc;
269
270         sc = (struct ds3231_softc *)arg1;
271         error = ds3231_ctrl_read(sc);
272         if (error != 0)
273                 return (error);
274         tmp = (sc->sc_ctrl & DS3231_CTRL_RS_MASK) >> DS3231_CTRL_RS_SHIFT;
275         if (tmp >= nitems(ds3231_sqw_freq))
276                 tmp = nitems(ds3231_sqw_freq) - 1;
277         freq = ds3231_sqw_freq[tmp];
278         error = sysctl_handle_int(oidp, &freq, 0, req);
279         if (error != 0 || req->newptr == NULL)
280                 return (error);
281         if (freq != ds3231_sqw_freq[tmp]) {
282                 newf = 0;
283                 for (i = 0; i < nitems(ds3231_sqw_freq); i++)
284                         if (freq >= ds3231_sqw_freq[i])
285                                 newf = i;
286                 sc->sc_ctrl &= ~DS3231_CTRL_RS_MASK;
287                 sc->sc_ctrl |= newf << DS3231_CTRL_RS_SHIFT;
288                 error = ds3231_ctrl_write(sc);
289                 if (error != 0)
290                         return (error);
291         }
292
293         return (error);
294 }
295
296 static int
297 ds3231_str_sqw_mode(char *buf)
298 {
299         int len, rtrn;
300
301         rtrn = -1;
302         len = strlen(buf);
303         if ((len > 2 && strncasecmp("interrupt", buf, len) == 0) ||
304             (len > 2 && strncasecmp("int", buf, len) == 0)) {
305                 rtrn = 1;
306         } else if ((len > 2 && strncasecmp("square-wave", buf, len) == 0) ||
307             (len > 2 && strncasecmp("sqw", buf, len) == 0)) {
308                 rtrn = 0;
309         }
310
311         return (rtrn);
312 }
313
314 static int
315 ds3231_sqw_mode_sysctl(SYSCTL_HANDLER_ARGS)
316 {
317         char buf[16];
318         int error, mode, newm;
319         struct ds3231_softc *sc;
320
321         sc = (struct ds3231_softc *)arg1;
322         error = ds3231_ctrl_read(sc);
323         if (error != 0)
324                 return (error);
325         if (sc->sc_ctrl & DS3231_CTRL_INTCN) {
326                 mode = 1;
327                 strlcpy(buf, "interrupt", sizeof(buf));
328         } else {
329                 mode = 0;
330                 strlcpy(buf, "square-wave", sizeof(buf));
331         }
332         error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
333         if (error != 0 || req->newptr == NULL)
334                 return (error);
335         newm = ds3231_str_sqw_mode(buf);
336         if (newm != -1 && mode != newm) {
337                 sc->sc_ctrl &= ~DS3231_CTRL_INTCN;
338                 if (newm == 1)
339                         sc->sc_ctrl |= DS3231_CTRL_INTCN;
340                 error = ds3231_ctrl_write(sc);
341                 if (error != 0)
342                         return (error);
343         }
344
345         return (error);
346 }
347
348 static int
349 ds3231_en32khz_sysctl(SYSCTL_HANDLER_ARGS)
350 {
351         int error, en32khz, tmp;
352         struct ds3231_softc *sc;
353
354         sc = (struct ds3231_softc *)arg1;
355         error = ds3231_status_read(sc);
356         if (error != 0)
357                 return (error);
358         tmp = en32khz = (sc->sc_status & DS3231_STATUS_EN32KHZ) ? 1 : 0;
359         error = sysctl_handle_int(oidp, &en32khz, 0, req);
360         if (error != 0 || req->newptr == NULL)
361                 return (error);
362         if (en32khz != tmp) {
363                 sc->sc_status &= ~DS3231_STATUS_EN32KHZ;
364                 if (en32khz)
365                         sc->sc_status |= DS3231_STATUS_EN32KHZ;
366                 error = ds3231_status_write(sc, 0, 0);
367                 if (error != 0)
368                         return (error);
369         }
370
371         return (error);
372 }
373
374 static int
375 ds3231_probe(device_t dev)
376 {
377
378 #ifdef FDT
379         if (!ofw_bus_status_okay(dev))
380                 return (ENXIO);
381         if (!ofw_bus_is_compatible(dev, "maxim,ds3231"))
382                 return (ENXIO);
383 #endif
384         device_set_desc(dev, "Maxim DS3231 RTC");
385
386         return (BUS_PROBE_DEFAULT);
387 }
388
389 static int
390 ds3231_attach(device_t dev)
391 {
392         struct ds3231_softc *sc;
393
394         sc = device_get_softc(dev);
395         sc->sc_dev = dev;
396         sc->sc_addr = iicbus_get_addr(dev);
397         sc->sc_last_c = -1;
398         sc->sc_year0 = 1900;
399         sc->enum_hook.ich_func = ds3231_start;
400         sc->enum_hook.ich_arg = dev;
401
402         /*
403          * We have to wait until interrupts are enabled.  Usually I2C read
404          * and write only works when the interrupts are available.
405          */
406         if (config_intrhook_establish(&sc->enum_hook) != 0)
407                 return (ENOMEM);
408
409         return (0);
410 }
411
412 static int
413 ds3231_detach(device_t dev)
414 {
415
416         clock_unregister(dev);
417         return (0);
418 }
419
420 static void
421 ds3231_start(void *xdev)
422 {
423         device_t dev;
424         struct ds3231_softc *sc;
425         struct sysctl_ctx_list *ctx;
426         struct sysctl_oid *tree_node;
427         struct sysctl_oid_list *tree;
428
429         dev = (device_t)xdev;
430         sc = device_get_softc(dev);
431         ctx = device_get_sysctl_ctx(dev);
432         tree_node = device_get_sysctl_tree(dev);
433         tree = SYSCTL_CHILDREN(tree_node);
434
435         config_intrhook_disestablish(&sc->enum_hook);
436         if (ds3231_ctrl_read(sc) != 0)
437                 return;
438         if (ds3231_status_read(sc) != 0)
439                 return;
440         /* Clear the OSF bit and ack any pending alarm interrupt. */
441         if (sc->sc_status & DS3231_STATUS_OSF) {
442                 device_printf(sc->sc_dev,
443                     "oscillator has stopped, check the battery.\n");
444                 sc->sc_status &= ~DS3231_STATUS_OSF;
445         }
446         if (ds3231_status_write(sc, 1, 1) != 0)
447                 return;
448         /* Always enable the oscillator. */
449         if (ds3231_ctrl_write(sc) != 0)
450                 return;
451         /* Set the 24 hours mode. */
452         if (ds3231_set_24hrs_mode(sc) != 0)
453                 return;
454
455         /* Temperature. */
456         SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "temperature",
457             CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
458             ds3231_temp_sysctl, "IK", "Current temperature");
459         /* Configuration parameters. */
460         SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "temp_conv",
461             CTLFLAG_RW | CTLTYPE_UINT | CTLFLAG_MPSAFE, sc, 0,
462             ds3231_conv_sysctl, "IU",
463             "DS3231 start a new temperature converstion");
464         SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "bbsqw",
465             CTLFLAG_RW | CTLTYPE_UINT | CTLFLAG_MPSAFE, sc, 0,
466             ds3231_bbsqw_sysctl, "IU",
467             "DS3231 battery-backed square-wave output enable");
468         SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "sqw_freq",
469             CTLFLAG_RW | CTLTYPE_UINT | CTLFLAG_MPSAFE, sc, 0,
470             ds3231_sqw_freq_sysctl, "IU",
471             "DS3231 square-wave output frequency");
472         SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "sqw_mode",
473             CTLFLAG_RW | CTLTYPE_STRING | CTLFLAG_MPSAFE, sc, 0,
474             ds3231_sqw_mode_sysctl, "A", "DS3231 SQW output mode control");
475         SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "32khz_enable",
476             CTLFLAG_RW | CTLTYPE_UINT | CTLFLAG_MPSAFE, sc, 0,
477             ds3231_en32khz_sysctl, "IU", "DS3231 enable the 32kHz output");
478
479         /* 1 second resolution. */
480         clock_register(dev, 1000000);
481 }
482
483 static int
484 ds3231_gettime(device_t dev, struct timespec *ts)
485 {
486         int c, error;
487         struct clocktime ct;
488         struct ds3231_softc *sc;
489         uint8_t data[7];
490
491         sc = device_get_softc(dev);
492         memset(data, 0, sizeof(data));
493         error = iicdev_readfrom(sc->sc_dev, DS3231_SECS, data, sizeof(data),
494             IIC_INTRWAIT);
495         if (error != 0) {
496                 device_printf(dev, "cannot read from RTC.\n");
497                 return (error);
498         }
499         ct.nsec = 0;
500         ct.sec = FROMBCD(data[DS3231_SECS] & DS3231_SECS_MASK);
501         ct.min = FROMBCD(data[DS3231_MINS] & DS3231_MINS_MASK);
502         ct.hour = FROMBCD(data[DS3231_HOUR] & DS3231_HOUR_MASK);
503         ct.day = FROMBCD(data[DS3231_DATE] & DS3231_DATE_MASK);
504         ct.dow = data[DS3231_WEEKDAY] & DS3231_WEEKDAY_MASK;
505         ct.mon = FROMBCD(data[DS3231_MONTH] & DS3231_MONTH_MASK);
506         ct.year = FROMBCD(data[DS3231_YEAR] & DS3231_YEAR_MASK);
507         c = (data[DS3231_MONTH] & DS3231_C_MASK) ? 1 : 0;
508         if (sc->sc_last_c == -1)
509                 sc->sc_last_c = c;
510         else if (c != sc->sc_last_c) {
511                 sc->sc_year0 += 100;
512                 sc->sc_last_c = c;
513         }
514         ct.year += sc->sc_year0;
515         if (ct.year < POSIX_BASE_YEAR)
516                 ct.year += 100; /* assume [1970, 2069] */
517
518         return (clock_ct_to_ts(&ct, ts));
519 }
520
521 static int
522 ds3231_settime(device_t dev, struct timespec *ts)
523 {
524         int error;
525         struct clocktime ct;
526         struct ds3231_softc *sc;
527         uint8_t data[7];
528
529         sc = device_get_softc(dev);
530         /* Accuracy is only one second. */
531         if (ts->tv_nsec >= 500000000)
532                 ts->tv_sec++;
533         ts->tv_nsec = 0;
534         clock_ts_to_ct(ts, &ct);
535         memset(data, 0, sizeof(data));
536         data[DS3231_SECS] = TOBCD(ct.sec);
537         data[DS3231_MINS] = TOBCD(ct.min);
538         data[DS3231_HOUR] = TOBCD(ct.hour);
539         data[DS3231_DATE] = TOBCD(ct.day);
540         data[DS3231_WEEKDAY] = ct.dow;
541         data[DS3231_MONTH] = TOBCD(ct.mon);
542         data[DS3231_YEAR] = TOBCD(ct.year % 100);
543         if (sc->sc_last_c)
544                 data[DS3231_MONTH] |= DS3231_C_MASK;
545         /* Write the time back to RTC. */
546         error = iicdev_writeto(dev, DS3231_SECS, data, sizeof(data),
547             IIC_INTRWAIT);
548         if (error != 0)
549                 device_printf(dev, "cannot write to RTC.\n");
550
551         return (error);
552 }
553
554 static device_method_t ds3231_methods[] = {
555         DEVMETHOD(device_probe,         ds3231_probe),
556         DEVMETHOD(device_attach,        ds3231_attach),
557         DEVMETHOD(device_detach,        ds3231_detach),
558
559         DEVMETHOD(clock_gettime,        ds3231_gettime),
560         DEVMETHOD(clock_settime,        ds3231_settime),
561
562         DEVMETHOD_END
563 };
564
565 static driver_t ds3231_driver = {
566         "ds3231",
567         ds3231_methods,
568         sizeof(struct ds3231_softc),
569 };
570
571 static devclass_t ds3231_devclass;
572
573 DRIVER_MODULE(ds3231, iicbus, ds3231_driver, ds3231_devclass, NULL, NULL);
574 MODULE_VERSION(ds3231, 1);
575 MODULE_DEPEND(ds3231, iicbus, 1, 1, 1);