LCOV - code coverage report
Current view: top level - dev/i2c - adm1025.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 126 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: adm1025.c,v 1.25 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             : /* ADM 1025 registers */
      27             : #define ADM1025_V2_5            0x20
      28             : #define ADM1025_Vccp            0x21
      29             : #define ADM1025_V3_3            0x22
      30             : #define ADM1025_V5              0x23
      31             : #define ADM1025_V12             0x24
      32             : #define ADM1025_Vcc             0x25
      33             : #define ADM1025_EXT_TEMP        0x26
      34             : #define ADM1025_INT_TEMP        0x27
      35             : #define ADM1025_STATUS2         0x42
      36             : #define  ADM1025_STATUS2_EXT    0x40
      37             : #define ADM1025_COMPANY         0x3e    /* contains 0x41 */
      38             : #define ADM1025_STEPPING        0x3f    /* contains 0x2? */
      39             : #define ADM1025_CONFIG          0x40
      40             : #define  ADM1025_CONFIG_START   0x01
      41             : #define SMSC47M192_V1_5         0x50
      42             : #define SMSC47M192_V1_8         0x51
      43             : #define SMSC47M192_TEMP2        0x52
      44             : 
      45             : /* Sensors */
      46             : #define ADMTM_INT               0
      47             : #define ADMTM_EXT               1
      48             : #define ADMTM_V2_5              2
      49             : #define ADMTM_Vccp              3
      50             : #define ADMTM_V3_3              4
      51             : #define ADMTM_V5                5
      52             : #define ADMTM_V12               6
      53             : #define ADMTM_Vcc               7
      54             : #define ADMTM_NUM_SENSORS       8
      55             : #define SMSC_V1_5               8
      56             : #define SMSC_V1_8               9
      57             : #define SMSC_TEMP2              10
      58             : #define SMSC_NUM_SENSORS        3
      59             : struct admtm_softc {
      60             :         struct device   sc_dev;
      61             :         i2c_tag_t       sc_tag;
      62             :         i2c_addr_t      sc_addr;
      63             : 
      64             :         struct ksensor  sc_sensor[ADMTM_NUM_SENSORS + SMSC_NUM_SENSORS];
      65             :         struct ksensordev sc_sensordev;
      66             :         int             sc_nsensors;
      67             :         int             sc_model;
      68             : };
      69             : 
      70             : int     admtm_match(struct device *, void *, void *);
      71             : void    admtm_attach(struct device *, struct device *, void *);
      72             : void    admtm_refresh(void *);
      73             : 
      74             : struct cfattach admtm_ca = {
      75             :         sizeof(struct admtm_softc), admtm_match, admtm_attach
      76             : };
      77             : 
      78             : struct cfdriver admtm_cd = {
      79             :         NULL, "admtm", DV_DULL
      80             : };
      81             : 
      82             : int
      83           0 : admtm_match(struct device *parent, void *match, void *aux)
      84             : {
      85           0 :         struct i2c_attach_args *ia = aux;
      86             : 
      87           0 :         if (strcmp(ia->ia_name, "adm1025") == 0 ||
      88           0 :             strcmp(ia->ia_name, "47m192") == 0 ||
      89           0 :             strcmp(ia->ia_name, "ne1619") == 0)
      90           0 :                 return (1);
      91           0 :         return (0);
      92           0 : }
      93             : 
      94             : void
      95           0 : admtm_attach(struct device *parent, struct device *self, void *aux)
      96             : {
      97           0 :         struct admtm_softc *sc = (struct admtm_softc *)self;
      98           0 :         struct i2c_attach_args *ia = aux;
      99           0 :         u_int8_t cmd, data, data2;
     100             :         int i;
     101             : 
     102           0 :         sc->sc_tag = ia->ia_tag;
     103           0 :         sc->sc_addr = ia->ia_addr;
     104             : 
     105           0 :         printf(": %s", ia->ia_name);
     106             : 
     107           0 :         sc->sc_nsensors = ADMTM_NUM_SENSORS;
     108           0 :         sc->sc_model = 1025;
     109           0 :         if (strcmp(ia->ia_name, "47m192") == 0) {
     110           0 :                 sc->sc_nsensors += SMSC_NUM_SENSORS;
     111           0 :                 sc->sc_model = 192;
     112           0 :         }
     113             : 
     114           0 :         iic_acquire_bus(sc->sc_tag, 0);
     115           0 :         cmd = ADM1025_CONFIG;
     116           0 :         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     117           0 :             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
     118           0 :                 iic_release_bus(sc->sc_tag, 0);
     119           0 :                 printf(", cannot get control register\n");
     120           0 :                 return;
     121             :         }
     122             : 
     123           0 :         data2 = data | ADM1025_CONFIG_START;
     124           0 :         if (data != data2) {
     125           0 :                 if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
     126           0 :                     sc->sc_addr, &cmd, sizeof cmd, &data2, sizeof data2, 0)) {
     127           0 :                         iic_release_bus(sc->sc_tag, 0);
     128           0 :                         printf(", cannot set control register\n");
     129           0 :                         return;
     130             :                 }
     131             :         }
     132           0 :         iic_release_bus(sc->sc_tag, 0);
     133             : 
     134             :         /* Initialize sensor data. */
     135           0 :         strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
     136             :             sizeof(sc->sc_sensordev.xname));
     137             : 
     138           0 :         sc->sc_sensor[ADMTM_INT].type = SENSOR_TEMP;
     139           0 :         strlcpy(sc->sc_sensor[ADMTM_INT].desc, "Internal",
     140             :             sizeof(sc->sc_sensor[ADMTM_INT].desc));
     141             : 
     142           0 :         sc->sc_sensor[ADMTM_EXT].type = SENSOR_TEMP;
     143           0 :         strlcpy(sc->sc_sensor[ADMTM_EXT].desc, "External",
     144             :             sizeof(sc->sc_sensor[ADMTM_EXT].desc));
     145             : 
     146           0 :         sc->sc_sensor[ADMTM_V2_5].type = SENSOR_VOLTS_DC;
     147           0 :         strlcpy(sc->sc_sensor[ADMTM_V2_5].desc, "2.5 V",
     148             :             sizeof(sc->sc_sensor[ADMTM_V2_5].desc));
     149             : 
     150           0 :         sc->sc_sensor[ADMTM_Vccp].type = SENSOR_VOLTS_DC;
     151           0 :         strlcpy(sc->sc_sensor[ADMTM_Vccp].desc, "Vccp",
     152             :             sizeof(sc->sc_sensor[ADMTM_Vccp].desc));
     153             : 
     154           0 :         sc->sc_sensor[ADMTM_V3_3].type = SENSOR_VOLTS_DC;
     155           0 :         strlcpy(sc->sc_sensor[ADMTM_V3_3].desc, "3.3 V",
     156             :             sizeof(sc->sc_sensor[ADMTM_V3_3].desc));
     157             : 
     158           0 :         sc->sc_sensor[ADMTM_V5].type = SENSOR_VOLTS_DC;
     159           0 :         strlcpy(sc->sc_sensor[ADMTM_V5].desc, "5 V",
     160             :             sizeof(sc->sc_sensor[ADMTM_V5].desc));
     161             : 
     162           0 :         sc->sc_sensor[ADMTM_V12].type = SENSOR_VOLTS_DC;
     163           0 :         strlcpy(sc->sc_sensor[ADMTM_V12].desc, "12 V",
     164             :             sizeof(sc->sc_sensor[ADMTM_V12].desc));
     165             : 
     166           0 :         sc->sc_sensor[ADMTM_Vcc].type = SENSOR_VOLTS_DC;
     167           0 :         strlcpy(sc->sc_sensor[ADMTM_Vcc].desc, "Vcc",
     168             :             sizeof(sc->sc_sensor[ADMTM_Vcc].desc));
     169             : 
     170           0 :         sc->sc_sensor[SMSC_V1_5].type = SENSOR_VOLTS_DC;
     171           0 :         strlcpy(sc->sc_sensor[SMSC_V1_5].desc, "1.5 V",
     172             :             sizeof(sc->sc_sensor[SMSC_V1_5].desc));
     173             : 
     174           0 :         sc->sc_sensor[SMSC_V1_8].type = SENSOR_VOLTS_DC;
     175           0 :         strlcpy(sc->sc_sensor[SMSC_V1_8].desc, "1.8 V",
     176             :             sizeof(sc->sc_sensor[SMSC_V1_8].desc));
     177             : 
     178           0 :         sc->sc_sensor[SMSC_TEMP2].type = SENSOR_TEMP;
     179           0 :         strlcpy(sc->sc_sensor[SMSC_TEMP2].desc, "External",
     180             :             sizeof(sc->sc_sensor[SMSC_TEMP2].desc));
     181             : 
     182           0 :         if (sensor_task_register(sc, admtm_refresh, 5) == NULL) {
     183           0 :                 printf(", unable to register update task\n");
     184           0 :                 return;
     185             :         }
     186             : 
     187           0 :         for (i = 0; i < sc->sc_nsensors; i++)
     188           0 :                 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
     189           0 :         sensordev_install(&sc->sc_sensordev);
     190             : 
     191           0 :         printf("\n");
     192           0 : }
     193             : 
     194             : void
     195           0 : admtm_refresh(void *arg)
     196             : {
     197           0 :         struct admtm_softc *sc = arg;
     198           0 :         u_int8_t cmd, data;
     199           0 :         int8_t sdata;
     200             : 
     201           0 :         iic_acquire_bus(sc->sc_tag, 0);
     202             : 
     203           0 :         cmd = ADM1025_INT_TEMP;
     204           0 :         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     205           0 :             sc->sc_addr, &cmd, sizeof cmd, &sdata, sizeof sdata, 0) == 0)
     206           0 :                 sc->sc_sensor[ADMTM_INT].value = 273150000 + 1000000 * sdata;
     207             : 
     208           0 :         cmd = ADM1025_EXT_TEMP;
     209           0 :         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     210           0 :             sc->sc_addr, &cmd, sizeof cmd, &sdata, sizeof sdata, 0) == 0)
     211           0 :                 sc->sc_sensor[ADMTM_EXT].value = 273150000 + 1000000 * sdata;
     212             : 
     213           0 :         cmd = ADM1025_STATUS2;
     214           0 :         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     215           0 :             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) {
     216           0 :                 if (data & ADM1025_STATUS2_EXT)
     217           0 :                         sc->sc_sensor[ADMTM_EXT].flags |= SENSOR_FINVALID;
     218             :                 else
     219           0 :                         sc->sc_sensor[ADMTM_EXT].flags &= ~SENSOR_FINVALID;
     220             :         }
     221             : 
     222           0 :         cmd = ADM1025_V2_5;
     223           0 :         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     224           0 :             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
     225           0 :                 sc->sc_sensor[ADMTM_V2_5].value = 2500000 * data / 192;
     226             : 
     227           0 :         cmd = ADM1025_Vccp;
     228           0 :         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     229           0 :             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
     230           0 :                 sc->sc_sensor[ADMTM_Vcc].value = 2249000 * data / 192;
     231             : 
     232           0 :         cmd = ADM1025_V3_3;
     233           0 :         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     234           0 :             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
     235           0 :                 sc->sc_sensor[ADMTM_V3_3].value = 3300000 * data / 192;
     236             : 
     237           0 :         cmd = ADM1025_V5;
     238           0 :         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     239           0 :             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
     240           0 :                 sc->sc_sensor[ADMTM_V5].value = 5000000 * data / 192;
     241             : 
     242           0 :         cmd = ADM1025_V12;
     243           0 :         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     244           0 :             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
     245           0 :                 sc->sc_sensor[ADMTM_V12].value = 12000000 * data / 192;
     246             : 
     247           0 :         cmd = ADM1025_Vcc;
     248           0 :         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     249           0 :             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
     250           0 :                 sc->sc_sensor[ADMTM_Vcc].value = 3300000 * data / 192;
     251             : 
     252           0 :         if (sc->sc_model == 192) {
     253           0 :                 cmd = SMSC47M192_V1_5;
     254           0 :                 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     255           0 :                     sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
     256           0 :                         sc->sc_sensor[SMSC_V1_5].value = 1500000 * data / 192;
     257             : 
     258           0 :                 cmd = SMSC47M192_V1_8;
     259           0 :                 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     260           0 :                     sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
     261           0 :                         sc->sc_sensor[SMSC_V1_8].value = 1800000 * data / 192;
     262             : 
     263           0 :                 cmd = SMSC47M192_TEMP2;
     264           0 :                 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     265           0 :                     sc->sc_addr, &cmd, sizeof cmd, &sdata, sizeof sdata,
     266           0 :                     0) == 0)
     267           0 :                         sc->sc_sensor[SMSC_TEMP2].value = 273150000 + 1000000 * sdata;
     268             : 
     269             :         }
     270             : 
     271           0 :         iic_release_bus(sc->sc_tag, 0);
     272           0 : }

Generated by: LCOV version 1.13