root/dev/i2c/ds1631.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. maxds_match
  2. maxds_attach
  3. maxds_refresh

    1 /*      $OpenBSD: ds1631.c,v 1.9 2007/06/24 05:34:35 dlg Exp $  */
    2 
    3 /*
    4  * Copyright (c) 2005 Theo de Raadt
    5  *
    6  * Permission to use, copy, modify, and distribute this software for any
    7  * purpose with or without fee is hereby granted, provided that the above
    8  * copyright notice and this permission notice appear in all copies.
    9  *
   10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   17  */
   18 
   19 #include <sys/param.h>
   20 #include <sys/systm.h>
   21 #include <sys/device.h>
   22 #include <sys/sensors.h>
   23 
   24 #include <dev/i2c/i2cvar.h>
   25 
   26 /* Maxim ds 1631 registers */
   27 #define DS1631_START            0x51
   28 #define DS1624_START            0xee
   29 #define DS1631_TEMP             0xaa
   30 #define DS1631_CONTROL          0xac
   31 #define  DS1631_CONTROL_DONE    0x80
   32 #define  DS1631_CONTROL_1SHOT   0x01
   33 
   34 /* Sensors */
   35 #define MAXDS_TEMP              0
   36 #define MAXDS_NUM_SENSORS       1
   37 
   38 struct maxds_softc {
   39         struct device   sc_dev;
   40         i2c_tag_t       sc_tag;
   41         i2c_addr_t      sc_addr;
   42 
   43         struct ksensor  sc_sensor[MAXDS_NUM_SENSORS];
   44         struct ksensordev sc_sensordev;
   45 };
   46 
   47 int     maxds_match(struct device *, void *, void *);
   48 void    maxds_attach(struct device *, struct device *, void *);
   49 void    maxds_refresh(void *);
   50 
   51 struct cfattach maxds_ca = {
   52         sizeof(struct maxds_softc), maxds_match, maxds_attach
   53 };
   54 
   55 struct cfdriver maxds_cd = {
   56         NULL, "maxds", DV_DULL
   57 };
   58 
   59 int
   60 maxds_match(struct device *parent, void *match, void *aux)
   61 {
   62         struct i2c_attach_args *ia = aux;
   63 
   64         if (strcmp(ia->ia_name, "ds1631") == 0 ||
   65             strcmp(ia->ia_name, "ds1624") == 0 ||
   66             strcmp(ia->ia_name, "ds1721") == 0)
   67                 return (1);
   68         return (0);
   69 }
   70 
   71 void
   72 maxds_attach(struct device *parent, struct device *self, void *aux)
   73 {
   74         struct maxds_softc *sc = (struct maxds_softc *)self;
   75         struct i2c_attach_args *ia = aux;
   76         u_int8_t cmd, data;
   77         int i;
   78 
   79         printf(": %s", ia->ia_name);
   80 
   81         sc->sc_tag = ia->ia_tag;
   82         sc->sc_addr = ia->ia_addr;
   83 
   84         iic_acquire_bus(sc->sc_tag, 0);
   85 
   86         cmd = DS1631_CONTROL;
   87         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
   88             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) {
   89                 if (data & DS1631_CONTROL_1SHOT) {
   90                         /*
   91                          * 1-Shot mode would require us to write every refresh
   92                          * which is stupid.  Put us into continuous mode.
   93                          */
   94                         data &= ~DS1631_CONTROL_1SHOT;
   95 
   96                         (void) iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
   97                             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0);
   98                         //delay(10 * 1000);
   99                         printf(", continuous");
  100                         goto dostart;
  101                 }
  102                 if (data & DS1631_CONTROL_DONE) {
  103 dostart:
  104                         cmd = DS1631_START;
  105                         if (strcmp(ia->ia_name, "ds1624") == 0)
  106                                 cmd = DS1624_START;
  107                         (void) iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
  108                             sc->sc_addr, &cmd, sizeof cmd, NULL, 0, 0);
  109                         printf(", starting");
  110                 }
  111         }
  112 
  113         iic_release_bus(sc->sc_tag, 0);
  114 
  115         /* Initialize sensor data. */
  116         strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
  117             sizeof(sc->sc_sensordev.xname));
  118 
  119         sc->sc_sensor[MAXDS_TEMP].type = SENSOR_TEMP;
  120         strlcpy(sc->sc_sensor[MAXDS_TEMP].desc, "Internal",
  121             sizeof(sc->sc_sensor[MAXDS_TEMP].desc));
  122 
  123         if (sensor_task_register(sc, maxds_refresh, 5) == NULL) {
  124                 printf(", unable to register update task\n");
  125                 return;
  126         }
  127 
  128         for (i = 0; i < MAXDS_NUM_SENSORS; i++)
  129                 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
  130         sensordev_install(&sc->sc_sensordev);
  131 
  132         printf("\n");
  133 }
  134 
  135 void
  136 maxds_refresh(void *arg)
  137 {
  138         struct maxds_softc *sc = arg;
  139         u_int8_t cmd, data[2];
  140 
  141         iic_acquire_bus(sc->sc_tag, 0);
  142 
  143         cmd = DS1631_TEMP;
  144         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
  145             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
  146                 sc->sc_sensor[MAXDS_TEMP].value = 273150000 +
  147                     ((int)((u_int16_t)data[0] << 8 | data[1])) / 8 * 31250;
  148 
  149         iic_release_bus(sc->sc_tag, 0);
  150 }

/* [<][>][^][v][top][bottom][index][help] */