]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/hwmon/lm63.c
Merge branch 'master' of git://git.denx.de/u-boot-nand-flash
[karo-tx-uboot.git] / drivers / hwmon / lm63.c
1 /*
2  * (C) Copyright 2007-2008
3  * Dirk Eibach,  Guntermann & Drunck GmbH, eibach@gdsys.de
4  * based on lm75.c by Bill Hunter
5  *
6  * See file CREDITS for list of people who contributed to this
7  * project.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22  * MA 02111-1307 USA
23  */
24
25 /*
26  * National LM63/LM64 Temperature Sensor
27  * Main difference: LM 64 has -16 Kelvin temperature offset
28  */
29
30 #include <common.h>
31 #include <i2c.h>
32 #include <dtt.h>
33
34 #define DTT_I2C_LM63_ADDR       0x4C    /* National LM63 device */
35
36 #define DTT_READ_TEMP_RMT_MSB   0x01
37 #define DTT_CONFIG              0x03
38 #define DTT_READ_TEMP_RMT_LSB   0x10
39 #define DTT_TACHLIM_LSB         0x48
40 #define DTT_TACHLIM_MSB         0x49
41 #define DTT_FAN_CONFIG          0x4A
42 #define DTT_PWM_FREQ            0x4D
43 #define DTT_PWM_LOOKUP_BASE     0x50
44
45 struct pwm_lookup_entry {
46         u8 temp;
47         u8 pwm;
48 };
49
50 /*
51  * Device code
52  */
53
54 int dtt_read(int sensor, int reg)
55 {
56         int dlen;
57         uchar data[2];
58
59         /*
60          * Calculate sensor address and register.
61          */
62         if (!sensor)
63                 sensor = DTT_I2C_LM63_ADDR;     /* legacy config */
64
65         dlen = 1;
66
67         /*
68          * Now try to read the register.
69          */
70         if (i2c_read(sensor, reg, 1, data, dlen) != 0)
71                 return -1;
72
73         return (int)data[0];
74 }                               /* dtt_read() */
75
76 int dtt_write(int sensor, int reg, int val)
77 {
78         int dlen;
79         uchar data[2];
80
81         /*
82          * Calculate sensor address and register.
83          */
84         if (!sensor)
85                 sensor = DTT_I2C_LM63_ADDR;     /* legacy config */
86
87         dlen = 1;
88         data[0] = (char)(val & 0xff);
89
90         /*
91          * Write value to register.
92          */
93         if (i2c_write(sensor, reg, 1, data, dlen) != 0)
94                 return 1;
95
96         return 0;
97 }                               /* dtt_write() */
98
99 static int is_lm64(int sensor)
100 {
101         return sensor && (sensor != DTT_I2C_LM63_ADDR);
102 }
103
104 int dtt_init_one(int sensor)
105 {
106         int i;
107         int val;
108
109         struct pwm_lookup_entry pwm_lookup[] = CONFIG_DTT_PWM_LOOKUPTABLE;
110
111         /*
112          * Set PWM Frequency to 2.5% resolution
113          */
114         val = 20;
115         if (dtt_write(sensor, DTT_PWM_FREQ, val) != 0)
116                 return 1;
117
118         /*
119          * Set Tachometer Limit
120          */
121         val = CONFIG_DTT_TACH_LIMIT;
122         if (dtt_write(sensor, DTT_TACHLIM_LSB, val & 0xff) != 0)
123                 return 1;
124         if (dtt_write(sensor, DTT_TACHLIM_MSB, (val >> 8) & 0xff) != 0)
125                 return 1;
126
127         /*
128          * Make sure PWM Lookup-Table is writeable
129          */
130         if (dtt_write(sensor, DTT_FAN_CONFIG, 0x20) != 0)
131                 return 1;
132
133         /*
134          * Setup PWM Lookup-Table
135          */
136         for (i = 0; i < ARRAY_SIZE(pwm_lookup); i++) {
137                 int address = DTT_PWM_LOOKUP_BASE + 2 * i;
138                 val = pwm_lookup[i].temp;
139                 if (is_lm64(sensor))
140                         val -= 16;
141                 if (dtt_write(sensor, address, val) != 0)
142                         return 1;
143                 val = dtt_read(sensor, address);
144                 val = pwm_lookup[i].pwm;
145                 if (dtt_write(sensor, address + 1, val) != 0)
146                         return 1;
147         }
148
149         /*
150          * Enable PWM Lookup-Table, PWM Clock 360 kHz, Tachometer Mode 2
151          */
152         val = 0x02;
153         if (dtt_write(sensor, DTT_FAN_CONFIG, val) != 0)
154                 return 1;
155
156         /*
157          * Enable Tach input
158          */
159         val = dtt_read(sensor, DTT_CONFIG) | 0x04;
160         if (dtt_write(sensor, DTT_CONFIG, val) != 0)
161                 return 1;
162
163         return 0;
164 }
165
166 int dtt_get_temp(int sensor)
167 {
168         s16 temp = (dtt_read(sensor, DTT_READ_TEMP_RMT_MSB) << 8)
169             | (dtt_read(sensor, DTT_READ_TEMP_RMT_LSB));
170
171         if (is_lm64(sensor))
172                 temp += 16 << 8;
173
174         /* Ignore LSB for now, U-Boot only prints natural numbers */
175         return temp >> 8;
176 }