root/dev/i2c/adm1030.c

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

DEFINITIONS

This source file includes following definitions.
  1. admtmp_match
  2. admtmp_attach
  3. admtmp_refresh

    1 /*      $OpenBSD: adm1030.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 1030 registers */
   27 #define ADM1030_INT_TEMP        0x0a
   28 #define ADM1030_EXT_TEMP        0x0b
   29 #define ADM1030_FAN             0x08
   30 #define ADM1030_FANC            0x20
   31 #define  ADM1024_FANC_VAL(x)    (x >> 6)
   32 
   33 /* Sensors */
   34 #define ADMTMP_INT              0
   35 #define ADMTMP_EXT              1
   36 #define ADMTMP_FAN              2
   37 #define ADMTMP_NUM_SENSORS      3
   38 
   39 struct admtmp_softc {
   40         struct device   sc_dev;
   41         i2c_tag_t       sc_tag;
   42         i2c_addr_t      sc_addr;
   43         int             sc_fanmul;
   44 
   45         struct ksensor  sc_sensor[ADMTMP_NUM_SENSORS];
   46         struct ksensordev sc_sensordev;
   47 };
   48 
   49 int     admtmp_match(struct device *, void *, void *);
   50 void    admtmp_attach(struct device *, struct device *, void *);
   51 void    admtmp_refresh(void *);
   52 
   53 struct cfattach admtmp_ca = {
   54         sizeof(struct admtmp_softc), admtmp_match, admtmp_attach
   55 };
   56 
   57 struct cfdriver admtmp_cd = {
   58         NULL, "admtmp", DV_DULL
   59 };
   60 
   61 int
   62 admtmp_match(struct device *parent, void *match, void *aux)
   63 {
   64         struct i2c_attach_args *ia = aux;
   65 
   66         if (strcmp(ia->ia_name, "adm1030") == 0)
   67                 return (1);
   68         return (0);
   69 }
   70 
   71 void
   72 admtmp_attach(struct device *parent, struct device *self, void *aux)
   73 {
   74         struct admtmp_softc *sc = (struct admtmp_softc *)self;
   75         struct i2c_attach_args *ia = aux;
   76         u_int8_t cmd, data;
   77         int i;
   78 
   79         sc->sc_tag = ia->ia_tag;
   80         sc->sc_addr = ia->ia_addr;
   81 
   82         cmd = ADM1030_FANC;
   83         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
   84             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
   85                 printf(", unable to read fan setting\n");
   86                 return;
   87         }
   88 
   89         sc->sc_fanmul = 11250/8 * (1 << ADM1024_FANC_VAL(data)) * 60;
   90 
   91         /* Initialize sensor data. */
   92         strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
   93             sizeof(sc->sc_sensordev.xname));
   94 
   95         sc->sc_sensor[ADMTMP_INT].type = SENSOR_TEMP;
   96         strlcpy(sc->sc_sensor[ADMTMP_INT].desc, "Internal",
   97             sizeof(sc->sc_sensor[ADMTMP_INT].desc));
   98 
   99         sc->sc_sensor[ADMTMP_EXT].type = SENSOR_TEMP;
  100         strlcpy(sc->sc_sensor[ADMTMP_EXT].desc, "External",
  101             sizeof(sc->sc_sensor[ADMTMP_EXT].desc));
  102 
  103         sc->sc_sensor[ADMTMP_FAN].type = SENSOR_FANRPM;
  104 
  105         if (sensor_task_register(sc, admtmp_refresh, 5) == NULL) {
  106                 printf(", unable to register update task\n");
  107                 return;
  108         }
  109 
  110         for (i = 0; i < ADMTMP_NUM_SENSORS; i++)
  111                 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
  112         sensordev_install(&sc->sc_sensordev);
  113 
  114         printf("\n");
  115 }
  116 
  117 void
  118 admtmp_refresh(void *arg)
  119 {
  120         struct admtmp_softc *sc = arg;
  121         u_int8_t cmd, data;
  122 
  123         iic_acquire_bus(sc->sc_tag, 0);
  124 
  125         cmd = ADM1030_INT_TEMP;
  126         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
  127             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
  128                 sc->sc_sensor[ADMTMP_INT].value = 273150000 + 1000000 * data;
  129 
  130         cmd = ADM1030_EXT_TEMP;
  131         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
  132             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
  133                 sc->sc_sensor[ADMTMP_EXT].value = 273150000 + 1000000 * data;
  134 
  135         cmd = ADM1030_FAN;
  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                 if (data == 0)
  139                         sc->sc_sensor[ADMTMP_FAN].flags |= SENSOR_FINVALID;
  140                 else {
  141                         sc->sc_sensor[ADMTMP_FAN].value =
  142                             sc->sc_fanmul / (2 * (int)data);
  143                         sc->sc_sensor[ADMTMP_FAN].flags &= ~SENSOR_FINVALID;
  144                 }
  145         }
  146 
  147         iic_release_bus(sc->sc_tag, 0);
  148 }

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