File: sens_via686.c

package info (click to toggle)
xmbmon 2.05-6
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd, lenny, squeeze, wheezy
  • size: 752 kB
  • ctags: 907
  • sloc: ansic: 6,089; sh: 2,923; makefile: 141; perl: 87
file content (234 lines) | stat: -rw-r--r-- 5,861 bytes parent folder | download | duplicates (5)
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/*
 * VIA VT82C686A/B hardware monitor chip
 *
 ***************************************************************
 * Before calling these routines, one must call method->Open() *
 * After calling these routines, one must call method->Close() *
 ***************************************************************
 *

VIA
         Chip         Temp    Volt    Fan     SMBus   IOport
        via686a        3       5       2       yes     yes

 *
 * by YRS
 */


#include "pci_pm.h"
#include "sensors.h"

/* external (global) data */
extern int smb_slave;
extern int pm_smb_detected;
extern LM_METHODS method_via, method_smb;
extern int numSMBSlave, canSMBSlave[128];


#define	VIA_ADDR_START		0x50	/*0x50-0x5E*/
#define	VIA_ADDR_END		0x5E

/* temp nr=0,1,2; volt nr=0,...4; fan nr=0,1 */
#define	VIA686_TEMP(nr)	(0x1F + (nr))
#define	VIA686_VOLT(nr)	(0x22 + (nr))
#define	VIA686_FAN(nr)	(0x29 + (nr))
#define	VIA686_FANDIV	0x47

static	int		via686_probe(LM_METHODS *methods);
static	float	via686_temp(LM_METHODS *methods, int no);
static	int		via686_fanrpm(LM_METHODS *methods, int no);
static	float	via686_volt(LM_METHODS *methods, int no);

 SENSOR via686 = {
	"VIA Chip VT82C686A/B",
	via686_probe,
	via686_temp,
	via686_volt,
	via686_fanrpm
};


#define VIA_chkRegNum 5

/* Register checked for probing */
static int chkReg[] = {
	0x40, 0x41, 0x42, 0x43,
	0x44, 0x47, 0x49, 0x4B,
	0x3F, 0x14, 0x1F, 0x20,
	0x21, 0x22, 0x23, 0x24,
	0x25, 0x26, 0x29, 0x2B,
	-1 };


/*
 *  return 0 if not probed
 */
static	int     via686_probe(LM_METHODS *method)
{
	int n, save;

	if (method != &method_via && method != &method_smb)
		return 0;

  	if (pm_smb_detected != VIA686HWM && pm_smb_detected !=  VIA686SMB)
		return 0;

	save = smb_slave;

	if (method == &method_smb) {
		for (n = VIA_ADDR_START; n <= VIA_ADDR_END;) {
			if (!(smb_slave = get_smb_slave(n, VIA_ADDR_END)))
				goto ret0;
			else {
				if (chkReg_Probe(smb_slave, "Probing VIA686A/B chip:\n",
						chkReg, method) >= VIA_chkRegNum)
					goto ret1;
				else
				n = smb_slave + 2;
			}
		}
	} else {
		if (chkReg_Probe(0, "Probing VIA686A/B chip:\n",
					chkReg, method) >= VIA_chkRegNum)
			goto ret1;
	}

ret0:
	smb_slave = save;
	return 0;
ret1:
	if (method == &method_smb)
		kill_smb_slave(smb_slave);
	return 1;
}


