dme1737.c 77.9 KB
Newer Older
J
Juerg Haefliger 已提交
1
/*
2 3 4 5
 * dme1737.c - Driver for the SMSC DME1737, Asus A8000, SMSC SCH311x, SCH5027,
 *             and SCH5127 Super-I/O chips integrated hardware monitoring
 *             features.
 * Copyright (c) 2007, 2008, 2009, 2010 Juerg Haefliger <juergh@gmail.com>
J
Juerg Haefliger 已提交
6
 *
7
 * This driver is an I2C/ISA hybrid, meaning that it uses the I2C bus to access
8
 * the chip registers if a DME1737, A8000, or SCH5027 is found and the ISA bus
9 10 11
 * if a SCH311x or SCH5127 chip is found. Both types of chips have very
 * similar hardware monitoring capabilities but differ in the way they can be
 * accessed.
J
Juerg Haefliger 已提交
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

28 29
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

J
Juerg Haefliger 已提交
30 31 32 33 34
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
35
#include <linux/platform_device.h>
J
Juerg Haefliger 已提交
36 37 38 39 40
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/mutex.h>
41
#include <linux/acpi.h>
42
#include <linux/io.h>
J
Juerg Haefliger 已提交
43

44 45 46
/* ISA device, if found */
static struct platform_device *pdev;

J
Juerg Haefliger 已提交
47
/* Module load parameters */
48
static bool force_start;
J
Juerg Haefliger 已提交
49 50 51
module_param(force_start, bool, 0);
MODULE_PARM_DESC(force_start, "Force the chip to start monitoring inputs");

52 53 54 55
static unsigned short force_id;
module_param(force_id, ushort, 0);
MODULE_PARM_DESC(force_id, "Override the detected device ID");

56
static bool probe_all_addr;
57
module_param(probe_all_addr, bool, 0);
58 59
MODULE_PARM_DESC(probe_all_addr,
		 "Include probing of non-standard LPC addresses");
60

J
Juerg Haefliger 已提交
61
/* Addresses to scan */
62
static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END};
J
Juerg Haefliger 已提交
63

64
enum chips { dme1737, sch5027, sch311x, sch5127 };
J
Juerg Haefliger 已提交
65

66 67
#define	DO_REPORT "Please report to the driver maintainer."

J
Juerg Haefliger 已提交
68 69 70 71 72 73 74 75 76 77 78 79 80 81
/* ---------------------------------------------------------------------
 * Registers
 *
 * The sensors are defined as follows:
 *
 * Voltages                          Temperatures
 * --------                          ------------
 * in0   +5VTR (+5V stdby)           temp1   Remote diode 1
 * in1   Vccp  (proc core)           temp2   Internal temp
 * in2   VCC   (internal +3.3V)      temp3   Remote diode 2
 * in3   +5V
 * in4   +12V
 * in5   VTR   (+3.3V stby)
 * in6   Vbat
82
 * in7   Vtrip (sch5127 only)
J
Juerg Haefliger 已提交
83 84 85
 *
 * --------------------------------------------------------------------- */

86
/* Voltages (in) numbered 0-7 (ix) */
87
#define DME1737_REG_IN(ix)		((ix) < 5 ? 0x20 + (ix) : \
88 89
					 (ix) < 7 ? 0x94 + (ix) : \
						    0x1f)
90
#define DME1737_REG_IN_MIN(ix)		((ix) < 5 ? 0x44 + (ix) * 2 \
J
Juerg Haefliger 已提交
91
						  : 0x91 + (ix) * 2)
92
#define DME1737_REG_IN_MAX(ix)		((ix) < 5 ? 0x45 + (ix) * 2 \
J
Juerg Haefliger 已提交
93 94 95 96 97 98 99 100 101
						  : 0x92 + (ix) * 2)

/* Temperatures (temp) numbered 0-2 (ix) */
#define DME1737_REG_TEMP(ix)		(0x25 + (ix))
#define DME1737_REG_TEMP_MIN(ix)	(0x4e + (ix) * 2)
#define DME1737_REG_TEMP_MAX(ix)	(0x4f + (ix) * 2)
#define DME1737_REG_TEMP_OFFSET(ix)	((ix) == 0 ? 0x1f \
						   : 0x1c + (ix))

102 103
/*
 * Voltage and temperature LSBs
J
Juerg Haefliger 已提交
104 105 106 107 108
 * The LSBs (4 bits each) are stored in 5 registers with the following layouts:
 *    IN_TEMP_LSB(0) = [in5, in6]
 *    IN_TEMP_LSB(1) = [temp3, temp1]
 *    IN_TEMP_LSB(2) = [in4, temp2]
 *    IN_TEMP_LSB(3) = [in3, in0]
109
 *    IN_TEMP_LSB(4) = [in2, in1]
110 111
 *    IN_TEMP_LSB(5) = [res, in7]
 */
J
Juerg Haefliger 已提交
112
#define DME1737_REG_IN_TEMP_LSB(ix)	(0x84 + (ix))
113 114
static const u8 DME1737_REG_IN_LSB[] = {3, 4, 4, 3, 2, 0, 0, 5};
static const u8 DME1737_REG_IN_LSB_SHL[] = {4, 4, 0, 0, 0, 0, 4, 4};
J
Juerg Haefliger 已提交
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
static const u8 DME1737_REG_TEMP_LSB[] = {1, 2, 1};
static const u8 DME1737_REG_TEMP_LSB_SHL[] = {4, 4, 0};

/* Fans numbered 0-5 (ix) */
#define DME1737_REG_FAN(ix)		((ix) < 4 ? 0x28 + (ix) * 2 \
						  : 0xa1 + (ix) * 2)
#define DME1737_REG_FAN_MIN(ix)		((ix) < 4 ? 0x54 + (ix) * 2 \
						  : 0xa5 + (ix) * 2)
#define DME1737_REG_FAN_OPT(ix)		((ix) < 4 ? 0x90 + (ix) \
						  : 0xb2 + (ix))
#define DME1737_REG_FAN_MAX(ix)		(0xb4 + (ix)) /* only for fan[4-5] */

/* PWMs numbered 0-2, 4-5 (ix) */
#define DME1737_REG_PWM(ix)		((ix) < 3 ? 0x30 + (ix) \
						  : 0xa1 + (ix))
#define DME1737_REG_PWM_CONFIG(ix)	(0x5c + (ix)) /* only for pwm[0-2] */
#define DME1737_REG_PWM_MIN(ix)		(0x64 + (ix)) /* only for pwm[0-2] */
#define DME1737_REG_PWM_FREQ(ix)	((ix) < 3 ? 0x5f + (ix) \
						  : 0xa3 + (ix))
134 135
/*
 * The layout of the ramp rate registers is different from the other pwm
J
Juerg Haefliger 已提交
136 137
 * registers. The bits for the 3 PWMs are stored in 2 registers:
 *    PWM_RR(0) = [OFF3, OFF2,  OFF1,  RES,   RR1E, RR1-2, RR1-1, RR1-0]
138 139
 *    PWM_RR(1) = [RR2E, RR2-2, RR2-1, RR2-0, RR3E, RR3-2, RR3-1, RR3-0]
 */
J
Juerg Haefliger 已提交
140 141 142 143 144
#define DME1737_REG_PWM_RR(ix)		(0x62 + (ix)) /* only for pwm[0-2] */

/* Thermal zones 0-2 */
#define DME1737_REG_ZONE_LOW(ix)	(0x67 + (ix))
#define DME1737_REG_ZONE_ABS(ix)	(0x6a + (ix))
145 146
/*
 * The layout of the hysteresis registers is different from the other zone
J
Juerg Haefliger 已提交
147 148
 * registers. The bits for the 3 zones are stored in 2 registers:
 *    ZONE_HYST(0) = [H1-3,  H1-2,  H1-1, H1-0, H2-3, H2-2, H2-1, H2-0]
149 150
 *    ZONE_HYST(1) = [H3-3,  H3-2,  H3-1, H3-0, RES,  RES,  RES,  RES]
 */
J
Juerg Haefliger 已提交
151 152
#define DME1737_REG_ZONE_HYST(ix)	(0x6d + (ix))

153 154
/*
 * Alarm registers and bit mapping
J
Juerg Haefliger 已提交
155
 * The 3 8-bit alarm registers will be concatenated to a single 32-bit
156 157
 * alarm value [0, ALARM3, ALARM2, ALARM1].
 */
J
Juerg Haefliger 已提交
158 159 160
#define DME1737_REG_ALARM1		0x41
#define DME1737_REG_ALARM2		0x42
#define DME1737_REG_ALARM3		0x83
161
static const u8 DME1737_BIT_ALARM_IN[] = {0, 1, 2, 3, 8, 16, 17, 18};
J
Juerg Haefliger 已提交
162 163 164 165
static const u8 DME1737_BIT_ALARM_TEMP[] = {4, 5, 6};
static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23};

/* Miscellaneous registers */
166
#define DME1737_REG_DEVICE		0x3d
J
Juerg Haefliger 已提交
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
#define DME1737_REG_COMPANY		0x3e
#define DME1737_REG_VERSTEP		0x3f
#define DME1737_REG_CONFIG		0x40
#define DME1737_REG_CONFIG2		0x7f
#define DME1737_REG_VID			0x43
#define DME1737_REG_TACH_PWM		0x81

/* ---------------------------------------------------------------------
 * Misc defines
 * --------------------------------------------------------------------- */

/* Chip identification */
#define DME1737_COMPANY_SMSC	0x5c
#define DME1737_VERSTEP		0x88
#define DME1737_VERSTEP_MASK	0xf8
182
#define SCH311X_DEVICE		0x8c
183
#define SCH5027_VERSTEP		0x69
184 185 186 187 188 189 190 191 192 193
#define SCH5127_DEVICE		0x8e

/* Device ID values (global configuration register index 0x20) */
#define DME1737_ID_1	0x77
#define DME1737_ID_2	0x78
#define SCH3112_ID	0x7c
#define SCH3114_ID	0x7d
#define SCH3116_ID	0x7f
#define SCH5027_ID	0x89
#define SCH5127_ID	0x86
194 195 196

/* Length of ISA address segment */
#define DME1737_EXTENT	2
J
Juerg Haefliger 已提交
197

198 199 200 201 202 203 204 205
/* chip-dependent features */
#define HAS_TEMP_OFFSET		(1 << 0)		/* bit 0 */
#define HAS_VID			(1 << 1)		/* bit 1 */
#define HAS_ZONE3		(1 << 2)		/* bit 2 */
#define HAS_ZONE_HYST		(1 << 3)		/* bit 3 */
#define HAS_PWM_MIN		(1 << 4)		/* bit 4 */
#define HAS_FAN(ix)		(1 << ((ix) + 5))	/* bits 5-10 */
#define HAS_PWM(ix)		(1 << ((ix) + 11))	/* bits 11-16 */
206
#define HAS_IN7			(1 << 17)		/* bit 17 */
207

J
Juerg Haefliger 已提交
208 209 210 211 212
/* ---------------------------------------------------------------------
 * Data structures and manipulation thereof
 * --------------------------------------------------------------------- */

struct dme1737_data {
213
	struct i2c_client *client;	/* for I2C devices only */
214
	struct device *hwmon_dev;
215 216
	const char *name;
	unsigned int addr;		/* for ISA devices only */
J
Juerg Haefliger 已提交
217 218 219 220 221

	struct mutex update_lock;
	int valid;			/* !=0 if following fields are valid */
	unsigned long last_update;	/* in jiffies */
	unsigned long last_vbat;	/* in jiffies */
222
	enum chips type;
223
	const int *in_nominal;		/* pointer to IN_NOMINAL array */
J
Juerg Haefliger 已提交
224 225 226

	u8 vid;
	u8 pwm_rr_en;
227
	u32 has_features;
J
Juerg Haefliger 已提交
228 229

	/* Register values */
230 231 232
	u16 in[8];
	u8  in_min[8];
	u8  in_max[8];
J
Juerg Haefliger 已提交
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
	s16 temp[3];
	s8  temp_min[3];
	s8  temp_max[3];
	s8  temp_offset[3];
	u8  config;
	u8  config2;
	u8  vrm;
	u16 fan[6];
	u16 fan_min[6];
	u8  fan_max[2];
	u8  fan_opt[6];
	u8  pwm[6];
	u8  pwm_min[3];
	u8  pwm_config[3];
	u8  pwm_acz[3];
	u8  pwm_freq[6];
	u8  pwm_rr[2];
250 251
	s8  zone_low[3];
	s8  zone_abs[3];
J
Juerg Haefliger 已提交
252 253 254 255 256
	u8  zone_hyst[2];
	u32 alarms;
};

/* Nominal voltage values */
257 258 259 260
static const int IN_NOMINAL_DME1737[] = {5000, 2250, 3300, 5000, 12000, 3300,
					 3300};
static const int IN_NOMINAL_SCH311x[] = {2500, 1500, 3300, 5000, 12000, 3300,
					 3300};
261 262
static const int IN_NOMINAL_SCH5027[] = {5000, 2250, 3300, 1125, 1125, 3300,
					 3300};
263
static const int IN_NOMINAL_SCH5127[] = {2500, 2250, 3300, 1125, 1125, 3300,
264
					 3300, 1500};
265 266
#define IN_NOMINAL(type)	((type) == sch311x ? IN_NOMINAL_SCH311x : \
				 (type) == sch5027 ? IN_NOMINAL_SCH5027 : \
267
				 (type) == sch5127 ? IN_NOMINAL_SCH5127 : \
268
				 IN_NOMINAL_DME1737)
J
Juerg Haefliger 已提交
269

270 271
/*
 * Voltage input
J
Juerg Haefliger 已提交
272
 * Voltage inputs have 16 bits resolution, limit values have 8 bits
273 274
 * resolution.
 */
275
static inline int IN_FROM_REG(int reg, int nominal, int res)
J
Juerg Haefliger 已提交
276
{
277
	return (reg * nominal + (3 << (res - 3))) / (3 << (res - 2));
J
Juerg Haefliger 已提交
278 279
}

280
static inline int IN_TO_REG(long val, int nominal)
J
Juerg Haefliger 已提交
281
{
282
	return clamp_val((val * 192 + nominal / 2) / nominal, 0, 255);
J
Juerg Haefliger 已提交
283 284
}

285 286
/*
 * Temperature input
J
Juerg Haefliger 已提交
287 288
 * The register values represent temperatures in 2's complement notation from
 * -127 degrees C to +127 degrees C. Temp inputs have 16 bits resolution, limit
289 290
 * values have 8 bits resolution.
 */
J
Juerg Haefliger 已提交
291 292 293 294 295
static inline int TEMP_FROM_REG(int reg, int res)
{
	return (reg * 1000) >> (res - 8);
}

296
static inline int TEMP_TO_REG(long val)
J
Juerg Haefliger 已提交
297
{
298
	return clamp_val((val < 0 ? val - 500 : val + 500) / 1000, -128, 127);
J
Juerg Haefliger 已提交
299 300 301 302 303 304 305 306 307 308 309 310
}

/* Temperature range */
static const int TEMP_RANGE[] = {2000, 2500, 3333, 4000, 5000, 6666, 8000,
				 10000, 13333, 16000, 20000, 26666, 32000,
				 40000, 53333, 80000};

static inline int TEMP_RANGE_FROM_REG(int reg)
{
	return TEMP_RANGE[(reg >> 4) & 0x0f];
}

311
static int TEMP_RANGE_TO_REG(long val, int reg)
J
Juerg Haefliger 已提交
312 313 314 315
{
	int i;

	for (i = 15; i > 0; i--) {
316
		if (val > (TEMP_RANGE[i] + TEMP_RANGE[i - 1] + 1) / 2)
J
Juerg Haefliger 已提交
317 318 319 320 321 322
			break;
	}

	return (reg & 0x0f) | (i << 4);
}

323 324
/*
 * Temperature hysteresis
J
Juerg Haefliger 已提交
325 326
 * Register layout:
 *    reg[0] = [H1-3, H1-2, H1-1, H1-0, H2-3, H2-2, H2-1, H2-0]
327 328
 *    reg[1] = [H3-3, H3-2, H3-1, H3-0, xxxx, xxxx, xxxx, xxxx]
 */
J
Juerg Haefliger 已提交
329 330 331 332 333
static inline int TEMP_HYST_FROM_REG(int reg, int ix)
{
	return (((ix == 1) ? reg : reg >> 4) & 0x0f) * 1000;
}

