1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28#include <common.h>
29#include <asm/arch/s3c24x0_cpu.h>
30#include <asm/io.h>
31#include <div64.h>
32#include "tsc2000.h"
33
34#include "Pt1000_temp_data.h"
35
36
37#define abs(value) (((value) < 0) ? ((value)*-1) : (value))
38
39
40
41
42
43
44#define MAX_DEVIATION 18
45
46void tsc2000_spi_init(void)
47{
48 struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
49 struct s3c24x0_spi * const spi = s3c24x0_get_base_spi();
50 int i;
51
52
53 gpio->PDCON = (gpio->PDCON & 0xF3FFFF) | 0x040000;
54 gpio->PGCON = (gpio->PGCON & 0x0F3FFF) | 0x008000;
55 gpio->PGCON = (gpio->PGCON & 0x0CFFFF) | 0x020000;
56 gpio->PGCON = (gpio->PGCON & 0x03FFFF) | 0x080000;
57
58 CLR_CS_TOUCH();
59
60 spi->ch[0].SPPRE = 0x1F;
61 spi->ch[0].SPPIN = 0x01;
62 spi->ch[0].SPCON = 0x1A;
63
64
65
66 for (i = 0; i < 10; i++) {
67 spi->ch[0].SPTDAT = 0xFF;
68 }
69 spi_wait_transmit_done();
70}
71
72
73void spi_wait_transmit_done(void)
74{
75 struct s3c24x0_spi * const spi = s3c24x0_get_base_spi();
76
77 while (!(spi->ch[0].SPSTA & 0x01));
78}
79
80
81void tsc2000_write(unsigned short reg, unsigned short data)
82{
83 struct s3c24x0_spi * const spi = s3c24x0_get_base_spi();
84 unsigned int command;
85
86 SET_CS_TOUCH();
87 command = reg;
88 spi->ch[0].SPTDAT = (command & 0xFF00) >> 8;
89 spi_wait_transmit_done();
90 spi->ch[0].SPTDAT = (command & 0x00FF);
91 spi_wait_transmit_done();
92 spi->ch[0].SPTDAT = (data & 0xFF00) >> 8;
93 spi_wait_transmit_done();
94 spi->ch[0].SPTDAT = (data & 0x00FF);
95 spi_wait_transmit_done();
96
97 CLR_CS_TOUCH();
98}
99
100
101unsigned short tsc2000_read (unsigned short reg)
102{
103 unsigned short command, data;
104 struct s3c24x0_spi * const spi = s3c24x0_get_base_spi();
105
106 SET_CS_TOUCH();
107 command = 0x8000 | reg;
108
109 spi->ch[0].SPTDAT = (command & 0xFF00) >> 8;
110 spi_wait_transmit_done();
111 spi->ch[0].SPTDAT = (command & 0x00FF);
112 spi_wait_transmit_done();
113
114 spi->ch[0].SPTDAT = 0xFF;
115 spi_wait_transmit_done();
116 data = spi->ch[0].SPRDAT;
117 spi->ch[0].SPTDAT = 0xFF;
118 spi_wait_transmit_done();
119
120 CLR_CS_TOUCH();
121 return (spi->ch[0].SPRDAT & 0x0FF) | (data << 8);
122}
123
124
125void tsc2000_set_mux (unsigned int channel)
126{
127 struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
128
129 CLR_MUX1_ENABLE; CLR_MUX2_ENABLE;
130 CLR_MUX3_ENABLE; CLR_MUX4_ENABLE;
131 switch (channel) {
132 case 0:
133 CLR_MUX0; CLR_MUX1;
134 SET_MUX1_ENABLE;
135 break;
136 case 1:
137 SET_MUX0; CLR_MUX1;
138 SET_MUX1_ENABLE;
139 break;
140 case 2:
141 CLR_MUX0; SET_MUX1;
142 SET_MUX1_ENABLE;
143 break;
144 case 3:
145 SET_MUX0; SET_MUX1;
146 SET_MUX1_ENABLE;
147 break;
148 case 4:
149 CLR_MUX0; CLR_MUX1;
150 SET_MUX2_ENABLE;
151 break;
152 case 5:
153 SET_MUX0; CLR_MUX1;
154 SET_MUX2_ENABLE;
155 break;
156 case 6:
157 CLR_MUX0; SET_MUX1;
158 SET_MUX2_ENABLE;
159 break;
160 case 7:
161 SET_MUX0; SET_MUX1;
162 SET_MUX2_ENABLE;
163 break;
164 case 8:
165 CLR_MUX0; CLR_MUX1;
166 SET_MUX3_ENABLE;
167 break;
168 case 9:
169 SET_MUX0; CLR_MUX1;
170 SET_MUX3_ENABLE;
171 break;
172 case 10:
173 CLR_MUX0; SET_MUX1;
174 SET_MUX3_ENABLE;
175 break;
176 case 11:
177 SET_MUX0; SET_MUX1;
178 SET_MUX3_ENABLE;
179 break;
180 case 12:
181 CLR_MUX0; CLR_MUX1;
182 SET_MUX4_ENABLE;
183 break;
184 case 13:
185 SET_MUX0; CLR_MUX1;
186 SET_MUX4_ENABLE;
187 break;
188 case 14:
189 CLR_MUX0; SET_MUX1;
190 SET_MUX4_ENABLE;
191 break;
192 case 15:
193 SET_MUX0; SET_MUX1;
194 SET_MUX4_ENABLE;
195 break;
196 default:
197 CLR_MUX0; CLR_MUX1;
198 }
199}
200
201
202void tsc2000_set_range (unsigned int range)
203{
204 struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
205
206 switch (range) {
207 case 1:
208 CLR_SEL_TEMP_V_0; SET_SEL_TEMP_V_1;
209 CLR_SEL_TEMP_V_2; CLR_SEL_TEMP_V_3;
210 break;
211 case 2:
212 CLR_SEL_TEMP_V_0; CLR_SEL_TEMP_V_1;
213 CLR_SEL_TEMP_V_2; SET_SEL_TEMP_V_3;
214 break;
215 case 3:
216 SET_SEL_TEMP_V_0; CLR_SEL_TEMP_V_1;
217 SET_SEL_TEMP_V_2; CLR_SEL_TEMP_V_3;
218 break;
219 }
220}
221
222
223u16 tsc2000_read_channel (unsigned int channel)
224{
225 u16 res;
226
227 tsc2000_set_mux(channel);
228 udelay(20 * TSC2000_DELAY_BASE);
229
230 tsc2000_write(TSC2000_REG_ADC, 0x2036);
231 adc_wait_conversion_done ();
232 res = tsc2000_read(TSC2000_REG_AUX1);
233 return res;
234}
235
236
237s32 tsc2000_contact_temp (void)
238{
239 long adc_pt1000, offset;
240 long u_pt1000;
241 long contact_temp;
242 long temp1, temp2;
243
244 tsc2000_reg_init ();
245 tsc2000_set_range (3);
246
247
248
249
250
251
252
253
254 temp1 = tsc2000_read_channel (14);
255 temp2 = tsc2000_read_channel (14);
256 if (abs(temp2 - temp1) < MAX_DEVIATION)
257 adc_pt1000 = temp2;
258 else {
259 printf ("%s: read adc value (channel 14) exceeded max allowed "
260 "deviation: %d * 0.0276 °C\n",
261 __FUNCTION__, MAX_DEVIATION);
262 printf ("adc value 1: %ld DIGITs\nadc value 2: %ld DIGITs\n",
263 temp1, temp2);
264 adc_pt1000 = tsc2000_read_channel (14);
265 printf ("use (third read) adc value: adc_pt1000 = "
266 "%ld DIGITs\n", adc_pt1000);
267 }
268 debug ("read channel 14 (pt1000 adc value): %ld\n", adc_pt1000);
269
270 temp1 = tsc2000_read_channel (15);
271 temp2 = tsc2000_read_channel (15);
272 if (abs(temp2 - temp1) < MAX_DEVIATION)
273 offset = temp2;
274 else {
275 printf ("%s: read adc value (channel 15) exceeded max allowed "
276 "deviation: %d * 0.0276 °C\n",
277 __FUNCTION__, MAX_DEVIATION);
278 printf ("adc value 1: %ld DIGITs\nadc value 2: %ld DIGITs\n",
279 temp1, temp2);
280 offset = tsc2000_read_channel (15);
281 printf ("use (third read) adc value: offset = %ld DIGITs\n",
282 offset);
283 }
284 debug ("read channel 15 (offset): %ld\n", offset);
285
286
287
288
289
290
291
292
293 u_pt1000 = (101750 * (adc_pt1000 - offset)) / 10;
294 debug ("u_pt1000: %ld\n", u_pt1000);
295
296 if (tsc2000_interpolate(u_pt1000, Pt1000_temp_table,
297 &contact_temp) == -1) {
298 printf ("%s: error interpolating PT1000 vlaue\n",
299 __FUNCTION__);
300 return (-1000);
301 }
302 debug ("contact_temp: %ld\n", contact_temp);
303
304 return contact_temp;
305}
306
307
308void tsc2000_reg_init (void)
309{
310 struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
311
312 tsc2000_write(TSC2000_REG_ADC, 0x2036);
313 tsc2000_write(TSC2000_REG_REF, 0x0011);
314 tsc2000_write(TSC2000_REG_DACCTL, 0x0000);
315
316 CON_MUX0;
317 CON_MUX1;
318
319 CON_MUX1_ENABLE;
320 CON_MUX2_ENABLE;
321 CON_MUX3_ENABLE;
322 CON_MUX4_ENABLE;
323
324 CON_SEL_TEMP_V_0;
325 CON_SEL_TEMP_V_1;
326 CON_SEL_TEMP_V_2;
327 CON_SEL_TEMP_V_3;
328
329 tsc2000_set_mux(0);
330 tsc2000_set_range(0);
331}
332
333
334int tsc2000_interpolate(long value, long data[][2], long *result)
335{
336 int i;
337 unsigned long long val;
338
339
340
341
342 if (data[0][0] < value || data[1][0] > value)
343 return -1;
344
345 i = 1;
346 while (data[i][0] < value)
347 i++;
348
349
350
351
352
353 val = ((unsigned long long)(data[i][1] - data[i-1][1])
354 * (unsigned long long)(value - data[i-1][0]));
355 do_div(val, (data[i][0] - data[i-1][0]));
356 *result = data[i-1][1] + val;
357
358 return 0;
359}
360
361
362void adc_wait_conversion_done(void)
363{
364 while (!(tsc2000_read(TSC2000_REG_ADC) & (1 << 14)));
365}
366