The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/iicbus/ds3231.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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         bool            sc_use_ampm;
   66 };
   67 
   68 static void ds3231_start(void *);
   69 
   70 static int
   71 ds3231_read1(device_t dev, uint8_t reg, uint8_t *data)
   72 {
   73 
   74         return (iicdev_readfrom(dev, reg, data, 1, IIC_INTRWAIT));
   75 }
   76 
   77 static int
   78 ds3231_write1(device_t dev, uint8_t reg, uint8_t data)
   79 {
   80 
   81         return (iicdev_writeto(dev, reg, &data, 1, IIC_INTRWAIT));
   82 }
   83 
   84 static int
   85 ds3231_ctrl_read(struct ds3231_softc *sc)
   86 {
   87         int error;
   88 
   89         error = ds3231_read1(sc->sc_dev, DS3231_CONTROL, &sc->sc_ctrl);
   90         if (error) {
   91                 device_printf(sc->sc_dev, "cannot read from RTC.\n");
   92                 return (error);
   93         }
   94         return (0);
   95 }
   96 
   97 static int
   98 ds3231_ctrl_write(struct ds3231_softc *sc)
   99 {
  100         int error;
  101         uint8_t data;
  102 
  103         /* Always enable the oscillator.  Always disable both alarms. */
  104         data = sc->sc_ctrl & ~DS3231_CTRL_MASK;
  105         error = ds3231_write1(sc->sc_dev, DS3231_CONTROL, data);
  106         if (error != 0)
  107                 device_printf(sc->sc_dev, "cannot write to RTC.\n");
  108 
  109         return (error);
  110 }
  111 
  112 static int
  113 ds3231_status_read(struct ds3231_softc *sc)
  114 {
  115         int error;
  116 
  117         error = ds3231_read1(sc->sc_dev, DS3231_STATUS, &sc->sc_status);
  118         if (error) {
  119                 device_printf(sc->sc_dev, "cannot read from RTC.\n");
  120                 return (error);
  121         }
  122 
  123         return (0);
  124 }
  125 
  126 static int
  127 ds3231_status_write(struct ds3231_softc *sc, int clear_a1, int clear_a2)
  128 {
  129         int error;
  130         uint8_t data;
  131 
  132         data = sc->sc_status;
  133         if (clear_a1 == 0)
  134                 data |= DS3231_STATUS_A1F;
  135         if (clear_a2 == 0)
  136                 data |= DS3231_STATUS_A2F;
  137         error = ds3231_write1(sc->sc_dev, DS3231_STATUS, data);
  138         if (error != 0)
  139                 device_printf(sc->sc_dev, "cannot write to RTC.\n");
  140 
  141         return (error);
  142 }
  143 
  144 static int
  145 ds3231_temp_read(struct ds3231_softc *sc, int *temp)
  146 {
  147         int error, neg, t;
  148         uint8_t buf8[2];
  149         uint16_t buf;
  150 
  151         error = iicdev_readfrom(sc->sc_dev, DS3231_TEMP, buf8, sizeof(buf8),
  152             IIC_INTRWAIT);
  153         if (error != 0)
  154                 return (error);
  155         buf = (buf8[0] << 8) | (buf8[1] & 0xff);
  156         neg = 0;
  157         if (buf & DS3231_NEG_BIT) {
  158                 buf = ~(buf & DS3231_TEMP_MASK) + 1;
  159                 neg = 1;
  160         }
  161         *temp = ((int16_t)buf >> 8) * 10;
  162         t = 0;
  163         if (buf & DS3231_0250C)
  164                 t += 250;
  165         if (buf & DS3231_0500C)
  166                 t += 500;
  167         t /= 100;
  168         *temp += t;
  169         if (neg)
  170                 *temp = -(*temp);
  171         *temp += TZ_ZEROC;
  172 
  173         return (0);
  174 }
  175 
  176 static int
  177 ds3231_temp_sysctl(SYSCTL_HANDLER_ARGS)
  178 {
  179         int error, temp;
  180         struct ds3231_softc *sc;
  181 
  182         sc = (struct ds3231_softc *)arg1;
  183         if (ds3231_temp_read(sc, &temp) != 0)
  184                 return (EIO);
  185         error = sysctl_handle_int(oidp, &temp, 0, req);
  186 
  187         return (error);
  188 }
  189 
  190 static int
  191 ds3231_conv_sysctl(SYSCTL_HANDLER_ARGS)
  192 {
  193         int error, conv, newc;
  194         struct ds3231_softc *sc;
  195 
  196         sc = (struct ds3231_softc *)arg1;
  197         error = ds3231_ctrl_read(sc);
  198         if (error != 0)
  199                 return (error);
  200         newc = conv = (sc->sc_ctrl & DS3231_CTRL_CONV) ? 1 : 0;
  201         error = sysctl_handle_int(oidp, &newc, 0, req);
  202         if (error != 0 || req->newptr == NULL)
  203                 return (error);
  204         if (conv == 0 && newc != 0) {
  205                 error = ds3231_status_read(sc);
  206                 if (error != 0)
  207                         return (error);
  208                 if (sc->sc_status & DS3231_STATUS_BUSY)
  209                         return (0);
  210                 sc->sc_ctrl |= DS3231_CTRL_CONV;
  211                 error = ds3231_ctrl_write(sc);
  212                 if (error != 0)
  213                         return (error);
  214         }
  215 
  216         return (error);
  217 }
  218 
  219 static int
  220 ds3231_bbsqw_sysctl(SYSCTL_HANDLER_ARGS)
  221 {
  222         int bbsqw, error, newb;
  223         struct ds3231_softc *sc;
  224 
  225         sc = (struct ds3231_softc *)arg1;
  226         error = ds3231_ctrl_read(sc);
  227         if (error != 0)
  228                 return (error);
  229         bbsqw = newb = (sc->sc_ctrl & DS3231_CTRL_BBSQW) ? 1 : 0;
  230         error = sysctl_handle_int(oidp, &newb, 0, req);
  231         if (error != 0 || req->newptr == NULL)
  232                 return (error);
  233         if (bbsqw != newb) {
  234                 sc->sc_ctrl &= ~DS3231_CTRL_BBSQW;
  235                 if (newb)
  236                         sc->sc_ctrl |= DS3231_CTRL_BBSQW;
  237                 error = ds3231_ctrl_write(sc);
  238                 if (error != 0)
  239                         return (error);
  240         }
  241 
  242         return (error);
  243 }
  244 
  245 static int
  246 ds3231_sqw_freq_sysctl(SYSCTL_HANDLER_ARGS)
  247 {
  248         int ds3231_sqw_freq[] = { 1, 1024, 4096, 8192 };
  249         int error, freq, i, newf, tmp;
  250         struct ds3231_softc *sc;
  251 
  252         sc = (struct ds3231_softc *)arg1;
  253         error = ds3231_ctrl_read(sc);
  254         if (error != 0)
  255                 return (error);
  256         tmp = (sc->sc_ctrl & DS3231_CTRL_RS_MASK) >> DS3231_CTRL_RS_SHIFT;
  257         if (tmp >= nitems(ds3231_sqw_freq))
  258                 tmp = nitems(ds3231_sqw_freq) - 1;
  259         freq = ds3231_sqw_freq[tmp];
  260         error = sysctl_handle_int(oidp, &freq, 0, req);
  261         if (error != 0 || req->newptr == NULL)
  262                 return (error);
  263         if (freq != ds3231_sqw_freq[tmp]) {
  264                 newf = 0;
  265                 for (i = 0; i < nitems(ds3231_sqw_freq); i++)
  266                         if (freq >= ds3231_sqw_freq[i])
  267                                 newf = i;
  268                 sc->sc_ctrl &= ~DS3231_CTRL_RS_MASK;
  269                 sc->sc_ctrl |= newf << DS3231_CTRL_RS_SHIFT;
  270                 error = ds3231_ctrl_write(sc);
  271                 if (error != 0)
  272                         return (error);
  273         }
  274 
  275         return (error);
  276 }
  277 
  278 static int
  279 ds3231_str_sqw_mode(char *buf)
  280 {
  281         int len, rtrn;
  282 
  283         rtrn = -1;
  284         len = strlen(buf);
  285         if ((len > 2 && strncasecmp("interrupt", buf, len) == 0) ||
  286             (len > 2 && strncasecmp("int", buf, len) == 0)) {
  287                 rtrn = 1;
  288         } else if ((len > 2 && strncasecmp("square-wave", buf, len) == 0) ||
  289             (len > 2 && strncasecmp("sqw", buf, len) == 0)) {
  290                 rtrn = 0;
  291         }
  292 
  293         return (rtrn);
  294 }
  295 
  296 static int
  297 ds3231_sqw_mode_sysctl(SYSCTL_HANDLER_ARGS)
  298 {
  299         char buf[16];
  300         int error, mode, newm;
  301         struct ds3231_softc *sc;
  302 
  303         sc = (struct ds3231_softc *)arg1;
  304         error = ds3231_ctrl_read(sc);
  305         if (error != 0)
  306                 return (error);
  307         if (sc->sc_ctrl & DS3231_CTRL_INTCN) {
  308                 mode = 1;
  309                 strlcpy(buf, "interrupt", sizeof(buf));
  310         } else {
  311                 mode = 0;
  312                 strlcpy(buf, "square-wave", sizeof(buf));
  313         }
  314         error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
  315         if (error != 0 || req->newptr == NULL)
  316                 return (error);
  317         newm = ds3231_str_sqw_mode(buf);
  318         if (newm != -1 && mode != newm) {
  319                 sc->sc_ctrl &= ~DS3231_CTRL_INTCN;
  320                 if (newm == 1)
  321                         sc->sc_ctrl |= DS3231_CTRL_INTCN;
  322                 error = ds3231_ctrl_write(sc);
  323                 if (error != 0)
  324                         return (error);
  325         }
  326 
  327         return (error);
  328 }
  329 
  330 static int
  331 ds3231_en32khz_sysctl(SYSCTL_HANDLER_ARGS)
  332 {
  333         int error, en32khz, tmp;
  334         struct ds3231_softc *sc;
  335 
  336         sc = (struct ds3231_softc *)arg1;
  337         error = ds3231_status_read(sc);
  338         if (error != 0)
  339                 return (error);
  340         tmp = en32khz = (sc->sc_status & DS3231_STATUS_EN32KHZ) ? 1 : 0;
  341         error = sysctl_handle_int(oidp, &en32khz, 0, req);
  342         if (error != 0 || req->newptr == NULL)
  343                 return (error);
  344         if (en32khz != tmp) {
  345                 sc->sc_status &= ~DS3231_STATUS_EN32KHZ;
  346                 if (en32khz)
  347                         sc->sc_status |= DS3231_STATUS_EN32KHZ;
  348                 error = ds3231_status_write(sc, 0, 0);
  349                 if (error != 0)
  350                         return (error);
  351         }
  352 
  353         return (error);
  354 }
  355 
  356 static int
  357 ds3231_probe(device_t dev)
  358 {
  359         int rc;
  360 
  361 #ifdef FDT
  362         if (!ofw_bus_status_okay(dev))
  363                 return (ENXIO);
  364         if (ofw_bus_is_compatible(dev, "maxim,ds3231"))
  365                 rc = BUS_PROBE_DEFAULT;
  366         else
  367 #endif
  368                 rc = BUS_PROBE_NOWILDCARD;
  369 
  370         device_set_desc(dev, "Maxim DS3231 RTC");
  371 
  372         return (rc);
  373 }
  374 
  375 static int
  376 ds3231_attach(device_t dev)
  377 {
  378         struct ds3231_softc *sc;
  379 
  380         sc = device_get_softc(dev);
  381         sc->sc_dev = dev;
  382         sc->sc_addr = iicbus_get_addr(dev);
  383         sc->sc_last_c = -1;
  384         sc->sc_year0 = 0;
  385         sc->enum_hook.ich_func = ds3231_start;
  386         sc->enum_hook.ich_arg = dev;
  387 
  388         /*
  389          * We have to wait until interrupts are enabled.  Usually I2C read
  390          * and write only works when the interrupts are available.
  391          */
  392         if (config_intrhook_establish(&sc->enum_hook) != 0)
  393                 return (ENOMEM);
  394 
  395         return (0);
  396 }
  397 
  398 static int
  399 ds3231_detach(device_t dev)
  400 {
  401 
  402         clock_unregister(dev);
  403         return (0);
  404 }
  405 
  406 static void
  407 ds3231_start(void *xdev)
  408 {
  409         device_t dev;
  410         struct ds3231_softc *sc;
  411         struct sysctl_ctx_list *ctx;
  412         struct sysctl_oid *tree_node;
  413         struct sysctl_oid_list *tree;
  414 
  415         dev = (device_t)xdev;
  416         sc = device_get_softc(dev);
  417         ctx = device_get_sysctl_ctx(dev);
  418         tree_node = device_get_sysctl_tree(dev);
  419         tree = SYSCTL_CHILDREN(tree_node);
  420 
  421         config_intrhook_disestablish(&sc->enum_hook);
  422         if (ds3231_ctrl_read(sc) != 0)
  423                 return;
  424         if (ds3231_status_read(sc) != 0)
  425                 return;
  426         /*
  427          * Warn if the clock stopped, but don't restart it until the first
  428          * clock_settime() call.
  429          */
  430         if (sc->sc_status & DS3231_STATUS_OSF) {
  431                 device_printf(sc->sc_dev,
  432                     "WARNING: RTC clock stopped, check the battery.\n");
  433         }
  434 
  435         /*
  436          * Ack any pending alarm interrupts and clear the EOSC bit to ensure the
  437          * clock runs even when on battery power.  Do not give up if these
  438          * writes fail, because a factory-fresh chip is in a special mode that
  439          * disables much of the chip to save battery power, and the only thing
  440          * that gets it out of that mode is writing to the time registers.  In
  441          * these pristine chips, the EOSC and alarm bits are zero already, so
  442          * the first valid write of time will get everything running properly.
  443          */
  444         ds3231_status_write(sc, 1, 1);
  445         ds3231_ctrl_write(sc);
  446 
  447         /* Temperature. */
  448         SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "temperature",
  449             CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
  450             ds3231_temp_sysctl, "IK", "Current temperature");
  451         /* Configuration parameters. */
  452         SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "temp_conv",
  453             CTLFLAG_RW | CTLTYPE_UINT | CTLFLAG_MPSAFE, sc, 0,
  454             ds3231_conv_sysctl, "IU",
  455             "DS3231 start a new temperature converstion");
  456         SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "bbsqw",
  457             CTLFLAG_RW | CTLTYPE_UINT | CTLFLAG_MPSAFE, sc, 0,
  458             ds3231_bbsqw_sysctl, "IU",
  459             "DS3231 battery-backed square-wave output enable");
  460         SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "sqw_freq",
  461             CTLFLAG_RW | CTLTYPE_UINT | CTLFLAG_MPSAFE, sc, 0,
  462             ds3231_sqw_freq_sysctl, "IU",
  463             "DS3231 square-wave output frequency");
  464         SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "sqw_mode",
  465             CTLFLAG_RW | CTLTYPE_STRING | CTLFLAG_MPSAFE, sc, 0,
  466             ds3231_sqw_mode_sysctl, "A", "DS3231 SQW output mode control");
  467         SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "32khz_enable",
  468             CTLFLAG_RW | CTLTYPE_UINT | CTLFLAG_MPSAFE, sc, 0,
  469             ds3231_en32khz_sysctl, "IU", "DS3231 enable the 32kHz output");
  470 
  471         /*
  472          * Register as a clock with 1 second resolution.  Schedule the
  473          * clock_settime() method to be called just after top-of-second;
  474          * resetting the time resets top-of-second in the hardware.
  475          */
  476         clock_register_flags(dev, 1000000, CLOCKF_SETTIME_NO_ADJ);
  477         clock_schedule(dev, 1);
  478 }
  479 
  480 static int
  481 ds3231_gettime(device_t dev, struct timespec *ts)
  482 {
  483         int c, error;
  484         struct bcd_clocktime bct;
  485         struct ds3231_softc *sc;
  486         uint8_t data[7], hourmask;
  487 
  488         sc = device_get_softc(dev);
  489 
  490         /* If the clock halted, we don't have good data. */
  491         if ((error = ds3231_status_read(sc)) != 0) {
  492                 device_printf(dev, "cannot read from RTC.\n");
  493                 return (error);
  494         }
  495         if (sc->sc_status & DS3231_STATUS_OSF)
  496                 return (EINVAL);
  497 
  498         error = iicdev_readfrom(sc->sc_dev, DS3231_SECS, data, sizeof(data),
  499             IIC_INTRWAIT);
  500         if (error != 0) {
  501                 device_printf(dev, "cannot read from RTC.\n");
  502                 return (error);
  503         }
  504 
  505         /* If chip is in AM/PM mode remember that. */
  506         if (data[DS3231_HOUR] & DS3231_HOUR_USE_AMPM) {
  507                 sc->sc_use_ampm = true;
  508                 hourmask = DS3231_HOUR_MASK_12HR;
  509         } else
  510                 hourmask = DS3231_HOUR_MASK_24HR;
  511 
  512         bct.nsec = 0;
  513         bct.sec  = data[DS3231_SECS]  & DS3231_SECS_MASK;
  514         bct.min  = data[DS3231_MINS]  & DS3231_MINS_MASK;
  515         bct.hour = data[DS3231_HOUR]  & hourmask;
  516         bct.day  = data[DS3231_DATE]  & DS3231_DATE_MASK;
  517         bct.mon  = data[DS3231_MONTH] & DS3231_MONTH_MASK;
  518         bct.year = data[DS3231_YEAR]  & DS3231_YEAR_MASK;
  519         bct.ispm = data[DS3231_HOUR]  & DS3231_HOUR_IS_PM;
  520 
  521         /*
  522          * If the century flag has toggled since we last saw it, there has been
  523          * a century rollover.  If this is the first time we're seeing it,
  524          * remember the state so we can preserve its polarity on writes.
  525          */
  526         c = (data[DS3231_MONTH] & DS3231_C_MASK) ? 1 : 0;
  527         if (sc->sc_last_c == -1)
  528                 sc->sc_last_c = c;
  529         else if (c != sc->sc_last_c) {
  530                 sc->sc_year0 += 0x100;
  531                 sc->sc_last_c = c;
  532         }
  533         bct.year |= sc->sc_year0;
  534 
  535         clock_dbgprint_bcd(sc->sc_dev, CLOCK_DBG_READ, &bct); 
  536         return (clock_bcd_to_ts(&bct, ts, sc->sc_use_ampm));
  537 }
  538 
  539 static int
  540 ds3231_settime(device_t dev, struct timespec *ts)
  541 {
  542         int error;
  543         struct bcd_clocktime bct;
  544         struct ds3231_softc *sc;
  545         uint8_t data[7];
  546         uint8_t pmflags;
  547 
  548         sc = device_get_softc(dev);
  549 
  550         /*
  551          * We request a timespec with no resolution-adjustment.  That also
  552          * disables utc adjustment, so apply that ourselves.
  553          */
  554         ts->tv_sec -= utc_offset();
  555         clock_ts_to_bcd(ts, &bct, sc->sc_use_ampm);
  556         clock_dbgprint_bcd(sc->sc_dev, CLOCK_DBG_WRITE, &bct); 
  557 
  558         /* If the chip is in AM/PM mode, adjust hour and set flags as needed. */
  559         if (sc->sc_use_ampm) {
  560                 pmflags = DS3231_HOUR_USE_AMPM;
  561                 if (bct.ispm)
  562                         pmflags |= DS3231_HOUR_IS_PM;
  563         } else
  564                 pmflags = 0;
  565 
  566         data[DS3231_SECS]    = bct.sec;
  567         data[DS3231_MINS]    = bct.min;
  568         data[DS3231_HOUR]    = bct.hour | pmflags;
  569         data[DS3231_DATE]    = bct.day;
  570         data[DS3231_WEEKDAY] = bct.dow + 1;
  571         data[DS3231_MONTH]   = bct.mon;
  572         data[DS3231_YEAR]    = bct.year & 0xff;
  573         if (sc->sc_last_c)
  574                 data[DS3231_MONTH] |= DS3231_C_MASK;
  575 
  576         /* Write the time back to RTC. */
  577         error = iicdev_writeto(dev, DS3231_SECS, data, sizeof(data),
  578             IIC_INTRWAIT);
  579         if (error != 0) {
  580                 device_printf(dev, "cannot write to RTC.\n");
  581                 return (error);
  582         }
  583 
  584         /*
  585          * Unlike most hardware, the osc-was-stopped bit does not clear itself
  586          * after setting the time, it has to be manually written to zero.
  587          */
  588         if (sc->sc_status & DS3231_STATUS_OSF) {
  589                 if ((error = ds3231_status_read(sc)) != 0) {
  590                         device_printf(dev, "cannot read from RTC.\n");
  591                         return (error);
  592                 }
  593                 sc->sc_status &= ~DS3231_STATUS_OSF;
  594                 if ((error = ds3231_status_write(sc, 0, 0)) != 0) {
  595                         device_printf(dev, "cannot write to RTC.\n");
  596                         return (error);
  597                 }
  598         }
  599 
  600         return (error);
  601 }
  602 
  603 static device_method_t ds3231_methods[] = {
  604         DEVMETHOD(device_probe,         ds3231_probe),
  605         DEVMETHOD(device_attach,        ds3231_attach),
  606         DEVMETHOD(device_detach,        ds3231_detach),
  607 
  608         DEVMETHOD(clock_gettime,        ds3231_gettime),
  609         DEVMETHOD(clock_settime,        ds3231_settime),
  610 
  611         DEVMETHOD_END
  612 };
  613 
  614 static driver_t ds3231_driver = {
  615         "ds3231",
  616         ds3231_methods,
  617         sizeof(struct ds3231_softc),
  618 };
  619 
  620 DRIVER_MODULE(ds3231, iicbus, ds3231_driver, NULL, NULL);
  621 MODULE_VERSION(ds3231, 1);
  622 MODULE_DEPEND(ds3231, iicbus, 1, 1, 1);

Cache object: a8c041cf3e3867c2cb04e19599452d42


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.