334
static inline int TEMP_HYST_TO_REG(long val, int ix, int reg)
J
Juerg Haefliger 已提交
335
{
336
	int hyst = clamp_val((val + 500) / 1000, 0, 15);
J
Juerg Haefliger 已提交
337 338 339 340 341 342 343

	return (ix == 1) ? (reg & 0xf0) | hyst : (reg & 0x0f) | (hyst << 4);
}

/* Fan input RPM */
static inline int FAN_FROM_REG(int reg, int tpc)
{
344
	if (tpc)
345
		return tpc * reg;
346
	else
347
		return (reg == 0 || reg == 0xffff) ? 0 : 90000 * 60 / reg;
J
Juerg Haefliger 已提交
348 349
}

350
static inline int FAN_TO_REG(long val, int tpc)
J
Juerg Haefliger 已提交
351
{
352
	if (tpc) {
353
		return clamp_val(val / tpc, 0, 0xffff);
354 355
	} else {
		return (val <= 0) ? 0xffff :
356
			clamp_val(90000 * 60 / val, 0, 0xfffe);
357
	}
J
Juerg Haefliger 已提交
358 359
}

360 361
/*
 * Fan TPC (tach pulse count)
J
Juerg Haefliger 已提交
362
 * Converts a register value to a TPC multiplier or returns 0 if the tachometer
363 364
 * is configured in legacy (non-tpc) mode
 */
J
Juerg Haefliger 已提交
365 366 367 368 369
static inline int FAN_TPC_FROM_REG(int reg)
{
	return (reg & 0x20) ? 0 : 60 >> (reg & 0x03);
}

370 371
/*
 * Fan type
J
Juerg Haefliger 已提交
372
 * The type of a fan is expressed in number of pulses-per-revolution that it
373 374
 * emits
 */
J
Juerg Haefliger 已提交
375 376 377 378 379 380 381
static inline int FAN_TYPE_FROM_REG(int reg)
{
	int edge = (reg >> 1) & 0x03;

	return (edge > 0) ? 1 << (edge - 1) : 0;
}

382
static inline int FAN_TYPE_TO_REG(long val, int reg)
J
Juerg Haefliger 已提交
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
{
	int edge = (val == 4) ? 3 : val;

	return (reg & 0xf9) | (edge << 1);
}

/* Fan max RPM */
static const int FAN_MAX[] = {0x54, 0x38, 0x2a, 0x21, 0x1c, 0x18, 0x15, 0x12,
			      0x11, 0x0f, 0x0e};

static int FAN_MAX_FROM_REG(int reg)
{
	int i;

	for (i = 10; i > 0; i--) {
398
		if (reg == FAN_MAX[i])
J
Juerg Haefliger 已提交
399 400 401 402 403 404
			break;
	}

	return 1000 + i * 500;
}

405
static int FAN_MAX_TO_REG(long val)
J
Juerg Haefliger 已提交
406 407 408 409
{
	int i;

	for (i = 10; i > 0; i--) {
410
		if (val > (1000 + (i - 1) * 500))
J
Juerg Haefliger 已提交
411 412 413 414 415 416
			break;
	}

	return FAN_MAX[i];
}

417 418
/*
 * PWM enable
J
Juerg Haefliger 已提交
419 420 421 422 423 424 425 426
 * Register to enable mapping:
 * 000:  2  fan on zone 1 auto
 * 001:  2  fan on zone 2 auto
 * 010:  2  fan on zone 3 auto
 * 011:  0  fan full on
 * 100: -1  fan disabled
 * 101:  2  fan on hottest of zones 2,3 auto
 * 110:  2  fan on hottest of zones 1,2,3 auto
427 428
 * 111:  1  fan in manual mode
 */
J
Juerg Haefliger 已提交
429 430 431 432 433 434 435 436 437 438 439 440 441 442
static inline int PWM_EN_FROM_REG(int reg)
{
	static const int en[] = {2, 2, 2, 0, -1, 2, 2, 1};

	return en[(reg >> 5) & 0x07];
}

static inline int PWM_EN_TO_REG(int val, int reg)
{
	int en = (val == 1) ? 7 : 3;

	return (reg & 0x1f) | ((en & 0x07) << 5);
}

443 444
/*
 * PWM auto channels zone
J
Juerg Haefliger 已提交
445 446 447 448 449 450 451 452 453
 * Register to auto channels zone mapping (ACZ is a bitfield with bit x
 * corresponding to zone x+1):
 * 000: 001  fan on zone 1 auto
 * 001: 010  fan on zone 2 auto
 * 010: 100  fan on zone 3 auto
 * 011: 000  fan full on
 * 100: 000  fan disabled
 * 101: 110  fan on hottest of zones 2,3 auto
 * 110: 111  fan on hottest of zones 1,2,3 auto
454 455
 * 111: 000  fan in manual mode
 */
J
Juerg Haefliger 已提交
456 457 458 459 460 461 462
static inline int PWM_ACZ_FROM_REG(int reg)
{
	static const int acz[] = {1, 2, 4, 0, 0, 6, 7, 0};

	return acz[(reg >> 5) & 0x07];
}

463
static inline int PWM_ACZ_TO_REG(long val, int reg)
J
Juerg Haefliger 已提交
464 465 466 467 468 469 470 471 472 473 474 475 476 477 478
{
	int acz = (val == 4) ? 2 : val - 1;

	return (reg & 0x1f) | ((acz & 0x07) << 5);
}

/* PWM frequency */
static const int PWM_FREQ[] = {11, 15, 22, 29, 35, 44, 59, 88,
			       15000, 20000, 30000, 25000, 0, 0, 0, 0};

static inline int PWM_FREQ_FROM_REG(int reg)
{
	return PWM_FREQ[reg & 0x0f];
}

479
static int PWM_FREQ_TO_REG(long val, int reg)
J
Juerg Haefliger 已提交
480 481 482 483 484 485 486 487 488 489
{
	int i;

	/* the first two cases are special - stupid chip design! */
	if (val > 27500) {
		i = 10;
	} else if (val > 22500) {
		i = 11;
	} else {
		for (i = 9; i > 0; i--) {
490
			if (val > (PWM_FREQ[i] + PWM_FREQ[i - 1] + 1) / 2)
J
Juerg Haefliger 已提交
491 492 493 494 495 496 497
				break;
		}
	}

	return (reg & 0xf0) | i;
}

498 499
/*
 * PWM ramp rate
J
Juerg Haefliger 已提交
500 501
 * Register layout:
 *    reg[0] = [OFF3,  OFF2,  OFF1,  RES,   RR1-E, RR1-2, RR1-1, RR1-0]
502 503
 *    reg[1] = [RR2-E, RR2-2, RR2-1, RR2-0, RR3-E, RR3-2, RR3-1, RR3-0]
 */
J
Juerg Haefliger 已提交
504 505 506 507 508 509 510 511 512
static const u8 PWM_RR[] = {206, 104, 69, 41, 26, 18, 10, 5};

static inline int PWM_RR_FROM_REG(int reg, int ix)
{
	int rr = (ix == 1) ? reg >> 4 : reg;

	return (rr & 0x08) ? PWM_RR[rr & 0x07] : 0;
}

513
static int PWM_RR_TO_REG(long val, int ix, int reg)
J
Juerg Haefliger 已提交
514 515 516 517
{
	int i;

	for (i = 0; i < 7; i++) {
518
		if (val > (PWM_RR[i] + PWM_RR[i + 1] + 1) / 2)
J
Juerg Haefliger 已提交
519 520 521 522 523 524 525 526 527 528 529 530
			break;
	}

	return (ix == 1) ? (reg & 0x8f) | (i << 4) : (reg & 0xf8) | i;
}

/* PWM ramp rate enable */
static inline int PWM_RR_EN_FROM_REG(int reg, int ix)
{
	return PWM_RR_FROM_REG(reg, ix) ? 1 : 0;
}

531
static inline int PWM_RR_EN_TO_REG(long val, int ix, int reg)
J
Juerg Haefliger 已提交
532 533 534 535 536 537
{
	int en = (ix == 1) ? 0x80 : 0x08;

	return val ? reg | en : reg & ~en;
}

538 539
/*
 * PWM min/off
J
Juerg Haefliger 已提交
540
 * The PWM min/off bits are part of the PMW ramp rate register 0 (see above for
541 542
 * the register layout).
 */
J
Juerg Haefliger 已提交
543 544 545 546 547 548 549 550 551 552 553 554
static inline int PWM_OFF_FROM_REG(int reg, int ix)
{
	return (reg >> (ix + 5)) & 0x01;
}

static inline int PWM_OFF_TO_REG(int val, int ix, int reg)
{
	return (reg & ~(1 << (ix + 5))) | ((val & 0x01) << (ix + 5));
}

/* ---------------------------------------------------------------------
 * Device I/O access
555 556 557 558 559
 *
 * ISA access is performed through an index/data register pair and needs to
 * be protected by a mutex during runtime (not required for initialization).
 * We use data->update_lock for this and need to ensure that we acquire it
 * before calling dme1737_read or dme1737_write.
J
Juerg Haefliger 已提交
560 561
 * --------------------------------------------------------------------- */

562
static u8 dme1737_read(const struct dme1737_data *data, u8 reg)
J
Juerg Haefliger 已提交
563
{
564
	struct i2c_client *client = data->client;
565
	s32 val;
J
Juerg Haefliger 已提交
566

567
	if (client) { /* I2C device */
568 569 570
		val = i2c_smbus_read_byte_data(client, reg);

		if (val < 0) {
571 572 573
			dev_warn(&client->dev,
				 "Read from register 0x%02x failed! %s\n",
				 reg, DO_REPORT);
574 575
		}
	} else { /* ISA device */
576 577
		outb(reg, data->addr);
		val = inb(data->addr + 1);
J
Juerg Haefliger 已提交
578 579 580 581 582
	}

	return val;
}

583
static s32 dme1737_write(const struct dme1737_data *data, u8 reg, u8 val)
J
Juerg Haefliger 已提交
584
{
585
	struct i2c_client *client = data->client;
586 587
	s32 res = 0;

588
	if (client) { /* I2C device */
589
		res = i2c_smbus_write_byte_data(client, reg, val);
J
Juerg Haefliger 已提交
590

591
		if (res < 0) {
592 593 594
			dev_warn(&client->dev,
				 "Write to register 0x%02x failed! %s\n",
				 reg, DO_REPORT);
595 596
		}
	} else { /* ISA device */
597 598
		outb(reg, data->addr);
		outb(val, data->addr + 1);
J
Juerg Haefliger 已提交
599 600 601 602 603 604 605
	}

	return res;
}

static struct dme1737_data *dme1737_update_device(struct device *dev)
{
J
Juerg Haefliger 已提交
606
	struct dme1737_data *data = dev_get_drvdata(dev);
J
Juerg Haefliger 已提交
607
	int ix;
608
	u8 lsb[6];
J
Juerg Haefliger 已提交
609 610 611 612 613

	mutex_lock(&data->update_lock);

	/* Enable a Vbat monitoring cycle every 10 mins */
	if (time_after(jiffies, data->last_vbat + 600 * HZ) || !data->valid) {
614
		dme1737_write(data, DME1737_REG_CONFIG, dme1737_read(data,
J
Juerg Haefliger 已提交
615 616 617 618 619 620
						DME1737_REG_CONFIG) | 0x10);
		data->last_vbat = jiffies;
	}

	/* Sample register contents every 1 sec */
	if (time_after(jiffies, data->last_update + HZ) || !data->valid) {
621
		if (data->has_features & HAS_VID) {
622
			data->vid = dme1737_read(data, DME1737_REG_VID) &
623 624
				0x3f;
		}
J
Juerg Haefliger 已提交
625 626 627

		/* In (voltage) registers */
		for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) {
628 629
			/*
			 * Voltage inputs are stored as 16 bit values even
J
Juerg Haefliger 已提交
630
			 * though they have only 12 bits resolution. This is
631 632 633
			 * to make it consistent with the temp inputs.
			 */
			if (ix == 7 && !(data->has_features & HAS_IN7))
634
				continue;
635
			data->in[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
636
					DME1737_REG_IN(ix)) << 8;
637
			data->in_min[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
638
					DME1737_REG_IN_MIN(ix));
639
			data->in_max[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
640 641 642 643 644
					DME1737_REG_IN_MAX(ix));
		}

		/* Temp registers */
		for (ix = 0; ix < ARRAY_SIZE(data->temp); ix++) {
645 646
			/*
			 * Temp inputs are stored as 16 bit values even
J
Juerg Haefliger 已提交
647 648 649
			 * though they have only 12 bits resolution. This is
			 * to take advantage of implicit conversions between
			 * register values (2's complement) and temp values
650 651
			 * (signed decimal).
			 */
652
			data->temp[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
653
					DME1737_REG_TEMP(ix)) << 8;
654
			data->temp_min[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
655
					DME1737_REG_TEMP_MIN(ix));
656
			data->temp_max[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
657
					DME1737_REG_TEMP_MAX(ix));
658
			if (data->has_features & HAS_TEMP_OFFSET) {
659
				data->temp_offset[ix] = dme1737_read(data,
660 661
						DME1737_REG_TEMP_OFFSET(ix));
			}
J
Juerg Haefliger 已提交
662 663
		}

664 665
		/*
		 * In and temp LSB registers
J
Juerg Haefliger 已提交
666 667
		 * The LSBs are latched when the MSBs are read, so the order in
		 * which the registers are read (MSB first, then LSB) is
668 669
		 * important!
		 */
J
Juerg Haefliger 已提交
670
		for (ix = 0; ix < ARRAY_SIZE(lsb); ix++) {
671
			if (ix == 5 && !(data->has_features & HAS_IN7))
672
				continue;
673
			lsb[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
674 675 676
					DME1737_REG_IN_TEMP_LSB(ix));
		}
		for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) {
677
			if (ix == 7 && !(data->has_features & HAS_IN7))
678
				continue;
J
Juerg Haefliger 已提交
679 680 681 682 683 684 685 686 687 688
			data->in[ix] |= (lsb[DME1737_REG_IN_LSB[ix]] <<
					DME1737_REG_IN_LSB_SHL[ix]) & 0xf0;
		}
		for (ix = 0; ix < ARRAY_SIZE(data->temp); ix++) {
			data->temp[ix] |= (lsb[DME1737_REG_TEMP_LSB[ix]] <<
					DME1737_REG_TEMP_LSB_SHL[ix]) & 0xf0;
		}

		/* Fan registers */
		for (ix = 0; ix < ARRAY_SIZE(data->fan); ix++) {
689 690 691 692 693
			/*
			 * Skip reading registers if optional fans are not
			 * present
			 */
			if (!(data->has_features & HAS_FAN(ix)))
J
Juerg Haefliger 已提交
694
				continue;
695
			data->fan[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
696
					DME1737_REG_FAN(ix));
697
			data->fan[ix] |= dme1737_read(data,
J
Juerg Haefliger 已提交
698
					DME1737_REG_FAN(ix) + 1) << 8;
699
			data->fan_min[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
700
					DME1737_REG_FAN_MIN(ix));
701
			data->fan_min[ix] |= dme1737_read(data,
J
Juerg Haefliger 已提交
702
					DME1737_REG_FAN_MIN(ix) + 1) << 8;
703
			data->fan_opt[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
704 705 706
					DME1737_REG_FAN_OPT(ix));
			/* fan_max exists only for fan[5-6] */
			if (ix > 3) {
707
				data->fan_max[ix - 4] = dme1737_read(data,
J
Juerg Haefliger 已提交
708 709 710 711 712 713
					DME1737_REG_FAN_MAX(ix));
			}
		}

		/* PWM registers */
		for (ix = 0; ix < ARRAY_SIZE(data->pwm); ix++) {
714 715 716 717 718
			/*
			 * Skip reading registers if optional PWMs are not
			 * present
			 */
			if (!(data->has_features & HAS_PWM(ix)))
J
Juerg Haefliger 已提交
719
				continue;
720
			data->pwm[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
721
					DME1737_REG_PWM(ix));
722
			data->pwm_freq[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
723 724 725
					DME1737_REG_PWM_FREQ(ix));
			/* pwm_config and pwm_min exist only for pwm[1-3] */
			if (ix < 3) {
726
				data->pwm_config[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
727
						DME1737_REG_PWM_CONFIG(ix));
728
				data->pwm_min[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
729 730 731 732
						DME1737_REG_PWM_MIN(ix));
			}
		}
		for (ix = 0; ix < ARRAY_SIZE(data->pwm_rr); ix++) {
733
			data->pwm_rr[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
734 735 736 737 738
						DME1737_REG_PWM_RR(ix));
		}

		/* Thermal zone registers */
		for (ix = 0; ix < ARRAY_SIZE(data->zone_low); ix++) {
739
			/* Skip reading registers if zone3 is not present */
740
			if ((ix == 2) && !(data->has_features & HAS_ZONE3))
741 742 743 744 745 746 747 748 749 750 751 752 753
				continue;
			/* sch5127 zone2 registers are special */
			if ((ix == 1) && (data->type == sch5127)) {
				data->zone_low[1] = dme1737_read(data,
						DME1737_REG_ZONE_LOW(2));
				data->zone_abs[1] = dme1737_read(data,
						DME1737_REG_ZONE_ABS(2));
			} else {
				data->zone_low[ix] = dme1737_read(data,
						DME1737_REG_ZONE_LOW(ix));
				data->zone_abs[ix] = dme1737_read(data,
						DME1737_REG_ZONE_ABS(ix));
			}
J
Juerg Haefliger 已提交
754
		}
