]> git.sur5r.net Git - u-boot/blob - drivers/hwmon/ds1621.c
Merge branch 'master' of git://www.denx.de/git/u-boot-imx
[u-boot] / drivers / hwmon / ds1621.c
1 /*
2  * (C) Copyright 2001
3  * Erik Theisen,  Wave 7 Optics, etheisen@mindspring.com.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 /*
9  * Dallas Semiconductor's DS1621/1631 Digital Thermometer and Thermostat.
10  */
11
12 #include <common.h>
13 #include <i2c.h>
14 #include <dtt.h>
15
16 /*
17  * Device code
18  */
19 #define DTT_I2C_DEV_CODE        0x48    /* Dallas Semi's DS1621 */
20 #define DTT_READ_TEMP           0xAA
21 #define DTT_READ_COUNTER        0xA8
22 #define DTT_READ_SLOPE          0xA9
23 #define DTT_WRITE_START_CONV    0xEE
24 #define DTT_WRITE_STOP_CONV     0x22
25 #define DTT_TEMP_HIGH           0xA1
26 #define DTT_TEMP_LOW            0xA2
27 #define DTT_CONFIG              0xAC
28
29 /*
30  * Config register bits
31  */
32 #define DTT_CONFIG_1SHOT        0x01
33 #define DTT_CONFIG_POLARITY     0x02
34 #define DTT_CONFIG_R0           0x04    /* ds1631 only */
35 #define DTT_CONFIG_R1           0x08    /* ds1631 only */
36 #define DTT_CONFIG_NVB          0x10
37 #define DTT_CONFIG_TLF          0x20
38 #define DTT_CONFIG_THF          0x40
39 #define DTT_CONFIG_DONE         0x80
40
41
42 int dtt_read(int sensor, int reg)
43 {
44         int dlen;
45         uchar data[2];
46
47         /* Calculate sensor address and command */
48         sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* Calculate addr of ds1621*/
49
50         /* Prepare to handle 2 byte result */
51         switch(reg) {
52         case DTT_READ_TEMP:
53         case DTT_TEMP_HIGH:
54         case DTT_TEMP_LOW:
55                 dlen = 2;
56                 break;
57         default:
58                 dlen = 1;
59         }
60
61         /* Now try to read the register */
62         if (i2c_read(sensor, reg, 1, data, dlen) != 0)
63                 return 1;
64
65         /* Handle 2 byte result */
66         if (dlen == 2)
67                 return (short)((data[0] << 8) | data[1]);
68
69         return (int)data[0];
70 }
71
72
73 int dtt_write(int sensor, int reg, int val)
74 {
75         int dlen;
76         uchar data[2];
77
78         /* Calculate sensor address and register */
79         sensor = DTT_I2C_DEV_CODE + (sensor & 0x07);
80
81         /* Handle various data sizes. */
82         switch(reg) {
83         case DTT_READ_TEMP:
84         case DTT_TEMP_HIGH:
85         case DTT_TEMP_LOW:
86                 dlen = 2;
87                 data[0] = (char)((val >> 8) & 0xff);    /* MSB first */
88                 data[1] = (char)(val & 0xff);
89                 break;
90         case DTT_WRITE_START_CONV:
91         case DTT_WRITE_STOP_CONV:
92                 dlen = 0;
93                 data[0] = (char)0;
94                 data[1] = (char)0;
95                 break;
96         default:
97                 dlen = 1;
98                 data[0] = (char)(val & 0xff);
99         }
100
101         /* Write value to device */
102         if (i2c_write(sensor, reg, 1, data, dlen) != 0)
103                 return 1;
104
105         /* Poll NV memory busy bit in case write was to register stored in EEPROM */
106         while(i2c_reg_read(sensor, DTT_CONFIG) & DTT_CONFIG_NVB)
107                 ;
108
109         return 0;
110 }
111
112
113 int dtt_init_one(int sensor)
114 {
115         int val;
116
117         /* Setup High Temp */
118         val = ((CONFIG_SYS_DTT_MAX_TEMP * 2) << 7) & 0xff80;
119         if (dtt_write(sensor, DTT_TEMP_HIGH, val) != 0)
120                 return 1;
121
122         /* Setup Low Temp - hysteresis */
123         val = (((CONFIG_SYS_DTT_MAX_TEMP - CONFIG_SYS_DTT_HYSTERESIS) * 2) << 7) & 0xff80;
124         if (dtt_write(sensor, DTT_TEMP_LOW, val) != 0)
125                 return 1;
126
127         /*
128          * Setup configuraton register
129          *
130          * Clear THF & TLF, Reserved = 1, Polarity = Active Low, One Shot = YES
131          *
132          * We run in polled mode, since there isn't any way to know if this
133          * lousy device is ready to provide temperature readings on power up.
134          */
135         val = 0x9;
136         if (dtt_write(sensor, DTT_CONFIG, val) != 0)
137                 return 1;
138
139         return 0;
140 }
141
142 int dtt_get_temp(int sensor)
143 {
144         int i;
145
146         /* Start a conversion, may take up to 1 second. */
147         dtt_write(sensor, DTT_WRITE_START_CONV, 0);
148         for (i = 0; i <= 10; i++) {
149                 udelay(100000);
150                 if (dtt_read(sensor, DTT_CONFIG) & DTT_CONFIG_DONE)
151                         break;
152         }
153
154         return (dtt_read(sensor, DTT_READ_TEMP) / 256);
155 }