LCOV - code coverage report
Current view: top level - dev/i2c - ad741x.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: ad741x.c,v 1.14 2008/04/17 19:01:48 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             : /* AD741x registers */
      27             : #define AD741X_TEMP     0x00
      28             : #define AD741X_CONFIG   0x01
      29             : #define AD741X_THYST    0x02
      30             : #define AD741X_TOTI     0x03
      31             : #define AD741X_ADC      0x04
      32             : #define AD741X_CONFIG2  0x05
      33             : 
      34             : #define AD741X_CONFMASK 0xe0
      35             : 
      36             : /* Sensors */
      37             : #define ADC_TEMP                0
      38             : #define ADC_ADC0                1
      39             : #define ADC_ADC1                2
      40             : #define ADC_ADC2                3
      41             : #define ADC_ADC3                4
      42             : #define ADC_MAX_SENSORS         5
      43             : 
      44             : struct adc_softc {
      45             :         struct device   sc_dev;
      46             :         i2c_tag_t       sc_tag;
      47             :         i2c_addr_t      sc_addr;
      48             :         int             sc_chip;
      49             :         u_int8_t        sc_config;
      50             : 
      51             :         struct ksensor sc_sensor[ADC_MAX_SENSORS];
      52             :         struct ksensordev sc_sensordev;
      53             : };
      54             : 
      55             : int     adc_match(struct device *, void *, void *);
      56             : void    adc_attach(struct device *, struct device *, void *);
      57             : void    adc_refresh(void *);
      58             : 
      59             : struct cfattach adc_ca = {
      60             :         sizeof(struct adc_softc), adc_match, adc_attach
      61             : };
      62             : 
      63             : struct cfdriver adc_cd = {
      64             :         NULL, "adc", DV_DULL
      65             : };
      66             : 
      67             : int
      68           0 : adc_match(struct device *parent, void *match, void *aux)
      69             : {
      70           0 :         struct i2c_attach_args *ia = aux;
      71             : 
      72           0 :         if (strcmp(ia->ia_name, "ad7417") == 0 ||
      73           0 :             strcmp(ia->ia_name, "ad7418") == 0)
      74           0 :                 return (1);
      75           0 :         return (0);
      76           0 : }
      77             : 
      78             : void
      79           0 : adc_attach(struct device *parent, struct device *self, void *aux)
      80             : {
      81           0 :         struct adc_softc *sc = (struct adc_softc *)self;
      82           0 :         struct i2c_attach_args *ia = aux;
      83           0 :         u_int8_t cmd, data;
      84             :         int nsens = 0, i;
      85             : 
      86           0 :         sc->sc_tag = ia->ia_tag;
      87           0 :         sc->sc_addr = ia->ia_addr;
      88             : 
      89           0 :         printf(": %s", ia->ia_name);
      90             : 
      91           0 :         sc->sc_chip = 0;
      92           0 :         if (strcmp(ia->ia_name, "ad7417") == 0)
      93           0 :                 sc->sc_chip = 7417;
      94           0 :         if (strcmp(ia->ia_name, "ad7418") == 0)
      95           0 :                 sc->sc_chip = 7418;
      96             : 
      97           0 :         if (sc->sc_chip != 0) {
      98           0 :                 cmd = AD741X_CONFIG2;
      99           0 :                 data = 0;
     100           0 :                 if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
     101           0 :                     sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
     102           0 :                         printf(", config2 reset failed\n");
     103           0 :                         return;
     104             :                 }
     105             :         }
     106             : 
     107           0 :         cmd = AD741X_CONFIG;
     108           0 :         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     109           0 :             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
     110           0 :                 printf(", config reset failed\n");
     111           0 :                 return;
     112             :         }
     113           0 :         data &= 0xfe;
     114           0 :         if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
     115           0 :             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
     116           0 :                 printf(", config reset failed\n");
     117           0 :                 return;
     118             :         }
     119           0 :         sc->sc_config = data;
     120             : 
     121             :         /* Initialize sensor data. */
     122           0 :         strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
     123             :             sizeof(sc->sc_sensordev.xname));
     124             : 
     125           0 :         sc->sc_sensor[ADC_TEMP].type = SENSOR_TEMP;
     126           0 :         strlcpy(sc->sc_sensor[ADC_TEMP].desc, "Internal",
     127             :             sizeof(sc->sc_sensor[ADC_TEMP].desc));
     128             :         nsens = 1;
     129             : 
     130           0 :         if (sc->sc_chip == 7417 || sc->sc_chip == 7418) {
     131           0 :                 sc->sc_sensor[ADC_ADC0].type = SENSOR_INTEGER;
     132             :                 nsens++;
     133           0 :         }
     134           0 :         if (sc->sc_chip == 7417 || sc->sc_chip == 7418) {
     135           0 :                 sc->sc_sensor[ADC_ADC1].type = SENSOR_INTEGER;
     136           0 :                 sc->sc_sensor[ADC_ADC2].type = SENSOR_INTEGER;
     137           0 :                 sc->sc_sensor[ADC_ADC3].type = SENSOR_INTEGER;
     138           0 :                 nsens += 3;
     139           0 :         }
     140             : 
     141           0 :         if (sensor_task_register(sc, adc_refresh, 5) == NULL) {
     142           0 :                 printf(", unable to register update task\n");
     143           0 :                 return;
     144             :         }
     145             : 
     146           0 :         sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[0]);
     147           0 :         if (sc->sc_chip == 7417 || sc->sc_chip == 7418)
     148           0 :                 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[1]);
     149           0 :         if (sc->sc_chip == 7417)
     150           0 :                 for (i = 2; i < nsens; i++)
     151           0 :                         sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
     152           0 :         sensordev_install(&sc->sc_sensordev);
     153             : 
     154           0 :         printf("\n");
     155           0 : }
     156             : 
     157             : void
     158           0 : adc_refresh(void *arg)
     159             : {
     160           0 :         struct adc_softc *sc = arg;
     161           0 :         u_int8_t cmd, reg;
     162           0 :         u_int16_t data;
     163             :         int i;
     164             : 
     165           0 :         iic_acquire_bus(sc->sc_tag, 0);
     166             : 
     167           0 :         reg = (sc->sc_config & AD741X_CONFMASK) | (0 << 5);
     168           0 :         if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
     169           0 :             sc->sc_addr, &cmd, sizeof cmd, &reg, sizeof reg, 0))
     170             :                 goto done;
     171           0 :         delay(1000);
     172           0 :         cmd = AD741X_TEMP;
     173           0 :         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     174           0 :             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0))
     175             :                 goto done;
     176           0 :         sc->sc_sensor[ADC_TEMP].value = 273150000 +
     177           0 :             (betoh16(data) >> 6) * 250000;
     178             : 
     179           0 :         if (sc->sc_chip == 0)
     180             :                 goto done;
     181             : 
     182           0 :         if (sc->sc_chip == 7418) {
     183           0 :                 reg = (reg & AD741X_CONFMASK) | (4 << 5);
     184           0 :                 if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
     185           0 :                     sc->sc_addr, &cmd, sizeof cmd, &reg, sizeof reg, 0))
     186             :                         goto done;
     187           0 :                 delay(1000);
     188           0 :                 cmd = AD741X_ADC;
     189           0 :                 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     190           0 :                     sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0))
     191             :                         goto done;
     192           0 :                 sc->sc_sensor[ADC_ADC0].value = betoh16(data) >> 6;
     193           0 :                 goto done;
     194             :         }
     195             : 
     196           0 :         for (i = 0; i < 4; i++) {
     197           0 :                 reg = (reg & AD741X_CONFMASK) | (i << 5);
     198           0 :                 if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
     199           0 :                     sc->sc_addr, &cmd, sizeof cmd, &reg, sizeof reg, 0))
     200             :                         goto done;
     201           0 :                 delay(1000);
     202           0 :                 cmd = AD741X_ADC;
     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             :                         goto done;
     206           0 :                 sc->sc_sensor[ADC_ADC0 + i].value = betoh16(data) >> 6;
     207             :         }
     208             : 
     209             : done:
     210           0 :         iic_release_bus(sc->sc_tag, 0);
     211           0 : }

Generated by: LCOV version 1.13