755
		if (data->has_features & HAS_ZONE_HYST) {
756
			for (ix = 0; ix < ARRAY_SIZE(data->zone_hyst); ix++) {
757
				data->zone_hyst[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
758
						DME1737_REG_ZONE_HYST(ix));
759
			}
J
Juerg Haefliger 已提交
760 761 762
		}

		/* Alarm registers */
763
		data->alarms = dme1737_read(data,
J
Juerg Haefliger 已提交
764
						DME1737_REG_ALARM1);
765 766 767 768
		/*
		 * Bit 7 tells us if the other alarm registers are non-zero and
		 * therefore also need to be read
		 */
J
Juerg Haefliger 已提交
769
		if (data->alarms & 0x80) {
770
			data->alarms |= dme1737_read(data,
J
Juerg Haefliger 已提交
771
						DME1737_REG_ALARM2) << 8;
772
			data->alarms |= dme1737_read(data,
J
Juerg Haefliger 已提交
773 774 775
						DME1737_REG_ALARM3) << 16;
		}

776 777
		/*
		 * The ISA chips require explicit clearing of alarm bits.
778
		 * Don't worry, an alarm will come back if the condition
779 780
		 * that causes it still exists
		 */
781
		if (!data->client) {
782 783 784 785 786 787
			if (data->alarms & 0xff0000)
				dme1737_write(data, DME1737_REG_ALARM3, 0xff);
			if (data->alarms & 0xff00)
				dme1737_write(data, DME1737_REG_ALARM2, 0xff);
			if (data->alarms & 0xff)
				dme1737_write(data, DME1737_REG_ALARM1, 0xff);
788 789
		}

J
Juerg Haefliger 已提交
790 791 792 793 794 795 796 797 798 799 800
		data->last_update = jiffies;
		data->valid = 1;
	}

	mutex_unlock(&data->update_lock);

	return data;
}

/* ---------------------------------------------------------------------
 * Voltage sysfs attributes
801
 * ix = [0-7]
J
Juerg Haefliger 已提交
802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820
 * --------------------------------------------------------------------- */

#define SYS_IN_INPUT	0
#define SYS_IN_MIN	1
#define SYS_IN_MAX	2
#define SYS_IN_ALARM	3

static ssize_t show_in(struct device *dev, struct device_attribute *attr,
		       char *buf)
{
	struct dme1737_data *data = dme1737_update_device(dev);
	struct sensor_device_attribute_2
		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
	int ix = sensor_attr_2->index;
	int fn = sensor_attr_2->nr;
	int res;

	switch (fn) {
	case SYS_IN_INPUT:
821
		res = IN_FROM_REG(data->in[ix], data->in_nominal[ix], 16);
J
Juerg Haefliger 已提交
822 823
		break;
	case SYS_IN_MIN:
824
		res = IN_FROM_REG(data->in_min[ix], data->in_nominal[ix], 8);
J
Juerg Haefliger 已提交
825 826
		break;
	case SYS_IN_MAX:
827
		res = IN_FROM_REG(data->in_max[ix], data->in_nominal[ix], 8);
J
Juerg Haefliger 已提交
828 829 830 831 832 833
		break;
	case SYS_IN_ALARM:
		res = (data->alarms >> DME1737_BIT_ALARM_IN[ix]) & 0x01;
		break;
	default:
		res = 0;
J
Juerg Haefliger 已提交
834
		dev_dbg(dev, "Unknown function %d.\n", fn);
J
Juerg Haefliger 已提交
835 836 837 838 839 840 841 842
	}

	return sprintf(buf, "%d\n", res);
}

static ssize_t set_in(struct device *dev, struct device_attribute *attr,
		      const char *buf, size_t count)
{
J
Juerg Haefliger 已提交
843
	struct dme1737_data *data = dev_get_drvdata(dev);
J
Juerg Haefliger 已提交
844 845 846 847
	struct sensor_device_attribute_2
		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
	int ix = sensor_attr_2->index;
	int fn = sensor_attr_2->nr;
848 849 850 851 852 853
	long val;
	int err;

	err = kstrtol(buf, 10, &val);
	if (err)
		return err;
J
Juerg Haefliger 已提交
854 855 856 857

	mutex_lock(&data->update_lock);
	switch (fn) {
	case SYS_IN_MIN:
858
		data->in_min[ix] = IN_TO_REG(val, data->in_nominal[ix]);
859
		dme1737_write(data, DME1737_REG_IN_MIN(ix),
J
Juerg Haefliger 已提交
860 861 862
			      data->in_min[ix]);
		break;
	case SYS_IN_MAX:
863
		data->in_max[ix] = IN_TO_REG(val, data->in_nominal[ix]);
864
		dme1737_write(data, DME1737_REG_IN_MAX(ix),
J
Juerg Haefliger 已提交
865 866 867
			      data->in_max[ix]);
		break;
	default:
J
Juerg Haefliger 已提交
868
		dev_dbg(dev, "Unknown function %d.\n", fn);
J
Juerg Haefliger 已提交
869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913
	}
	mutex_unlock(&data->update_lock);

	return count;
}

/* ---------------------------------------------------------------------
 * Temperature sysfs attributes
 * ix = [0-2]
 * --------------------------------------------------------------------- */

#define SYS_TEMP_INPUT			0
#define SYS_TEMP_MIN			1
#define SYS_TEMP_MAX			2
#define SYS_TEMP_OFFSET			3
#define SYS_TEMP_ALARM			4
#define SYS_TEMP_FAULT			5

static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
			 char *buf)
{
	struct dme1737_data *data = dme1737_update_device(dev);
	struct sensor_device_attribute_2
		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
	int ix = sensor_attr_2->index;
	int fn = sensor_attr_2->nr;
	int res;

	switch (fn) {
	case SYS_TEMP_INPUT:
		res = TEMP_FROM_REG(data->temp[ix], 16);
		break;
	case SYS_TEMP_MIN:
		res = TEMP_FROM_REG(data->temp_min[ix], 8);
		break;
	case SYS_TEMP_MAX:
		res = TEMP_FROM_REG(data->temp_max[ix], 8);
		break;
	case SYS_TEMP_OFFSET:
		res = TEMP_FROM_REG(data->temp_offset[ix], 8);
		break;
	case SYS_TEMP_ALARM:
		res = (data->alarms >> DME1737_BIT_ALARM_TEMP[ix]) & 0x01;
		break;
	case SYS_TEMP_FAULT:
914
		res = (((u16)data->temp[ix] & 0xff00) == 0x8000);
J
Juerg Haefliger 已提交
915 916 917
		break;
	default:
		res = 0;
J
Juerg Haefliger 已提交
918
		dev_dbg(dev, "Unknown function %d.\n", fn);
J
Juerg Haefliger 已提交
919 920 921 922 923 924 925 926
	}

	return sprintf(buf, "%d\n", res);
}

static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
			const char *buf, size_t count)
{
J
Juerg Haefliger 已提交
927
	struct dme1737_data *data = dev_get_drvdata(dev);
J
Juerg Haefliger 已提交
928 929 930 931
	struct sensor_device_attribute_2
		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
	int ix = sensor_attr_2->index;
	int fn = sensor_attr_2->nr;
932 933 934 935 936 937
	long val;
	int err;

	err = kstrtol(buf, 10, &val);
	if (err)
		return err;
J
Juerg Haefliger 已提交
938 939 940 941 942

	mutex_lock(&data->update_lock);
	switch (fn) {
	case SYS_TEMP_MIN:
		data->temp_min[ix] = TEMP_TO_REG(val);
943
		dme1737_write(data, DME1737_REG_TEMP_MIN(ix),
J
Juerg Haefliger 已提交
944 945 946 947
			      data->temp_min[ix]);
		break;
	case SYS_TEMP_MAX:
		data->temp_max[ix] = TEMP_TO_REG(val);
948
		dme1737_write(data, DME1737_REG_TEMP_MAX(ix),
J
Juerg Haefliger 已提交
949 950 951 952
			      data->temp_max[ix]);
		break;
	case SYS_TEMP_OFFSET:
		data->temp_offset[ix] = TEMP_TO_REG(val);
953
		dme1737_write(data, DME1737_REG_TEMP_OFFSET(ix),
J
Juerg Haefliger 已提交
954 955 956
			      data->temp_offset[ix]);
		break;
	default:
J
Juerg Haefliger 已提交
957
		dev_dbg(dev, "Unknown function %d.\n", fn);
J
Juerg Haefliger 已提交
958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987
	}
	mutex_unlock(&data->update_lock);

	return count;
}

/* ---------------------------------------------------------------------
 * Zone sysfs attributes
 * ix = [0-2]
 * --------------------------------------------------------------------- */

#define SYS_ZONE_AUTO_CHANNELS_TEMP	0
#define SYS_ZONE_AUTO_POINT1_TEMP_HYST	1
#define SYS_ZONE_AUTO_POINT1_TEMP	2
#define SYS_ZONE_AUTO_POINT2_TEMP	3
#define SYS_ZONE_AUTO_POINT3_TEMP	4

static ssize_t show_zone(struct device *dev, struct device_attribute *attr,
			 char *buf)
{
	struct dme1737_data *data = dme1737_update_device(dev);
	struct sensor_device_attribute_2
		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
	int ix = sensor_attr_2->index;
	int fn = sensor_attr_2->nr;
	int res;

	switch (fn) {
	case SYS_ZONE_AUTO_CHANNELS_TEMP:
		/* check config2 for non-standard temp-to-zone mapping */
988
		if ((ix == 1) && (data->config2 & 0x02))
J
Juerg Haefliger 已提交
989
			res = 4;
990
		else
J
Juerg Haefliger 已提交
991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009
			res = 1 << ix;
		break;
	case SYS_ZONE_AUTO_POINT1_TEMP_HYST:
		res = TEMP_FROM_REG(data->zone_low[ix], 8) -
		      TEMP_HYST_FROM_REG(data->zone_hyst[ix == 2], ix);
		break;
	case SYS_ZONE_AUTO_POINT1_TEMP:
		res = TEMP_FROM_REG(data->zone_low[ix], 8);
		break;
	case SYS_ZONE_AUTO_POINT2_TEMP:
		/* pwm_freq holds the temp range bits in the upper nibble */
		res = TEMP_FROM_REG(data->zone_low[ix], 8) +
		      TEMP_RANGE_FROM_REG(data->pwm_freq[ix]);
		break;
	case SYS_ZONE_AUTO_POINT3_TEMP:
		res = TEMP_FROM_REG(data->zone_abs[ix], 8);
		break;
	default:
		res = 0;
J
Juerg Haefliger 已提交
1010
		dev_dbg(dev, "Unknown function %d.\n", fn);
J
Juerg Haefliger 已提交
1011 1012 1013 1014 1015 1016 1017 1018
	}

	return sprintf(buf, "%d\n", res);
}

static ssize_t set_zone(struct device *dev, struct device_attribute *attr,
			const char *buf, size_t count)
{
J
Juerg Haefliger 已提交
1019
	struct dme1737_data *data = dev_get_drvdata(dev);
J
Juerg Haefliger 已提交
1020 1021 1022 1023
	struct sensor_device_attribute_2
		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
	int ix = sensor_attr_2->index;
	int fn = sensor_attr_2->nr;
1024 1025 1026 1027 1028 1029
	long val;
	int err;

	err = kstrtol(buf, 10, &val);
	if (err)
		return err;
J
Juerg Haefliger 已提交
1030 1031 1032 1033 1034

	mutex_lock(&data->update_lock);
	switch (fn) {
	case SYS_ZONE_AUTO_POINT1_TEMP_HYST:
		/* Refresh the cache */
1035
		data->zone_low[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
1036 1037 1038 1039
						  DME1737_REG_ZONE_LOW(ix));
		/* Modify the temp hyst value */
		data->zone_hyst[ix == 2] = TEMP_HYST_TO_REG(
					TEMP_FROM_REG(data->zone_low[ix], 8) -
1040
					val, ix, dme1737_read(data,
J
Juerg Haefliger 已提交
1041
					DME1737_REG_ZONE_HYST(ix == 2)));
1042
		dme1737_write(data, DME1737_REG_ZONE_HYST(ix == 2),
J
Juerg Haefliger 已提交
1043 1044 1045 1046
			      data->zone_hyst[ix == 2]);
		break;
	case SYS_ZONE_AUTO_POINT1_TEMP:
		data->zone_low[ix] = TEMP_TO_REG(val);
1047
		dme1737_write(data, DME1737_REG_ZONE_LOW(ix),
J
Juerg Haefliger 已提交
1048 1049 1050 1051
			      data->zone_low[ix]);
		break;
	case SYS_ZONE_AUTO_POINT2_TEMP:
		/* Refresh the cache */
1052
		data->zone_low[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
1053
						  DME1737_REG_ZONE_LOW(ix));
1054 1055 1056 1057
		/*
		 * Modify the temp range value (which is stored in the upper
		 * nibble of the pwm_freq register)
		 */
J
Juerg Haefliger 已提交
1058 1059
		data->pwm_freq[ix] = TEMP_RANGE_TO_REG(val -
					TEMP_FROM_REG(data->zone_low[ix], 8),
1060
					dme1737_read(data,
J
Juerg Haefliger 已提交
1061
					DME1737_REG_PWM_FREQ(ix)));
1062
		dme1737_write(data, DME1737_REG_PWM_FREQ(ix),
J
Juerg Haefliger 已提交
1063 1064 1065 1066
			      data->pwm_freq[ix]);
		break;
	case SYS_ZONE_AUTO_POINT3_TEMP:
		data->zone_abs[ix] = TEMP_TO_REG(val);
1067
		dme1737_write(data, DME1737_REG_ZONE_ABS(ix),
J
Juerg Haefliger 已提交
1068 1069 1070
			      data->zone_abs[ix]);
		break;
	default:
J
Juerg Haefliger 已提交
1071
		dev_dbg(dev, "Unknown function %d.\n", fn);
J
Juerg Haefliger 已提交
1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122
	}
	mutex_unlock(&data->update_lock);

	return count;
}

/* ---------------------------------------------------------------------
 * Fan sysfs attributes
 * ix = [0-5]
 * --------------------------------------------------------------------- */

#define SYS_FAN_INPUT	0
#define SYS_FAN_MIN	1
#define SYS_FAN_MAX	2
#define SYS_FAN_ALARM	3
#define SYS_FAN_TYPE	4

static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
			char *buf)
{
	struct dme1737_data *data = dme1737_update_device(dev);
	struct sensor_device_attribute_2
		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
	int ix = sensor_attr_2->index;
	int fn = sensor_attr_2->nr;
	int res;

	switch (fn) {
	case SYS_FAN_INPUT:
		res = FAN_FROM_REG(data->fan[ix],
				   ix < 4 ? 0 :
				   FAN_TPC_FROM_REG(data->fan_opt[ix]));
		break;
	case SYS_FAN_MIN:
		res = FAN_FROM_REG(data->fan_min[ix],
				   ix < 4 ? 0 :
				   FAN_TPC_FROM_REG(data->fan_opt[ix]));
		break;
	case SYS_FAN_MAX:
		/* only valid for fan[5-6] */
		res = FAN_MAX_FROM_REG(data->fan_max[ix - 4]);
		break;
	case SYS_FAN_ALARM:
		res = (data->alarms >> DME1737_BIT_ALARM_FAN[ix]) & 0x01;
		break;
	case SYS_FAN_TYPE:
		/* only valid for fan[1-4] */
		res = FAN_TYPE_FROM_REG(data->fan_opt[ix]);
		break;
	default:
		res = 0;
J
Juerg Haefliger 已提交
1123
		dev_dbg(dev, "Unknown function %d.\n", fn);
J
Juerg Haefliger 已提交
1124 1125 1126 1127 1128 1129 1130 1131
	}

	return sprintf(buf, "%d\n", res);
}

