blob: c1fc42a83321d002f4c971844e956a447a88916b [file] [log] [blame]
Heiko Schocher6dedf3d2006-12-21 16:14:48 +01001/*
2 * (C) Copyright 2006
3 * Heiko Schocher, DENX Software Enginnering <hs@denx.de>
4 *
5 * based on dtt/lm75.c which is ...
6 *
7 * (C) Copyright 2001
8 * Bill Hunter, Wave 7 Optics, williamhunter@mediaone.net
9 *
Wolfgang Denk1a459662013-07-08 09:37:19 +020010 * SPDX-License-Identifier: GPL-2.0+
Heiko Schocher6dedf3d2006-12-21 16:14:48 +010011 */
12
13/*
14 * On Semiconductor's LM81 Temperature Sensor
15 */
16
17#include <common.h>
Heiko Schocher6dedf3d2006-12-21 16:14:48 +010018#include <i2c.h>
19#include <dtt.h>
20
21/*
22 * Device code
23 */
24#define DTT_I2C_DEV_CODE 0x2c /* ON Semi's LM81 device */
Michal Simek6ecbb452008-07-11 11:50:53 +020025#define DTT_READ_TEMP 0x27
26#define DTT_CONFIG_TEMP 0x4b
27#define DTT_TEMP_MAX 0x39
28#define DTT_TEMP_HYST 0x3a
29#define DTT_CONFIG 0x40
Heiko Schocher6dedf3d2006-12-21 16:14:48 +010030
31int dtt_read(int sensor, int reg)
32{
33 int dlen = 1;
34 uchar data[2];
35
36 /*
37 * Calculate sensor address and register.
38 */
39 sensor = DTT_I2C_DEV_CODE + (sensor & 0x03); /* calculate address of lm81 */
40
41 /*
42 * Now try to read the register.
43 */
44 if (i2c_read(sensor, reg, 1, data, dlen) != 0)
45 return -1;
46
47 return (int)data[0];
48} /* dtt_read() */
49
50
51int dtt_write(int sensor, int reg, int val)
52{
53 uchar data;
54
55 /*
56 * Calculate sensor address and register.
57 */
58 sensor = DTT_I2C_DEV_CODE + (sensor & 0x03); /* calculate address of lm81 */
59
60 data = (char)(val & 0xff);
61
62 /*
63 * Write value to register.
64 */
Heiko Schochera443d312007-01-14 13:35:31 +010065 if (i2c_write(sensor, reg, 1, &data, 1) != 0)
Heiko Schocher6dedf3d2006-12-21 16:14:48 +010066 return 1;
67
68 return 0;
69} /* dtt_write() */
70
71#define DTT_MANU 0x3e
72#define DTT_REV 0x3f
Heiko Schochera443d312007-01-14 13:35:31 +010073#define DTT_CONFIG 0x40
Heiko Schocher6dedf3d2006-12-21 16:14:48 +010074#define DTT_ADR 0x48
75
Heiko Schocher780f13a2011-08-01 04:01:43 +000076int dtt_init_one(int sensor)
Heiko Schocher6dedf3d2006-12-21 16:14:48 +010077{
78 int man;
79 int adr;
80 int rev;
81
82 if (dtt_write (sensor, DTT_CONFIG, 0x01) < 0)
83 return 1;
Heiko Schochera443d312007-01-14 13:35:31 +010084 /* The LM81 needs 400ms to get the correct values ... */
85 udelay (400000);
Heiko Schocher6dedf3d2006-12-21 16:14:48 +010086 man = dtt_read (sensor, DTT_MANU);
87 if (man != 0x01)
88 return 1;
89 adr = dtt_read (sensor, DTT_ADR);
90 if (adr < 0)
91 return 1;
92 rev = dtt_read (sensor, DTT_REV);
93 if (adr < 0)
94 return 1;
95
Heiko Schocher3426d652009-08-11 10:37:58 +020096 debug ("DTT: Found LM81@%x Rev: %d\n", adr, rev);
Heiko Schocher6dedf3d2006-12-21 16:14:48 +010097 return 0;
Heiko Schocher780f13a2011-08-01 04:01:43 +000098} /* dtt_init_one() */
Heiko Schocher6dedf3d2006-12-21 16:14:48 +010099
100
Heiko Schocher6dedf3d2006-12-21 16:14:48 +0100101#define TEMP_FROM_REG(temp) \
Wolfgang Denkf11033e2007-01-15 13:41:04 +0100102 ((temp)<256?((((temp)&0x1fe) >> 1) * 10) + ((temp) & 1) * 5: \
103 ((((temp)&0x1fe) >> 1) -255) * 10 - ((temp) & 1) * 5) \
Heiko Schocher6dedf3d2006-12-21 16:14:48 +0100104
105int dtt_get_temp(int sensor)
106{
107 int val = dtt_read (sensor, DTT_READ_TEMP);
108 int tmpcnf = dtt_read (sensor, DTT_CONFIG_TEMP);
109
110 return (TEMP_FROM_REG((val << 1) + ((tmpcnf & 0x80) >> 7))) / 10;
111} /* dtt_get_temp() */