static const float via686temp_tab[256] = {\
   .00,   .00,   .00,   .00,   .00,   .00,   .00,   .00,
   .00,   .00,   .00,   .00,   .00,   .00,   .00,-50.00,
-48.00,-46.09,-44.26,-42.52,-40.86,-39.28,-37.78,-36.35,
-34.99,-33.70,-32.47,-31.31,-30.20,-29.15,-28.14,-27.18,
-26.27,-25.39,-24.55,-23.73,-22.95,-22.18,-21.44,-20.70,
-19.98,-19.27,-18.57,-17.87,-17.19,-16.51,-15.85,-15.20,
-14.56,-13.93,-13.32,-12.72,-12.14,-11.58,-11.03,-10.50,
 -9.99, -9.50, -9.03, -8.57, -8.11, -7.67, -7.22, -6.77,
 -6.31, -5.85, -5.37, -4.87, -4.36, -3.81, -3.24, -2.64,
 -2.00, -1.33,  -.65,   .00,   .59,  1.12,  1.60,  2.03,
  2.42,  2.79,  3.12,  3.44,  3.75,  4.05,  4.35,  4.67,
  4.99,  5.34,  5.71,  6.09,  6.49,  6.91,  7.34,  7.78,
  8.23,  8.69,  9.15,  9.62, 10.09, 10.57, 11.04, 11.51,
 11.98, 12.44, 12.90, 13.35, 13.80, 14.24, 14.68, 15.12,
 15.55, 15.99, 16.42, 16.85, 17.27, 17.70, 18.13, 18.56,
 18.99, 19.42, 19.85, 20.29, 20.72, 21.15, 21.59, 22.03,
 22.47, 22.90, 23.34, 23.78, 24.22, 24.66, 25.10, 25.54,
 25.99, 26.43, 26.87, 27.31, 27.75, 28.19, 28.63, 29.07,
 29.51, 29.95, 30.38, 30.82, 31.25, 31.68, 32.11, 32.53,
 32.96, 33.38, 33.80, 34.22, 34.63, 35.05, 35.48, 35.90,
 36.33, 36.76, 37.20, 37.64, 38.09, 38.55, 39.02, 39.50,
 39.99, 40.49, 41.00, 41.52, 42.06, 42.60, 43.15, 43.70,
 44.27, 44.84, 45.41, 45.99, 46.57, 47.16, 47.75, 48.35,
 48.94, 49.54, 50.13, 50.73, 51.33, 51.94, 52.55, 53.16,
 53.78, 54.41, 55.04, 55.68, 56.32, 56.98, 57.64, 58.32,
 59.00, 59.69, 60.40, 61.12, 61.85, 62.60, 63.36, 64.13,
 64.93, 65.73, 66.56, 67.40, 68.26, 69.14, 70.05, 70.97,
 71.91, 72.88, 73.86, 74.88, 75.92, 76.98, 78.08, 79.21,
 80.36, 81.55, 82.78, 84.03, 85.33, 86.66, 88.04, 89.45,
 90.90, 92.40, 93.94, 95.53, 97.16, 98.85,100.58,102.36,
104.19,106.07,108.01,110.00,   .00,   .00,   .00,   .00,
   .00,   .00,   .00,   .00,   .00,   .00,   .00,   .00
};

/*
 *	\retval	0xFFFF	no sensor
 *	\retval	other	temperature
 *  no = 0,1,2,...
 */
static	float	via686_temp(LM_METHODS *method, int no)
{
	if (no < 0 || 2 < no)
		return 0xFFFF;

	return via686temp_tab[method->Read(VIA686_TEMP(no))];
}


/*
 *	\retval	0x0000FFFF	no sensor
 *  no = 0,1,2,...
 */
static	float	via686_volt(LM_METHODS *method, int no)
{
	int n;
	float fac;

	if ( no < 0 || 4 < no )
		return 0xFFFF;

	switch (no) {
		case 0:
		case 1:
			fac = 5.  / 10512.;
			break;
		case 2:
			fac = 5.  /  7884.;
			break;
		case 3:
			fac = 26. / 26280.;
			break;
		case 4:
			fac = 63. / 26280.;
	}

	if ((n = method->Read(VIA686_VOLT(no))) <= 0x40)
		n |= 0x100;

	return (float) (n * 25 + 133) * fac;
}


/*
	Controlling Fan Divisor: CR = 0x47.
	highest two bits for fan2, next two bits for fan1

         7       3     0
        +-+-+-+-+-+-+-+-+     xx = 00,01,10,11  div1fac = 1,2,4,8
        |y y|x x| VolID |     yy = 00,01,10,11  div2fac = 1,2,4,8
        +-+-+-+-+-+-+-+-+    initial values: xx=01, yy=01

 */

/*
 *	\retval	0x0000FFFF	no sensor
 *  no = 0,1,2,...
 *
 *  Clock is 22.5kHz (22,500 x 60 = 1350000 counts/minute)
 */
static	int		via686_fanrpm(LM_METHODS *method, int no)
{
	int r, n;
	static int div[2] = {1,1};

	if (no < 0 || 1 < no)
		return 0xFFFF;

	n = method->Read(VIA686_FANDIV);
	div[0] = (n >> 4) & 0x03;
	div[1] =  n >> 6;

	r = method->Read(VIA686_FAN(no));
	if (r == 0xFF) {
		/* change divisor for the sake of next call ! */
		if (div[no] < 3)
			++(div[no]);
		else
			div[no] = 0;
		r = (n & 0x0F) | (div[0] << 4) | (div[1] << 6);
		method->Write(VIA686_FANDIV, r);
		return 0xFFFF;
	} else if (r == 0) {
		return 0xFFFF;
	}

	return 1350000 / (r * (1 << div[no]));
}