static ssize_t set_fan(struct device *dev, struct device_attribute *attr,
		       const char *buf, size_t count)
{
J
Juerg Haefliger 已提交
1132
	struct dme1737_data *data = dev_get_drvdata(dev);
J
Juerg Haefliger 已提交
1133 1134 1135 1136
	struct sensor_device_attribute_2
		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
	int ix = sensor_attr_2->index;
	int fn = sensor_attr_2->nr;
1137 1138 1139 1140 1141 1142
	long val;
	int err;

	err = kstrtol(buf, 10, &val);
	if (err)
		return err;
J
Juerg Haefliger 已提交
1143 1144 1145 1146 1147 1148 1149 1150

	mutex_lock(&data->update_lock);
	switch (fn) {
	case SYS_FAN_MIN:
		if (ix < 4) {
			data->fan_min[ix] = FAN_TO_REG(val, 0);
		} else {
			/* Refresh the cache */
1151
			data->fan_opt[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
1152 1153 1154 1155 1156
						DME1737_REG_FAN_OPT(ix));
			/* Modify the fan min value */
			data->fan_min[ix] = FAN_TO_REG(val,
					FAN_TPC_FROM_REG(data->fan_opt[ix]));
		}
1157
		dme1737_write(data, DME1737_REG_FAN_MIN(ix),
J
Juerg Haefliger 已提交
1158
			      data->fan_min[ix] & 0xff);
1159
		dme1737_write(data, DME1737_REG_FAN_MIN(ix) + 1,
J
Juerg Haefliger 已提交
1160 1161 1162 1163 1164
			      data->fan_min[ix] >> 8);
		break;
	case SYS_FAN_MAX:
		/* Only valid for fan[5-6] */
		data->fan_max[ix - 4] = FAN_MAX_TO_REG(val);
1165
		dme1737_write(data, DME1737_REG_FAN_MAX(ix),
J
Juerg Haefliger 已提交
1166 1167 1168 1169 1170 1171
			      data->fan_max[ix - 4]);
		break;
	case SYS_FAN_TYPE:
		/* Only valid for fan[1-4] */
		if (!(val == 1 || val == 2 || val == 4)) {
			count = -EINVAL;
1172 1173
			dev_warn(dev,
				 "Fan type value %ld not supported. Choose one of 1, 2, or 4.\n",
J
Juerg Haefliger 已提交
1174 1175 1176
				 val);
			goto exit;
		}
1177
		data->fan_opt[ix] = FAN_TYPE_TO_REG(val, dme1737_read(data,
J
Juerg Haefliger 已提交
1178
					DME1737_REG_FAN_OPT(ix)));
1179
		dme1737_write(data, DME1737_REG_FAN_OPT(ix),
J
Juerg Haefliger 已提交
1180 1181 1182
			      data->fan_opt[ix]);
		break;
	default:
J
Juerg Haefliger 已提交
1183
		dev_dbg(dev, "Unknown function %d.\n", fn);
J
Juerg Haefliger 已提交
1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216
	}
exit:
	mutex_unlock(&data->update_lock);

	return count;
}

/* ---------------------------------------------------------------------
 * PWM sysfs attributes
 * ix = [0-4]
 * --------------------------------------------------------------------- */

#define SYS_PWM				0
#define SYS_PWM_FREQ			1
#define SYS_PWM_ENABLE			2
#define SYS_PWM_RAMP_RATE		3
#define SYS_PWM_AUTO_CHANNELS_ZONE	4
#define SYS_PWM_AUTO_PWM_MIN		5
#define SYS_PWM_AUTO_POINT1_PWM		6
#define SYS_PWM_AUTO_POINT2_PWM		7

static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
			char *buf)
{
	struct dme1737_data *data = dme1737_update_device(dev);
	struct sensor_device_attribute_2
		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
	int ix = sensor_attr_2->index;
	int fn = sensor_attr_2->nr;
	int res;

	switch (fn) {
	case SYS_PWM:
1217
		if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 0)
J
Juerg Haefliger 已提交
1218
			res = 255;
1219
		else
J
Juerg Haefliger 已提交
1220 1221 1222 1223 1224 1225
			res = data->pwm[ix];
		break;
	case SYS_PWM_FREQ:
		res = PWM_FREQ_FROM_REG(data->pwm_freq[ix]);
		break;
	case SYS_PWM_ENABLE:
1226
		if (ix >= 3)
J
Juerg Haefliger 已提交
1227
			res = 1; /* pwm[5-6] hard-wired to manual mode */
1228
		else
J
Juerg Haefliger 已提交
1229 1230 1231 1232 1233 1234 1235 1236
			res = PWM_EN_FROM_REG(data->pwm_config[ix]);
		break;
	case SYS_PWM_RAMP_RATE:
		/* Only valid for pwm[1-3] */
		res = PWM_RR_FROM_REG(data->pwm_rr[ix > 0], ix);
		break;
	case SYS_PWM_AUTO_CHANNELS_ZONE:
		/* Only valid for pwm[1-3] */
1237
		if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2)
J
Juerg Haefliger 已提交
1238
			res = PWM_ACZ_FROM_REG(data->pwm_config[ix]);
1239
		else
J
Juerg Haefliger 已提交
1240 1241 1242 1243
			res = data->pwm_acz[ix];
		break;
	case SYS_PWM_AUTO_PWM_MIN:
		/* Only valid for pwm[1-3] */
1244
		if (PWM_OFF_FROM_REG(data->pwm_rr[0], ix))
J
Juerg Haefliger 已提交
1245
			res = data->pwm_min[ix];
1246
		else
J
Juerg Haefliger 已提交
1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258
			res = 0;
		break;
	case SYS_PWM_AUTO_POINT1_PWM:
		/* Only valid for pwm[1-3] */
		res = data->pwm_min[ix];
		break;
	case SYS_PWM_AUTO_POINT2_PWM:
		/* Only valid for pwm[1-3] */
		res = 255; /* hard-wired */
		break;
	default:
		res = 0;
J
Juerg Haefliger 已提交
1259
		dev_dbg(dev, "Unknown function %d.\n", fn);
J
Juerg Haefliger 已提交
1260 1261 1262 1263 1264
	}

	return sprintf(buf, "%d\n", res);
}

J
Juerg Haefliger 已提交
1265
static struct attribute *dme1737_pwm_chmod_attr[];
A
Al Viro 已提交
1266
static void dme1737_chmod_file(struct device*, struct attribute*, umode_t);
J
Juerg Haefliger 已提交
1267 1268 1269 1270

static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
		       const char *buf, size_t count)
{
J
Juerg Haefliger 已提交
1271
	struct dme1737_data *data = dev_get_drvdata(dev);
J
Juerg Haefliger 已提交
1272 1273 1274 1275
	struct sensor_device_attribute_2
		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
	int ix = sensor_attr_2->index;
	int fn = sensor_attr_2->nr;
1276 1277 1278 1279 1280 1281
	long val;
	int err;

	err = kstrtol(buf, 10, &val);
	if (err)
		return err;
J
Juerg Haefliger 已提交
1282 1283 1284 1285

	mutex_lock(&data->update_lock);
	switch (fn) {
	case SYS_PWM:
1286
		data->pwm[ix] = clamp_val(val, 0, 255);
1287
		dme1737_write(data, DME1737_REG_PWM(ix), data->pwm[ix]);
J
Juerg Haefliger 已提交
1288 1289
		break;
	case SYS_PWM_FREQ:
1290
		data->pwm_freq[ix] = PWM_FREQ_TO_REG(val, dme1737_read(data,
J
Juerg Haefliger 已提交
1291
						DME1737_REG_PWM_FREQ(ix)));
1292
		dme1737_write(data, DME1737_REG_PWM_FREQ(ix),
J
Juerg Haefliger 已提交
1293 1294 1295 1296 1297 1298
			      data->pwm_freq[ix]);
		break;
	case SYS_PWM_ENABLE:
		/* Only valid for pwm[1-3] */
		if (val < 0 || val > 2) {
			count = -EINVAL;
1299 1300
			dev_warn(dev,
				 "PWM enable %ld not supported. Choose one of 0, 1, or 2.\n",
J
Juerg Haefliger 已提交
1301 1302 1303 1304
				 val);
			goto exit;
		}
		/* Refresh the cache */
1305
		data->pwm_config[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316
						DME1737_REG_PWM_CONFIG(ix));
		if (val == PWM_EN_FROM_REG(data->pwm_config[ix])) {
			/* Bail out if no change */
			goto exit;
		}
		/* Do some housekeeping if we are currently in auto mode */
		if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) {
			/* Save the current zone channel assignment */
			data->pwm_acz[ix] = PWM_ACZ_FROM_REG(
							data->pwm_config[ix]);
			/* Save the current ramp rate state and disable it */
1317
			data->pwm_rr[ix > 0] = dme1737_read(data,
J
Juerg Haefliger 已提交
1318 1319 1320 1321 1322 1323
						DME1737_REG_PWM_RR(ix > 0));
			data->pwm_rr_en &= ~(1 << ix);
			if (PWM_RR_EN_FROM_REG(data->pwm_rr[ix > 0], ix)) {
				data->pwm_rr_en |= (1 << ix);
				data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(0, ix,
							data->pwm_rr[ix > 0]);
1324
				dme1737_write(data,
J
Juerg Haefliger 已提交
1325 1326 1327 1328 1329 1330 1331 1332
					      DME1737_REG_PWM_RR(ix > 0),
					      data->pwm_rr[ix > 0]);
			}
		}
		/* Set the new PWM mode */
		switch (val) {
		case 0:
			/* Change permissions of pwm[ix] to read-only */
J
Juerg Haefliger 已提交
1333
			dme1737_chmod_file(dev, dme1737_pwm_chmod_attr[ix],
J
Juerg Haefliger 已提交
1334 1335 1336 1337
					   S_IRUGO);
			/* Turn fan fully on */
			data->pwm_config[ix] = PWM_EN_TO_REG(0,
							data->pwm_config[ix]);
1338
			dme1737_write(data, DME1737_REG_PWM_CONFIG(ix),
J
Juerg Haefliger 已提交
1339 1340 1341 1342 1343 1344
				      data->pwm_config[ix]);
			break;
		case 1:
			/* Turn on manual mode */
			data->pwm_config[ix] = PWM_EN_TO_REG(1,
							data->pwm_config[ix]);
1345
			dme1737_write(data, DME1737_REG_PWM_CONFIG(ix),
J
Juerg Haefliger 已提交
1346 1347
				      data->pwm_config[ix]);
			/* Change permissions of pwm[ix] to read-writeable */
J
Juerg Haefliger 已提交
1348
			dme1737_chmod_file(dev, dme1737_pwm_chmod_attr[ix],
J
Juerg Haefliger 已提交
1349 1350 1351 1352
					   S_IRUGO | S_IWUSR);
			break;
		case 2:
			/* Change permissions of pwm[ix] to read-only */
J
Juerg Haefliger 已提交
1353
			dme1737_chmod_file(dev, dme1737_pwm_chmod_attr[ix],
J
Juerg Haefliger 已提交
1354
					   S_IRUGO);
1355 1356 1357 1358
			/*
			 * Turn on auto mode using the saved zone channel
			 * assignment
			 */
J
Juerg Haefliger 已提交
1359 1360 1361
			data->pwm_config[ix] = PWM_ACZ_TO_REG(
							data->pwm_acz[ix],
							data->pwm_config[ix]);
1362
			dme1737_write(data, DME1737_REG_PWM_CONFIG(ix),
J
Juerg Haefliger 已提交
1363 1364 1365 1366
				      data->pwm_config[ix]);
			/* Enable PWM ramp rate if previously enabled */
			if (data->pwm_rr_en & (1 << ix)) {
				data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(1, ix,
1367
						dme1737_read(data,
J
Juerg Haefliger 已提交
1368
						DME1737_REG_PWM_RR(ix > 0)));
1369
				dme1737_write(data,
J
Juerg Haefliger 已提交
1370 1371 1372 1373 1374 1375 1376 1377 1378
					      DME1737_REG_PWM_RR(ix > 0),
					      data->pwm_rr[ix > 0]);
			}
			break;
		}
		break;
	case SYS_PWM_RAMP_RATE:
		/* Only valid for pwm[1-3] */
		/* Refresh the cache */
1379
		data->pwm_config[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
1380
						DME1737_REG_PWM_CONFIG(ix));
1381
		data->pwm_rr[ix > 0] = dme1737_read(data,
J
Juerg Haefliger 已提交
1382 1383 1384 1385 1386 1387
						DME1737_REG_PWM_RR(ix > 0));
		/* Set the ramp rate value */
		if (val > 0) {
			data->pwm_rr[ix > 0] = PWM_RR_TO_REG(val, ix,
							data->pwm_rr[ix > 0]);
		}
1388 1389 1390 1391
		/*
		 * Enable/disable the feature only if the associated PWM
		 * output is in automatic mode.
		 */
J
Juerg Haefliger 已提交
1392 1393 1394 1395
		if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) {
			data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(val > 0, ix,
							data->pwm_rr[ix > 0]);
		}
1396
		dme1737_write(data, DME1737_REG_PWM_RR(ix > 0),
J
Juerg Haefliger 已提交
1397 1398 1399 1400 1401 1402 1403
			      data->pwm_rr[ix > 0]);
		break;
	case SYS_PWM_AUTO_CHANNELS_ZONE:
		/* Only valid for pwm[1-3] */
		if (!(val == 1 || val == 2 || val == 4 ||
		      val == 6 || val == 7)) {
			count = -EINVAL;
1404 1405
			dev_warn(dev,
				 "PWM auto channels zone %ld not supported. Choose one of 1, 2, 4, 6, "
J
Juerg Haefliger 已提交
1406 1407 1408 1409
				 "or 7.\n", val);
			goto exit;
		}
		/* Refresh the cache */
1410
		data->pwm_config[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
1411 1412
						DME1737_REG_PWM_CONFIG(ix));
		if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) {
1413 1414 1415 1416
			/*
			 * PWM is already in auto mode so update the temp
			 * channel assignment
			 */
J
Juerg Haefliger 已提交
1417 1418
			data->pwm_config[ix] = PWM_ACZ_TO_REG(val,
						data->pwm_config[ix]);
1419
			dme1737_write(data, DME1737_REG_PWM_CONFIG(ix),
J
Juerg Haefliger 已提交
1420 1421
				      data->pwm_config[ix]);
		} else {
1422 1423 1424 1425
			/*
			 * PWM is not in auto mode so we save the temp
			 * channel assignment for later use
			 */
J
Juerg Haefliger 已提交
1426 1427 1428 1429 1430 1431
			data->pwm_acz[ix] = val;
		}
		break;
	case SYS_PWM_AUTO_PWM_MIN:
		/* Only valid for pwm[1-3] */
		/* Refresh the cache */
1432
		data->pwm_min[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
1433
						DME1737_REG_PWM_MIN(ix));
1434 1435
		/*
		 * There are only 2 values supported for the auto_pwm_min
J
Juerg Haefliger 已提交
1436 1437
		 * value: 0 or auto_point1_pwm. So if the temperature drops
		 * below the auto_point1_temp_hyst value, the fan either turns
1438 1439
		 * off or runs at auto_point1_pwm duty-cycle.
		 */
J
Juerg Haefliger 已提交
1440 1441
		if (val > ((data->pwm_min[ix] + 1) / 2)) {
			data->pwm_rr[0] = PWM_OFF_TO_REG(1, ix,
1442
						dme1737_read(data,
J
Juerg Haefliger 已提交
1443 1444 1445
						DME1737_REG_PWM_RR(0)));
		} else {
			data->pwm_rr[0] = PWM_OFF_TO_REG(0, ix,
1446
						dme1737_read(data,
J
Juerg Haefliger 已提交
1447 1448
						DME1737_REG_PWM_RR(0)));
		}
1449
		dme1737_write(data, DME1737_REG_PWM_RR(0),
J
Juerg Haefliger 已提交
1450 1451 1452 1453
			      data->pwm_rr[0]);
		break;
	case SYS_PWM_AUTO_POINT1_PWM:
		/* Only valid for pwm[1-3] */
1454
		data->pwm_min[ix] = clamp_val(val, 0, 255);
1455
		dme1737_write(data, DME1737_REG_PWM_MIN(ix),
J
Juerg Haefliger 已提交
1456 1457 1458
			      data->pwm_min[ix]);
		break;
	default:
J
Juerg Haefliger 已提交
1459
		dev_dbg(dev, "Unknown function %d.\n", fn);
J
Juerg Haefliger 已提交
1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482
	}
exit:
	mutex_unlock(&data->update_lock);

	return count;
}

