uboot/drivers/hwmon/lm73.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2007-2008
   3 * Larry Johnson, lrj@acm.org
   4 *
   5 * based on dtt/lm75.c which is ...
   6 *
   7 * (C) Copyright 2001
   8 * Bill Hunter,  Wave 7 Optics, williamhunter@mediaone.net
   9 *
  10 * See file CREDITS for list of people who contributed to this
  11 * project.
  12 *
  13 * This program is free software; you can redistribute it and/or
  14 * modify it under the terms of the GNU General Public License as
  15 * published by the Free Software Foundation; either version 2 of
  16 * the License, or (at your option) any later version.
  17 *
  18 * This program is distributed in the hope that it will be useful,
  19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21 * GNU General Public License for more details.
  22 *
  23 * You should have received a copy of the GNU General Public License
  24 * along with this program; if not, write to the Free Software
  25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  26 * MA 02111-1307 USA
  27 */
  28
  29/*
  30 * National Semiconductor LM73 Temperature Sensor
  31 */
  32
  33#include <common.h>
  34#include <i2c.h>
  35#include <dtt.h>
  36
  37/*
  38 * Device code
  39 */
  40#define DTT_I2C_DEV_CODE 0x48   /* National Semi's LM73 device */
  41#define DTT_READ_TEMP           0x0
  42#define DTT_CONFIG              0x1
  43#define DTT_TEMP_HIGH           0x2
  44#define DTT_TEMP_LOW            0x3
  45#define DTT_CONTROL             0x4
  46#define DTT_ID                  0x7
  47
  48int dtt_read(int const sensor, int const reg)
  49{
  50        int dlen;
  51        uint8_t data[2];
  52
  53        /*
  54         * Validate 'reg' param and get register size.
  55         */
  56        switch (reg) {
  57        case DTT_CONFIG:
  58        case DTT_CONTROL:
  59                dlen = 1;
  60                break;
  61        case DTT_READ_TEMP:
  62        case DTT_TEMP_HIGH:
  63        case DTT_TEMP_LOW:
  64        case DTT_ID:
  65                dlen = 2;
  66                break;
  67        default:
  68                return -1;
  69        }
  70        /*
  71         * Try to read the register at the calculated sensor address.
  72         */
  73        if (0 !=
  74            i2c_read(DTT_I2C_DEV_CODE + (sensor & 0x07), reg, 1, data, dlen))
  75                return -1;
  76        /*
  77         * Handle 2 byte result.
  78         */
  79        if (2 == dlen)
  80                return (int)((unsigned)data[0] << 8 | (unsigned)data[1]);
  81
  82        return (int)data[0];
  83} /* dtt_read() */
  84
  85int dtt_write(int const sensor, int const reg, int const val)
  86{
  87        int dlen;
  88        uint8_t data[2];
  89
  90        /*
  91         * Validate 'reg' param and handle register size
  92         */
  93        switch (reg) {
  94        case DTT_CONFIG:
  95        case DTT_CONTROL:
  96                dlen = 1;
  97                data[0] = (uint8_t) val;
  98                break;
  99        case DTT_TEMP_HIGH:
 100        case DTT_TEMP_LOW:
 101                dlen = 2;
 102                data[0] = (uint8_t) (val >> 8); /* MSB first */
 103                data[1] = (uint8_t) val;
 104                break;
 105        default:
 106                return -1;
 107        }
 108        /*
 109         * Write value to register at the calculated sensor address.
 110         */
 111        return 0 != i2c_write(DTT_I2C_DEV_CODE + (sensor & 0x07), reg, 1, data,
 112                              dlen);
 113} /* dtt_write() */
 114
 115static int _dtt_init(int const sensor)
 116{
 117        int val;
 118
 119        /*
 120         * Validate the Identification register
 121         */
 122        if (0x0190 != dtt_read(sensor, DTT_ID))
 123                return -1;
 124        /*
 125         * Setup THIGH (upper-limit) and TLOW (lower-limit) registers
 126         */
 127        val = CONFIG_SYS_DTT_MAX_TEMP << 7;
 128        if (dtt_write(sensor, DTT_TEMP_HIGH, val))
 129                return -1;
 130
 131        val = CONFIG_SYS_DTT_MIN_TEMP << 7;
 132        if (dtt_write(sensor, DTT_TEMP_LOW, val))
 133                return -1;
 134        /*
 135         * Setup configuraton register
 136         */
 137        /* config = alert active low, disabled, and reset */
 138        val = 0x64;
 139        if (dtt_write(sensor, DTT_CONFIG, val))
 140                return -1;
 141        /*
 142         * Setup control/status register
 143         */
 144        /* control = temp resolution 0.25C */
 145        val = 0x00;
 146        if (dtt_write(sensor, DTT_CONTROL, val))
 147                return -1;
 148
 149        dtt_read(sensor, DTT_CONTROL);  /* clear temperature flags */
 150        return 0;
 151} /* _dtt_init() */
 152
 153int dtt_init(void)
 154{
 155        int i;
 156        unsigned char sensors[] = CONFIG_DTT_SENSORS;
 157        const char *const header = "DTT:   ";
 158
 159        for (i = 0; i < sizeof(sensors); i++) {
 160                if (0 != _dtt_init(sensors[i]))
 161                        printf("%s%d FAILED INIT\n", header, i + 1);
 162                else
 163                        printf("%s%d is %i C\n", header, i + 1,
 164                               dtt_get_temp(sensors[i]));
 165        }
 166        return 0;
 167} /* dtt_init() */
 168
 169int dtt_get_temp(int const sensor)
 170{
 171        int const ret = dtt_read(sensor, DTT_READ_TEMP);
 172
 173        if (ret < 0) {
 174                printf("DTT temperature read failed.\n");
 175                return 0;
 176        }
 177        return (int)((int16_t) ret + 0x0040) >> 7;
 178} /* dtt_get_temp() */
 179