blob: d753e9a72f778d5fbc03233ee382bcf7e2be12db [file] [log] [blame]
wdenk6dd652f2003-06-19 23:40:20 +00001/*
2 * (C) Copyright 2003
3 * Murray Jensen, CSIRO-MIT, Murray.Jensen@csiro.au
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 * Analog Devices's ADM1021
31 * "Low Cost Microprocessor System Temperature Monitor"
32 */
33
34#include <common.h>
35
wdenk6dd652f2003-06-19 23:40:20 +000036#include <i2c.h>
37#include <dtt.h>
38
Michal Simek6ecbb452008-07-11 11:50:53 +020039#define DTT_READ_LOC_VALUE 0x00
40#define DTT_READ_REM_VALUE 0x01
41#define DTT_READ_STATUS 0x02
42#define DTT_READ_CONFIG 0x03
43#define DTT_READ_CONVRATE 0x04
44#define DTT_READ_LOC_HIGHLIM 0x05
45#define DTT_READ_LOC_LOWLIM 0x06
46#define DTT_READ_REM_HIGHLIM 0x07
47#define DTT_READ_REM_LOWLIM 0x08
48#define DTT_READ_DEVID 0xfe
49
50#define DTT_WRITE_CONFIG 0x09
51#define DTT_WRITE_CONVRATE 0x0a
52#define DTT_WRITE_LOC_HIGHLIM 0x0b
53#define DTT_WRITE_LOC_LOWLIM 0x0c
54#define DTT_WRITE_REM_HIGHLIM 0x0d
55#define DTT_WRITE_REM_LOWLIM 0x0e
56#define DTT_WRITE_ONESHOT 0x0f
57
58#define DTT_STATUS_BUSY 0x80 /* 1=ADC Converting */
59#define DTT_STATUS_LHIGH 0x40 /* 1=Local High Temp Limit Tripped */
60#define DTT_STATUS_LLOW 0x20 /* 1=Local Low Temp Limit Tripped */
61#define DTT_STATUS_RHIGH 0x10 /* 1=Remote High Temp Limit Tripped */
62#define DTT_STATUS_RLOW 0x08 /* 1=Remote Low Temp Limit Tripped */
63#define DTT_STATUS_OPEN 0x04 /* 1=Remote Sensor Open-Circuit */
64
65#define DTT_CONFIG_ALERT_MASKED 0x80 /* 0=ALERT Enabled, 1=ALERT Masked */
66#define DTT_CONFIG_STANDBY 0x40 /* 0=Run, 1=Standby */
67
68#define DTT_ADM1021_DEVID 0x41
69
wdenk6dd652f2003-06-19 23:40:20 +000070typedef
71 struct {
72 uint i2c_addr:7; /* 7bit i2c chip address */
73 uint conv_rate:3; /* conversion rate */
74 uint enable_alert:1; /* enable alert output pin */
75 uint enable_local:1; /* enable internal temp sensor */
76 uint max_local:8; /* internal temp maximum */
77 uint min_local:8; /* internal temp minimum */
78 uint enable_remote:1; /* enable remote temp sensor */
79 uint max_remote:8; /* remote temp maximum */
80 uint min_remote:8; /* remote temp minimum */
81 }
82dtt_cfg_t;
83
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020084dtt_cfg_t dttcfg[] = CONFIG_SYS_DTT_ADM1021;
wdenk6dd652f2003-06-19 23:40:20 +000085
86int
87dtt_read (int sensor, int reg)
88{
89 dtt_cfg_t *dcp = &dttcfg[sensor >> 1];
90 uchar data;
91
92 if (i2c_read(dcp->i2c_addr, reg, 1, &data, 1) != 0)
93 return -1;
94
95 return (int)data;
96} /* dtt_read() */
97
98int
99dtt_write (int sensor, int reg, int val)
100{
101 dtt_cfg_t *dcp = &dttcfg[sensor >> 1];
102 uchar data;
103
104 data = (uchar)(val & 0xff);
105
106 if (i2c_write(dcp->i2c_addr, reg, 1, &data, 1) != 0)
107 return 1;
108
109 return 0;
110} /* dtt_write() */
111
112static int
113_dtt_init (int sensor)
114{
115 dtt_cfg_t *dcp = &dttcfg[sensor >> 1];
116 int reg, val;
117
118 if (((sensor & 1) == 0 ? dcp->enable_local : dcp->enable_remote) == 0)
119 return 1; /* sensor is disabled (or rather ignored) */
120
121 /*
122 * Setup High Limit register
123 */
124 if ((sensor & 1) == 0) {
125 reg = DTT_WRITE_LOC_HIGHLIM;
126 val = dcp->max_local;
127 }
128 else {
129 reg = DTT_WRITE_REM_HIGHLIM;
130 val = dcp->max_remote;
131 }
132 if (dtt_write (sensor, reg, val) != 0)
133 return 1;
134
135 /*
136 * Setup Low Limit register
137 */
138 if ((sensor & 1) == 0) {
139 reg = DTT_WRITE_LOC_LOWLIM;
140 val = dcp->min_local;
141 }
142 else {
143 reg = DTT_WRITE_REM_LOWLIM;
144 val = dcp->min_remote;
145 }
146 if (dtt_write (sensor, reg, val) != 0)
147 return 1;
148
149 /* shouldn't hurt if the rest gets done twice */
150
151 /*
152 * Setup Conversion Rate register
153 */
154 if (dtt_write (sensor, DTT_WRITE_CONVRATE, dcp->conv_rate) != 0)
155 return 1;
156
157 /*
158 * Setup configuraton register
159 */
160 val = 0; /* running */
161 if (dcp->enable_alert == 0)
162 val |= DTT_CONFIG_ALERT_MASKED; /* mask ALERT pin */
163 if (dtt_write (sensor, DTT_WRITE_CONFIG, val) != 0)
164 return 1;
165
166 return 0;
167} /* _dtt_init() */
168
169int
170dtt_init (void)
171{
172 int i;
173 unsigned char sensors[] = CONFIG_DTT_SENSORS;
174 const char *const header = "DTT: ";
175
Stefan Roese0dc018e2007-02-20 10:51:26 +0100176 /* switch to correct I2C bus */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200177 I2C_SET_BUS(CONFIG_SYS_DTT_BUS_NUM);
Stefan Roese0dc018e2007-02-20 10:51:26 +0100178
wdenk6dd652f2003-06-19 23:40:20 +0000179 for (i = 0; i < sizeof(sensors); i++) {
Stefan Roese0dc018e2007-02-20 10:51:26 +0100180 if (_dtt_init(sensors[i]) != 0)
181 printf ("%s%d FAILED INIT\n", header, i+1);
182 else
183 printf ("%s%d is %i C\n", header, i+1,
184 dtt_get_temp(sensors[i]));
wdenk6dd652f2003-06-19 23:40:20 +0000185 }
186
187 return (0);
188} /* dtt_init() */
189
190int
191dtt_get_temp (int sensor)
192{
193 signed char val;
194
195 if ((sensor & 1) == 0)
196 val = dtt_read(sensor, DTT_READ_LOC_VALUE);
197 else
198 val = dtt_read(sensor, DTT_READ_REM_VALUE);
199
200 return (int) val;
201} /* dtt_get_temp() */