/* ---------------------------------------------------------------------
 * Miscellaneous sysfs attributes
 * --------------------------------------------------------------------- */

static ssize_t show_vrm(struct device *dev, struct device_attribute *attr,
			char *buf)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct dme1737_data *data = i2c_get_clientdata(client);

	return sprintf(buf, "%d\n", data->vrm);
}

static ssize_t set_vrm(struct device *dev, struct device_attribute *attr,
		       const char *buf, size_t count)
{
J
Juerg Haefliger 已提交
1483
	struct dme1737_data *data = dev_get_drvdata(dev);
1484
	unsigned long val;
1485 1486
	int err;

1487
	err = kstrtoul(buf, 10, &val);
1488 1489
	if (err)
		return err;
J
Juerg Haefliger 已提交
1490

1491 1492 1493
	if (val > 255)
		return -EINVAL;

J
Juerg Haefliger 已提交
1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505
	data->vrm = val;
	return count;
}

static ssize_t show_vid(struct device *dev, struct device_attribute *attr,
			char *buf)
{
	struct dme1737_data *data = dme1737_update_device(dev);

	return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
}

1506 1507 1508 1509 1510
static ssize_t show_name(struct device *dev, struct device_attribute *attr,
			 char *buf)
{
	struct dme1737_data *data = dev_get_drvdata(dev);

1511
	return sprintf(buf, "%s\n", data->name);
1512 1513
}

J
Juerg Haefliger 已提交
1514 1515 1516 1517
/* ---------------------------------------------------------------------
 * Sysfs device attribute defines and structs
 * --------------------------------------------------------------------- */

1518
/* Voltages 0-7 */
J
Juerg Haefliger 已提交
1519 1520 1521

#define SENSOR_DEVICE_ATTR_IN(ix) \
static SENSOR_DEVICE_ATTR_2(in##ix##_input, S_IRUGO, \
J
Juerg Haefliger 已提交
1522
	show_in, NULL, SYS_IN_INPUT, ix); \
J
Juerg Haefliger 已提交
1523
static SENSOR_DEVICE_ATTR_2(in##ix##_min, S_IRUGO | S_IWUSR, \
J
Juerg Haefliger 已提交
1524
	show_in, set_in, SYS_IN_MIN, ix); \
J
Juerg Haefliger 已提交
1525
static SENSOR_DEVICE_ATTR_2(in##ix##_max, S_IRUGO | S_IWUSR, \
J
Juerg Haefliger 已提交
1526
	show_in, set_in, SYS_IN_MAX, ix); \
J
Juerg Haefliger 已提交
1527
static SENSOR_DEVICE_ATTR_2(in##ix##_alarm, S_IRUGO, \
J
Juerg Haefliger 已提交
1528
	show_in, NULL, SYS_IN_ALARM, ix)
J
Juerg Haefliger 已提交
1529 1530 1531 1532 1533 1534 1535 1536

SENSOR_DEVICE_ATTR_IN(0);
SENSOR_DEVICE_ATTR_IN(1);
SENSOR_DEVICE_ATTR_IN(2);
SENSOR_DEVICE_ATTR_IN(3);
SENSOR_DEVICE_ATTR_IN(4);
SENSOR_DEVICE_ATTR_IN(5);
SENSOR_DEVICE_ATTR_IN(6);
1537
SENSOR_DEVICE_ATTR_IN(7);
J
Juerg Haefliger 已提交
1538 1539 1540 1541 1542

/* Temperatures 1-3 */

#define SENSOR_DEVICE_ATTR_TEMP(ix) \
static SENSOR_DEVICE_ATTR_2(temp##ix##_input, S_IRUGO, \
J
Juerg Haefliger 已提交
1543
	show_temp, NULL, SYS_TEMP_INPUT, ix-1); \
J
Juerg Haefliger 已提交
1544
static SENSOR_DEVICE_ATTR_2(temp##ix##_min, S_IRUGO | S_IWUSR, \
J
Juerg Haefliger 已提交
1545
	show_temp, set_temp, SYS_TEMP_MIN, ix-1); \
J
Juerg Haefliger 已提交
1546
static SENSOR_DEVICE_ATTR_2(temp##ix##_max, S_IRUGO | S_IWUSR, \
J
Juerg Haefliger 已提交
1547
	show_temp, set_temp, SYS_TEMP_MAX, ix-1); \
J
Juerg Haefliger 已提交
1548
static SENSOR_DEVICE_ATTR_2(temp##ix##_offset, S_IRUGO, \
J
Juerg Haefliger 已提交
1549
	show_temp, set_temp, SYS_TEMP_OFFSET, ix-1); \
J
Juerg Haefliger 已提交
1550
static SENSOR_DEVICE_ATTR_2(temp##ix##_alarm, S_IRUGO, \
J
Juerg Haefliger 已提交
1551
	show_temp, NULL, SYS_TEMP_ALARM, ix-1); \
J
Juerg Haefliger 已提交
1552
static SENSOR_DEVICE_ATTR_2(temp##ix##_fault, S_IRUGO, \
J
Juerg Haefliger 已提交
1553
	show_temp, NULL, SYS_TEMP_FAULT, ix-1)
J
Juerg Haefliger 已提交
1554 1555 1556 1557 1558 1559 1560 1561 1562

SENSOR_DEVICE_ATTR_TEMP(1);
SENSOR_DEVICE_ATTR_TEMP(2);
SENSOR_DEVICE_ATTR_TEMP(3);

/* Zones 1-3 */

#define SENSOR_DEVICE_ATTR_ZONE(ix) \
static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_channels_temp, S_IRUGO, \
J
Juerg Haefliger 已提交
1563
	show_zone, NULL, SYS_ZONE_AUTO_CHANNELS_TEMP, ix-1); \
J
Juerg Haefliger 已提交
1564
static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_point1_temp_hyst, S_IRUGO, \
J
Juerg Haefliger 已提交
1565
	show_zone, set_zone, SYS_ZONE_AUTO_POINT1_TEMP_HYST, ix-1); \
J
Juerg Haefliger 已提交
1566
static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_point1_temp, S_IRUGO, \
J
Juerg Haefliger 已提交
1567
	show_zone, set_zone, SYS_ZONE_AUTO_POINT1_TEMP, ix-1); \
J
Juerg Haefliger 已提交
1568
static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_point2_temp, S_IRUGO, \
J
Juerg Haefliger 已提交
1569
	show_zone, set_zone, SYS_ZONE_AUTO_POINT2_TEMP, ix-1); \
J
Juerg Haefliger 已提交
1570
static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_point3_temp, S_IRUGO, \
J
Juerg Haefliger 已提交
1571
	show_zone, set_zone, SYS_ZONE_AUTO_POINT3_TEMP, ix-1)
J
Juerg Haefliger 已提交
1572 1573 1574 1575 1576 1577 1578 1579 1580

SENSOR_DEVICE_ATTR_ZONE(1);
SENSOR_DEVICE_ATTR_ZONE(2);
SENSOR_DEVICE_ATTR_ZONE(3);

/* Fans 1-4 */

#define SENSOR_DEVICE_ATTR_FAN_1TO4(ix) \
static SENSOR_DEVICE_ATTR_2(fan##ix##_input, S_IRUGO, \
J
Juerg Haefliger 已提交
1581
	show_fan, NULL, SYS_FAN_INPUT, ix-1); \
J
Juerg Haefliger 已提交
1582
static SENSOR_DEVICE_ATTR_2(fan##ix##_min, S_IRUGO | S_IWUSR, \
J
Juerg Haefliger 已提交
1583
	show_fan, set_fan, SYS_FAN_MIN, ix-1); \
J
Juerg Haefliger 已提交
1584
static SENSOR_DEVICE_ATTR_2(fan##ix##_alarm, S_IRUGO, \
J
Juerg Haefliger 已提交
1585
	show_fan, NULL, SYS_FAN_ALARM, ix-1); \
J
Juerg Haefliger 已提交
1586
static SENSOR_DEVICE_ATTR_2(fan##ix##_type, S_IRUGO | S_IWUSR, \
J
Juerg Haefliger 已提交
1587
	show_fan, set_fan, SYS_FAN_TYPE, ix-1)
J
Juerg Haefliger 已提交
1588 1589 1590 1591 1592 1593 1594 1595 1596 1597

SENSOR_DEVICE_ATTR_FAN_1TO4(1);
SENSOR_DEVICE_ATTR_FAN_1TO4(2);
SENSOR_DEVICE_ATTR_FAN_1TO4(3);
SENSOR_DEVICE_ATTR_FAN_1TO4(4);

/* Fans 5-6 */

#define SENSOR_DEVICE_ATTR_FAN_5TO6(ix) \
static SENSOR_DEVICE_ATTR_2(fan##ix##_input, S_IRUGO, \
J
Juerg Haefliger 已提交
1598
	show_fan, NULL, SYS_FAN_INPUT, ix-1); \
J
Juerg Haefliger 已提交
1599
static SENSOR_DEVICE_ATTR_2(fan##ix##_min, S_IRUGO | S_IWUSR, \
J
Juerg Haefliger 已提交
1600
	show_fan, set_fan, SYS_FAN_MIN, ix-1); \
J
Juerg Haefliger 已提交
1601
static SENSOR_DEVICE_ATTR_2(fan##ix##_alarm, S_IRUGO, \
J
Juerg Haefliger 已提交
1602
	show_fan, NULL, SYS_FAN_ALARM, ix-1); \
J
Juerg Haefliger 已提交
1603
static SENSOR_DEVICE_ATTR_2(fan##ix##_max, S_IRUGO | S_IWUSR, \
J
Juerg Haefliger 已提交
1604
	show_fan, set_fan, SYS_FAN_MAX, ix-1)
J
Juerg Haefliger 已提交
1605 1606 1607 1608 1609 1610 1611 1612

SENSOR_DEVICE_ATTR_FAN_5TO6(5);
SENSOR_DEVICE_ATTR_FAN_5TO6(6);

/* PWMs 1-3 */

#define SENSOR_DEVICE_ATTR_PWM_1TO3(ix) \
static SENSOR_DEVICE_ATTR_2(pwm##ix, S_IRUGO, \
J
Juerg Haefliger 已提交
1613
	show_pwm, set_pwm, SYS_PWM, ix-1); \
J
Juerg Haefliger 已提交
1614
static SENSOR_DEVICE_ATTR_2(pwm##ix##_freq, S_IRUGO, \
J
Juerg Haefliger 已提交
1615
	show_pwm, set_pwm, SYS_PWM_FREQ, ix-1); \
J
Juerg Haefliger 已提交
1616
static SENSOR_DEVICE_ATTR_2(pwm##ix##_enable, S_IRUGO, \
J
Juerg Haefliger 已提交
1617
	show_pwm, set_pwm, SYS_PWM_ENABLE, ix-1); \
J
Juerg Haefliger 已提交
1618
static SENSOR_DEVICE_ATTR_2(pwm##ix##_ramp_rate, S_IRUGO, \
J
Juerg Haefliger 已提交
1619
	show_pwm, set_pwm, SYS_PWM_RAMP_RATE, ix-1); \
J
Juerg Haefliger 已提交
1620
static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_channels_zone, S_IRUGO, \
J
Juerg Haefliger 已提交
1621
	show_pwm, set_pwm, SYS_PWM_AUTO_CHANNELS_ZONE, ix-1); \
J
Juerg Haefliger 已提交
1622
static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_pwm_min, S_IRUGO, \
J
Juerg Haefliger 已提交
1623
	show_pwm, set_pwm, SYS_PWM_AUTO_PWM_MIN, ix-1); \
J
Juerg Haefliger 已提交
1624
static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_point1_pwm, S_IRUGO, \
J
Juerg Haefliger 已提交
1625
	show_pwm, set_pwm, SYS_PWM_AUTO_POINT1_PWM, ix-1); \
J
Juerg Haefliger 已提交
1626
static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_point2_pwm, S_IRUGO, \
J
Juerg Haefliger 已提交
1627
	show_pwm, NULL, SYS_PWM_AUTO_POINT2_PWM, ix-1)
J
Juerg Haefliger 已提交
1628 1629 1630 1631 1632 1633 1634 1635

SENSOR_DEVICE_ATTR_PWM_1TO3(1);
SENSOR_DEVICE_ATTR_PWM_1TO3(2);
SENSOR_DEVICE_ATTR_PWM_1TO3(3);

/* PWMs 5-6 */

#define SENSOR_DEVICE_ATTR_PWM_5TO6(ix) \
1636
static SENSOR_DEVICE_ATTR_2(pwm##ix, S_IRUGO, \
J
Juerg Haefliger 已提交
1637
	show_pwm, set_pwm, SYS_PWM, ix-1); \
1638
static SENSOR_DEVICE_ATTR_2(pwm##ix##_freq, S_IRUGO, \
J
Juerg Haefliger 已提交
1639
	show_pwm, set_pwm, SYS_PWM_FREQ, ix-1); \
J
Juerg Haefliger 已提交
1640
static SENSOR_DEVICE_ATTR_2(pwm##ix##_enable, S_IRUGO, \
J
Juerg Haefliger 已提交
1641
	show_pwm, NULL, SYS_PWM_ENABLE, ix-1)
J
Juerg Haefliger 已提交
1642 1643 1644 1645 1646 1647 1648 1649

SENSOR_DEVICE_ATTR_PWM_5TO6(5);
SENSOR_DEVICE_ATTR_PWM_5TO6(6);

/* Misc */

static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
1650
static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);   /* for ISA devices */
J
Juerg Haefliger 已提交
1651

1652 1653
/*
 * This struct holds all the attributes that are always present and need to be
J
Juerg Haefliger 已提交
1654 1655
 * created unconditionally. The attributes that need modification of their
 * permissions are created read-only and write permissions are added or removed
1656 1657
 * on the fly when required
 */
1658
static struct attribute *dme1737_attr[] = {
J
Juerg Haefliger 已提交
1659
	/* Voltages */
1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687
	&sensor_dev_attr_in0_input.dev_attr.attr,
	&sensor_dev_attr_in0_min.dev_attr.attr,
	&sensor_dev_attr_in0_max.dev_attr.attr,
	&sensor_dev_attr_in0_alarm.dev_attr.attr,
	&sensor_dev_attr_in1_input.dev_attr.attr,
	&sensor_dev_attr_in1_min.dev_attr.attr,
	&sensor_dev_attr_in1_max.dev_attr.attr,
	&sensor_dev_attr_in1_alarm.dev_attr.attr,
	&sensor_dev_attr_in2_input.dev_attr.attr,
	&sensor_dev_attr_in2_min.dev_attr.attr,
	&sensor_dev_attr_in2_max.dev_attr.attr,
	&sensor_dev_attr_in2_alarm.dev_attr.attr,
	&sensor_dev_attr_in3_input.dev_attr.attr,
	&sensor_dev_attr_in3_min.dev_attr.attr,
	&sensor_dev_attr_in3_max.dev_attr.attr,
	&sensor_dev_attr_in3_alarm.dev_attr.attr,
	&sensor_dev_attr_in4_input.dev_attr.attr,
	&sensor_dev_attr_in4_min.dev_attr.attr,
	&sensor_dev_attr_in4_max.dev_attr.attr,
	&sensor_dev_attr_in4_alarm.dev_attr.attr,
	&sensor_dev_attr_in5_input.dev_attr.attr,
	&sensor_dev_attr_in5_min.dev_attr.attr,
	&sensor_dev_attr_in5_max.dev_attr.attr,
	&sensor_dev_attr_in5_alarm.dev_attr.attr,
	&sensor_dev_attr_in6_input.dev_attr.attr,
	&sensor_dev_attr_in6_min.dev_attr.attr,
	&sensor_dev_attr_in6_max.dev_attr.attr,
	&sensor_dev_attr_in6_alarm.dev_attr.attr,
J
Juerg Haefliger 已提交
1688
	/* Temperatures */
1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703
	&sensor_dev_attr_temp1_input.dev_attr.attr,
	&sensor_dev_attr_temp1_min.dev_attr.attr,
	&sensor_dev_attr_temp1_max.dev_attr.attr,
	&sensor_dev_attr_temp1_alarm.dev_attr.attr,
	&sensor_dev_attr_temp1_fault.dev_attr.attr,
	&sensor_dev_attr_temp2_input.dev_attr.attr,
	&sensor_dev_attr_temp2_min.dev_attr.attr,
	&sensor_dev_attr_temp2_max.dev_attr.attr,
	&sensor_dev_attr_temp2_alarm.dev_attr.attr,
	&sensor_dev_attr_temp2_fault.dev_attr.attr,
	&sensor_dev_attr_temp3_input.dev_attr.attr,
	&sensor_dev_attr_temp3_min.dev_attr.attr,
	&sensor_dev_attr_temp3_max.dev_attr.attr,
	&sensor_dev_attr_temp3_alarm.dev_attr.attr,
	&sensor_dev_attr_temp3_fault.dev_attr.attr,
J
Juerg Haefliger 已提交
1704
	/* Zones */
1705 1706 1707 1708 1709 1710 1711 1712
	&sensor_dev_attr_zone1_auto_point1_temp.dev_attr.attr,
	&sensor_dev_attr_zone1_auto_point2_temp.dev_attr.attr,
	&sensor_dev_attr_zone1_auto_point3_temp.dev_attr.attr,
	&sensor_dev_attr_zone1_auto_channels_temp.dev_attr.attr,
	&sensor_dev_attr_zone2_auto_point1_temp.dev_attr.attr,
	&sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr,
	&sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr,
	&sensor_dev_attr_zone2_auto_channels_temp.dev_attr.attr,
1713 1714 1715 1716 1717 1718 1719
	NULL
};

