LCOV - code coverage report
Current view: top level - dev/i2c - lm93.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 58 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: lm93.c,v 1.8 2007/10/31 20:46:17 cnst Exp $   */
       2             : 
       3             : /*
       4             :  * Copyright (c) 2007 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             : /* LM93 registers */
      27             : #define LM93_CPU1_TEMP          0x50
      28             : #define LM93_CPU2_TEMP          0x51
      29             : #define LM93_INT_TEMP           0x52
      30             : #define LM93_EXT_TEMP           0x53
      31             : #define LM93_IN1_V              0x56
      32             : #define LM93_IN2_V              0x57
      33             : #define LM93_IN3_V              0x58
      34             : #define LM93_IN4_V              0x59
      35             : #define LM93_IN5_V              0x5a
      36             : #define LM93_IN6_V              0x5b
      37             : #define LM93_IN7_V              0x5c
      38             : #define LM93_IN8_V              0x5d
      39             : #define LM93_IN9_V              0x5e
      40             : #define LM93_IN10_V             0x5f
      41             : #define LM93_IN11_V             0x60
      42             : #define LM93_IN12_V             0x61
      43             : #define LM93_IN13_V             0x62
      44             : #define LM93_IN14_V             0x63
      45             : #define LM93_IN15_V             0x64
      46             : #define LM93_IN16_V             0x65
      47             : #define LM93_TACH1L             0x6e
      48             : #define LM93_TACH1H             0x6f
      49             : #define LM93_TACH2L             0x70
      50             : #define LM93_TACH2H             0x71
      51             : #define LM93_TACH3L             0x72
      52             : #define LM93_TACH3H             0x73
      53             : #define LM93_TACH4L             0x74
      54             : #define LM93_TACH4H             0x75
      55             : #define LM93_REVISION           0x3f
      56             : 
      57             : /* Sensors */
      58             : #define LMN_CPU1_TEMP           0
      59             : #define LMN_CPU2_TEMP           1
      60             : #define LMN_INT_TEMP            2
      61             : #define LMN_EXT_TEMP            3
      62             : #define LMN_IN1_V               4
      63             : #define LMN_IN2_V               5
      64             : #define LMN_IN3_V               6
      65             : #define LMN_IN4_V               7
      66             : #define LMN_IN5_V               8
      67             : #define LMN_IN6_V               9
      68             : #define LMN_IN7_V               10
      69             : #define LMN_IN8_V               11
      70             : #define LMN_IN9_V               12
      71             : #define LMN_IN10_V              13
      72             : #define LMN_IN11_V              14
      73             : #define LMN_IN12_V              15
      74             : #define LMN_IN13_V              16
      75             : #define LMN_IN14_V              17
      76             : #define LMN_IN15_V              18
      77             : #define LMN_IN16_V              19
      78             : #define LMN_TACH1               20
      79             : #define LMN_TACH2               21
      80             : #define LMN_TACH3               22
      81             : #define LMN_TACH4               23
      82             : #define LMN_NUM_SENSORS         24
      83             : 
      84             : struct {
      85             :         char            sensor;
      86             :         u_int8_t        cmd;
      87             :         char            *name;
      88             :         u_short         mVscale;
      89             :         u_short         tempscale;              /* else a fan */
      90             : } lmn_worklist[] = {
      91             :         { LMN_CPU1_TEMP, LM93_CPU1_TEMP, "CPU", 0, 1 },
      92             :         { LMN_CPU2_TEMP, LM93_CPU2_TEMP, "CPU", 0, 1 },
      93             :         { LMN_INT_TEMP, LM93_INT_TEMP, "Internal", 0, 1 },
      94             :         { LMN_EXT_TEMP, LM93_EXT_TEMP, "External", 0, 1 },
      95             : 
      96             :         { LMN_IN1_V, LM93_IN1_V, "+12V", 1236*10, 0 },
      97             :         { LMN_IN2_V, LM93_IN2_V, "+12V", 1236*10, 0 },
      98             :         { LMN_IN3_V, LM93_IN3_V, "+12V", 1236*10, 0 },
      99             :         { LMN_IN4_V, LM93_IN4_V, "FSB_Vtt 1.6V", 1600, 0 },
     100             :         { LMN_IN5_V, LM93_IN5_V, "3GIO 2V ", 2000, 0 },
     101             :         { LMN_IN6_V, LM93_IN6_V, "ICH_Core 2V", 2000, 0 },
     102             :         { LMN_IN7_V, LM93_IN7_V, "Vccp 1.6V", 1600, 0 },
     103             :         { LMN_IN8_V, LM93_IN8_V, "Vccp 1.6V", 1600, 0 },
     104             :         { LMN_IN9_V, LM93_IN9_V, "+3.3V", 4400, 0 },
     105             :         { LMN_IN10_V, LM93_IN10_V, "+5V", 6667, 0 },
     106             :         { LMN_IN11_V, LM93_IN11_V, "SCSI_Core 3.3V", 3333, 0 },
     107             :         { LMN_IN12_V, LM93_IN12_V, "Mem_Core 2.6V", 2625, 0 },
     108             :         { LMN_IN13_V, LM93_IN13_V, "Mem_Vtt 1.3V", 1312, 0 },
     109             :         { LMN_IN14_V, LM93_IN14_V, "Gbit_Core 1.3V", 1312, 0 },
     110             :         { LMN_IN15_V, LM93_IN15_V, "-12V", -1236*10, 0 },
     111             :         { LMN_IN16_V, LM93_IN16_V, "+3.3V S/B", 3600, 0 },
     112             : 
     113             :         { LMN_TACH1, LM93_TACH1L, "", 0, 0 },
     114             :         { LMN_TACH2, LM93_TACH2L, "", 0, 0 },
     115             :         { LMN_TACH3, LM93_TACH3L, "", 0, 0 },
     116             :         { LMN_TACH4, LM93_TACH4L, "", 0, 0 }
     117             : };
     118             : 
     119             : struct lmn_softc {
     120             :         struct device sc_dev;
     121             :         i2c_tag_t sc_tag;
     122             :         i2c_addr_t sc_addr;
     123             :         u_int8_t sc_conf;
     124             : 
     125             :         struct ksensor sc_sensor[LMN_NUM_SENSORS];
     126             :         struct ksensordev sc_sensordev;
     127             : };
     128             : 
     129             : int     lmn_match(struct device *, void *, void *);
     130             : void    lmn_attach(struct device *, struct device *, void *);
     131             : 
     132             : void    lmn_refresh(void *);
     133             : 
     134             : struct cfattach lmn_ca = {
     135             :         sizeof(struct lmn_softc), lmn_match, lmn_attach
     136             : };
     137             : 
     138             : struct cfdriver lmn_cd = {
     139             :         NULL, "lmn", DV_DULL
     140             : };
     141             : 
     142             : int
     143           0 : lmn_match(struct device *parent, void *match, void *aux)
     144             : {
     145           0 :         struct i2c_attach_args *ia = aux;
     146             : 
     147           0 :         if (strcmp(ia->ia_name, "lm93") == 0)
     148           0 :                 return (1);
     149           0 :         return (0);
     150           0 : }
     151             : 
     152             : void
     153           0 : lmn_attach(struct device *parent, struct device *self, void *aux)
     154             : {
     155           0 :         struct lmn_softc *sc = (struct lmn_softc *)self;
     156           0 :         struct i2c_attach_args *ia = aux;
     157             :         int i;
     158             : 
     159           0 :         sc->sc_tag = ia->ia_tag;
     160           0 :         sc->sc_addr = ia->ia_addr;
     161             : 
     162           0 :         printf(": %s", ia->ia_name);
     163             : 
     164             :         /* Initialize sensor data. */
     165           0 :         strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
     166             :             sizeof(sc->sc_sensordev.xname));
     167             : 
     168           0 :         if (sensor_task_register(sc, lmn_refresh, 5) == NULL) {
     169           0 :                 printf(", unable to register update task\n");
     170           0 :                 return;
     171             :         }
     172             : 
     173           0 :         for (i = 0; i < LMN_NUM_SENSORS; i++) {
     174           0 :                 if (lmn_worklist[i].tempscale)
     175           0 :                         sc->sc_sensor[i].type = SENSOR_TEMP;
     176           0 :                 else if (lmn_worklist[i].mVscale)
     177           0 :                         sc->sc_sensor[i].type = SENSOR_VOLTS_DC;
     178             :                 else
     179           0 :                         sc->sc_sensor[i].type = SENSOR_FANRPM;
     180           0 :                 strlcpy(sc->sc_sensor[i].desc, lmn_worklist[i].name,
     181             :                     sizeof(sc->sc_sensor[i].desc));
     182             : 
     183           0 :                 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
     184             :         }
     185           0 :         sensordev_install(&sc->sc_sensordev);
     186             : 
     187           0 :         printf("\n");
     188           0 : }
     189             : 
     190             : void
     191           0 : lmn_refresh(void *arg)
     192             : {
     193           0 :         struct lmn_softc *sc = arg;
     194           0 :         u_int8_t cmd, data, data2;
     195             :         u_int16_t fan;
     196             :         int i;
     197             : 
     198           0 :         iic_acquire_bus(sc->sc_tag, 0);
     199             : 
     200           0 :         for (i = 0; i < sizeof lmn_worklist / sizeof(lmn_worklist[0]); i++) {
     201             : 
     202           0 :                 cmd = lmn_worklist[i].cmd;
     203           0 :                 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     204           0 :                     sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
     205           0 :                         sc->sc_sensor[i].flags |= SENSOR_FINVALID;
     206           0 :                         continue;
     207             :                 }
     208             : 
     209           0 :                 sc->sc_sensor[i].flags &= ~SENSOR_FINVALID;
     210           0 :                 if (lmn_worklist[i].tempscale) {
     211           0 :                         if (data == 0x80)
     212           0 :                                 sc->sc_sensor[i].flags |= SENSOR_FINVALID;
     213             :                         else
     214           0 :                                 sc->sc_sensor[i].value =
     215           0 :                                     (int8_t)data * 1000000 + 273150000;
     216           0 :                 } else if (lmn_worklist[i].mVscale) {
     217           0 :                         sc->sc_sensor[i].value = lmn_worklist[i].mVscale *
     218           0 :                             1000 * (u_int)data / 192;
     219           0 :                 } else {
     220           0 :                         cmd = lmn_worklist[i].cmd + 1; /* TACHnH follows TACHnL */
     221           0 :                         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     222           0 :                             sc->sc_addr, &cmd, sizeof cmd, &data2, sizeof data2, 0)) {
     223           0 :                                 sc->sc_sensor[i].flags |= SENSOR_FINVALID;
     224           0 :                                 continue;
     225             :                         }
     226             : 
     227           0 :                         fan = data + (data2 << 8);
     228           0 :                         if (fan == 0 || fan == 0xffff)
     229           0 :                                 sc->sc_sensor[i].flags |= SENSOR_FINVALID;
     230             :                         else
     231           0 :                                 sc->sc_sensor[i].value = (90000 * 60) / fan;
     232             :                 }
     233             :         }
     234             : 
     235           0 :         iic_release_bus(sc->sc_tag, 0);
     236           0 : }

Generated by: LCOV version 1.13