davinci_emac: fix for running with dcache enabled
[platform/kernel/u-boot.git] / drivers / hwmon / ds1775.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License as
4  * published by the Free Software Foundation; either version 2 of
5  * the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
15  * MA 02111-1307 USA
16  */
17
18 /*
19  * Dallas Semiconductor's DS1775 Digital Thermometer and Thermostat
20  */
21
22 #include <common.h>
23
24 #include <i2c.h>
25 #include <dtt.h>
26
27 #define DTT_I2C_DEV_CODE        CONFIG_SYS_I2C_DTT_ADDR /* Dallas Semi's DS1775 device code */
28 #define DTT_READ_TEMP           0x0
29 #define DTT_CONFIG              0x1
30 #define DTT_TEMP_HYST           0x2
31 #define DTT_TEMP_OS             0x3
32
33 int dtt_read(int sensor, int reg)
34 {
35         int dlen;
36         uchar data[2];
37
38         /*
39          * Calculate sensor address and command
40          */
41         sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* Calculate addr of ds1775 */
42
43         /*
44          * Prepare to handle 2 byte result
45          */
46         if ((reg == DTT_READ_TEMP) ||
47             (reg == DTT_TEMP_OS) || (reg == DTT_TEMP_HYST))
48                 dlen = 2;
49         else
50                 dlen = 1;
51
52         /*
53          * Now try to read the register
54          */
55         if (i2c_read(sensor, reg, 1, data, dlen) != 0)
56                 return 1;
57
58         /*
59          * Handle 2 byte result
60          */
61         if (dlen == 2)
62                 return ((int)((short)data[1] + (((short)data[0]) << 8)));
63
64         return (int) data[0];
65 }
66
67
68 int dtt_write(int sensor, int reg, int val)
69 {
70         int dlen;
71         uchar data[2];
72
73         /*
74          * Calculate sensor address and register
75          */
76         sensor = DTT_I2C_DEV_CODE + (sensor & 0x07);
77
78         /*
79          * Handle various data sizes
80          */
81         if ((reg == DTT_READ_TEMP) ||
82             (reg == DTT_TEMP_OS) || (reg == DTT_TEMP_HYST)) {
83                 dlen = 2;
84                 data[0] = (char)((val >> 8) & 0xff); /* MSB first */
85                 data[1] = (char)(val & 0xff);
86         } else {
87                 dlen = 1;
88                 data[0] = (char)(val & 0xff);
89         }
90
91         /*
92          * Write value to device
93          */
94         if (i2c_write(sensor, reg, 1, data, dlen) != 0)
95                 return 1;
96
97         return 0;
98 }
99
100
101 int dtt_init_one(int sensor)
102 {
103         int val;
104
105         /*
106          * Setup High Temp
107          */
108         val = ((CONFIG_SYS_DTT_MAX_TEMP * 2) << 7) & 0xff80;
109         if (dtt_write(sensor, DTT_TEMP_OS, val) != 0)
110                 return 1;
111         udelay(50000);                  /* Max 50ms */
112
113         /*
114          * Setup Low Temp - hysteresis
115          */
116         val = (((CONFIG_SYS_DTT_MAX_TEMP - CONFIG_SYS_DTT_HYSTERESIS) * 2) << 7) & 0xff80;
117         if (dtt_write(sensor, DTT_TEMP_HYST, val) != 0)
118                 return 1;
119         udelay(50000);                  /* Max 50ms */
120
121         /*
122          * Setup configuraton register
123          *
124          * Fault Tolerance limits 4, Thermometer resolution bits is 9,
125          * Polarity = Active Low,continuous conversion mode, Thermostat
126          * mode is interrupt mode
127          */
128         val = 0xa;
129         if (dtt_write(sensor, DTT_CONFIG, val) != 0)
130                 return 1;
131         udelay(50000);                  /* Max 50ms */
132
133         return 0;
134 }
135
136 int dtt_get_temp(int sensor)
137 {
138         return (dtt_read(sensor, DTT_READ_TEMP) / 256);
139 }