11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * lm85.c - Part of lm_sensors, Linux kernel modules for hardware
309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck *	    monitoring
409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * Copyright (c) 2002, 2003  Philip Pokorny <ppokorny@penguincomputing.com>
609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * Copyright (c) 2003        Margit Schubert-While <margitsw@t-online.de>
709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * Copyright (c) 2004        Justin Thiessen <jthiessen@penguincomputing.com>
8590e8534447ce9f2f5e5e64681764079530ee8c7Jean Delvare * Copyright (C) 2007--2014  Jean Delvare <jdelvare@suse.de>
909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck *
1009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * Chip details at	      <http://www.national.com/ds/LM/LM85.pdf>
1109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck *
1209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * This program is free software; you can redistribute it and/or modify
1309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * it under the terms of the GNU General Public License as published by
1409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * the Free Software Foundation; either version 2 of the License, or
1509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * (at your option) any later version.
1609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck *
1709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * This program is distributed in the hope that it will be useful,
1809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * but WITHOUT ANY WARRANTY; without even the implied warranty of
1909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * GNU General Public License for more details.
2109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck *
2209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * You should have received a copy of the GNU General Public License
2309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * along with this program; if not, write to the Free Software
2409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck */
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h>
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/slab.h>
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/jiffies.h>
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/i2c.h>
32943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman#include <linux/hwmon.h>
33303760b44a7a142cb9f4c9df4609fb63bbda98dbJean Delvare#include <linux/hwmon-vid.h>
34b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare#include <linux/hwmon-sysfs.h>
35943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman#include <linux/err.h>
369a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar#include <linux/mutex.h>
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Addresses to scan */
3925e9c86d5a6d82ea45eb680fc66bf73ac5e50dffMark M. Hoffmanstatic const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
41e5e9f44c246fbafe723e579e9fe887677beb40e4Jean Delvareenum chips {
42590e8534447ce9f2f5e5e64681764079530ee8c7Jean Delvare	lm85,
43e5e9f44c246fbafe723e579e9fe887677beb40e4Jean Delvare	adm1027, adt7463, adt7468,
4406923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck	emc6d100, emc6d102, emc6d103, emc6d103s
45e5e9f44c246fbafe723e579e9fe887677beb40e4Jean Delvare};
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* The LM85 registers */
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_IN(nr)			(0x20 + (nr))
5009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_IN_MIN(nr)		(0x44 + (nr) * 2)
5109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_IN_MAX(nr)		(0x45 + (nr) * 2)
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_TEMP(nr)		(0x25 + (nr))
5409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_TEMP_MIN(nr)		(0x4e + (nr) * 2)
5509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_TEMP_MAX(nr)		(0x4f + (nr) * 2)
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Fan speeds are LSB, MSB (2 bytes) */
5809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_FAN(nr)		(0x28 + (nr) * 2)
5909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_FAN_MIN(nr)		(0x54 + (nr) * 2)
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_PWM(nr)		(0x30 + (nr))
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_COMPANY		0x3e
6409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_VERSTEP		0x3f
6579b92f2bab0dc5ac70e8391548f75ac3268426e4Darrick J. Wong
6609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define ADT7468_REG_CFG5		0x7c
6709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define ADT7468_OFF64			(1 << 0)
6809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define ADT7468_HFPWM			(1 << 1)
6909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define IS_ADT7468_OFF64(data)		\
7079b92f2bab0dc5ac70e8391548f75ac3268426e4Darrick J. Wong	((data)->type == adt7468 && !((data)->cfg5 & ADT7468_OFF64))
7109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define IS_ADT7468_HFPWM(data)		\
72f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare	((data)->type == adt7468 && !((data)->cfg5 & ADT7468_HFPWM))
7379b92f2bab0dc5ac70e8391548f75ac3268426e4Darrick J. Wong
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* These are the recognized values for the above regs */
7509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_COMPANY_NATIONAL		0x01
7609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_COMPANY_ANALOG_DEV		0x41
7709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_COMPANY_SMSC		0x5c
7809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_LM85C		0x60
7909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_LM85B		0x62
8009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_LM96000_1		0x68
8109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_LM96000_2		0x69
8209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_ADM1027		0x60
8309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_ADT7463		0x62
8409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_ADT7463C		0x6A
8509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_ADT7468_1		0x71
8609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_ADT7468_2		0x72
8709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_EMC6D100_A0        0x60
8809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_EMC6D100_A1        0x61
8909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_EMC6D102		0x65
9009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_EMC6D103_A0	0x68
9109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_EMC6D103_A1	0x69
9209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_EMC6D103S		0x6A	/* Also known as EMC6D103:A2 */
9309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck
9409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_CONFIG			0x40
9509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck
9609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_ALARM1			0x41
9709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_ALARM2			0x42
9809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck
9909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_VID			0x43
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Automated FAN control */
10209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_AFAN_CONFIG(nr)	(0x5c + (nr))
10309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_AFAN_RANGE(nr)		(0x5f + (nr))
10409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_AFAN_SPIKE1		0x62
10509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_AFAN_MINPWM(nr)	(0x64 + (nr))
10609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_AFAN_LIMIT(nr)		(0x67 + (nr))
10709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_AFAN_CRITICAL(nr)	(0x6a + (nr))
10809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_AFAN_HYST1		0x6d
10909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_AFAN_HYST2		0x6e
11009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck
11109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define ADM1027_REG_EXTEND_ADC1		0x76
11209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define ADM1027_REG_EXTEND_ADC2		0x77
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define EMC6D100_REG_ALARM3             0x7d
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* IN5, IN6 and IN7 */
11609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define EMC6D100_REG_IN(nr)             (0x70 + ((nr) - 5))
11709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define EMC6D100_REG_IN_MIN(nr)         (0x73 + ((nr) - 5) * 2)
11809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define EMC6D100_REG_IN_MAX(nr)         (0x74 + ((nr) - 5) * 2)
11909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define EMC6D102_REG_EXTEND_ADC1	0x85
12009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define EMC6D102_REG_EXTEND_ADC2	0x86
12109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define EMC6D102_REG_EXTEND_ADC3	0x87
12209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define EMC6D102_REG_EXTEND_ADC4	0x88
12309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck
12409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck/*
12509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * Conversions. Rounding and limit checking is only done on the TO_REG
12609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * variants. Note that you should be a bit careful with which arguments
12709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * these macros are called: arguments may be evaluated more than once.
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13025985edcedea6396277003854657b5f3cb31a628Lucas De Marchi/* IN are scaled according to built-in resistors */
131e89e22b23bceb3fbbcfb931ad17a564b7c1eaa55Jean Delvarestatic const int lm85_scaling[] = {  /* .001 Volts */
1321f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	2500, 2250, 3300, 5000, 12000,
1331f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	3300, 1500, 1800 /*EMC6D100*/
1341f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare};
1351f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare#define SCALE(val, from, to)	(((val) * (to) + ((from) / 2)) / (from))
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1371f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare#define INS_TO_REG(n, val)	\
1382a844c148e1f714ebf42cb96e1b172ce394c36c9Guenter Roeck		clamp_val(SCALE(val, lm85_scaling[n], 192), 0, 255)
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1401f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare#define INSEXT_FROM_REG(n, val, ext)	\
1415a4d3ef317c845893fe3f9d3517cb0a99375da53Jean Delvare		SCALE(((val) << 4) + (ext), 192 << 4, lm85_scaling[n])
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1431f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare#define INS_FROM_REG(n, val)	SCALE((val), 192, lm85_scaling[n])
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* FAN speed is measured using 90kHz clock */
14663f281a6e32ebc93c62dac0d399d8e054eb7b2ecJean Delvarestatic inline u16 FAN_TO_REG(unsigned long val)
14763f281a6e32ebc93c62dac0d399d8e054eb7b2ecJean Delvare{
14863f281a6e32ebc93c62dac0d399d8e054eb7b2ecJean Delvare	if (!val)
14963f281a6e32ebc93c62dac0d399d8e054eb7b2ecJean Delvare		return 0xffff;
1502a844c148e1f714ebf42cb96e1b172ce394c36c9Guenter Roeck	return clamp_val(5400000 / val, 1, 0xfffe);
15163f281a6e32ebc93c62dac0d399d8e054eb7b2ecJean Delvare}
1521f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare#define FAN_FROM_REG(val)	((val) == 0 ? -1 : (val) == 0xffff ? 0 : \
1531f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare				 5400000 / (val))
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Temperature is reported in .001 degC increments */
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TEMP_TO_REG(val)	\
1573248c3b771ddd9d31695da17ba350eb6e1b80a53Guenter Roeck		DIV_ROUND_CLOSEST(clamp_val((val), -127000, 127000), 1000)
1581f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare#define TEMPEXT_FROM_REG(val, ext)	\
1595a4d3ef317c845893fe3f9d3517cb0a99375da53Jean Delvare		SCALE(((val) << 4) + (ext), 16, 1000)
1605a4d3ef317c845893fe3f9d3517cb0a99375da53Jean Delvare#define TEMP_FROM_REG(val)	((val) * 1000)
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1622a844c148e1f714ebf42cb96e1b172ce394c36c9Guenter Roeck#define PWM_TO_REG(val)			clamp_val(val, 0, 255)
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PWM_FROM_REG(val)		(val)
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck/*
16709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * ZONEs have the following parameters:
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Limit (low) temp,           1. degC
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Hysteresis (below limit),   1. degC (0-15)
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Range of speed control,     .1 degC (2-80)
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Critical (high) temp,       1. degC
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FAN PWMs have the following parameters:
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Reference Zone,                 1, 2, 3, etc.
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Spinup time,                    .05 sec
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    PWM value at limit/low temp,    1 count
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    PWM Frequency,                  1. Hz
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    PWM is Min or OFF below limit,  flag
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Invert PWM output,              flag
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Some chips filter the temp, others the fan.
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Filter constant (or disabled)   .1 seconds
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* These are the zone temperature range encodings in .001 degree C */
186e89e22b23bceb3fbbcfb931ad17a564b7c1eaa55Jean Delvarestatic const int lm85_range_map[] = {
1871f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	2000, 2500, 3300, 4000, 5000, 6600, 8000, 10000,
1881f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	13300, 16000, 20000, 26600, 32000, 40000, 53300, 80000
1891f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare};
1901f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare
1913248c3b771ddd9d31695da17ba350eb6e1b80a53Guenter Roeckstatic int RANGE_TO_REG(long range)
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
195d38b149794e7444a55e741446717147e7f0467f8Jean Delvare	/* Find the closest match */
1961b92adaddd7e96e1ba68d4f17a25747ab8057efeJean Delvare	for (i = 0; i < 15; ++i) {
1971b92adaddd7e96e1ba68d4f17a25747ab8057efeJean Delvare		if (range <= (lm85_range_map[i] + lm85_range_map[i + 1]) / 2)
1981b92adaddd7e96e1ba68d4f17a25747ab8057efeJean Delvare			break;
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
200d38b149794e7444a55e741446717147e7f0467f8Jean Delvare
2011b92adaddd7e96e1ba68d4f17a25747ab8057efeJean Delvare	return i;
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2031f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare#define RANGE_FROM_REG(val)	lm85_range_map[(val) & 0x0f]
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* These are the PWM frequency encodings */
20634e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvarestatic const int lm85_freq_map[8] = { /* 1 Hz */
2078a0795d9b8ce2247f9b34da81f8a229702c90f2dJean Delvare	10, 15, 23, 30, 38, 47, 61, 94
2088a0795d9b8ce2247f9b34da81f8a229702c90f2dJean Delvare};
2098a0795d9b8ce2247f9b34da81f8a229702c90f2dJean Delvarestatic const int adm1027_freq_map[8] = { /* 1 Hz */
2108a0795d9b8ce2247f9b34da81f8a229702c90f2dJean Delvare	11, 15, 22, 29, 35, 44, 59, 88
2111f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare};
2121f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare
2133248c3b771ddd9d31695da17ba350eb6e1b80a53Guenter Roeckstatic int FREQ_TO_REG(const int *map, unsigned long freq)
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
21786010c982db2030aad2c31f178b208964f5f6806Jean Delvare	/* Find the closest match */
2181f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	for (i = 0; i < 7; ++i)
2198a0795d9b8ce2247f9b34da81f8a229702c90f2dJean Delvare		if (freq <= (map[i] + map[i + 1]) / 2)
2201f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare			break;
221e89e22b23bceb3fbbcfb931ad17a564b7c1eaa55Jean Delvare	return i;
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2238a0795d9b8ce2247f9b34da81f8a229702c90f2dJean Delvare
2248a0795d9b8ce2247f9b34da81f8a229702c90f2dJean Delvarestatic int FREQ_FROM_REG(const int *map, u8 reg)
2258a0795d9b8ce2247f9b34da81f8a229702c90f2dJean Delvare{
2268a0795d9b8ce2247f9b34da81f8a229702c90f2dJean Delvare	return map[reg & 0x07];
2278a0795d9b8ce2247f9b34da81f8a229702c90f2dJean Delvare}
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
22909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck/*
23009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * Since we can't use strings, I'm abusing these numbers
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *   to stand in for the following meanings:
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *      1 -- PWM responds to Zone 1
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *      2 -- PWM responds to Zone 2
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *      3 -- PWM responds to Zone 3
2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     23 -- PWM responds to the higher temp of Zone 2 or 3
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    123 -- PWM responds to highest of Zone 1, 2, or 3
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *      0 -- PWM is always at 0% (ie, off)
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     -1 -- PWM is always at 100%
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     -2 -- PWM responds to manual control
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
242e89e22b23bceb3fbbcfb931ad17a564b7c1eaa55Jean Delvarestatic const int lm85_zone_map[] = { 1, 2, 3, -1, 0, 23, 123, -2 };
243e89e22b23bceb3fbbcfb931ad17a564b7c1eaa55Jean Delvare#define ZONE_FROM_REG(val)	lm85_zone_map[(val) >> 5]
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2451f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvarestatic int ZONE_TO_REG(int zone)
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2491f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	for (i = 0; i <= 7; ++i)
2501f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare		if (zone == lm85_zone_map[i])
2511f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare			break;
2521f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	if (i > 7)   /* Not found. */
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		i = 3;  /* Always 100% */
254e89e22b23bceb3fbbcfb931ad17a564b7c1eaa55Jean Delvare	return i << 5;
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2572a844c148e1f714ebf42cb96e1b172ce394c36c9Guenter Roeck#define HYST_TO_REG(val)	clamp_val(((val) + 500) / 1000, 0, 15)
2581f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare#define HYST_FROM_REG(val)	((val) * 1000)
2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
26009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck/*
26109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * Chip sampling rates
2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Some sensors are not updated more frequently than once per second
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    so it doesn't make sense to read them more often than that.
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    We cache the results and return the saved data if the driver
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    is called again before a second has elapsed.
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Also, there is significant configuration data for this chip
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    given the automatic PWM fan control that is possible.  There
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    are about 47 bytes of config data to only 22 bytes of actual
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    readings.  So, we keep the config data up to date in the cache
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    when it is written and only sample it once every 1 *minute*
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM85_DATA_INTERVAL  (HZ + HZ / 2)
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM85_CONFIG_INTERVAL  (1 * 60 * HZ)
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
27709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck/*
27809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * LM85 can automatically adjust fan speeds based on temperature
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This structure encapsulates an entire Zone config.  There are
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * three zones (one for each temperature input) on the lm85
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct lm85_zone {
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	s8 limit;	/* Low temp limit */
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u8 hyst;	/* Low limit hysteresis. (0-15) */
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u8 range;	/* Temp range, encoded */
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	s8 critical;	/* "All fans ON" temp limit */
28709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	u8 max_desired; /*
28809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck			 * Actual "max" temperature specified.  Preserved
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * to prevent "drift" as other autofan control
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * values change.
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct lm85_autofan {
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u8 config;	/* Register value */
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u8 min_pwm;	/* Minimum PWM value, encoded */
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u8 min_off;	/* Min PWM or OFF below "limit", flag */
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
30009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck/*
30109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * For each registered chip, we need to keep some data in memory.
30209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * The structure is dynamically allocated.
30309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck */
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct lm85_data {
305746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct i2c_client *client;
306746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	const struct attribute_group *groups[6];
3078a0795d9b8ce2247f9b34da81f8a229702c90f2dJean Delvare	const int *freq_map;
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	enum chips type;
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
310de24880586b28f1dc4cf91f5db962f0083baab2aGuenter Roeck	bool has_vid5;	/* true if VID5 is configured for ADT7463 or ADT7468 */
311de24880586b28f1dc4cf91f5db962f0083baab2aGuenter Roeck
3129a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	struct mutex update_lock;
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int valid;		/* !=0 if following fields are valid */
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long last_reading;	/* In jiffies */
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long last_config;	/* In jiffies */
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u8 in[8];		/* Register value */
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u8 in_max[8];		/* Register value */
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u8 in_min[8];		/* Register value */
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	s8 temp[3];		/* Register value */
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	s8 temp_min[3];		/* Register value */
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	s8 temp_max[3];		/* Register value */
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u16 fan[4];		/* Register value */
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u16 fan_min[4];		/* Register value */
3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u8 pwm[3];		/* Register value */
32634e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare	u8 pwm_freq[3];		/* Register encoding */
3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u8 temp_ext[3];		/* Decoded values */
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u8 in_ext[8];		/* Decoded values */
3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u8 vid;			/* Register value */
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u8 vrm;			/* VRM version */
3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u32 alarms;		/* Register encoding, combined */
33279b92f2bab0dc5ac70e8391548f75ac3268426e4Darrick J. Wong	u8 cfg5;		/* Config Register 5 on ADT7468 */
3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm85_autofan autofan[3];
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm85_zone zone[3];
3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3376fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Linstatic int lm85_read_value(struct i2c_client *client, u8 reg)
3386fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin{
3396fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	int res;
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3416fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	/* What size location is it? */
3426fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	switch (reg) {
3436fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	case LM85_REG_FAN(0):  /* Read WORD data */
3446fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	case LM85_REG_FAN(1):
3456fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	case LM85_REG_FAN(2):
3466fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	case LM85_REG_FAN(3):
3476fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	case LM85_REG_FAN_MIN(0):
3486fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	case LM85_REG_FAN_MIN(1):
3496fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	case LM85_REG_FAN_MIN(2):
3506fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	case LM85_REG_FAN_MIN(3):
3516fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	case LM85_REG_ALARM1:	/* Read both bytes at once */
3526fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		res = i2c_smbus_read_byte_data(client, reg) & 0xff;
3536fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		res |= i2c_smbus_read_byte_data(client, reg + 1) << 8;
3546fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		break;
3556fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	default:	/* Read BYTE data */
3566fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		res = i2c_smbus_read_byte_data(client, reg);
3576fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		break;
3586fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	}
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3606fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	return res;
3616fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin}
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3636fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Linstatic void lm85_write_value(struct i2c_client *client, u8 reg, int value)
3646fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin{
3656fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	switch (reg) {
3666fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	case LM85_REG_FAN(0):  /* Write WORD data */
3676fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	case LM85_REG_FAN(1):
3686fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	case LM85_REG_FAN(2):
3696fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	case LM85_REG_FAN(3):
3706fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	case LM85_REG_FAN_MIN(0):
3716fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	case LM85_REG_FAN_MIN(1):
3726fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	case LM85_REG_FAN_MIN(2):
3736fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	case LM85_REG_FAN_MIN(3):
3746fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	/* NOTE: ALARM is read only, so not included here */
3756fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		i2c_smbus_write_byte_data(client, reg, value & 0xff);
3766fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		i2c_smbus_write_byte_data(client, reg + 1, value >> 8);
3776fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		break;
3786fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	default:	/* Write BYTE data */
3796fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		i2c_smbus_write_byte_data(client, reg, value);
3806fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		break;
3816fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	}
3826fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin}
38367712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare
3846fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Linstatic struct lm85_data *lm85_update_device(struct device *dev)
3856fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin{
386746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct lm85_data *data = dev_get_drvdata(dev);
387746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct i2c_client *client = data->client;
3886fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	int i;
3896fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
3906fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	mutex_lock(&data->update_lock);
3916fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
3926fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	if (!data->valid ||
3936fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	     time_after(jiffies, data->last_reading + LM85_DATA_INTERVAL)) {
3946fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		/* Things that change quickly */
3956fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		dev_dbg(&client->dev, "Reading sensor values\n");
3966fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
3976fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		/*
3986fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		 * Have to read extended bits first to "freeze" the
3996fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		 * more significant bits that are read later.
4006fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		 * There are 2 additional resolution bits per channel and we
4016fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		 * have room for 4, so we shift them to the left.
4026fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		 */
4036fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		if (data->type == adm1027 || data->type == adt7463 ||
4046fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		    data->type == adt7468) {
4056fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			int ext1 = lm85_read_value(client,
4066fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin						   ADM1027_REG_EXTEND_ADC1);
4076fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			int ext2 =  lm85_read_value(client,
4086fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin						    ADM1027_REG_EXTEND_ADC2);
4096fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			int val = (ext1 << 8) + ext2;
4106fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
4116fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			for (i = 0; i <= 4; i++)
4126fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin				data->in_ext[i] =
4136fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin					((val >> (i * 2)) & 0x03) << 2;
4146fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
4156fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			for (i = 0; i <= 2; i++)
4166fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin				data->temp_ext[i] =
4176fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin					(val >> ((i + 4) * 2)) & 0x0c;
4186fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		}
4196fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
4206fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		data->vid = lm85_read_value(client, LM85_REG_VID);
4216fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
4226fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		for (i = 0; i <= 3; ++i) {
4236fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->in[i] =
4246fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			    lm85_read_value(client, LM85_REG_IN(i));
4256fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->fan[i] =
4266fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			    lm85_read_value(client, LM85_REG_FAN(i));
4276fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		}
4286fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
4296fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		if (!data->has_vid5)
4306fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->in[4] = lm85_read_value(client, LM85_REG_IN(4));
4316fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
4326fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		if (data->type == adt7468)
4336fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->cfg5 = lm85_read_value(client, ADT7468_REG_CFG5);
4346fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
4356fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		for (i = 0; i <= 2; ++i) {
4366fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->temp[i] =
4376fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			    lm85_read_value(client, LM85_REG_TEMP(i));
4386fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->pwm[i] =
4396fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			    lm85_read_value(client, LM85_REG_PWM(i));
4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4416fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			if (IS_ADT7468_OFF64(data))
4426fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin				data->temp[i] -= 64;
4436fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		}
4446fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
4456fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		data->alarms = lm85_read_value(client, LM85_REG_ALARM1);
4466fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
4476fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		if (data->type == emc6d100) {
4486fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			/* Three more voltage sensors */
4496fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			for (i = 5; i <= 7; ++i) {
4506fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin				data->in[i] = lm85_read_value(client,
4516fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin							EMC6D100_REG_IN(i));
4526fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			}
4536fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			/* More alarm bits */
4546fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->alarms |= lm85_read_value(client,
4556fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin						EMC6D100_REG_ALARM3) << 16;
4566fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		} else if (data->type == emc6d102 || data->type == emc6d103 ||
4576fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			   data->type == emc6d103s) {
4586fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			/*
4596fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			 * Have to read LSB bits after the MSB ones because
4606fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			 * the reading of the MSB bits has frozen the
4616fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			 * LSBs (backward from the ADM1027).
4626fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			 */
4636fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			int ext1 = lm85_read_value(client,
4646fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin						   EMC6D102_REG_EXTEND_ADC1);
4656fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			int ext2 = lm85_read_value(client,
4666fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin						   EMC6D102_REG_EXTEND_ADC2);
4676fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			int ext3 = lm85_read_value(client,
4686fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin						   EMC6D102_REG_EXTEND_ADC3);
4696fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			int ext4 = lm85_read_value(client,
4706fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin						   EMC6D102_REG_EXTEND_ADC4);
4716fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->in_ext[0] = ext3 & 0x0f;
4726fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->in_ext[1] = ext4 & 0x0f;
4736fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->in_ext[2] = ext4 >> 4;
4746fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->in_ext[3] = ext3 >> 4;
4756fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->in_ext[4] = ext2 >> 4;
4766fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
4776fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->temp_ext[0] = ext1 & 0x0f;
4786fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->temp_ext[1] = ext2 & 0x0f;
4796fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->temp_ext[2] = ext1 >> 4;
4806fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		}
4816fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
4826fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		data->last_reading = jiffies;
4836fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	}  /* last_reading */
4846fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
4856fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	if (!data->valid ||
4866fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	     time_after(jiffies, data->last_config + LM85_CONFIG_INTERVAL)) {
4876fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		/* Things that don't change often */
4886fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		dev_dbg(&client->dev, "Reading config values\n");
4896fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
4906fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		for (i = 0; i <= 3; ++i) {
4916fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->in_min[i] =
4926fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			    lm85_read_value(client, LM85_REG_IN_MIN(i));
4936fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->in_max[i] =
4946fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			    lm85_read_value(client, LM85_REG_IN_MAX(i));
4956fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->fan_min[i] =
4966fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			    lm85_read_value(client, LM85_REG_FAN_MIN(i));
4976fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		}
4986fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
4996fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		if (!data->has_vid5)  {
5006fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->in_min[4] = lm85_read_value(client,
5016fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin					  LM85_REG_IN_MIN(4));
5026fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->in_max[4] = lm85_read_value(client,
5036fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin					  LM85_REG_IN_MAX(4));
5046fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		}
5056fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
5066fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		if (data->type == emc6d100) {
5076fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			for (i = 5; i <= 7; ++i) {
5086fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin				data->in_min[i] = lm85_read_value(client,
5096fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin						EMC6D100_REG_IN_MIN(i));
5106fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin				data->in_max[i] = lm85_read_value(client,
5116fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin						EMC6D100_REG_IN_MAX(i));
5126fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			}
5136fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		}
5146fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
5156fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		for (i = 0; i <= 2; ++i) {
5166fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			int val;
5176fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
5186fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->temp_min[i] =
5196fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			    lm85_read_value(client, LM85_REG_TEMP_MIN(i));
5206fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->temp_max[i] =
5216fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			    lm85_read_value(client, LM85_REG_TEMP_MAX(i));
5226fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
5236fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->autofan[i].config =
5246fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			    lm85_read_value(client, LM85_REG_AFAN_CONFIG(i));
5256fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			val = lm85_read_value(client, LM85_REG_AFAN_RANGE(i));
5266fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->pwm_freq[i] = val & 0x07;
5276fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->zone[i].range = val >> 4;
5286fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->autofan[i].min_pwm =
5296fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			    lm85_read_value(client, LM85_REG_AFAN_MINPWM(i));
5306fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->zone[i].limit =
5316fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			    lm85_read_value(client, LM85_REG_AFAN_LIMIT(i));
5326fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->zone[i].critical =
5336fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			    lm85_read_value(client, LM85_REG_AFAN_CRITICAL(i));
5346fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
5356fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			if (IS_ADT7468_OFF64(data)) {
5366fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin				data->temp_min[i] -= 64;
5376fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin				data->temp_max[i] -= 64;
5386fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin				data->zone[i].limit -= 64;
5396fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin				data->zone[i].critical -= 64;
5406fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			}
5416fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		}
5426fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
5436fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		if (data->type != emc6d103s) {
5446fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			i = lm85_read_value(client, LM85_REG_AFAN_SPIKE1);
5456fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->autofan[0].min_off = (i & 0x20) != 0;
5466fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->autofan[1].min_off = (i & 0x40) != 0;
5476fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->autofan[2].min_off = (i & 0x80) != 0;
5486fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
5496fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			i = lm85_read_value(client, LM85_REG_AFAN_HYST1);
5506fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->zone[0].hyst = i >> 4;
5516fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->zone[1].hyst = i & 0x0f;
5526fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
5536fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			i = lm85_read_value(client, LM85_REG_AFAN_HYST2);
5546fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin			data->zone[2].hyst = i >> 4;
5556fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		}
5566fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
5576fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		data->last_config = jiffies;
5586fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	}  /* last_config */
5596fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
5606fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	data->valid = 1;
5616fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
5626fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	mutex_unlock(&data->update_lock);
5636fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin
5646fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	return data;
5656fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin}
5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 4 Fans */
568b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_fan(struct device *dev, struct device_attribute *attr,
569b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		char *buf)
5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
571b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm85_data *data = lm85_update_device(dev);
5731f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr]));
5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
575b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
576b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_fan_min(struct device *dev, struct device_attribute *attr,
577b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		char *buf)
5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
579b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm85_data *data = lm85_update_device(dev);
5811f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr]));
5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
583b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
584b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
585b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		const char *buf, size_t count)
5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
587b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
588746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct lm85_data *data = dev_get_drvdata(dev);
589746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct i2c_client *client = data->client;
59009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	unsigned long val;
59109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	int err;
59209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck
59309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	err = kstrtoul(buf, 10, &val);
59409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	if (err)
59509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck		return err;
5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5979a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_lock(&data->update_lock);
5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	data->fan_min[nr] = FAN_TO_REG(val);
5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	lm85_write_value(client, LM85_REG_FAN_MIN(nr), data->fan_min[nr]);
6009a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_unlock(&data->update_lock);
6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return count;
6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define show_fan_offset(offset)						\
605b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO,			\
606b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		show_fan, NULL, offset - 1);				\
607b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,		\
608b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		show_fan_min, set_fan_min, offset - 1)
6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_fan_offset(1);
6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_fan_offset(2);
6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_fan_offset(3);
6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_fan_offset(4);
6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* vid, vrm, alarms */
6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6171f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvarestatic ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr,
6181f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare		char *buf)
6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm85_data *data = lm85_update_device(dev);
6219c516ef496c857aa4b1b41dc313010f11d39c496Jean Delvare	int vid;
6229c516ef496c857aa4b1b41dc313010f11d39c496Jean Delvare
623de24880586b28f1dc4cf91f5db962f0083baab2aGuenter Roeck	if (data->has_vid5) {
6249c516ef496c857aa4b1b41dc313010f11d39c496Jean Delvare		/* 6-pin VID (VRM 10) */
6259c516ef496c857aa4b1b41dc313010f11d39c496Jean Delvare		vid = vid_from_reg(data->vid & 0x3f, data->vrm);
6269c516ef496c857aa4b1b41dc313010f11d39c496Jean Delvare	} else {
6279c516ef496c857aa4b1b41dc313010f11d39c496Jean Delvare		/* 5-pin VID (VRM 9) */
6289c516ef496c857aa4b1b41dc313010f11d39c496Jean Delvare		vid = vid_from_reg(data->vid & 0x1f, data->vrm);
6299c516ef496c857aa4b1b41dc313010f11d39c496Jean Delvare	}
6309c516ef496c857aa4b1b41dc313010f11d39c496Jean Delvare
6319c516ef496c857aa4b1b41dc313010f11d39c496Jean Delvare	return sprintf(buf, "%d\n", vid);
6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6361f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvarestatic ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr,
6371f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare		char *buf)
6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
63990d6619a916062cb75a176aacb318d108758b4a5Jean Delvare	struct lm85_data *data = dev_get_drvdata(dev);
6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return sprintf(buf, "%ld\n", (long) data->vrm);
6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6431f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvarestatic ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr,
6441f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare		const char *buf, size_t count)
6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6468f74efe81d122c071410fd74f42879ef81439fa4Jean Delvare	struct lm85_data *data = dev_get_drvdata(dev);
64709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	unsigned long val;
64809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	int err;
64909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck
65009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	err = kstrtoul(buf, 10, &val);
65109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	if (err)
65209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck		return err;
65309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck
6543248c3b771ddd9d31695da17ba350eb6e1b80a53Guenter Roeck	if (val > 255)
6553248c3b771ddd9d31695da17ba350eb6e1b80a53Guenter Roeck		return -EINVAL;
6563248c3b771ddd9d31695da17ba350eb6e1b80a53Guenter Roeck
65709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	data->vrm = val;
6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return count;
6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6631f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvarestatic ssize_t show_alarms_reg(struct device *dev, struct device_attribute
6641f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare		*attr, char *buf)
6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm85_data *data = lm85_update_device(dev);
66768188ba7de2db9999ff08a4544a78b2f10eb08bdJean Delvare	return sprintf(buf, "%u\n", data->alarms);
6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
672bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
673bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare		char *buf)
674bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare{
675bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
676bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare	struct lm85_data *data = lm85_update_device(dev);
677bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare	return sprintf(buf, "%u\n", (data->alarms >> nr) & 1);
678bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare}
679bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare
680bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
681bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
682bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2);
683bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3);
684bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8);
685bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 18);
686bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 16);
687bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 17);
688bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4);
689bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, show_alarm, NULL, 14);
690bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5);
691bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 6);
692bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 15);
693bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 10);
694bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 11);
695bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 12);
696bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 13);
697bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare
6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* pwm */
6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
700b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
701b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		char *buf)
7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
703b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm85_data *data = lm85_update_device(dev);
7051f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr]));
7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
707b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
708b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
709b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		const char *buf, size_t count)
7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
711b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
712746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct lm85_data *data = dev_get_drvdata(dev);
713746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct i2c_client *client = data->client;
71409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	unsigned long val;
71509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	int err;
71609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck
71709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	err = kstrtoul(buf, 10, &val);
71809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	if (err)
71909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck		return err;
7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7219a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_lock(&data->update_lock);
7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	data->pwm[nr] = PWM_TO_REG(val);
7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	lm85_write_value(client, LM85_REG_PWM(nr), data->pwm[nr]);
7249a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_unlock(&data->update_lock);
7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return count;
7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
727b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
728b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_pwm_enable(struct device *dev, struct device_attribute
729b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		*attr, char *buf)
7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
731b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm85_data *data = lm85_update_device(dev);
7334b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare	int pwm_zone, enable;
7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pwm_zone = ZONE_FROM_REG(data->autofan[nr].config);
7364b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare	switch (pwm_zone) {
7374b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare	case -1:	/* PWM is always at 100% */
7384b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare		enable = 0;
7394b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare		break;
7404b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare	case 0:		/* PWM is always at 0% */
7414b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare	case -2:	/* PWM responds to manual control */
7424b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare		enable = 1;
7434b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare		break;
7444b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare	default:	/* PWM in automatic mode */
7454b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare		enable = 2;
7464b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare	}
7474b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare	return sprintf(buf, "%d\n", enable);
7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
750455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvarestatic ssize_t set_pwm_enable(struct device *dev, struct device_attribute
751455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare		*attr, const char *buf, size_t count)
752455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare{
753455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
754746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct lm85_data *data = dev_get_drvdata(dev);
755746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct i2c_client *client = data->client;
756455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare	u8 config;
75709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	unsigned long val;
75809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	int err;
75909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck
76009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	err = kstrtoul(buf, 10, &val);
76109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	if (err)
76209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck		return err;
763455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare
764455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare	switch (val) {
765455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare	case 0:
766455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare		config = 3;
767455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare		break;
768455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare	case 1:
769455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare		config = 7;
770455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare		break;
771455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare	case 2:
77209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck		/*
77309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck		 * Here we have to choose arbitrarily one of the 5 possible
77409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck		 * configurations; I go for the safest
77509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck		 */
776455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare		config = 6;
777455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare		break;
778455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare	default:
779455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare		return -EINVAL;
780455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare	}
781455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare
782455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare	mutex_lock(&data->update_lock);
783455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare	data->autofan[nr].config = lm85_read_value(client,
784455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare		LM85_REG_AFAN_CONFIG(nr));
785455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare	data->autofan[nr].config = (data->autofan[nr].config & ~0xe0)
786455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare		| (config << 5);
787455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare	lm85_write_value(client, LM85_REG_AFAN_CONFIG(nr),
788455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare		data->autofan[nr].config);
789455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare	mutex_unlock(&data->update_lock);
790455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare	return count;
791455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare}
792455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare
79334e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvarestatic ssize_t show_pwm_freq(struct device *dev,
79434e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare		struct device_attribute *attr, char *buf)
79534e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare{
79634e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare	int nr = to_sensor_dev_attr(attr)->index;
79734e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare	struct lm85_data *data = lm85_update_device(dev);
798f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare	int freq;
799f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare
800f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare	if (IS_ADT7468_HFPWM(data))
801f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare		freq = 22500;
802f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare	else
803f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare		freq = FREQ_FROM_REG(data->freq_map, data->pwm_freq[nr]);
804f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare
805f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare	return sprintf(buf, "%d\n", freq);
80634e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare}
80734e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare
80834e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvarestatic ssize_t set_pwm_freq(struct device *dev,
80934e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare		struct device_attribute *attr, const char *buf, size_t count)
81034e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare{
81134e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare	int nr = to_sensor_dev_attr(attr)->index;
812746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct lm85_data *data = dev_get_drvdata(dev);
813746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct i2c_client *client = data->client;
81409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	unsigned long val;
81509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	int err;
81609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck
81709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	err = kstrtoul(buf, 10, &val);
81809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	if (err)
81909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck		return err;
82034e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare
82134e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare	mutex_lock(&data->update_lock);
82209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	/*
82309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	 * The ADT7468 has a special high-frequency PWM output mode,
824f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare	 * where all PWM outputs are driven by a 22.5 kHz clock.
82509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	 * This might confuse the user, but there's not much we can do.
82609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	 */
827f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare	if (data->type == adt7468 && val >= 11300) {	/* High freq. mode */
828f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare		data->cfg5 &= ~ADT7468_HFPWM;
829f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare		lm85_write_value(client, ADT7468_REG_CFG5, data->cfg5);
830f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare	} else {					/* Low freq. mode */
831f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare		data->pwm_freq[nr] = FREQ_TO_REG(data->freq_map, val);
832f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare		lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
833f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare				 (data->zone[nr].range << 4)
834f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare				 | data->pwm_freq[nr]);
835f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare		if (data->type == adt7468) {
836f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare			data->cfg5 |= ADT7468_HFPWM;
837f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare			lm85_write_value(client, ADT7468_REG_CFG5, data->cfg5);
838f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare		}
839f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare	}
84034e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare	mutex_unlock(&data->update_lock);
84134e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare	return count;
84234e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare}
84334e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare
8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define show_pwm_reg(offset)						\
845b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR,		\
846b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		show_pwm, set_pwm, offset - 1);				\
847455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvarestatic SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR,	\
84834e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare		show_pwm_enable, set_pwm_enable, offset - 1);		\
84934e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvarestatic SENSOR_DEVICE_ATTR(pwm##offset##_freq, S_IRUGO | S_IWUSR,	\
85034e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare		show_pwm_freq, set_pwm_freq, offset - 1)
8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_pwm_reg(1);
8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_pwm_reg(2);
8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_pwm_reg(3);
8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Voltages */
8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
858b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_in(struct device *dev, struct device_attribute *attr,
859b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		char *buf)
8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
861b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm85_data *data = lm85_update_device(dev);
8631f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	return sprintf(buf, "%d\n", INSEXT_FROM_REG(nr, data->in[nr],
8641f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare						    data->in_ext[nr]));
8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
866b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
8671f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvarestatic ssize_t show_in_min(struct device *dev, struct device_attribute *attr,
868b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		char *buf)
8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
870b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm85_data *data = lm85_update_device(dev);
8721f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	return sprintf(buf, "%d\n", INS_FROM_REG(nr, data->in_min[nr]));
8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
874b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
875b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
876b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		const char *buf, size_t count)
8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
878b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
879746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct lm85_data *data = dev_get_drvdata(dev);
880746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct i2c_client *client = data->client;
88109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	long val;
88209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	int err;
88309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck
88409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	err = kstrtol(buf, 10, &val);
88509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	if (err)
88609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck		return err;
8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8889a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_lock(&data->update_lock);
8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	data->in_min[nr] = INS_TO_REG(nr, val);
8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	lm85_write_value(client, LM85_REG_IN_MIN(nr), data->in_min[nr]);
8919a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_unlock(&data->update_lock);
8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return count;
8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
894b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
895b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_in_max(struct device *dev, struct device_attribute *attr,
896b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		char *buf)
8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
898b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm85_data *data = lm85_update_device(dev);
9001f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	return sprintf(buf, "%d\n", INS_FROM_REG(nr, data->in_max[nr]));
9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
902b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
903b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
904b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		const char *buf, size_t count)
9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
906b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
907746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct lm85_data *data = dev_get_drvdata(dev);
908746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct i2c_client *client = data->client;
90909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	long val;
91009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	int err;
91109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck
91209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	err = kstrtol(buf, 10, &val);
91309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	if (err)
91409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck		return err;
9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9169a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_lock(&data->update_lock);
9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	data->in_max[nr] = INS_TO_REG(nr, val);
9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	lm85_write_value(client, LM85_REG_IN_MAX(nr), data->in_max[nr]);
9199a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_unlock(&data->update_lock);
9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return count;
9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
922b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define show_in_reg(offset)						\
924b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO,			\
925b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		show_in, NULL, offset);					\
926b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR,		\
927b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		show_in_min, set_in_min, offset);			\
928b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR,		\
929b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		show_in_max, set_in_max, offset)
9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_in_reg(0);
9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_in_reg(1);
9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_in_reg(2);
9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_in_reg(3);
9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_in_reg(4);
9366b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvareshow_in_reg(5);
9376b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvareshow_in_reg(6);
9386b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvareshow_in_reg(7);
9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Temps */
9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
942b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_temp(struct device *dev, struct device_attribute *attr,
943b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		char *buf)
9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
945b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm85_data *data = lm85_update_device(dev);
9471f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	return sprintf(buf, "%d\n", TEMPEXT_FROM_REG(data->temp[nr],
9481f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare						     data->temp_ext[nr]));
9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
950b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
951b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_temp_min(struct device *dev, struct device_attribute *attr,
952b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		char *buf)
9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
954b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm85_data *data = lm85_update_device(dev);
9561f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[nr]));
9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
958b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
959b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
960b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		const char *buf, size_t count)
9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
962b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
963746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct lm85_data *data = dev_get_drvdata(dev);
964746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct i2c_client *client = data->client;
96509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	long val;
96609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	int err;
96709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck
96809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	err = kstrtol(buf, 10, &val);
96909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	if (err)
97009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck		return err;
9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
97279b92f2bab0dc5ac70e8391548f75ac3268426e4Darrick J. Wong	if (IS_ADT7468_OFF64(data))
97379b92f2bab0dc5ac70e8391548f75ac3268426e4Darrick J. Wong		val += 64;
97479b92f2bab0dc5ac70e8391548f75ac3268426e4Darrick J. Wong
9759a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_lock(&data->update_lock);
9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	data->temp_min[nr] = TEMP_TO_REG(val);
9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	lm85_write_value(client, LM85_REG_TEMP_MIN(nr), data->temp_min[nr]);
9789a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_unlock(&data->update_lock);
9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return count;
9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
981b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
982b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_temp_max(struct device *dev, struct device_attribute *attr,
983b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		char *buf)
9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
985b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm85_data *data = lm85_update_device(dev);
9871f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[nr]));
9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
989b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
990b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
991b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		const char *buf, size_t count)
9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
993b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
994746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct lm85_data *data = dev_get_drvdata(dev);
995746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct i2c_client *client = data->client;
99609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	long val;
99709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	int err;
99809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck
99909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	err = kstrtol(buf, 10, &val);
100009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	if (err)
100109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck		return err;
10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
100379b92f2bab0dc5ac70e8391548f75ac3268426e4Darrick J. Wong	if (IS_ADT7468_OFF64(data))
100479b92f2bab0dc5ac70e8391548f75ac3268426e4Darrick J. Wong		val += 64;
100579b92f2bab0dc5ac70e8391548f75ac3268426e4Darrick J. Wong
10069a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_lock(&data->update_lock);
10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	data->temp_max[nr] = TEMP_TO_REG(val);
10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	lm85_write_value(client, LM85_REG_TEMP_MAX(nr), data->temp_max[nr]);
10099a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_unlock(&data->update_lock);
10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return count;
10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1012b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define show_temp_reg(offset)						\
1014b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO,		\
1015b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		show_temp, NULL, offset - 1);				\
1016b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR,	\
1017b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		show_temp_min, set_temp_min, offset - 1);		\
1018b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR,	\
1019b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		show_temp_max, set_temp_max, offset - 1);
10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_temp_reg(1);
10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_temp_reg(2);
10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_temp_reg(3);
10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Automatic PWM control */
10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1028b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_pwm_auto_channels(struct device *dev,
1029b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		struct device_attribute *attr, char *buf)
10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1031b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm85_data *data = lm85_update_device(dev);
10331f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	return sprintf(buf, "%d\n", ZONE_FROM_REG(data->autofan[nr].config));
10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1035b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
1036b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_pwm_auto_channels(struct device *dev,
1037b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		struct device_attribute *attr, const char *buf, size_t count)
10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1039b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
1040746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct lm85_data *data = dev_get_drvdata(dev);
1041746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct i2c_client *client = data->client;
104209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	long val;
104309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	int err;
104409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck
104509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	err = kstrtol(buf, 10, &val);
104609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	if (err)
104709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck		return err;
10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10499a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_lock(&data->update_lock);
10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	data->autofan[nr].config = (data->autofan[nr].config & (~0xe0))
10511f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare		| ZONE_TO_REG(val);
10521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	lm85_write_value(client, LM85_REG_AFAN_CONFIG(nr),
10531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		data->autofan[nr].config);
10549a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_unlock(&data->update_lock);
10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return count;
10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1057b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
1058b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_pwm_auto_pwm_min(struct device *dev,
1059b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		struct device_attribute *attr, char *buf)
10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1061b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm85_data *data = lm85_update_device(dev);
10631f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	return sprintf(buf, "%d\n", PWM_FROM_REG(data->autofan[nr].min_pwm));
10641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1065b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
1066b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_pwm_auto_pwm_min(struct device *dev,
1067b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		struct device_attribute *attr, const char *buf, size_t count)
10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1069b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
1070746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct lm85_data *data = dev_get_drvdata(dev);
1071746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct i2c_client *client = data->client;
107209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	unsigned long val;
107309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	int err;
107409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck
107509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	err = kstrtoul(buf, 10, &val);
107609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	if (err)
107709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck		return err;
10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10799a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_lock(&data->update_lock);
10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	data->autofan[nr].min_pwm = PWM_TO_REG(val);
10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	lm85_write_value(client, LM85_REG_AFAN_MINPWM(nr),
10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		data->autofan[nr].min_pwm);
10839a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_unlock(&data->update_lock);
10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return count;
10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1086b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
1087b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_pwm_auto_pwm_minctl(struct device *dev,
1088b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		struct device_attribute *attr, char *buf)
10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1090b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm85_data *data = lm85_update_device(dev);
10921f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	return sprintf(buf, "%d\n", data->autofan[nr].min_off);
10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1094b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
1095b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_pwm_auto_pwm_minctl(struct device *dev,
1096b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		struct device_attribute *attr, const char *buf, size_t count)
10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1098b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
1099746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct lm85_data *data = dev_get_drvdata(dev);
1100746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct i2c_client *client = data->client;
11017133e56f29030b13601d3399e20050053e560860Jean Delvare	u8 tmp;
110209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	long val;
110309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	int err;
110409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck
110509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	err = kstrtol(buf, 10, &val);
110609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	if (err)
110709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck		return err;
11081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11099a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_lock(&data->update_lock);
11101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	data->autofan[nr].min_off = val;
11117133e56f29030b13601d3399e20050053e560860Jean Delvare	tmp = lm85_read_value(client, LM85_REG_AFAN_SPIKE1);
11127133e56f29030b13601d3399e20050053e560860Jean Delvare	tmp &= ~(0x20 << nr);
11137133e56f29030b13601d3399e20050053e560860Jean Delvare	if (data->autofan[nr].min_off)
11147133e56f29030b13601d3399e20050053e560860Jean Delvare		tmp |= 0x20 << nr;
11157133e56f29030b13601d3399e20050053e560860Jean Delvare	lm85_write_value(client, LM85_REG_AFAN_SPIKE1, tmp);
11169a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_unlock(&data->update_lock);
11171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return count;
11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1119b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
11201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define pwm_auto(offset)						\
1121b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(pwm##offset##_auto_channels,			\
1122b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		S_IRUGO | S_IWUSR, show_pwm_auto_channels,		\
1123b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		set_pwm_auto_channels, offset - 1);			\
1124b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(pwm##offset##_auto_pwm_min,			\
1125b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		S_IRUGO | S_IWUSR, show_pwm_auto_pwm_min,		\
1126b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		set_pwm_auto_pwm_min, offset - 1);			\
1127b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(pwm##offset##_auto_pwm_minctl,		\
1128b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		S_IRUGO | S_IWUSR, show_pwm_auto_pwm_minctl,		\
112934e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare		set_pwm_auto_pwm_minctl, offset - 1)
1130b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldspwm_auto(1);
11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldspwm_auto(2);
11331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldspwm_auto(3);
11341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Temperature settings for automatic PWM control */
11361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1137b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_temp_auto_temp_off(struct device *dev,
1138b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		struct device_attribute *attr, char *buf)
11391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1140b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
11411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm85_data *data = lm85_update_device(dev);
11421f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->zone[nr].limit) -
11431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		HYST_FROM_REG(data->zone[nr].hyst));
11441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1145b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
1146b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_temp_auto_temp_off(struct device *dev,
1147b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		struct device_attribute *attr, const char *buf, size_t count)
11481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1149b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
1150746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct lm85_data *data = dev_get_drvdata(dev);
1151746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct i2c_client *client = data->client;
11521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int min;
115309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	long val;
115409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	int err;
115509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck
115609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	err = kstrtol(buf, 10, &val);
115709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	if (err)
115809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck		return err;
11591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11609a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_lock(&data->update_lock);
11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	min = TEMP_FROM_REG(data->zone[nr].limit);
11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	data->zone[nr].hyst = HYST_TO_REG(min - val);
11631f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	if (nr == 0 || nr == 1) {
11641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		lm85_write_value(client, LM85_REG_AFAN_HYST1,
11651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			(data->zone[0].hyst << 4)
11661f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare			| data->zone[1].hyst);
11671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		lm85_write_value(client, LM85_REG_AFAN_HYST2,
11691f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare			(data->zone[2].hyst << 4));
11701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
11719a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_unlock(&data->update_lock);
11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return count;
11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1174b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
1175b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_temp_auto_temp_min(struct device *dev,
1176b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		struct device_attribute *attr, char *buf)
11771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1178b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
11791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm85_data *data = lm85_update_device(dev);
11801f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->zone[nr].limit));
11811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1182b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
1183b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_temp_auto_temp_min(struct device *dev,
1184b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		struct device_attribute *attr, const char *buf, size_t count)
11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1186b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
1187746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct lm85_data *data = dev_get_drvdata(dev);
1188746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct i2c_client *client = data->client;
118909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	long val;
119009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	int err;
119109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck
119209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	err = kstrtol(buf, 10, &val);
119309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	if (err)
119409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck		return err;
11951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11969a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_lock(&data->update_lock);
11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	data->zone[nr].limit = TEMP_TO_REG(val);
11981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	lm85_write_value(client, LM85_REG_AFAN_LIMIT(nr),
11991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		data->zone[nr].limit);
12001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Update temp_auto_max and temp_auto_range */
12021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	data->zone[nr].range = RANGE_TO_REG(
12031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		TEMP_FROM_REG(data->zone[nr].max_desired) -
12041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		TEMP_FROM_REG(data->zone[nr].limit));
12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
12061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		((data->zone[nr].range & 0x0f) << 4)
120734e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare		| (data->pwm_freq[nr] & 0x07));
12081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12099a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_unlock(&data->update_lock);
12101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return count;
12111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1212b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
1213b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_temp_auto_temp_max(struct device *dev,
1214b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		struct device_attribute *attr, char *buf)
12151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1216b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
12171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm85_data *data = lm85_update_device(dev);
12181f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->zone[nr].limit) +
12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		RANGE_FROM_REG(data->zone[nr].range));
12201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1221b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
1222b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_temp_auto_temp_max(struct device *dev,
1223b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		struct device_attribute *attr, const char *buf, size_t count)
12241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1225b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
1226746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct lm85_data *data = dev_get_drvdata(dev);
1227746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct i2c_client *client = data->client;
12281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int min;
122909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	long val;
123009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	int err;
123109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck
123209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	err = kstrtol(buf, 10, &val);
123309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	if (err)
123409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck		return err;
12351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12369a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_lock(&data->update_lock);
12371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	min = TEMP_FROM_REG(data->zone[nr].limit);
12381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	data->zone[nr].max_desired = TEMP_TO_REG(val);
12391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	data->zone[nr].range = RANGE_TO_REG(
12401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		val - min);
12411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
12421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		((data->zone[nr].range & 0x0f) << 4)
124334e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare		| (data->pwm_freq[nr] & 0x07));
12449a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_unlock(&data->update_lock);
12451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return count;
12461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1247b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
1248b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_temp_auto_temp_crit(struct device *dev,
1249b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		struct device_attribute *attr, char *buf)
12501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1251b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
12521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm85_data *data = lm85_update_device(dev);
12531f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->zone[nr].critical));
12541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1255b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
1256b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_temp_auto_temp_crit(struct device *dev,
12571f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare		struct device_attribute *attr, const char *buf, size_t count)
12581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1259b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	int nr = to_sensor_dev_attr(attr)->index;
1260746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct lm85_data *data = dev_get_drvdata(dev);
1261746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct i2c_client *client = data->client;
126209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	long val;
126309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	int err;
126409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck
126509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	err = kstrtol(buf, 10, &val);
126609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	if (err)
126709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck		return err;
12681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12699a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_lock(&data->update_lock);
12701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	data->zone[nr].critical = TEMP_TO_REG(val);
12711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	lm85_write_value(client, LM85_REG_AFAN_CRITICAL(nr),
12721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		data->zone[nr].critical);
12739a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_unlock(&data->update_lock);
12741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return count;
12751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1276b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define temp_auto(offset)						\
1278b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(temp##offset##_auto_temp_off,			\
1279b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		S_IRUGO | S_IWUSR, show_temp_auto_temp_off,		\
1280b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		set_temp_auto_temp_off, offset - 1);			\
1281b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(temp##offset##_auto_temp_min,			\
1282b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		S_IRUGO | S_IWUSR, show_temp_auto_temp_min,		\
1283b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		set_temp_auto_temp_min, offset - 1);			\
1284b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(temp##offset##_auto_temp_max,			\
1285b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		S_IRUGO | S_IWUSR, show_temp_auto_temp_max,		\
1286b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		set_temp_auto_temp_max, offset - 1);			\
1287b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(temp##offset##_auto_temp_crit,		\
1288b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		S_IRUGO | S_IWUSR, show_temp_auto_temp_crit,		\
1289b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare		set_temp_auto_temp_crit, offset - 1);
1290b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstemp_auto(1);
12921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstemp_auto(2);
12931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstemp_auto(3);
12941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12950501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffmanstatic struct attribute *lm85_attributes[] = {
1296b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_fan1_input.dev_attr.attr,
1297b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_fan2_input.dev_attr.attr,
1298b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_fan3_input.dev_attr.attr,
1299b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_fan4_input.dev_attr.attr,
1300b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_fan1_min.dev_attr.attr,
1301b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_fan2_min.dev_attr.attr,
1302b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_fan3_min.dev_attr.attr,
1303b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_fan4_min.dev_attr.attr,
1304bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare	&sensor_dev_attr_fan1_alarm.dev_attr.attr,
1305bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare	&sensor_dev_attr_fan2_alarm.dev_attr.attr,
1306bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare	&sensor_dev_attr_fan3_alarm.dev_attr.attr,
1307bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare	&sensor_dev_attr_fan4_alarm.dev_attr.attr,
1308b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
1309b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_pwm1.dev_attr.attr,
1310b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_pwm2.dev_attr.attr,
1311b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_pwm3.dev_attr.attr,
1312b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_pwm1_enable.dev_attr.attr,
1313b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_pwm2_enable.dev_attr.attr,
1314b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_pwm3_enable.dev_attr.attr,
131534e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare	&sensor_dev_attr_pwm1_freq.dev_attr.attr,
131634e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare	&sensor_dev_attr_pwm2_freq.dev_attr.attr,
131734e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare	&sensor_dev_attr_pwm3_freq.dev_attr.attr,
1318b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
1319b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_in0_input.dev_attr.attr,
1320b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_in1_input.dev_attr.attr,
1321b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_in2_input.dev_attr.attr,
1322b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_in3_input.dev_attr.attr,
1323b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_in0_min.dev_attr.attr,
1324b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_in1_min.dev_attr.attr,
1325b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_in2_min.dev_attr.attr,
1326b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_in3_min.dev_attr.attr,
1327b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_in0_max.dev_attr.attr,
1328b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_in1_max.dev_attr.attr,
1329b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_in2_max.dev_attr.attr,
1330b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_in3_max.dev_attr.attr,
1331bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare	&sensor_dev_attr_in0_alarm.dev_attr.attr,
1332bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare	&sensor_dev_attr_in1_alarm.dev_attr.attr,
1333bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare	&sensor_dev_attr_in2_alarm.dev_attr.attr,
1334bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare	&sensor_dev_attr_in3_alarm.dev_attr.attr,
1335b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
1336b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_temp1_input.dev_attr.attr,
1337b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_temp2_input.dev_attr.attr,
1338b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_temp3_input.dev_attr.attr,
1339b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_temp1_min.dev_attr.attr,
1340b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_temp2_min.dev_attr.attr,
1341b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_temp3_min.dev_attr.attr,
1342b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_temp1_max.dev_attr.attr,
1343b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_temp2_max.dev_attr.attr,
1344b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_temp3_max.dev_attr.attr,
1345bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare	&sensor_dev_attr_temp1_alarm.dev_attr.attr,
1346bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare	&sensor_dev_attr_temp2_alarm.dev_attr.attr,
1347bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare	&sensor_dev_attr_temp3_alarm.dev_attr.attr,
1348bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare	&sensor_dev_attr_temp1_fault.dev_attr.attr,
1349bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare	&sensor_dev_attr_temp3_fault.dev_attr.attr,
1350b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
1351b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_pwm1_auto_channels.dev_attr.attr,
1352b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_pwm2_auto_channels.dev_attr.attr,
1353b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_pwm3_auto_channels.dev_attr.attr,
1354b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr,
1355b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr,
1356b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr,
1357b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
1358b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_temp1_auto_temp_min.dev_attr.attr,
1359b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_temp2_auto_temp_min.dev_attr.attr,
1360b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_temp3_auto_temp_min.dev_attr.attr,
1361b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_temp1_auto_temp_max.dev_attr.attr,
1362b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_temp2_auto_temp_max.dev_attr.attr,
1363b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_temp3_auto_temp_max.dev_attr.attr,
1364b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_temp1_auto_temp_crit.dev_attr.attr,
1365b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_temp2_auto_temp_crit.dev_attr.attr,
1366b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_temp3_auto_temp_crit.dev_attr.attr,
1367b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare
13680501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman	&dev_attr_vrm.attr,
13690501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman	&dev_attr_cpu0_vid.attr,
13700501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman	&dev_attr_alarms.attr,
13710501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman	NULL
13720501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman};
13730501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman
13740501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffmanstatic const struct attribute_group lm85_group = {
13750501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman	.attrs = lm85_attributes,
13760501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman};
13770501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman
137806923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeckstatic struct attribute *lm85_attributes_minctl[] = {
137906923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck	&sensor_dev_attr_pwm1_auto_pwm_minctl.dev_attr.attr,
138006923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck	&sensor_dev_attr_pwm2_auto_pwm_minctl.dev_attr.attr,
138106923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck	&sensor_dev_attr_pwm3_auto_pwm_minctl.dev_attr.attr,
13825f441e2256506a5878d276399e0a22a13942fe4bJean Delvare	NULL
138306923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck};
138406923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck
138506923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeckstatic const struct attribute_group lm85_group_minctl = {
138606923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck	.attrs = lm85_attributes_minctl,
138706923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck};
138806923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck
138906923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeckstatic struct attribute *lm85_attributes_temp_off[] = {
139006923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck	&sensor_dev_attr_temp1_auto_temp_off.dev_attr.attr,
139106923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck	&sensor_dev_attr_temp2_auto_temp_off.dev_attr.attr,
139206923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck	&sensor_dev_attr_temp3_auto_temp_off.dev_attr.attr,
13935f441e2256506a5878d276399e0a22a13942fe4bJean Delvare	NULL
139406923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck};
139506923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck
139606923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeckstatic const struct attribute_group lm85_group_temp_off = {
139706923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck	.attrs = lm85_attributes_temp_off,
139806923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck};
139906923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck
14006b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvarestatic struct attribute *lm85_attributes_in4[] = {
1401b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_in4_input.dev_attr.attr,
1402b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_in4_min.dev_attr.attr,
1403b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare	&sensor_dev_attr_in4_max.dev_attr.attr,
1404bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare	&sensor_dev_attr_in4_alarm.dev_attr.attr,
14050501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman	NULL
14060501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman};
14070501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman
14086b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvarestatic const struct attribute_group lm85_group_in4 = {
14096b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare	.attrs = lm85_attributes_in4,
14106b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare};
14116b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare
14126b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvarestatic struct attribute *lm85_attributes_in567[] = {
14136b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare	&sensor_dev_attr_in5_input.dev_attr.attr,
14146b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare	&sensor_dev_attr_in6_input.dev_attr.attr,
14156b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare	&sensor_dev_attr_in7_input.dev_attr.attr,
14166b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare	&sensor_dev_attr_in5_min.dev_attr.attr,
14176b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare	&sensor_dev_attr_in6_min.dev_attr.attr,
14186b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare	&sensor_dev_attr_in7_min.dev_attr.attr,
14196b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare	&sensor_dev_attr_in5_max.dev_attr.attr,
14206b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare	&sensor_dev_attr_in6_max.dev_attr.attr,
14216b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare	&sensor_dev_attr_in7_max.dev_attr.attr,
1422bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare	&sensor_dev_attr_in5_alarm.dev_attr.attr,
1423bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare	&sensor_dev_attr_in6_alarm.dev_attr.attr,
1424bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare	&sensor_dev_attr_in7_alarm.dev_attr.attr,
14256b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare	NULL
14266b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare};
14276b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare
14286b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvarestatic const struct attribute_group lm85_group_in567 = {
14296b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare	.attrs = lm85_attributes_in567,
14300501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman};
14310501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman
14325f44759470f7248f74947a39cba339009d62052cJean Delvarestatic void lm85_init_client(struct i2c_client *client)
14335f44759470f7248f74947a39cba339009d62052cJean Delvare{
14345f44759470f7248f74947a39cba339009d62052cJean Delvare	int value;
14355f44759470f7248f74947a39cba339009d62052cJean Delvare
14365f44759470f7248f74947a39cba339009d62052cJean Delvare	/* Start monitoring if needed */
14375f44759470f7248f74947a39cba339009d62052cJean Delvare	value = lm85_read_value(client, LM85_REG_CONFIG);
14385f44759470f7248f74947a39cba339009d62052cJean Delvare	if (!(value & 0x01)) {
14395f44759470f7248f74947a39cba339009d62052cJean Delvare		dev_info(&client->dev, "Starting monitoring\n");
14405f44759470f7248f74947a39cba339009d62052cJean Delvare		lm85_write_value(client, LM85_REG_CONFIG, value | 0x01);
14415f44759470f7248f74947a39cba339009d62052cJean Delvare	}
14425f44759470f7248f74947a39cba339009d62052cJean Delvare
14435f44759470f7248f74947a39cba339009d62052cJean Delvare	/* Warn about unusual configuration bits */
14445f44759470f7248f74947a39cba339009d62052cJean Delvare	if (value & 0x02)
14455f44759470f7248f74947a39cba339009d62052cJean Delvare		dev_warn(&client->dev, "Device configuration is locked\n");
14465f44759470f7248f74947a39cba339009d62052cJean Delvare	if (!(value & 0x04))
14475f44759470f7248f74947a39cba339009d62052cJean Delvare		dev_warn(&client->dev, "Device is not ready\n");
14485f44759470f7248f74947a39cba339009d62052cJean Delvare}
14495f44759470f7248f74947a39cba339009d62052cJean Delvare
14505cfaf338134605ce8d9272b9c16605bc920d25beJean Delvarestatic int lm85_is_fake(struct i2c_client *client)
14515cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare{
14525cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare	/*
14535cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare	 * Differenciate between real LM96000 and Winbond WPCD377I. The latter
14545cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare	 * emulate the former except that it has no hardware monitoring function
14555cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare	 * so the readings are always 0.
14565cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare	 */
14575cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare	int i;
14585cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare	u8 in_temp, fan;
14595cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare
14605cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare	for (i = 0; i < 8; i++) {
14615cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare		in_temp = i2c_smbus_read_byte_data(client, 0x20 + i);
14625cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare		fan = i2c_smbus_read_byte_data(client, 0x28 + i);
14635cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare		if (in_temp != 0x00 || fan != 0xff)
14645cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare			return 0;
14655cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare	}
14665cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare
14675cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare	return 1;
14685cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare}
14695cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare
147067712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare/* Return 0 if detection is successful, -ENODEV otherwise */
1471310ec79210d754afe51e2e4a983e846b60179abdJean Delvarestatic int lm85_detect(struct i2c_client *client, struct i2c_board_info *info)
14721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
147367712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare	struct i2c_adapter *adapter = client->adapter;
147467712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare	int address = client->addr;
1475590e8534447ce9f2f5e5e64681764079530ee8c7Jean Delvare	const char *type_name = NULL;
1476d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare	int company, verstep;
14771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1478e89e22b23bceb3fbbcfb931ad17a564b7c1eaa55Jean Delvare	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
14791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* We need to be able to do byte I/O */
148067712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare		return -ENODEV;
14811f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	}
14821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1483d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare	/* Determine the chip type */
1484d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare	company = lm85_read_value(client, LM85_REG_COMPANY);
1485d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare	verstep = lm85_read_value(client, LM85_REG_VERSTEP);
1486d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare
1487b55f375725ff85aada394da488802b0a3cc99e88Guenter Roeck	dev_dbg(&adapter->dev,
1488b55f375725ff85aada394da488802b0a3cc99e88Guenter Roeck		"Detecting device at 0x%02x with COMPANY: 0x%02x and VERSTEP: 0x%02x\n",
1489d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare		address, company, verstep);
1490d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare
1491d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare	if (company == LM85_COMPANY_NATIONAL) {
1492d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare		switch (verstep) {
1493d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare		case LM85_VERSTEP_LM85C:
1494d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare			type_name = "lm85c";
1495d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare			break;
1496d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare		case LM85_VERSTEP_LM85B:
1497d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare			type_name = "lm85b";
1498d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare			break;
1499d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare		case LM85_VERSTEP_LM96000_1:
1500d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare		case LM85_VERSTEP_LM96000_2:
1501d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare			/* Check for Winbond WPCD377I */
1502d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare			if (lm85_is_fake(client)) {
1503d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare				dev_dbg(&adapter->dev,
1504d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare					"Found Winbond WPCD377I, ignoring\n");
1505d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare				return -ENODEV;
150669fc1feba2d5856ff74dedb6ae9d8c490210825cJean Delvare			}
1507590e8534447ce9f2f5e5e64681764079530ee8c7Jean Delvare			type_name = "lm85";
1508d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare			break;
1509d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare		}
1510d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare	} else if (company == LM85_COMPANY_ANALOG_DEV) {
1511d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare		switch (verstep) {
1512d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare		case LM85_VERSTEP_ADM1027:
1513d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare			type_name = "adm1027";
1514d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare			break;
1515d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare		case LM85_VERSTEP_ADT7463:
1516d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare		case LM85_VERSTEP_ADT7463C:
1517d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare			type_name = "adt7463";
1518d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare			break;
1519d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare		case LM85_VERSTEP_ADT7468_1:
1520d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare		case LM85_VERSTEP_ADT7468_2:
1521d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare			type_name = "adt7468";
1522d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare			break;
15231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1524d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare	} else if (company == LM85_COMPANY_SMSC) {
1525d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare		switch (verstep) {
1526d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare		case LM85_VERSTEP_EMC6D100_A0:
1527d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare		case LM85_VERSTEP_EMC6D100_A1:
1528d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare			/* Note: we can't tell a '100 from a '101 */
1529d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare			type_name = "emc6d100";
1530d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare			break;
1531d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare		case LM85_VERSTEP_EMC6D102:
1532d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare			type_name = "emc6d102";
1533d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare			break;
1534f065a93e168299569078bc6f52128b57f602fff3Jan Beulich		case LM85_VERSTEP_EMC6D103_A0:
1535f065a93e168299569078bc6f52128b57f602fff3Jan Beulich		case LM85_VERSTEP_EMC6D103_A1:
1536f065a93e168299569078bc6f52128b57f602fff3Jan Beulich			type_name = "emc6d103";
1537f065a93e168299569078bc6f52128b57f602fff3Jan Beulich			break;
1538f065a93e168299569078bc6f52128b57f602fff3Jan Beulich		case LM85_VERSTEP_EMC6D103S:
1539f065a93e168299569078bc6f52128b57f602fff3Jan Beulich			type_name = "emc6d103s";
1540f065a93e168299569078bc6f52128b57f602fff3Jan Beulich			break;
1541d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare		}
15421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
15431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1544590e8534447ce9f2f5e5e64681764079530ee8c7Jean Delvare	if (!type_name)
1545590e8534447ce9f2f5e5e64681764079530ee8c7Jean Delvare		return -ENODEV;
1546590e8534447ce9f2f5e5e64681764079530ee8c7Jean Delvare
154767712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare	strlcpy(info->type, type_name, I2C_NAME_SIZE);
154867712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare
154967712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare	return 0;
155067712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare}
15511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1552746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Linstatic int lm85_probe(struct i2c_client *client, const struct i2c_device_id *id)
155367712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare{
1554746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct device *dev = &client->dev;
1555746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	struct device *hwmon_dev;
155667712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare	struct lm85_data *data;
1557746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	int idx = 0;
155867712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare
1559746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	data = devm_kzalloc(dev, sizeof(struct lm85_data), GFP_KERNEL);
156067712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare	if (!data)
156167712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare		return -ENOMEM;
156267712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare
1563746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	data->client = client;
156467712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare	data->type = id->driver_data;
15659a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_init(&data->update_lock);
15661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
156767712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare	/* Fill in the chip specific driver values */
156867712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare	switch (data->type) {
156967712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare	case adm1027:
157067712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare	case adt7463:
1571fa7a5797e57d2ed71f9a6fb44f0ae42c2d7b74b7Jean Delvare	case adt7468:
157267712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare	case emc6d100:
157367712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare	case emc6d102:
1574f065a93e168299569078bc6f52128b57f602fff3Jan Beulich	case emc6d103:
157506923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck	case emc6d103s:
157667712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare		data->freq_map = adm1027_freq_map;
157767712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare		break;
157867712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare	default:
157967712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare		data->freq_map = lm85_freq_map;
158067712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare	}
15811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Set the VRM version */
1583303760b44a7a142cb9f4c9df4609fb63bbda98dbJean Delvare	data->vrm = vid_which_vrm();
15841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Initialize the LM85 chip */
1586e89e22b23bceb3fbbcfb931ad17a564b7c1eaa55Jean Delvare	lm85_init_client(client);
15871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1588746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	/* sysfs hooks */
1589746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	data->groups[idx++] = &lm85_group;
15901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
159106923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck	/* minctl and temp_off exist on all chips except emc6d103s */
159206923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck	if (data->type != emc6d103s) {
1593746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin		data->groups[idx++] = &lm85_group_minctl;
1594746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin		data->groups[idx++] = &lm85_group_temp_off;
159506923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck	}
159606923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck
159709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	/*
159809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	 * The ADT7463/68 have an optional VRM 10 mode where pin 21 is used
159909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	 * as a sixth digital VID input rather than an analog input.
160009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck	 */
1601de24880586b28f1dc4cf91f5db962f0083baab2aGuenter Roeck	if (data->type == adt7463 || data->type == adt7468) {
1602de24880586b28f1dc4cf91f5db962f0083baab2aGuenter Roeck		u8 vid = lm85_read_value(client, LM85_REG_VID);
1603de24880586b28f1dc4cf91f5db962f0083baab2aGuenter Roeck		if (vid & 0x80)
1604de24880586b28f1dc4cf91f5db962f0083baab2aGuenter Roeck			data->has_vid5 = true;
1605de24880586b28f1dc4cf91f5db962f0083baab2aGuenter Roeck	}
1606de24880586b28f1dc4cf91f5db962f0083baab2aGuenter Roeck
1607746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	if (!data->has_vid5)
1608746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin		data->groups[idx++] = &lm85_group_in4;
16096b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare
16106b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare	/* The EMC6D100 has 3 additional voltage inputs */
1611746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	if (data->type == emc6d100)
1612746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin		data->groups[idx++] = &lm85_group_in567;
16131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1614746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
1615746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin							   data, data->groups);
1616746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin	return PTR_ERR_OR_ZERO(hwmon_dev);
16171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
16181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16196fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Linstatic const struct i2c_device_id lm85_id[] = {
16206fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	{ "adm1027", adm1027 },
16216fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	{ "adt7463", adt7463 },
16226fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	{ "adt7468", adt7468 },
16236fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	{ "lm85", lm85 },
16246fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	{ "lm85b", lm85 },
16256fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	{ "lm85c", lm85 },
16266fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	{ "emc6d100", emc6d100 },
16276fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	{ "emc6d101", emc6d100 },
16286fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	{ "emc6d102", emc6d102 },
16296fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	{ "emc6d103", emc6d103 },
16306fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	{ "emc6d103s", emc6d103s },
16316fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	{ }
16326fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin};
16336fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel LinMODULE_DEVICE_TABLE(i2c, lm85_id);
16341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16356fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Linstatic struct i2c_driver lm85_driver = {
16366fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	.class		= I2C_CLASS_HWMON,
16376fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	.driver = {
16386fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin		.name   = "lm85",
16396fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	},
16406fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	.probe		= lm85_probe,
16416fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	.id_table	= lm85_id,
16426fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	.detect		= lm85_detect,
16436fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin	.address_list	= normal_i2c,
16446fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin};
16451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1646f0967eea80ec2a19a4fe1ad27e3ff1b22c79a3c7Axel Linmodule_i2c_driver(lm85_driver);
16471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL");
16491f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean DelvareMODULE_AUTHOR("Philip Pokorny <ppokorny@penguincomputing.com>, "
16501f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare	"Margit Schubert-While <margitsw@t-online.de>, "
1651e89e22b23bceb3fbbcfb931ad17a564b7c1eaa55Jean Delvare	"Justin Thiessen <jthiessen@penguincomputing.com>");
16521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("LM85-B, LM85-C driver");
1653