static const struct attribute_group dme1737_group = {
	.attrs = dme1737_attr,
};

1720 1721
/*
 * The following struct holds temp offset attributes, which are not available
1722
 * in all chips. The following chips support them:
1723 1724
 * DME1737, SCH311x
 */
1725
static struct attribute *dme1737_temp_offset_attr[] = {
1726 1727 1728
	&sensor_dev_attr_temp1_offset.dev_attr.attr,
	&sensor_dev_attr_temp2_offset.dev_attr.attr,
	&sensor_dev_attr_temp3_offset.dev_attr.attr,
J
Juerg Haefliger 已提交
1729 1730 1731
	NULL
};

1732 1733
static const struct attribute_group dme1737_temp_offset_group = {
	.attrs = dme1737_temp_offset_attr,
J
Juerg Haefliger 已提交
1734 1735
};

1736 1737
/*
 * The following struct holds VID related attributes, which are not available
1738
 * in all chips. The following chips support them:
1739 1740
 * DME1737
 */
1741 1742 1743 1744 1745 1746 1747 1748 1749 1750
static struct attribute *dme1737_vid_attr[] = {
	&dev_attr_vrm.attr,
	&dev_attr_cpu0_vid.attr,
	NULL
};

static const struct attribute_group dme1737_vid_group = {
	.attrs = dme1737_vid_attr,
};

1751 1752
/*
 * The following struct holds temp zone 3 related attributes, which are not
1753
 * available in all chips. The following chips support them:
1754 1755
 * DME1737, SCH311x, SCH5027
 */
1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768
static struct attribute *dme1737_zone3_attr[] = {
	&sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr,
	&sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr,
	&sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr,
	&sensor_dev_attr_zone3_auto_channels_temp.dev_attr.attr,
	NULL
};

static const struct attribute_group dme1737_zone3_group = {
	.attrs = dme1737_zone3_attr,
};


1769 1770
/*
 * The following struct holds temp zone hysteresis related attributes, which
1771
 * are not available in all chips. The following chips support them:
1772 1773
 * DME1737, SCH311x
 */
1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784
static struct attribute *dme1737_zone_hyst_attr[] = {
	&sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr,
	&sensor_dev_attr_zone2_auto_point1_temp_hyst.dev_attr.attr,
	&sensor_dev_attr_zone3_auto_point1_temp_hyst.dev_attr.attr,
	NULL
};

static const struct attribute_group dme1737_zone_hyst_group = {
	.attrs = dme1737_zone_hyst_attr,
};

1785 1786
/*
 * The following struct holds voltage in7 related attributes, which
1787
 * are not available in all chips. The following chips support them:
1788 1789
 * SCH5127
 */
1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801
static struct attribute *dme1737_in7_attr[] = {
	&sensor_dev_attr_in7_input.dev_attr.attr,
	&sensor_dev_attr_in7_min.dev_attr.attr,
	&sensor_dev_attr_in7_max.dev_attr.attr,
	&sensor_dev_attr_in7_alarm.dev_attr.attr,
	NULL
};

static const struct attribute_group dme1737_in7_group = {
	.attrs = dme1737_in7_attr,
};

1802 1803
/*
 * The following structs hold the PWM attributes, some of which are optional.
J
Juerg Haefliger 已提交
1804
 * Their creation depends on the chip configuration which is determined during
1805 1806
 * module load.
 */
J
Juerg Haefliger 已提交
1807
static struct attribute *dme1737_pwm1_attr[] = {
1808 1809 1810 1811 1812 1813 1814
	&sensor_dev_attr_pwm1.dev_attr.attr,
	&sensor_dev_attr_pwm1_freq.dev_attr.attr,
	&sensor_dev_attr_pwm1_enable.dev_attr.attr,
	&sensor_dev_attr_pwm1_ramp_rate.dev_attr.attr,
	&sensor_dev_attr_pwm1_auto_channels_zone.dev_attr.attr,
	&sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
	&sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
J
Juerg Haefliger 已提交
1815 1816
	NULL
};
J
Juerg Haefliger 已提交
1817
static struct attribute *dme1737_pwm2_attr[] = {
1818 1819 1820 1821 1822 1823 1824
	&sensor_dev_attr_pwm2.dev_attr.attr,
	&sensor_dev_attr_pwm2_freq.dev_attr.attr,
	&sensor_dev_attr_pwm2_enable.dev_attr.attr,
	&sensor_dev_attr_pwm2_ramp_rate.dev_attr.attr,
	&sensor_dev_attr_pwm2_auto_channels_zone.dev_attr.attr,
	&sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
	&sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
J
Juerg Haefliger 已提交
1825 1826
	NULL
};
J
Juerg Haefliger 已提交
1827
static struct attribute *dme1737_pwm3_attr[] = {
1828 1829 1830 1831 1832 1833 1834
	&sensor_dev_attr_pwm3.dev_attr.attr,
	&sensor_dev_attr_pwm3_freq.dev_attr.attr,
	&sensor_dev_attr_pwm3_enable.dev_attr.attr,
	&sensor_dev_attr_pwm3_ramp_rate.dev_attr.attr,
	&sensor_dev_attr_pwm3_auto_channels_zone.dev_attr.attr,
	&sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
	&sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr,
J
Juerg Haefliger 已提交
1835 1836
	NULL
};
J
Juerg Haefliger 已提交
1837
static struct attribute *dme1737_pwm5_attr[] = {
1838 1839 1840
	&sensor_dev_attr_pwm5.dev_attr.attr,
	&sensor_dev_attr_pwm5_freq.dev_attr.attr,
	&sensor_dev_attr_pwm5_enable.dev_attr.attr,
J
Juerg Haefliger 已提交
1841 1842
	NULL
};
J
Juerg Haefliger 已提交
1843
static struct attribute *dme1737_pwm6_attr[] = {
1844 1845 1846
	&sensor_dev_attr_pwm6.dev_attr.attr,
	&sensor_dev_attr_pwm6_freq.dev_attr.attr,
	&sensor_dev_attr_pwm6_enable.dev_attr.attr,
J
Juerg Haefliger 已提交
1847 1848 1849 1850
	NULL
};

static const struct attribute_group dme1737_pwm_group[] = {
J
Juerg Haefliger 已提交
1851 1852 1853
	{ .attrs = dme1737_pwm1_attr },
	{ .attrs = dme1737_pwm2_attr },
	{ .attrs = dme1737_pwm3_attr },
J
Juerg Haefliger 已提交
1854
	{ .attrs = NULL },
J
Juerg Haefliger 已提交
1855 1856
	{ .attrs = dme1737_pwm5_attr },
	{ .attrs = dme1737_pwm6_attr },
J
Juerg Haefliger 已提交
1857 1858
};

1859 1860
/*
 * The following struct holds auto PWM min attributes, which are not available
1861
 * in all chips. Their creation depends on the chip type which is determined
1862 1863
 * during module load.
 */
1864
static struct attribute *dme1737_auto_pwm_min_attr[] = {
1865 1866 1867 1868 1869
	&sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr,
	&sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr,
	&sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr,
};

1870 1871
/*
 * The following structs hold the fan attributes, some of which are optional.
J
Juerg Haefliger 已提交
1872
 * Their creation depends on the chip configuration which is determined during
1873 1874
 * module load.
 */
J
Juerg Haefliger 已提交
1875
static struct attribute *dme1737_fan1_attr[] = {
1876 1877 1878 1879
	&sensor_dev_attr_fan1_input.dev_attr.attr,
	&sensor_dev_attr_fan1_min.dev_attr.attr,
	&sensor_dev_attr_fan1_alarm.dev_attr.attr,
	&sensor_dev_attr_fan1_type.dev_attr.attr,
J
Juerg Haefliger 已提交
1880 1881
	NULL
};
J
Juerg Haefliger 已提交
1882
static struct attribute *dme1737_fan2_attr[] = {
1883 1884 1885 1886
	&sensor_dev_attr_fan2_input.dev_attr.attr,
	&sensor_dev_attr_fan2_min.dev_attr.attr,
	&sensor_dev_attr_fan2_alarm.dev_attr.attr,
	&sensor_dev_attr_fan2_type.dev_attr.attr,
J
Juerg Haefliger 已提交
1887 1888
	NULL
};
J
Juerg Haefliger 已提交
1889
static struct attribute *dme1737_fan3_attr[] = {
1890 1891 1892 1893
	&sensor_dev_attr_fan3_input.dev_attr.attr,
	&sensor_dev_attr_fan3_min.dev_attr.attr,
	&sensor_dev_attr_fan3_alarm.dev_attr.attr,
	&sensor_dev_attr_fan3_type.dev_attr.attr,
J
Juerg Haefliger 已提交
1894 1895
	NULL
};
J
Juerg Haefliger 已提交
1896
static struct attribute *dme1737_fan4_attr[] = {
1897 1898 1899 1900
	&sensor_dev_attr_fan4_input.dev_attr.attr,
	&sensor_dev_attr_fan4_min.dev_attr.attr,
	&sensor_dev_attr_fan4_alarm.dev_attr.attr,
	&sensor_dev_attr_fan4_type.dev_attr.attr,
J
Juerg Haefliger 已提交
1901 1902
	NULL
};
J
Juerg Haefliger 已提交
1903
static struct attribute *dme1737_fan5_attr[] = {
1904 1905 1906 1907
	&sensor_dev_attr_fan5_input.dev_attr.attr,
	&sensor_dev_attr_fan5_min.dev_attr.attr,
	&sensor_dev_attr_fan5_alarm.dev_attr.attr,
	&sensor_dev_attr_fan5_max.dev_attr.attr,
J
Juerg Haefliger 已提交
1908 1909
	NULL
};
J
Juerg Haefliger 已提交
1910
static struct attribute *dme1737_fan6_attr[] = {
1911 1912 1913 1914
	&sensor_dev_attr_fan6_input.dev_attr.attr,
	&sensor_dev_attr_fan6_min.dev_attr.attr,
	&sensor_dev_attr_fan6_alarm.dev_attr.attr,
	&sensor_dev_attr_fan6_max.dev_attr.attr,
J
Juerg Haefliger 已提交
1915 1916 1917 1918
	NULL
};

static const struct attribute_group dme1737_fan_group[] = {
J
Juerg Haefliger 已提交
1919 1920 1921 1922 1923 1924
	{ .attrs = dme1737_fan1_attr },
	{ .attrs = dme1737_fan2_attr },
	{ .attrs = dme1737_fan3_attr },
	{ .attrs = dme1737_fan4_attr },
	{ .attrs = dme1737_fan5_attr },
	{ .attrs = dme1737_fan6_attr },
J
Juerg Haefliger 已提交
1925 1926
};

1927 1928 1929 1930
/*
 * The permissions of the following zone attributes are changed to read-
 * writeable if the chip is *not* locked. Otherwise they stay read-only.
 */
1931
static struct attribute *dme1737_zone_chmod_attr[] = {
1932 1933 1934 1935 1936 1937
	&sensor_dev_attr_zone1_auto_point1_temp.dev_attr.attr,
	&sensor_dev_attr_zone1_auto_point2_temp.dev_attr.attr,
	&sensor_dev_attr_zone1_auto_point3_temp.dev_attr.attr,
	&sensor_dev_attr_zone2_auto_point1_temp.dev_attr.attr,
	&sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr,
	&sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr,
1938 1939 1940 1941 1942 1943 1944 1945
	NULL
};

static const struct attribute_group dme1737_zone_chmod_group = {
	.attrs = dme1737_zone_chmod_attr,
};


1946 1947 1948 1949
/*
 * The permissions of the following zone 3 attributes are changed to read-
 * writeable if the chip is *not* locked. Otherwise they stay read-only.
 */
1950
static struct attribute *dme1737_zone3_chmod_attr[] = {
1951 1952 1953
	&sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr,
	&sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr,
	&sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr,
J
Juerg Haefliger 已提交
1954 1955 1956
	NULL
};

1957 1958
static const struct attribute_group dme1737_zone3_chmod_group = {
	.attrs = dme1737_zone3_chmod_attr,
J
Juerg Haefliger 已提交
1959 1960
};

1961 1962
/*
 * The permissions of the following PWM attributes are changed to read-
J
Juerg Haefliger 已提交
1963
 * writeable if the chip is *not* locked and the respective PWM is available.
1964 1965
 * Otherwise they stay read-only.
 */
J
Juerg Haefliger 已提交
1966
static struct attribute *dme1737_pwm1_chmod_attr[] = {
1967 1968 1969 1970 1971
	&sensor_dev_attr_pwm1_freq.dev_attr.attr,
	&sensor_dev_attr_pwm1_enable.dev_attr.attr,
	&sensor_dev_attr_pwm1_ramp_rate.dev_attr.attr,
	&sensor_dev_attr_pwm1_auto_channels_zone.dev_attr.attr,
	&sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
J
Juerg Haefliger 已提交
1972 1973
	NULL
};
J
Juerg Haefliger 已提交
1974
static struct attribute *dme1737_pwm2_chmod_attr[] = {
1975 1976 1977 1978 1979
	&sensor_dev_attr_pwm2_freq.dev_attr.attr,
	&sensor_dev_attr_pwm2_enable.dev_attr.attr,
	&sensor_dev_attr_pwm2_ramp_rate.dev_attr.attr,
	&sensor_dev_attr_pwm2_auto_channels_zone.dev_attr.attr,
	&sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
J
Juerg Haefliger 已提交
1980 1981
	NULL
};
J
Juerg Haefliger 已提交
1982
static struct attribute *dme1737_pwm3_chmod_attr[] = {
1983 1984 1985 1986 1987
	&sensor_dev_attr_pwm3_freq.dev_attr.attr,
	&sensor_dev_attr_pwm3_enable.dev_attr.attr,
	&sensor_dev_attr_pwm3_ramp_rate.dev_attr.attr,
	&sensor_dev_attr_pwm3_auto_channels_zone.dev_attr.attr,
	&sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
J
Juerg Haefliger 已提交
1988 1989
	NULL
};
J
Juerg Haefliger 已提交
1990
static struct attribute *dme1737_pwm5_chmod_attr[] = {
1991 1992
	&sensor_dev_attr_pwm5.dev_attr.attr,
	&sensor_dev_attr_pwm5_freq.dev_attr.attr,
J
Juerg Haefliger 已提交
1993 1994
	NULL
};
J
Juerg Haefliger 已提交
1995
static struct attribute *dme1737_pwm6_chmod_attr[] = {
1996 1997
	&sensor_dev_attr_pwm6.dev_attr.attr,
	&sensor_dev_attr_pwm6_freq.dev_attr.attr,
J
Juerg Haefliger 已提交
1998 1999 2000
	NULL
};

J
Juerg Haefliger 已提交
2001 2002 2003 2004
static const struct attribute_group dme1737_pwm_chmod_group[] = {
	{ .attrs = dme1737_pwm1_chmod_attr },
	{ .attrs = dme1737_pwm2_chmod_attr },
	{ .attrs = dme1737_pwm3_chmod_attr },
J
Juerg Haefliger 已提交
2005
	{ .attrs = NULL },
J
Juerg Haefliger 已提交
2006 2007
	{ .attrs = dme1737_pwm5_chmod_attr },
	{ .attrs = dme1737_pwm6_chmod_attr },
J
Juerg Haefliger 已提交
2008 2009
};

2010 2011 2012 2013
/*
 * Pwm[1-3] are read-writeable if the associated pwm is in manual mode and the
 * chip is not locked. Otherwise they are read-only.
 */
