LCOV - code coverage report
Current view: top level - dev/i2c - adm1021.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 97 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: adm1021.c,v 1.28 2011/03/10 23:14:30 deraadt 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             : /* ADM 1021 registers */
      27             : #define ADM1021_INT_TEMP        0x00
      28             : #define ADM1021_EXT_TEMP        0x01
      29             : #define ADM1021_STATUS          0x02
      30             : #define  ADM1021_STATUS_INVAL   0x7f
      31             : #define  ADM1021_STATUS_NOEXT   0x40
      32             : #define ADM1021_CONFIG_READ     0x03
      33             : #define ADM1021_CONFIG_WRITE    0x09
      34             : #define  ADM1021_CONFIG_RUN     0x40
      35             : #define ADM1021_COMPANY         0xfe    /* contains 0x41 */
      36             : #define ADM1021_STEPPING        0xff    /* contains 0x3? */
      37             : 
      38             : /* Sensors */
      39             : #define ADMTEMP_EXT             0
      40             : #define ADMTEMP_INT             1
      41             : #define ADMTEMP_NUM_SENSORS     2
      42             : 
      43             : struct admtemp_softc {
      44             :         struct device   sc_dev;
      45             :         i2c_tag_t       sc_tag;
      46             :         i2c_addr_t      sc_addr;
      47             : 
      48             :         struct ksensor  sc_sensor[ADMTEMP_NUM_SENSORS];
      49             :         struct ksensordev sc_sensordev;
      50             :         int             sc_noexternal;
      51             : };
      52             : 
      53             : int     admtemp_match(struct device *, void *, void *);
      54             : void    admtemp_attach(struct device *, struct device *, void *);
      55             : void    admtemp_refresh(void *);
      56             : 
      57             : struct cfattach admtemp_ca = {
      58             :         sizeof(struct admtemp_softc), admtemp_match, admtemp_attach
      59             : };
      60             : 
      61             : struct cfdriver admtemp_cd = {
      62             :         NULL, "admtemp", DV_DULL
      63             : };
      64             : 
      65             : int
      66           0 : admtemp_match(struct device *parent, void *match, void *aux)
      67             : {
      68           0 :         struct i2c_attach_args *ia = aux;
      69             : 
      70           0 :         if (strcmp(ia->ia_name, "adm1021") == 0 ||
      71           0 :             strcmp(ia->ia_name, "adm1023") == 0 ||
      72           0 :             strcmp(ia->ia_name, "adm1032") == 0 ||
      73           0 :             strcmp(ia->ia_name, "g781") == 0 ||
      74           0 :             strcmp(ia->ia_name, "g781-1") == 0 ||
      75           0 :             strcmp(ia->ia_name, "gl523sm") == 0 ||
      76           0 :             strcmp(ia->ia_name, "max1617") == 0 ||
      77           0 :             strcmp(ia->ia_name, "sa56004x") == 0 ||
      78           0 :             strcmp(ia->ia_name, "xeontemp") == 0)
      79           0 :                 return (1);
      80           0 :         return (0);
      81           0 : }
      82             : 
      83             : void
      84           0 : admtemp_attach(struct device *parent, struct device *self, void *aux)
      85             : {
      86           0 :         struct admtemp_softc *sc = (struct admtemp_softc *)self;
      87           0 :         struct i2c_attach_args *ia = aux;
      88           0 :         u_int8_t cmd, data, stat;
      89             :         int xeon = 0, i;
      90             : 
      91           0 :         sc->sc_tag = ia->ia_tag;
      92           0 :         sc->sc_addr = ia->ia_addr;
      93             : 
      94           0 :         if (strcmp(ia->ia_name, "xeontemp") == 0) {
      95           0 :                 printf(": Xeon");
      96             :                 xeon = 1;
      97           0 :         } else
      98           0 :                 printf(": %s", ia->ia_name);
      99             : 
     100           0 :         iic_acquire_bus(sc->sc_tag, 0);
     101           0 :         cmd = ADM1021_CONFIG_READ;
     102           0 :         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     103           0 :             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
     104           0 :                 iic_release_bus(sc->sc_tag, 0);
     105           0 :                 printf(", cannot get control register\n");
     106           0 :                 return;
     107             :         }
     108           0 :         if (data & ADM1021_CONFIG_RUN) {
     109           0 :                 cmd = ADM1021_STATUS;
     110           0 :                 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     111           0 :                     sc->sc_addr, &cmd, sizeof cmd, &stat, sizeof stat, 0)) {
     112           0 :                         iic_release_bus(sc->sc_tag, 0);
     113           0 :                         printf(", cannot read status register\n");
     114           0 :                         return;
     115             :                 }
     116           0 :                 if ((stat & ADM1021_STATUS_INVAL) == ADM1021_STATUS_INVAL) {
     117           0 :                         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     118           0 :                             sc->sc_addr, &cmd, sizeof cmd, &stat, sizeof stat, 0)) {
     119           0 :                                 iic_release_bus(sc->sc_tag, 0);
     120           0 :                                 printf(", cannot read status register\n");
     121           0 :                                 return;
     122             :                         }
     123             :                 }
     124             : 
     125             :                 /* means external is dead */
     126           0 :                 if ((stat & ADM1021_STATUS_INVAL) != ADM1021_STATUS_INVAL &&
     127           0 :                     (stat & ADM1021_STATUS_NOEXT))
     128           0 :                         sc->sc_noexternal = 1;
     129             : 
     130           0 :                 data &= ~ADM1021_CONFIG_RUN;
     131           0 :                 cmd = ADM1021_CONFIG_WRITE;
     132           0 :                 if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
     133           0 :                     sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
     134           0 :                         iic_release_bus(sc->sc_tag, 0);
     135           0 :                         printf(", cannot set control register\n");
     136           0 :                         return;
     137             :                 }
     138             :         }
     139           0 :         iic_release_bus(sc->sc_tag, 0);
     140             : 
     141             :         /* Initialize sensor data. */
     142           0 :         strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
     143             :             sizeof(sc->sc_sensordev.xname));
     144             : 
     145           0 :         sc->sc_sensor[ADMTEMP_EXT].type = SENSOR_TEMP;
     146           0 :         strlcpy(sc->sc_sensor[ADMTEMP_EXT].desc,
     147           0 :             xeon ? "Xeon" : "External",
     148             :             sizeof(sc->sc_sensor[ADMTEMP_EXT].desc));
     149             : 
     150           0 :         sc->sc_sensor[ADMTEMP_INT].type = SENSOR_TEMP;
     151           0 :         strlcpy(sc->sc_sensor[ADMTEMP_INT].desc,
     152           0 :             xeon ? "Xeon" : "Internal",
     153             :             sizeof(sc->sc_sensor[ADMTEMP_INT].desc));
     154             : 
     155           0 :         if (sensor_task_register(sc, admtemp_refresh, 5) == NULL) {
     156           0 :                 printf(", unable to register update task\n");
     157           0 :                 return;
     158             :         }
     159             : 
     160           0 :         for (i = 0; i < (sc->sc_noexternal ? 1 : ADMTEMP_NUM_SENSORS); i++)
     161           0 :                 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
     162           0 :         sensordev_install(&sc->sc_sensordev);
     163             : 
     164           0 :         printf("\n");
     165           0 : }
     166             : 
     167             : void
     168           0 : admtemp_refresh(void *arg)
     169             : {
     170           0 :         struct admtemp_softc *sc = arg;
     171           0 :         u_int8_t cmd;
     172           0 :         int8_t sdata;
     173             : 
     174           0 :         iic_acquire_bus(sc->sc_tag, 0);
     175             : 
     176           0 :         if (sc->sc_noexternal == 0) {
     177           0 :                 cmd = ADM1021_EXT_TEMP;
     178           0 :                 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
     179           0 :                     &cmd, sizeof cmd, &sdata, sizeof sdata, 0) == 0) {
     180           0 :                         if (sdata == 0x7f) {
     181           0 :                                 sc->sc_sensor[ADMTEMP_EXT].flags |= SENSOR_FINVALID;
     182           0 :                         } else {
     183           0 :                                 sc->sc_sensor[ADMTEMP_EXT].value =
     184           0 :                                     273150000 + 1000000 * sdata;
     185           0 :                                 sc->sc_sensor[ADMTEMP_EXT].flags &= ~SENSOR_FINVALID;
     186             :                         }
     187             :                 }
     188             :         } else
     189           0 :                 sc->sc_sensor[ADMTEMP_EXT].flags |= SENSOR_FINVALID;
     190             : 
     191             : 
     192           0 :         cmd = ADM1021_INT_TEMP;
     193           0 :         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
     194           0 :             &cmd, sizeof cmd, &sdata,  sizeof sdata, 0) == 0) {
     195           0 :                 if (sdata == 0x7f) {
     196           0 :                         sc->sc_sensor[ADMTEMP_INT].flags |= SENSOR_FINVALID;
     197           0 :                 } else {
     198           0 :                         sc->sc_sensor[ADMTEMP_INT].value =
     199           0 :                             273150000 + 1000000 * sdata;
     200           0 :                         sc->sc_sensor[ADMTEMP_INT].flags &= ~SENSOR_FINVALID;
     201             :                 }
     202             :         }
     203             : 
     204           0 :         iic_release_bus(sc->sc_tag, 0);
     205           0 : }

Generated by: LCOV version 1.13