LCOV - code coverage report
Current view: top level - dev/i2c - ds1631.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 63 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 3 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: ds1631.c,v 1.12 2016/05/12 21:00:23 kettenis 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           0 : maxds_match(struct device *parent, void *match, void *aux)
      61             : {
      62           0 :         struct i2c_attach_args *ia = aux;
      63             : 
      64           0 :         if (strcmp(ia->ia_name, "ds1631") == 0 ||
      65           0 :             strcmp(ia->ia_name, "ds1624") == 0 ||
      66           0 :             strcmp(ia->ia_name, "ds1721") == 0)
      67           0 :                 return (1);
      68           0 :         return (0);
      69           0 : }
      70             : 
      71             : void
      72           0 : maxds_attach(struct device *parent, struct device *self, void *aux)
      73             : {
      74           0 :         struct maxds_softc *sc = (struct maxds_softc *)self;
      75           0 :         struct i2c_attach_args *ia = aux;
      76           0 :         u_int8_t cmd, data;
      77             :         int i;
      78             : 
      79           0 :         printf(": %s", ia->ia_name);
      80             : 
      81           0 :         sc->sc_tag = ia->ia_tag;
      82           0 :         sc->sc_addr = ia->ia_addr;
      83             : 
      84           0 :         iic_acquire_bus(sc->sc_tag, 0);
      85             : 
      86           0 :         cmd = DS1631_CONTROL;
      87           0 :         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
      88           0 :             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) {
      89           0 :                 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           0 :                         data &= ~DS1631_CONTROL_1SHOT;
      95             : 
      96           0 :                         (void) iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
      97           0 :                             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0);
      98             :                         //delay(10 * 1000);
      99           0 :                         printf(", continuous");
     100           0 :                         goto dostart;
     101             :                 }
     102           0 :                 if (data & DS1631_CONTROL_DONE) {
     103             : dostart:
     104           0 :                         cmd = DS1631_START;
     105           0 :                         if (strcmp(ia->ia_name, "ds1624") == 0)
     106           0 :                                 cmd = DS1624_START;
     107           0 :                         (void) iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
     108           0 :                             sc->sc_addr, &cmd, sizeof cmd, NULL, 0, 0);
     109           0 :                         printf(", starting");
     110           0 :                 }
     111             :         } else {
     112           0 :                 iic_release_bus(sc->sc_tag, 0);
     113           0 :                 printf(", fails to respond\n");
     114           0 :                 return;
     115             :         }
     116             : 
     117           0 :         iic_release_bus(sc->sc_tag, 0);
     118             : 
     119             :         /* Initialize sensor data. */
     120           0 :         strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
     121             :             sizeof(sc->sc_sensordev.xname));
     122             : 
     123           0 :         sc->sc_sensor[MAXDS_TEMP].type = SENSOR_TEMP;
     124           0 :         strlcpy(sc->sc_sensor[MAXDS_TEMP].desc, "Internal",
     125             :             sizeof(sc->sc_sensor[MAXDS_TEMP].desc));
     126             : 
     127           0 :         if (sensor_task_register(sc, maxds_refresh, 5) == NULL) {
     128           0 :                 printf(", unable to register update task\n");
     129           0 :                 return;
     130             :         }
     131             : 
     132           0 :         for (i = 0; i < MAXDS_NUM_SENSORS; i++)
     133           0 :                 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
     134           0 :         sensordev_install(&sc->sc_sensordev);
     135             : 
     136           0 :         printf("\n");
     137           0 : }
     138             : 
     139             : void
     140           0 : maxds_refresh(void *arg)
     141             : {
     142           0 :         struct maxds_softc *sc = arg;
     143           0 :         u_int8_t cmd;
     144           0 :         u_int16_t data;
     145             : 
     146           0 :         iic_acquire_bus(sc->sc_tag, 0);
     147             : 
     148           0 :         cmd = DS1631_TEMP;
     149           0 :         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     150           0 :             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) {
     151           0 :                 sc->sc_sensor[MAXDS_TEMP].value = 273150000 +
     152           0 :                     (int)(betoh16(data)) / 8 * 31250;
     153           0 :                 sc->sc_sensor[MAXDS_TEMP].flags &= ~SENSOR_FINVALID;
     154           0 :         } else
     155           0 :                 sc->sc_sensor[MAXDS_TEMP].flags |= SENSOR_FINVALID;
     156             : 
     157           0 :         iic_release_bus(sc->sc_tag, 0);
     158           0 : }

Generated by: LCOV version 1.13