J
Juerg Haefliger 已提交
2014
static struct attribute *dme1737_pwm_chmod_attr[] = {
J
Juerg Haefliger 已提交
2015 2016 2017 2018 2019 2020 2021 2022 2023
	&sensor_dev_attr_pwm1.dev_attr.attr,
	&sensor_dev_attr_pwm2.dev_attr.attr,
	&sensor_dev_attr_pwm3.dev_attr.attr,
};

/* ---------------------------------------------------------------------
 * Super-IO functions
 * --------------------------------------------------------------------- */

J
Juerg Haefliger 已提交
2024 2025 2026 2027 2028 2029 2030 2031 2032 2033
static inline void dme1737_sio_enter(int sio_cip)
{
	outb(0x55, sio_cip);
}

static inline void dme1737_sio_exit(int sio_cip)
{
	outb(0xaa, sio_cip);
}

J
Juerg Haefliger 已提交
2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046
static inline int dme1737_sio_inb(int sio_cip, int reg)
{
	outb(reg, sio_cip);
	return inb(sio_cip + 1);
}

static inline void dme1737_sio_outb(int sio_cip, int reg, int val)
{
	outb(reg, sio_cip);
	outb(val, sio_cip + 1);
}

/* ---------------------------------------------------------------------
2047
 * Device initialization
J
Juerg Haefliger 已提交
2048 2049
 * --------------------------------------------------------------------- */

2050
static int dme1737_i2c_get_features(int, struct dme1737_data*);
J
Juerg Haefliger 已提交
2051

J
Juerg Haefliger 已提交
2052
static void dme1737_chmod_file(struct device *dev,
A
Al Viro 已提交
2053
			       struct attribute *attr, umode_t mode)
J
Juerg Haefliger 已提交
2054
{
J
Juerg Haefliger 已提交
2055 2056
	if (sysfs_chmod_file(&dev->kobj, attr, mode)) {
		dev_warn(dev, "Failed to change permissions of %s.\n",
J
Juerg Haefliger 已提交
2057 2058 2059 2060
			 attr->name);
	}
}

J
Juerg Haefliger 已提交
2061
static void dme1737_chmod_group(struct device *dev,
J
Juerg Haefliger 已提交
2062
				const struct attribute_group *group,
A
Al Viro 已提交
2063
				umode_t mode)
J
Juerg Haefliger 已提交
2064 2065 2066
{
	struct attribute **attr;

2067
	for (attr = group->attrs; *attr; attr++)
J
Juerg Haefliger 已提交
2068
		dme1737_chmod_file(dev, *attr, mode);
J
Juerg Haefliger 已提交
2069 2070
}

J
Juerg Haefliger 已提交
2071
static void dme1737_remove_files(struct device *dev)
J
Juerg Haefliger 已提交
2072
{
J
Juerg Haefliger 已提交
2073 2074 2075 2076
	struct dme1737_data *data = dev_get_drvdata(dev);
	int ix;

	for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) {
2077
		if (data->has_features & HAS_FAN(ix)) {
J
Juerg Haefliger 已提交
2078 2079 2080 2081 2082 2083
			sysfs_remove_group(&dev->kobj,
					   &dme1737_fan_group[ix]);
		}
	}

	for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) {
2084
		if (data->has_features & HAS_PWM(ix)) {
J
Juerg Haefliger 已提交
2085 2086
			sysfs_remove_group(&dev->kobj,
					   &dme1737_pwm_group[ix]);
2087
			if ((data->has_features & HAS_PWM_MIN) && ix < 3) {
2088
				sysfs_remove_file(&dev->kobj,
2089
						dme1737_auto_pwm_min_attr[ix]);
2090
			}
J
Juerg Haefliger 已提交
2091 2092 2093
		}
	}

2094
	if (data->has_features & HAS_TEMP_OFFSET)
2095
		sysfs_remove_group(&dev->kobj, &dme1737_temp_offset_group);
2096
	if (data->has_features & HAS_VID)
2097
		sysfs_remove_group(&dev->kobj, &dme1737_vid_group);
2098
	if (data->has_features & HAS_ZONE3)
2099
		sysfs_remove_group(&dev->kobj, &dme1737_zone3_group);
2100
	if (data->has_features & HAS_ZONE_HYST)
2101
		sysfs_remove_group(&dev->kobj, &dme1737_zone_hyst_group);
2102
	if (data->has_features & HAS_IN7)
2103
		sysfs_remove_group(&dev->kobj, &dme1737_in7_group);
J
Juerg Haefliger 已提交
2104
	sysfs_remove_group(&dev->kobj, &dme1737_group);
2105

2106
	if (!data->client)
2107
		sysfs_remove_file(&dev->kobj, &dev_attr_name.attr);
J
Juerg Haefliger 已提交
2108 2109 2110 2111 2112 2113 2114
}

static int dme1737_create_files(struct device *dev)
{
	struct dme1737_data *data = dev_get_drvdata(dev);
	int err, ix;

2115
	/* Create a name attribute for ISA devices */
2116 2117
	if (!data->client) {
		err = sysfs_create_file(&dev->kobj, &dev_attr_name.attr);
2118
		if (err)
2119
			goto exit;
2120 2121
	}

J
Juerg Haefliger 已提交
2122
	/* Create standard sysfs attributes */
2123
	err = sysfs_create_group(&dev->kobj, &dme1737_group);
2124
	if (err)
2125
		goto exit_remove;
J
Juerg Haefliger 已提交
2126

2127
	/* Create chip-dependent sysfs attributes */
2128 2129 2130
	if (data->has_features & HAS_TEMP_OFFSET) {
		err = sysfs_create_group(&dev->kobj,
					 &dme1737_temp_offset_group);
2131
		if (err)
2132
			goto exit_remove;
2133
	}
2134 2135
	if (data->has_features & HAS_VID) {
		err = sysfs_create_group(&dev->kobj, &dme1737_vid_group);
2136
		if (err)
2137
			goto exit_remove;
2138
	}
2139 2140
	if (data->has_features & HAS_ZONE3) {
		err = sysfs_create_group(&dev->kobj, &dme1737_zone3_group);
2141
		if (err)
2142
			goto exit_remove;
2143
	}
2144 2145
	if (data->has_features & HAS_ZONE_HYST) {
		err = sysfs_create_group(&dev->kobj, &dme1737_zone_hyst_group);
2146
		if (err)
2147
			goto exit_remove;
2148
	}
2149 2150
	if (data->has_features & HAS_IN7) {
		err = sysfs_create_group(&dev->kobj, &dme1737_in7_group);
2151
		if (err)
2152 2153
			goto exit_remove;
	}
2154

J
Juerg Haefliger 已提交
2155 2156
	/* Create fan sysfs attributes */
	for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) {
2157
		if (data->has_features & HAS_FAN(ix)) {
2158 2159
			err = sysfs_create_group(&dev->kobj,
						 &dme1737_fan_group[ix]);
2160
			if (err)
J
Juerg Haefliger 已提交
2161 2162 2163 2164 2165 2166
				goto exit_remove;
		}
	}

	/* Create PWM sysfs attributes */
	for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) {
2167
		if (data->has_features & HAS_PWM(ix)) {
2168 2169
			err = sysfs_create_group(&dev->kobj,
						 &dme1737_pwm_group[ix]);
2170
			if (err)
J
Juerg Haefliger 已提交
2171
				goto exit_remove;
2172 2173 2174
			if ((data->has_features & HAS_PWM_MIN) && (ix < 3)) {
				err = sysfs_create_file(&dev->kobj,
						dme1737_auto_pwm_min_attr[ix]);
2175
				if (err)
2176
					goto exit_remove;
2177
			}
J
Juerg Haefliger 已提交
2178 2179 2180
		}
	}

2181 2182 2183 2184
	/*
	 * Inform if the device is locked. Otherwise change the permissions of
	 * selected attributes from read-only to read-writeable.
	 */
J
Juerg Haefliger 已提交
2185
	if (data->config & 0x02) {
2186 2187
		dev_info(dev,
			 "Device is locked. Some attributes will be read-only.\n");
J
Juerg Haefliger 已提交
2188
	} else {
2189 2190
		/* Change permissions of zone sysfs attributes */
		dme1737_chmod_group(dev, &dme1737_zone_chmod_group,
J
Juerg Haefliger 已提交
2191 2192
				    S_IRUGO | S_IWUSR);

2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203
		/* Change permissions of chip-dependent sysfs attributes */
		if (data->has_features & HAS_TEMP_OFFSET) {
			dme1737_chmod_group(dev, &dme1737_temp_offset_group,
					    S_IRUGO | S_IWUSR);
		}
		if (data->has_features & HAS_ZONE3) {
			dme1737_chmod_group(dev, &dme1737_zone3_chmod_group,
					    S_IRUGO | S_IWUSR);
		}
		if (data->has_features & HAS_ZONE_HYST) {
			dme1737_chmod_group(dev, &dme1737_zone_hyst_group,
2204 2205 2206
					    S_IRUGO | S_IWUSR);
		}

J
Juerg Haefliger 已提交
2207 2208
		/* Change permissions of PWM sysfs attributes */
		for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_chmod_group); ix++) {
2209
			if (data->has_features & HAS_PWM(ix)) {
J
Juerg Haefliger 已提交
2210
				dme1737_chmod_group(dev,
J
Juerg Haefliger 已提交
2211
						&dme1737_pwm_chmod_group[ix],
J
Juerg Haefliger 已提交
2212
						S_IRUGO | S_IWUSR);
2213 2214
				if ((data->has_features & HAS_PWM_MIN) &&
				    ix < 3) {
2215
					dme1737_chmod_file(dev,
2216
						dme1737_auto_pwm_min_attr[ix],
2217 2218
						S_IRUGO | S_IWUSR);
				}
J
Juerg Haefliger 已提交
2219 2220 2221 2222 2223
			}
		}

		/* Change permissions of pwm[1-3] if in manual mode */
		for (ix = 0; ix < 3; ix++) {
2224
			if ((data->has_features & HAS_PWM(ix)) &&
J
Juerg Haefliger 已提交
2225 2226
			    (PWM_EN_FROM_REG(data->pwm_config[ix]) == 1)) {
				dme1737_chmod_file(dev,
J
Juerg Haefliger 已提交
2227
						dme1737_pwm_chmod_attr[ix],
J
Juerg Haefliger 已提交
2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243
						S_IRUGO | S_IWUSR);
			}
		}
	}

	return 0;

exit_remove:
	dme1737_remove_files(dev);
exit:
	return err;
}

static int dme1737_init_device(struct device *dev)
{
	struct dme1737_data *data = dev_get_drvdata(dev);
2244
	struct i2c_client *client = data->client;
J
Juerg Haefliger 已提交
2245 2246 2247
	int ix;
	u8 reg;

2248 2249 2250
	/* Point to the right nominal voltages array */
	data->in_nominal = IN_NOMINAL(data->type);

2251
	data->config = dme1737_read(data, DME1737_REG_CONFIG);
J
Juerg Haefliger 已提交
2252 2253 2254
	/* Inform if part is not monitoring/started */
	if (!(data->config & 0x01)) {
		if (!force_start) {
2255 2256
			dev_err(dev,
				"Device is not monitoring. Use the force_start load parameter to override.\n");
J
Juerg Haefliger 已提交
2257 2258 2259 2260 2261
			return -EFAULT;
		}

		/* Force monitoring */
		data->config |= 0x01;
2262
		dme1737_write(data, DME1737_REG_CONFIG, data->config);
J
Juerg Haefliger 已提交
2263
	}
J
Juerg Haefliger 已提交
2264 2265
	/* Inform if part is not ready */
	if (!(data->config & 0x04)) {
J
Juerg Haefliger 已提交
2266
		dev_err(dev, "Device is not ready.\n");
J
Juerg Haefliger 已提交
2267 2268 2269
		return -EFAULT;
	}

2270 2271 2272 2273
	/*
	 * Determine which optional fan and pwm features are enabled (only
	 * valid for I2C devices)
	 */
2274 2275
	if (client) {   /* I2C chip */
		data->config2 = dme1737_read(data, DME1737_REG_CONFIG2);
2276
		/* Check if optional fan3 input is enabled */
2277
		if (data->config2 & 0x04)
2278
			data->has_features |= HAS_FAN(2);
J
Juerg Haefliger 已提交
2279

2280 2281
		/*
		 * Fan4 and pwm3 are only available if the client's I2C address
2282
		 * is the default 0x2e. Otherwise the I/Os associated with
2283 2284 2285
		 * these functions are used for addr enable/select.
		 */
		if (client->addr == 0x2e)
2286
			data->has_features |= HAS_FAN(3) | HAS_PWM(2);
J
Juerg Haefliger 已提交
2287

2288 2289
		/*
		 * Determine which of the optional fan[5-6] and pwm[5-6]
2290 2291
		 * features are enabled. For this, we need to query the runtime
		 * registers through the Super-IO LPC interface. Try both
2292 2293
		 * config ports 0x2e and 0x4e.
		 */
2294 2295
		if (dme1737_i2c_get_features(0x2e, data) &&
		    dme1737_i2c_get_features(0x4e, data)) {
2296 2297
			dev_warn(dev,
				 "Failed to query Super-IO for optional features.\n");
2298
		}
J
Juerg Haefliger 已提交
2299 2300
	}

2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317
	/* Fan[1-2] and pwm[1-2] are present in all chips */
	data->has_features |= HAS_FAN(0) | HAS_FAN(1) | HAS_PWM(0) | HAS_PWM(1);

	/* Chip-dependent features */
	switch (data->type) {
	case dme1737:
		data->has_features |= HAS_TEMP_OFFSET | HAS_VID | HAS_ZONE3 |
			HAS_ZONE_HYST | HAS_PWM_MIN;
		break;
	case sch311x:
		data->has_features |= HAS_TEMP_OFFSET | HAS_ZONE3 |
			HAS_ZONE_HYST | HAS_PWM_MIN | HAS_FAN(2) | HAS_PWM(2);
		break;
	case sch5027:
		data->has_features |= HAS_ZONE3;
		break;
	case sch5127:
2318
		data->has_features |= HAS_FAN(2) | HAS_PWM(2) | HAS_IN7;
2319 2320 2321 2322
		break;
	default:
		break;
	}
J
Juerg Haefliger 已提交
2323

2324 2325
	dev_info(dev,
		 "Optional features: pwm3=%s, pwm5=%s, pwm6=%s, fan3=%s, fan4=%s, fan5=%s, fan6=%s.\n",
2326 2327 2328 2329 2330 2331 2332
		 (data->has_features & HAS_PWM(2)) ? "yes" : "no",
		 (data->has_features & HAS_PWM(4)) ? "yes" : "no",
		 (data->has_features & HAS_PWM(5)) ? "yes" : "no",
		 (data->has_features & HAS_FAN(2)) ? "yes" : "no",
		 (data->has_features & HAS_FAN(3)) ? "yes" : "no",
		 (data->has_features & HAS_FAN(4)) ? "yes" : "no",
		 (data->has_features & HAS_FAN(5)) ? "yes" : "no");
J
Juerg Haefliger 已提交
2333

2334
	reg = dme1737_read(data, DME1737_REG_TACH_PWM);
J
Juerg Haefliger 已提交
2335
	/* Inform if fan-to-pwm mapping differs from the default */
2336
	if (client && reg != 0xa4) {   /* I2C chip */
2337 2338
		dev_warn(dev,
			 "Non-standard fan to pwm mapping: fan1->pwm%d, fan2->pwm%d, fan3->pwm%d, fan4->pwm%d. %s\n",
J
Juerg Haefliger 已提交
2339
			 (reg & 0x03) + 1, ((reg >> 2) & 0x03) + 1,
2340 2341
			 ((reg >> 4) & 0x03) + 1, ((reg >> 6) & 0x03) + 1,
			 DO_REPORT);
2342
	} else if (!client && reg != 0x24) {   /* ISA chip */
2343 2344
		dev_warn(dev,
			 "Non-standard fan to pwm mapping: fan1->pwm%d, fan2->pwm%d, fan3->pwm%d. %s\n",
2345
			 (reg & 0x03) + 1, ((reg >> 2) & 0x03) + 1,
2346
			 ((reg >> 4) & 0x03) + 1, DO_REPORT);
J
Juerg Haefliger 已提交
2347 2348
	}

2349 2350
	/*
	 * Switch pwm[1-3] to manual mode if they are currently disabled and
J
Juerg Haefliger 已提交
2351
	 * set the duty-cycles to 0% (which is identical to the PWMs being
2352 2353
	 * disabled).
	 */
J
Juerg Haefliger 已提交
2354 2355
	if (!(data->config & 0x02)) {
		for (ix = 0; ix < 3; ix++) {
2356
			data->pwm_config[ix] = dme1737_read(data,
J
Juerg Haefliger 已提交
2357
						DME1737_REG_PWM_CONFIG(ix));
2358
			if ((data->has_features & HAS_PWM(ix)) &&
J
Juerg Haefliger 已提交
2359
			    (PWM_EN_FROM_REG(data->pwm_config[ix]) == -1)) {
2360 2361 2362
				dev_info(dev,
					 "Switching pwm%d to manual mode.\n",
					 ix + 1);
J
Juerg Haefliger 已提交
2363 2364
				data->pwm_config[ix] = PWM_EN_TO_REG(1,
							data->pwm_config[ix]);
2365 2366
				dme1737_write(data, DME1737_REG_PWM(ix), 0);
				dme1737_write(data,
J
Juerg Haefliger 已提交
2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378
					      DME1737_REG_PWM_CONFIG(ix),
					      data->pwm_config[ix]);
			}
		}
	}

	/* Initialize the default PWM auto channels zone (acz) assignments */
	data->pwm_acz[0] = 1;	/* pwm1 -> zone1 */
	data->pwm_acz[1] = 2;	/* pwm2 -> zone2 */
	data->pwm_acz[2] = 4;	/* pwm3 -> zone3 */

	/* Set VRM */
2379
	if (data->has_features & HAS_VID)
2380
		data->vrm = vid_which_vrm();
J
Juerg Haefliger 已提交
2381 2382 2383 2384

	return 0;
}

