ds3231.c revision 279399
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: head/sys/dev/iicbus/ds3231.c 279399 2015-02-28 19:02:44Z loos $"); 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 57struct 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 67static int ds3231_sqw_freq[] = { 1, 1024, 4096, 8192 }; 68 69static void ds3231_start(void *); 70 71static int 72ds3231_read(device_t dev, uint16_t addr, uint8_t reg, uint8_t *data, size_t len) 73{ 74 struct iic_msg msg[2] = { 75 { addr, IIC_M_WR | IIC_M_NOSTOP, 1, ® }, 76 { addr, IIC_M_RD, len, data }, 77 }; 78 79 return (iicbus_transfer(dev, msg, nitems(msg))); 80} 81 82static int 83ds3231_write(device_t dev, uint16_t addr, uint8_t *data, size_t len) 84{ 85 struct iic_msg msg[1] = { 86 { addr, IIC_M_WR, len, data }, 87 }; 88 89 return (iicbus_transfer(dev, msg, nitems(msg))); 90} 91 92static int 93ds3231_ctrl_read(struct ds3231_softc *sc) 94{ 95 int error; 96 97 sc->sc_ctrl = 0; 98 error = ds3231_read(sc->sc_dev, sc->sc_addr, DS3231_CONTROL, 99 &sc->sc_ctrl, sizeof(sc->sc_ctrl)); 100 if (error) { 101 device_printf(sc->sc_dev, "cannot read from RTC.\n"); 102 return (error); 103 } 104 105 return (0); 106} 107 108static int 109ds3231_ctrl_write(struct ds3231_softc *sc) 110{ 111 int error; 112 uint8_t data[2]; 113 114 data[0] = DS3231_CONTROL; 115 /* Always enable the oscillator. Always disable both alarms. */ 116 data[1] = sc->sc_ctrl & ~DS3231_CTRL_MASK; 117 error = ds3231_write(sc->sc_dev, sc->sc_addr, data, sizeof(data)); 118 if (error != 0) 119 device_printf(sc->sc_dev, "cannot write to RTC.\n"); 120 121 return (error); 122} 123 124static int 125ds3231_status_read(struct ds3231_softc *sc) 126{ 127 int error; 128 129 sc->sc_status = 0; 130 error = ds3231_read(sc->sc_dev, sc->sc_addr, DS3231_STATUS, 131 &sc->sc_status, sizeof(sc->sc_status)); 132 if (error) { 133 device_printf(sc->sc_dev, "cannot read from RTC.\n"); 134 return (error); 135 } 136 137 return (0); 138} 139 140static int 141ds3231_status_write(struct ds3231_softc *sc, int clear_a1, int clear_a2) 142{ 143 int error; 144 uint8_t data[2]; 145 146 data[0] = DS3231_STATUS; 147 data[1] = sc->sc_status; 148 if (clear_a1 == 0) 149 data[1] |= DS3231_STATUS_A1F; 150 if (clear_a2 == 0) 151 data[1] |= DS3231_STATUS_A2F; 152 error = ds3231_write(sc->sc_dev, sc->sc_addr, data, sizeof(data)); 153 if (error != 0) 154 device_printf(sc->sc_dev, "cannot write to RTC.\n"); 155 156 return (error); 157} 158 159static int 160ds3231_set_24hrs_mode(struct ds3231_softc *sc) 161{ 162 int error; 163 uint8_t data[2], hour; 164 165 hour = 0; 166 error = ds3231_read(sc->sc_dev, sc->sc_addr, DS3231_HOUR, 167 &hour, sizeof(hour)); 168 if (error) { 169 device_printf(sc->sc_dev, "cannot read from RTC.\n"); 170 return (error); 171 } 172 data[0] = DS3231_HOUR; 173 data[1] = hour & ~DS3231_C_MASK; 174 error = ds3231_write(sc->sc_dev, sc->sc_addr, data, sizeof(data)); 175 if (error != 0) 176 device_printf(sc->sc_dev, "cannot write to RTC.\n"); 177 178 return (error); 179} 180 181static int 182ds3231_temp_read(struct ds3231_softc *sc, int *temp) 183{ 184 int error, neg, t; 185 uint8_t buf8[2]; 186 uint16_t buf; 187 188 error = ds3231_read(sc->sc_dev, sc->sc_addr, DS3231_TEMP, 189 buf8, sizeof(buf8)); 190 if (error != 0) 191 return (error); 192 buf = (buf8[0] << 8) | (buf8[1] & 0xff); 193 neg = 0; 194 if (buf & DS3231_NEG_BIT) { 195 buf = ~(buf & DS3231_TEMP_MASK) + 1; 196 neg = 1; 197 } 198 *temp = ((int16_t)buf >> 8) * 10; 199 t = 0; 200 if (buf & DS3231_0250C) 201 t += 250; 202 if (buf & DS3231_0500C) 203 t += 500; 204 t /= 100; 205 *temp += t; 206 if (neg) 207 *temp = -(*temp); 208 *temp += TZ_ZEROC; 209 210 return (0); 211} 212 213static int 214ds3231_temp_sysctl(SYSCTL_HANDLER_ARGS) 215{ 216 int error, temp; 217 struct ds3231_softc *sc; 218 219 sc = (struct ds3231_softc *)arg1; 220 if (ds3231_temp_read(sc, &temp) != 0) 221 return (EIO); 222 error = sysctl_handle_int(oidp, &temp, 0, req); 223 224 return (error); 225} 226 227static int 228ds3231_conv_sysctl(SYSCTL_HANDLER_ARGS) 229{ 230 int error, conv, newc; 231 struct ds3231_softc *sc; 232 233 sc = (struct ds3231_softc *)arg1; 234 error = ds3231_ctrl_read(sc); 235 if (error != 0) 236 return (error); 237 newc = conv = (sc->sc_ctrl & DS3231_CTRL_CONV) ? 1 : 0; 238 error = sysctl_handle_int(oidp, &newc, 0, req); 239 if (error != 0 || req->newptr == NULL) 240 return (error); 241 if (conv == 0 && newc != 0) { 242 error = ds3231_status_read(sc); 243 if (error != 0) 244 return (error); 245 if (sc->sc_status & DS3231_STATUS_BUSY) 246 return (0); 247 sc->sc_ctrl |= DS3231_CTRL_CONV; 248 error = ds3231_ctrl_write(sc); 249 if (error != 0) 250 return (error); 251 } 252 253 return (error); 254} 255 256static int 257ds3231_bbsqw_sysctl(SYSCTL_HANDLER_ARGS) 258{ 259 int bbsqw, error, newb; 260 struct ds3231_softc *sc; 261 262 sc = (struct ds3231_softc *)arg1; 263 error = ds3231_ctrl_read(sc); 264 if (error != 0) 265 return (error); 266 bbsqw = newb = (sc->sc_ctrl & DS3231_CTRL_BBSQW) ? 1 : 0; 267 error = sysctl_handle_int(oidp, &newb, 0, req); 268 if (error != 0 || req->newptr == NULL) 269 return (error); 270 if (bbsqw != newb) { 271 sc->sc_ctrl &= ~DS3231_CTRL_BBSQW; 272 if (newb) 273 sc->sc_ctrl |= DS3231_CTRL_BBSQW; 274 error = ds3231_ctrl_write(sc); 275 if (error != 0) 276 return (error); 277 } 278 279 return (error); 280} 281 282static int 283ds3231_sqw_freq_sysctl(SYSCTL_HANDLER_ARGS) 284{ 285 int error, freq, i, newf, tmp; 286 struct ds3231_softc *sc; 287 288 sc = (struct ds3231_softc *)arg1; 289 error = ds3231_ctrl_read(sc); 290 if (error != 0) 291 return (error); 292 tmp = (sc->sc_ctrl & DS3231_CTRL_RS_MASK) >> DS3231_CTRL_RS_SHIFT; 293 if (tmp > nitems(ds3231_sqw_freq)) 294 tmp = nitems(ds3231_sqw_freq); 295 freq = ds3231_sqw_freq[tmp]; 296 error = sysctl_handle_int(oidp, &freq, 0, req); 297 if (error != 0 || req->newptr == NULL) 298 return (error); 299 if (freq != ds3231_sqw_freq[tmp]) { 300 newf = 0; 301 for (i = 0; i < nitems(ds3231_sqw_freq); i++) 302 if (freq >= ds3231_sqw_freq[i]) 303 newf = i; 304 sc->sc_ctrl &= ~DS3231_CTRL_RS_MASK; 305 sc->sc_ctrl |= newf << DS3231_CTRL_RS_SHIFT; 306 error = ds3231_ctrl_write(sc); 307 if (error != 0) 308 return (error); 309 } 310 311 return (error); 312} 313 314static int 315ds3231_str_sqw_mode(char *buf) 316{ 317 int len, rtrn; 318 319 rtrn = -1; 320 len = strlen(buf); 321 if ((len > 2 && strncasecmp("interrupt", buf, len) == 0) || 322 (len > 2 && strncasecmp("int", buf, len) == 0)) { 323 rtrn = 1; 324 } else if ((len > 2 && strncasecmp("square-wave", buf, len) == 0) || 325 (len > 2 && strncasecmp("sqw", buf, len) == 0)) { 326 rtrn = 0; 327 } 328 329 return (rtrn); 330} 331 332static int 333ds3231_sqw_mode_sysctl(SYSCTL_HANDLER_ARGS) 334{ 335 char buf[16]; 336 int error, mode, newm; 337 struct ds3231_softc *sc; 338 339 sc = (struct ds3231_softc *)arg1; 340 error = ds3231_ctrl_read(sc); 341 if (error != 0) 342 return (error); 343 if (sc->sc_ctrl & DS3231_CTRL_INTCN) { 344 mode = 1; 345 strlcpy(buf, "interrupt", sizeof(buf)); 346 } else { 347 mode = 0; 348 strlcpy(buf, "square-wave", sizeof(buf)); 349 } 350 error = sysctl_handle_string(oidp, buf, sizeof(buf), req); 351 if (error != 0 || req->newptr == NULL) 352 return (error); 353 newm = ds3231_str_sqw_mode(buf); 354 if (newm != -1 && mode != newm) { 355 sc->sc_ctrl &= ~DS3231_CTRL_INTCN; 356 if (newm == 1) 357 sc->sc_ctrl |= DS3231_CTRL_INTCN; 358 error = ds3231_ctrl_write(sc); 359 if (error != 0) 360 return (error); 361 } 362 363 return (error); 364} 365 366static int 367ds3231_en32khz_sysctl(SYSCTL_HANDLER_ARGS) 368{ 369 int error, en32khz, tmp; 370 struct ds3231_softc *sc; 371 372 sc = (struct ds3231_softc *)arg1; 373 error = ds3231_status_read(sc); 374 if (error != 0) 375 return (error); 376 tmp = en32khz = (sc->sc_status & DS3231_STATUS_EN32KHZ) ? 1 : 0; 377 error = sysctl_handle_int(oidp, &en32khz, 0, req); 378 if (error != 0 || req->newptr == NULL) 379 return (error); 380 if (en32khz != tmp) { 381 sc->sc_status &= ~DS3231_STATUS_EN32KHZ; 382 if (en32khz) 383 sc->sc_status |= DS3231_STATUS_EN32KHZ; 384 error = ds3231_status_write(sc, 0, 0); 385 if (error != 0) 386 return (error); 387 } 388 389 return (error); 390} 391 392static int 393ds3231_probe(device_t dev) 394{ 395 396#ifdef FDT 397 if (!ofw_bus_status_okay(dev)) 398 return (ENXIO); 399 if (!ofw_bus_is_compatible(dev, "maxim,ds3231")) 400 return (ENXIO); 401#endif 402 device_set_desc(dev, "Maxim DS3231 RTC"); 403 404 return (BUS_PROBE_DEFAULT); 405} 406 407static int 408ds3231_attach(device_t dev) 409{ 410 struct ds3231_softc *sc; 411 412 sc = device_get_softc(dev); 413 sc->sc_dev = dev; 414 sc->sc_addr = iicbus_get_addr(dev); 415 sc->sc_last_c = -1; 416 sc->sc_year0 = 1900; 417 sc->enum_hook.ich_func = ds3231_start; 418 sc->enum_hook.ich_arg = dev; 419 420 /* 421 * We have to wait until interrupts are enabled. Usually I2C read 422 * and write only works when the interrupts are available. 423 */ 424 if (config_intrhook_establish(&sc->enum_hook) != 0) 425 return (ENOMEM); 426 427 return (0); 428} 429 430static void 431ds3231_start(void *xdev) 432{ 433 device_t dev; 434 struct ds3231_softc *sc; 435 struct sysctl_ctx_list *ctx; 436 struct sysctl_oid *tree_node; 437 struct sysctl_oid_list *tree; 438 439 dev = (device_t)xdev; 440 sc = device_get_softc(dev); 441 ctx = device_get_sysctl_ctx(dev); 442 tree_node = device_get_sysctl_tree(dev); 443 tree = SYSCTL_CHILDREN(tree_node); 444 445 config_intrhook_disestablish(&sc->enum_hook); 446 if (ds3231_ctrl_read(sc) != 0) 447 return; 448 if (ds3231_status_read(sc) != 0) 449 return; 450 /* Clear the OSF bit and ack any pending alarm interrupt. */ 451 if (sc->sc_status & DS3231_STATUS_OSF) { 452 device_printf(sc->sc_dev, 453 "oscillator has stopped, check the battery.\n"); 454 sc->sc_status &= ~DS3231_STATUS_OSF; 455 } 456 if (ds3231_status_write(sc, 1, 1) != 0) 457 return; 458 /* Always enable the oscillator. */ 459 if (ds3231_ctrl_write(sc) != 0) 460 return; 461 /* Set the 24 hours mode. */ 462 if (ds3231_set_24hrs_mode(sc) != 0) 463 return; 464 465 /* Temperature. */ 466 SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "temperature", 467 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0, 468 ds3231_temp_sysctl, "IK", "Current temperature"); 469 /* Configuration parameters. */ 470 SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "temp_conv", 471 CTLFLAG_RW | CTLTYPE_UINT | CTLFLAG_MPSAFE, sc, 0, 472 ds3231_conv_sysctl, "IU", 473 "DS3231 start a new temperature converstion"); 474 SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "bbsqw", 475 CTLFLAG_RW | CTLTYPE_UINT | CTLFLAG_MPSAFE, sc, 0, 476 ds3231_bbsqw_sysctl, "IU", 477 "DS3231 battery-backed square-wave output enable"); 478 SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "sqw_freq", 479 CTLFLAG_RW | CTLTYPE_UINT | CTLFLAG_MPSAFE, sc, 0, 480 ds3231_sqw_freq_sysctl, "IU", 481 "DS3231 square-wave output frequency"); 482 SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "sqw_mode", 483 CTLFLAG_RW | CTLTYPE_STRING | CTLFLAG_MPSAFE, sc, 0, 484 ds3231_sqw_mode_sysctl, "A", "DS3231 SQW output mode control"); 485 SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "32khz_enable", 486 CTLFLAG_RW | CTLTYPE_UINT | CTLFLAG_MPSAFE, sc, 0, 487 ds3231_en32khz_sysctl, "IU", "DS3231 enable the 32kHz output"); 488 489 /* 1 second resolution. */ 490 clock_register(dev, 1000000); 491} 492 493static int 494ds3231_gettime(device_t dev, struct timespec *ts) 495{ 496 int c, error; 497 struct clocktime ct; 498 struct ds3231_softc *sc; 499 uint8_t data[7]; 500 501 sc = device_get_softc(dev); 502 memset(data, 0, sizeof(data)); 503 error = ds3231_read(sc->sc_dev, sc->sc_addr, DS3231_SECS, 504 data, sizeof(data)); 505 if (error != 0) { 506 device_printf(dev, "cannot read from RTC.\n"); 507 return (error); 508 } 509 ct.nsec = 0; 510 ct.sec = FROMBCD(data[DS3231_SECS] & DS3231_SECS_MASK); 511 ct.min = FROMBCD(data[DS3231_MINS] & DS3231_MINS_MASK); 512 ct.hour = FROMBCD(data[DS3231_HOUR] & DS3231_HOUR_MASK); 513 ct.day = FROMBCD(data[DS3231_DATE] & DS3231_DATE_MASK); 514 ct.dow = data[DS3231_WEEKDAY] & DS3231_WEEKDAY_MASK; 515 ct.mon = FROMBCD(data[DS3231_MONTH] & DS3231_MONTH_MASK); 516 ct.year = FROMBCD(data[DS3231_YEAR] & DS3231_YEAR_MASK); 517 c = (data[DS3231_MONTH] & DS3231_C_MASK) ? 1 : 0; 518 if (sc->sc_last_c == -1) 519 sc->sc_last_c = c; 520 else if (c != sc->sc_last_c) { 521 sc->sc_year0 += 100; 522 sc->sc_last_c = c; 523 } 524 ct.year += sc->sc_year0; 525 if (ct.year < POSIX_BASE_YEAR) 526 ct.year += 100; /* assume [1970, 2069] */ 527 528 return (clock_ct_to_ts(&ct, ts)); 529} 530 531static int 532ds3231_settime(device_t dev, struct timespec *ts) 533{ 534 int error; 535 struct clocktime ct; 536 struct ds3231_softc *sc; 537 uint8_t data[8]; 538 539 sc = device_get_softc(dev); 540 /* Accuracy is only one second. */ 541 if (ts->tv_nsec >= 500000000) 542 ts->tv_sec++; 543 ts->tv_nsec = 0; 544 clock_ts_to_ct(ts, &ct); 545 memset(data, 0, sizeof(data)); 546 data[0] = DS3231_SECS; 547 data[DS3231_SECS + 1] = TOBCD(ct.sec); 548 data[DS3231_MINS + 1] = TOBCD(ct.min); 549 data[DS3231_HOUR + 1] = TOBCD(ct.hour); 550 data[DS3231_DATE + 1] = TOBCD(ct.day); 551 data[DS3231_WEEKDAY + 1] = ct.dow; 552 data[DS3231_MONTH + 1] = TOBCD(ct.mon); 553 data[DS3231_YEAR + 1] = TOBCD(ct.year % 100); 554 if (sc->sc_last_c) 555 data[DS3231_MONTH] |= DS3231_C_MASK; 556 /* Write the time back to RTC. */ 557 error = ds3231_write(dev, sc->sc_addr, data, sizeof(data)); 558 if (error != 0) 559 device_printf(dev, "cannot write to RTC.\n"); 560 561 return (error); 562} 563 564static device_method_t ds3231_methods[] = { 565 DEVMETHOD(device_probe, ds3231_probe), 566 DEVMETHOD(device_attach, ds3231_attach), 567 568 DEVMETHOD(clock_gettime, ds3231_gettime), 569 DEVMETHOD(clock_settime, ds3231_settime), 570 571 DEVMETHOD_END 572}; 573 574static driver_t ds3231_driver = { 575 "ds3231", 576 ds3231_methods, 577 sizeof(struct ds3231_softc), 578}; 579 580static devclass_t ds3231_devclass; 581 582DRIVER_MODULE(ds3231, iicbus, ds3231_driver, ds3231_devclass, NULL, NULL); 583MODULE_VERSION(ds3231, 1); 584MODULE_DEPEND(ds3231, iicbus, 1, 1, 1); 585