]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/hwmon/ds1621.c
socfpga: Move board/socfpga_cyclone5 to board/socfpga
[karo-tx-uboot.git] / drivers / hwmon / ds1621.c
1 /*
2  * (C) Copyright 2001
3  * Erik Theisen,  Wave 7 Optics, etheisen@mindspring.com.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 /*
25  * Dallas Semiconductor's DS1621/1631 Digital Thermometer and Thermostat.
26  */
27
28 #include <common.h>
29 #include <i2c.h>
30 #include <dtt.h>
31
32 /*
33  * Device code
34  */
35 #define DTT_I2C_DEV_CODE        0x48    /* Dallas Semi's DS1621 */
36 #define DTT_READ_TEMP           0xAA
37 #define DTT_READ_COUNTER        0xA8
38 #define DTT_READ_SLOPE          0xA9
39 #define DTT_WRITE_START_CONV    0xEE
40 #define DTT_WRITE_STOP_CONV     0x22
41 #define DTT_TEMP_HIGH           0xA1
42 #define DTT_TEMP_LOW            0xA2
43 #define DTT_CONFIG              0xAC
44
45 /*
46  * Config register bits
47  */
48 #define DTT_CONFIG_1SHOT        0x01
49 #define DTT_CONFIG_POLARITY     0x02
50 #define DTT_CONFIG_R0           0x04    /* ds1631 only */
51 #define DTT_CONFIG_R1           0x08    /* ds1631 only */
52 #define DTT_CONFIG_NVB          0x10
53 #define DTT_CONFIG_TLF          0x20
54 #define DTT_CONFIG_THF          0x40
55 #define DTT_CONFIG_DONE         0x80
56
57
58 int dtt_read(int sensor, int reg)
59 {
60         int dlen;
61         uchar data[2];
62
63         /* Calculate sensor address and command */
64         sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* Calculate addr of ds1621*/
65
66         /* Prepare to handle 2 byte result */
67         switch(reg) {
68         case DTT_READ_TEMP:
69         case DTT_TEMP_HIGH:
70         case DTT_TEMP_LOW:
71                 dlen = 2;
72                 break;
73         default:
74                 dlen = 1;
75         }
76
77         /* Now try to read the register */
78         if (i2c_read(sensor, reg, 1, data, dlen) != 0)
79                 return 1;
80
81         /* Handle 2 byte result */
82         if (dlen == 2)
83                 return (short)((data[0] << 8) | data[1]);
84
85         return (int)data[0];
86 }
87
88
89 int dtt_write(int sensor, int reg, int val)
90 {
91         int dlen;
92         uchar data[2];
93
94         /* Calculate sensor address and register */
95         sensor = DTT_I2C_DEV_CODE + (sensor & 0x07);
96
97         /* Handle various data sizes. */
98         switch(reg) {
99         case DTT_READ_TEMP:
100         case DTT_TEMP_HIGH:
101         case DTT_TEMP_LOW:
102                 dlen = 2;
103                 data[0] = (char)((val >> 8) & 0xff);    /* MSB first */
104                 data[1] = (char)(val & 0xff);
105                 break;
106         case DTT_WRITE_START_CONV:
107         case DTT_WRITE_STOP_CONV:
108                 dlen = 0;
109                 data[0] = (char)0;
110                 data[1] = (char)0;
111                 break;
112         default:
113                 dlen = 1;
114                 data[0] = (char)(val & 0xff);
115         }
116
117         /* Write value to device */
118         if (i2c_write(sensor, reg, 1, data, dlen) != 0)
119                 return 1;
120
121         /* Poll NV memory busy bit in case write was to register stored in EEPROM */
122         while(i2c_reg_read(sensor, DTT_CONFIG) & DTT_CONFIG_NVB)
123                 ;
124
125         return 0;
126 }
127
128
129 int dtt_init_one(int sensor)
130 {
131         int val;
132
133         /* Setup High Temp */
134         val = ((CONFIG_SYS_DTT_MAX_TEMP * 2) << 7) & 0xff80;
135         if (dtt_write(sensor, DTT_TEMP_HIGH, val) != 0)
136                 return 1;
137
138         /* Setup Low Temp - hysteresis */
139         val = (((CONFIG_SYS_DTT_MAX_TEMP - CONFIG_SYS_DTT_HYSTERESIS) * 2) << 7) & 0xff80;
140         if (dtt_write(sensor, DTT_TEMP_LOW, val) != 0)
141                 return 1;
142
143         /*
144          * Setup configuraton register
145          *
146          * Clear THF & TLF, Reserved = 1, Polarity = Active Low, One Shot = YES
147          *
148          * We run in polled mode, since there isn't any way to know if this
149          * lousy device is ready to provide temperature readings on power up.
150          */
151         val = 0x9;
152         if (dtt_write(sensor, DTT_CONFIG, val) != 0)
153                 return 1;
154
155         return 0;
156 }
157
158 int dtt_get_temp(int sensor)
159 {
160         int i;
161
162         /* Start a conversion, may take up to 1 second. */
163         dtt_write(sensor, DTT_WRITE_START_CONV, 0);
164         for (i = 0; i <= 10; i++) {
165                 udelay(100000);
166                 if (dtt_read(sensor, DTT_CONFIG) & DTT_CONFIG_DONE)
167                         break;
168         }
169
170         return (dtt_read(sensor, DTT_READ_TEMP) / 256);
171 }