root/dev/i2c/adm1031.c

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

DEFINITIONS

This source file includes following definitions.
  1. admtt_match
  2. admtt_attach
  3. admtt_refresh

    1 /*      $OpenBSD: adm1031.c,v 1.8 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 1031 registers */
   27 #define ADM1031_INT_TEMP        0x0a
   28 #define ADM1031_EXT_TEMP        0x0b
   29 #define ADM1031_EXT2_TEMP       0x0c
   30 #define ADM1031_FAN             0x08
   31 #define ADM1031_FANC            0x20
   32 #define ADM1031_FAN2            0x09
   33 #define ADM1031_FAN2C           0x21
   34 #define  ADM1024_FANC_VAL(x)    (x >> 6)
   35 
   36 /* Sensors */
   37 #define ADMTT_INT               0
   38 #define ADMTT_EXT               1
   39 #define ADMTT_EXT2              2
   40 #define ADMTT_FAN               3
   41 #define ADMTT_FAN2              4
   42 #define ADMTT_NUM_SENSORS       5
   43 
   44 struct admtt_softc {
   45         struct device   sc_dev;
   46         i2c_tag_t       sc_tag;
   47         i2c_addr_t      sc_addr;
   48         int             sc_fanmul;
   49 
   50         struct ksensor  sc_sensor[ADMTT_NUM_SENSORS];
   51         struct ksensordev sc_sensordev;
   52 };
   53 
   54 int     admtt_match(struct device *, void *, void *);
   55 void    admtt_attach(struct device *, struct device *, void *);
   56 void    admtt_refresh(void *);
   57 
   58 struct cfattach admtt_ca = {
   59         sizeof(struct admtt_softc), admtt_match, admtt_attach
   60 };
   61 
   62 struct cfdriver admtt_cd = {
   63         NULL, "admtt", DV_DULL
   64 };
   65 
   66 int
   67 admtt_match(struct device *parent, void *match, void *aux)
   68 {
   69         struct i2c_attach_args *ia = aux;
   70 
   71         if (strcmp(ia->ia_name, "adm1031") == 0)
   72                 return (1);
   73         return (0);
   74 }
   75 
   76 void
   77 admtt_attach(struct device *parent, struct device *self, void *aux)
   78 {
   79         struct admtt_softc *sc = (struct admtt_softc *)self;
   80         struct i2c_attach_args *ia = aux;
   81         u_int8_t cmd, data;
   82         int i;
   83 
   84         sc->sc_tag = ia->ia_tag;
   85         sc->sc_addr = ia->ia_addr;
   86 
   87         cmd = ADM1031_FANC;
   88         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
   89             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
   90                 printf(", unable to read fan setting\n");
   91                 return;
   92         }
   93         sc->sc_fanmul = 11250/8 * (1 << ADM1024_FANC_VAL(data)) * 60;
   94 
   95         /* Initialize sensor data. */
   96         strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
   97             sizeof(sc->sc_sensordev.xname));
   98 
   99         sc->sc_sensor[ADMTT_INT].type = SENSOR_TEMP;
  100         strlcpy(sc->sc_sensor[ADMTT_INT].desc, "Internal",
  101             sizeof(sc->sc_sensor[ADMTT_INT].desc));
  102 
  103         sc->sc_sensor[ADMTT_EXT].type = SENSOR_TEMP;
  104         strlcpy(sc->sc_sensor[ADMTT_EXT].desc, "External",
  105             sizeof(sc->sc_sensor[ADMTT_EXT].desc));
  106 
  107         sc->sc_sensor[ADMTT_EXT2].type = SENSOR_TEMP;
  108         strlcpy(sc->sc_sensor[ADMTT_EXT2].desc, "External",
  109             sizeof(sc->sc_sensor[ADMTT_EXT2].desc));
  110 
  111         sc->sc_sensor[ADMTT_FAN].type = SENSOR_FANRPM;
  112 
  113         sc->sc_sensor[ADMTT_FAN2].type = SENSOR_FANRPM;
  114 
  115         if (sensor_task_register(sc, admtt_refresh, 5) == NULL) {
  116                 printf(", unable to register update task\n");
  117                 return;
  118         }
  119 
  120         for (i = 0; i < ADMTT_NUM_SENSORS; i++)
  121                 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
  122         sensordev_install(&sc->sc_sensordev);
  123 
  124         printf("\n");
  125 }
  126 
  127 void
  128 admtt_refresh(void *arg)
  129 {
  130         struct admtt_softc *sc = arg;
  131         u_int8_t cmd, data;
  132 
  133         iic_acquire_bus(sc->sc_tag, 0);
  134 
  135         cmd = ADM1031_INT_TEMP;
  136         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
  137             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
  138                 sc->sc_sensor[ADMTT_INT].value = 273150000 + 1000000 * data;
  139 
  140         cmd = ADM1031_EXT_TEMP;
  141         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
  142             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
  143                 sc->sc_sensor[ADMTT_EXT].value = 273150000 + 1000000 * data;
  144 
  145         cmd = ADM1031_EXT2_TEMP;
  146         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
  147             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
  148                 sc->sc_sensor[ADMTT_EXT2].value = 273150000 + 1000000 * data;
  149 
  150         cmd = ADM1031_FAN;
  151         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
  152             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) {
  153                 if (data == 0)
  154                         sc->sc_sensor[ADMTT_FAN].flags |= SENSOR_FINVALID;
  155                 else {
  156                         sc->sc_sensor[ADMTT_FAN].value =
  157                             sc->sc_fanmul / (2 * (int)data);
  158                         sc->sc_sensor[ADMTT_FAN].flags &= ~SENSOR_FINVALID;
  159                 }
  160         }
  161 
  162         cmd = ADM1031_FAN2;
  163         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
  164             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) {
  165                 if (data == 0)
  166                         sc->sc_sensor[ADMTT_FAN2].flags |= SENSOR_FINVALID;
  167                 else {
  168                         sc->sc_sensor[ADMTT_FAN2].value =
  169                             sc->sc_fanmul / (2 * (int)data);
  170                         sc->sc_sensor[ADMTT_FAN2].flags &= ~SENSOR_FINVALID;
  171                 }
  172         }
  173 
  174         iic_release_bus(sc->sc_tag, 0);
  175 }

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