2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397
/* ---------------------------------------------------------------------
 * I2C device detection and registration
 * --------------------------------------------------------------------- */

static struct i2c_driver dme1737_i2c_driver;

static int dme1737_i2c_get_features(int sio_cip, struct dme1737_data *data)
{
	int err = 0, reg;
	u16 addr;

	dme1737_sio_enter(sio_cip);

2398 2399 2400 2401
	/*
	 * Check device ID
	 * We currently know about two kinds of DME1737 and SCH5027.
	 */
2402
	reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20);
2403 2404
	if (!(reg == DME1737_ID_1 || reg == DME1737_ID_2 ||
	      reg == SCH5027_ID)) {
2405 2406 2407 2408 2409 2410 2411 2412
		err = -ENODEV;
		goto exit;
	}

	/* Select logical device A (runtime registers) */
	dme1737_sio_outb(sio_cip, 0x07, 0x0a);

	/* Get the base address of the runtime registers */
2413 2414 2415
	addr = (dme1737_sio_inb(sio_cip, 0x60) << 8) |
		dme1737_sio_inb(sio_cip, 0x61);
	if (!addr) {
2416 2417 2418 2419
		err = -ENODEV;
		goto exit;
	}

2420 2421
	/*
	 * Read the runtime registers to determine which optional features
2422
	 * are enabled and available. Bits [3:2] of registers 0x43-0x46 are set
2423 2424 2425
	 * to '10' if the respective feature is enabled.
	 */
	if ((inb(addr + 0x43) & 0x0c) == 0x08) /* fan6 */
2426
		data->has_features |= HAS_FAN(5);
2427
	if ((inb(addr + 0x44) & 0x0c) == 0x08) /* pwm6 */
2428
		data->has_features |= HAS_PWM(5);
2429
	if ((inb(addr + 0x45) & 0x0c) == 0x08) /* fan5 */
2430
		data->has_features |= HAS_FAN(4);
2431
	if ((inb(addr + 0x46) & 0x0c) == 0x08) /* pwm5 */
2432
		data->has_features |= HAS_PWM(4);
2433 2434 2435 2436 2437 2438 2439

exit:
	dme1737_sio_exit(sio_cip);

	return err;
}

2440
/* Return 0 if detection is successful, -ENODEV otherwise */
2441
static int dme1737_i2c_detect(struct i2c_client *client,
2442
			      struct i2c_board_info *info)
J
Juerg Haefliger 已提交
2443
{
2444 2445
	struct i2c_adapter *adapter = client->adapter;
	struct device *dev = &adapter->dev;
J
Juerg Haefliger 已提交
2446 2447 2448
	u8 company, verstep = 0;
	const char *name;

2449
	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
2450
		return -ENODEV;
J
Juerg Haefliger 已提交
2451

J
Jean Delvare 已提交
2452 2453
	company = i2c_smbus_read_byte_data(client, DME1737_REG_COMPANY);
	verstep = i2c_smbus_read_byte_data(client, DME1737_REG_VERSTEP);
J
Juerg Haefliger 已提交
2454

J
Jean Delvare 已提交
2455 2456
	if (company == DME1737_COMPANY_SMSC &&
	    verstep == SCH5027_VERSTEP) {
2457
		name = "sch5027";
J
Jean Delvare 已提交
2458 2459
	} else if (company == DME1737_COMPANY_SMSC &&
		   (verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP) {
2460
		name = "dme1737";
J
Jean Delvare 已提交
2461 2462
	} else {
		return -ENODEV;
2463
	}
J
Juerg Haefliger 已提交
2464

2465
	dev_info(dev, "Found a %s chip at 0x%02x (rev 0x%02x).\n",
J
Jean Delvare 已提交
2466 2467
		 verstep == SCH5027_VERSTEP ? "SCH5027" : "DME1737",
		 client->addr, verstep);
2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479
	strlcpy(info->type, name, I2C_NAME_SIZE);

	return 0;
}

static int dme1737_i2c_probe(struct i2c_client *client,
			     const struct i2c_device_id *id)
{
	struct dme1737_data *data;
	struct device *dev = &client->dev;
	int err;

2480 2481 2482
	data = devm_kzalloc(dev, sizeof(struct dme1737_data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;
2483 2484 2485 2486 2487 2488

	i2c_set_clientdata(client, data);
	data->type = id->driver_data;
	data->client = client;
	data->name = client->name;
	mutex_init(&data->update_lock);
J
Juerg Haefliger 已提交
2489

J
Juerg Haefliger 已提交
2490
	/* Initialize the DME1737 chip */
2491 2492
	err = dme1737_init_device(dev);
	if (err) {
J
Juerg Haefliger 已提交
2493
		dev_err(dev, "Failed to initialize device.\n");
2494
		return err;
J
Juerg Haefliger 已提交
2495 2496
	}

J
Juerg Haefliger 已提交
2497
	/* Create sysfs files */
2498 2499
	err = dme1737_create_files(dev);
	if (err) {
J
Juerg Haefliger 已提交
2500
		dev_err(dev, "Failed to create sysfs files.\n");
2501
		return err;
J
Juerg Haefliger 已提交
2502 2503 2504
	}

	/* Register device */
2505
	data->hwmon_dev = hwmon_device_register(dev);
2506
	if (IS_ERR(data->hwmon_dev)) {
J
Juerg Haefliger 已提交
2507
		dev_err(dev, "Failed to register device.\n");
2508
		err = PTR_ERR(data->hwmon_dev);
J
Juerg Haefliger 已提交
2509 2510 2511 2512 2513 2514
		goto exit_remove;
	}

	return 0;

exit_remove:
J
Juerg Haefliger 已提交
2515
	dme1737_remove_files(dev);
J
Juerg Haefliger 已提交
2516 2517 2518
	return err;
}

2519
static int dme1737_i2c_remove(struct i2c_client *client)
J
Juerg Haefliger 已提交
2520 2521 2522
{
	struct dme1737_data *data = i2c_get_clientdata(client);

2523
	hwmon_device_unregister(data->hwmon_dev);
J
Juerg Haefliger 已提交
2524
	dme1737_remove_files(&client->dev);
J
Juerg Haefliger 已提交
2525 2526 2527 2528

	return 0;
}

2529 2530 2531 2532 2533 2534 2535
static const struct i2c_device_id dme1737_id[] = {
	{ "dme1737", dme1737 },
	{ "sch5027", sch5027 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, dme1737_id);

J
Juerg Haefliger 已提交
2536
static struct i2c_driver dme1737_i2c_driver = {
2537
	.class = I2C_CLASS_HWMON,
J
Juerg Haefliger 已提交
2538 2539 2540
	.driver = {
		.name = "dme1737",
	},
2541 2542 2543 2544
	.probe = dme1737_i2c_probe,
	.remove = dme1737_i2c_remove,
	.id_table = dme1737_id,
	.detect = dme1737_i2c_detect,
2545
	.address_list = normal_i2c,
J
Juerg Haefliger 已提交
2546 2547
};

2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558
/* ---------------------------------------------------------------------
 * ISA device detection and registration
 * --------------------------------------------------------------------- */

static int __init dme1737_isa_detect(int sio_cip, unsigned short *addr)
{
	int err = 0, reg;
	unsigned short base_addr;

	dme1737_sio_enter(sio_cip);

2559 2560 2561 2562
	/*
	 * Check device ID
	 * We currently know about SCH3112, SCH3114, SCH3116, and SCH5127
	 */
2563
	reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20);
2564 2565
	if (!(reg == SCH3112_ID || reg == SCH3114_ID || reg == SCH3116_ID ||
	      reg == SCH5127_ID)) {
2566 2567 2568 2569 2570 2571 2572 2573
		err = -ENODEV;
		goto exit;
	}

	/* Select logical device A (runtime registers) */
	dme1737_sio_outb(sio_cip, 0x07, 0x0a);

	/* Get the base address of the runtime registers */
2574 2575 2576
	base_addr = (dme1737_sio_inb(sio_cip, 0x60) << 8) |
		     dme1737_sio_inb(sio_cip, 0x61);
	if (!base_addr) {
2577
		pr_err("Base address not set\n");
2578 2579 2580 2581
		err = -ENODEV;
		goto exit;
	}

2582 2583 2584 2585
	/*
	 * Access to the hwmon registers is through an index/data register
	 * pair located at offset 0x70/0x71.
	 */
2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602
	*addr = base_addr + 0x70;

exit:
	dme1737_sio_exit(sio_cip);
	return err;
}

static int __init dme1737_isa_device_add(unsigned short addr)
{
	struct resource res = {
		.start	= addr,
		.end	= addr + DME1737_EXTENT - 1,
		.name	= "dme1737",
		.flags	= IORESOURCE_IO,
	};
	int err;

2603 2604 2605 2606
	err = acpi_check_resource_conflict(&res);
	if (err)
		goto exit;

2607 2608
	pdev = platform_device_alloc("dme1737", addr);
	if (!pdev) {
2609
		pr_err("Failed to allocate device\n");
2610 2611 2612 2613
		err = -ENOMEM;
		goto exit;
	}

2614 2615
	err = platform_device_add_resources(pdev, &res, 1);
	if (err) {
2616
		pr_err("Failed to add device resource (err = %d)\n", err);
2617 2618 2619
		goto exit_device_put;
	}

2620 2621
	err = platform_device_add(pdev);
	if (err) {
2622
		pr_err("Failed to add device (err = %d)\n", err);
2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634
		goto exit_device_put;
	}

	return 0;

exit_device_put:
	platform_device_put(pdev);
	pdev = NULL;
exit:
	return err;
}

B
Bill Pemberton 已提交
2635
static int dme1737_isa_probe(struct platform_device *pdev)
2636 2637 2638 2639 2640 2641 2642 2643
{
	u8 company, device;
	struct resource *res;
	struct dme1737_data *data;
	struct device *dev = &pdev->dev;
	int err;

	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
2644
	if (!devm_request_region(dev, res->start, DME1737_EXTENT, "dme1737")) {
2645 2646 2647
		dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n",
			(unsigned short)res->start,
			(unsigned short)res->start + DME1737_EXTENT - 1);
2648
		return -EBUSY;
2649
	}
2650

2651 2652 2653
	data = devm_kzalloc(dev, sizeof(struct dme1737_data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;
2654

2655
	data->addr = res->start;
2656 2657
	platform_set_drvdata(pdev, data);

2658
	/* Skip chip detection if module is loaded with force_id parameter */
2659 2660 2661 2662 2663 2664 2665 2666 2667 2668
	switch (force_id) {
	case SCH3112_ID:
	case SCH3114_ID:
	case SCH3116_ID:
		data->type = sch311x;
		break;
	case SCH5127_ID:
		data->type = sch5127;
		break;
	default:
2669 2670
		company = dme1737_read(data, DME1737_REG_COMPANY);
		device = dme1737_read(data, DME1737_REG_DEVICE);
2671

2672 2673 2674 2675 2676 2677 2678
		if ((company == DME1737_COMPANY_SMSC) &&
		    (device == SCH311X_DEVICE)) {
			data->type = sch311x;
		} else if ((company == DME1737_COMPANY_SMSC) &&
			   (device == SCH5127_DEVICE)) {
			data->type = sch5127;
		} else {
2679
			return -ENODEV;
2680
		}
2681 2682
	}

2683
	if (data->type == sch5127)
2684
		data->name = "sch5127";
2685
	else
2686 2687 2688
		data->name = "sch311x";

	/* Initialize the mutex */
2689 2690
	mutex_init(&data->update_lock);

2691 2692
	dev_info(dev, "Found a %s chip at 0x%04x\n",
		 data->type == sch5127 ? "SCH5127" : "SCH311x", data->addr);
2693 2694

	/* Initialize the chip */
2695 2696
	err = dme1737_init_device(dev);
	if (err) {
2697
		dev_err(dev, "Failed to initialize device.\n");
2698
		return err;
2699 2700 2701
	}

	/* Create sysfs files */
2702 2703
	err = dme1737_create_files(dev);
	if (err) {
2704
		dev_err(dev, "Failed to create sysfs files.\n");
2705
		return err;
2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722
	}

	/* Register device */
	data->hwmon_dev = hwmon_device_register(dev);
	if (IS_ERR(data->hwmon_dev)) {
		dev_err(dev, "Failed to register device.\n");
		err = PTR_ERR(data->hwmon_dev);
		goto exit_remove_files;
	}

	return 0;

exit_remove_files:
	dme1737_remove_files(dev);
	return err;
}

B
Bill Pemberton 已提交
2723
static int dme1737_isa_remove(struct platform_device *pdev)
2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738
{
	struct dme1737_data *data = platform_get_drvdata(pdev);

	hwmon_device_unregister(data->hwmon_dev);
	dme1737_remove_files(&pdev->dev);

	return 0;
}

static struct platform_driver dme1737_isa_driver = {
	.driver = {
		.owner = THIS_MODULE,
		.name = "dme1737",
	},
	.probe = dme1737_isa_probe,
B
Bill Pemberton 已提交
2739
	.remove = dme1737_isa_remove,
2740 2741
};

2742 2743 2744 2745
/* ---------------------------------------------------------------------
 * Module initialization and cleanup
 * --------------------------------------------------------------------- */

J
Juerg Haefliger 已提交
2746 2747
static int __init dme1737_init(void)
{
2748 2749 2750
	int err;
	unsigned short addr;

2751
	err = i2c_add_driver(&dme1737_i2c_driver);
2752
	if (err)
2753 2754 2755
		goto exit;

	if (dme1737_isa_detect(0x2e, &addr) &&
2756 2757 2758 2759
	    dme1737_isa_detect(0x4e, &addr) &&
	    (!probe_all_addr ||
	     (dme1737_isa_detect(0x162e, &addr) &&
	      dme1737_isa_detect(0x164e, &addr)))) {
2760 2761 2762 2763
		/* Return 0 if we didn't find an ISA device */
		return 0;
	}

2764
	err = platform_driver_register(&dme1737_isa_driver);
2765
	if (err)
2766 2767 2768
		goto exit_del_i2c_driver;

	/* Sets global pdev as a side effect */
2769
	err = dme1737_isa_device_add(addr);
2770
	if (err)
2771 2772 2773 2774 2775 2776 2777 2778 2779 2780
		goto exit_del_isa_driver;

	return 0;

exit_del_isa_driver:
	platform_driver_unregister(&dme1737_isa_driver);
exit_del_i2c_driver:
	i2c_del_driver(&dme1737_i2c_driver);
exit:
	return err;
J
Juerg Haefliger 已提交
2781 2782 2783 2784
}

static void __exit dme1737_exit(void)
{
2785 2786 2787 2788 2789
	if (pdev) {
		platform_device_unregister(pdev);
		platform_driver_unregister(&dme1737_isa_driver);
	}

J
Juerg Haefliger 已提交
2790
	i2c_del_driver(&dme1737_i2c_driver);
J
Juerg Haefliger 已提交
2791 2792 2793 2794 2795 2796 2797 2798
}

MODULE_AUTHOR("Juerg Haefliger <juergh@gmail.com>");
MODULE_DESCRIPTION("DME1737 sensors");
MODULE_LICENSE("GPL");

module_init(dme1737_init);
module_exit(dme1737_exit);