Blame view

drivers/hwmon/w83627ehf.c 80.5 KB
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1
2
  /*
      w83627ehf - Driver for the hardware monitoring functionality of
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
3
  		the Winbond W83627EHF Super-I/O chip
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
4
      Copyright (C) 2005-2011  Jean Delvare <khali@linux-fr.org>
3379ceeef   Jean Delvare   hwmon: Remove Yua...
5
      Copyright (C) 2006  Yuan Mu (Winbond),
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
6
7
  			Rudolf Marek <r.marek@assembler.cz>
  			David Hubbard <david.c.hubbard@gmail.com>
41e9a0623   Daniel J Blueman   hwmon: w83627ehf ...
8
  			Daniel J Blueman <daniel.blueman@gmail.com>
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
9
      Copyright (C) 2010  Sheng-Yuan Huang (Nuvoton) (PS00)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
10
11
12
13
14
15
  
      Shamelessly ripped from the w83627hf driver
      Copyright (C) 2003  Mark Studebaker
  
      Thanks to Leon Moonen, Steve Cliffe and Grant Coady for their help
      in testing and debugging this driver.
8dd2d2ca7   Jean Delvare   [PATCH] hwmon: Do...
16
17
      This driver also supports the W83627EHG, which is the lead-free
      version of the W83627EHF.
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
      This program is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published by
      the Free Software Foundation; either version 2 of the License, or
      (at your option) any later version.
  
      This program is distributed in the hope that it will be useful,
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      GNU General Public License for more details.
  
      You should have received a copy of the GNU General Public License
      along with this program; if not, write to the Free Software
      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  
  
      Supports the following chips:
657c93b10   David Hubbard   hwmon/w83627ehf: ...
34
35
      Chip        #vin    #fan    #pwm    #temp  chip IDs       man ID
      w83627ehf   10      5       4       3      0x8850 0x88    0x5ca3
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
36
  					       0x8860 0xa1
657c93b10   David Hubbard   hwmon/w83627ehf: ...
37
      w83627dhg    9      5       4       3      0xa020 0xc1    0x5ca3
c1e48dce0   Jean Delvare   hwmon: (w83627ehf...
38
      w83627dhg-p  9      5       4       3      0xb070 0xc1    0x5ca3
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
39
      w83627uhg    8      2       2       2      0xa230 0xc1    0x5ca3
237c8d2f5   Gong Jun   hwmon: (w83627ehf...
40
      w83667hg     9      5       3       3      0xa510 0xc1    0x5ca3
d36cf32c9   Guenter Roeck   hwmon: (w83627ehf...
41
      w83667hg-b   9      5       3       4      0xb350 0xc1    0x5ca3
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
42
43
      nct6775f     9      4       3       9      0xb470 0xc1    0x5ca3
      nct6776f     9      5       3       9      0xC330 0xc1    0x5ca3
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
44
  */
abdc6fd18   Joe Perches   hwmon: (w83627ehf...
45
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
46
47
48
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/slab.h>
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
49
50
  #include <linux/jiffies.h>
  #include <linux/platform_device.h>
943b0830c   Mark M. Hoffman   [PATCH] I2C hwmon...
51
  #include <linux/hwmon.h>
412fec821   Yuan Mu   [PATCH] w83627ehf...
52
  #include <linux/hwmon-sysfs.h>
fc18d6c04   Jean Delvare   hwmon/w83627ehf: ...
53
  #include <linux/hwmon-vid.h>
943b0830c   Mark M. Hoffman   [PATCH] I2C hwmon...
54
  #include <linux/err.h>
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
55
  #include <linux/mutex.h>
b9acb64a3   Jean Delvare   hwmon: Check for ...
56
  #include <linux/acpi.h>
6055fae8a   H Hartley Sweeten   hwmon: Include <l...
57
  #include <linux/io.h>
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
58
  #include "lm75.h"
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
59
60
61
62
  enum kinds {
  	w83627ehf, w83627dhg, w83627dhg_p, w83627uhg,
  	w83667hg, w83667hg_b, nct6775, nct6776,
  };
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
63

1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
64
  /* used to set data->name = w83627ehf_device_names[data->sio_kind] */
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
65
  static const char * const w83627ehf_device_names[] = {
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
66
67
  	"w83627ehf",
  	"w83627dhg",
c1e48dce0   Jean Delvare   hwmon: (w83627ehf...
68
  	"w83627dhg",
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
69
  	"w83627uhg",
237c8d2f5   Gong Jun   hwmon: (w83627ehf...
70
  	"w83667hg",
c39aedafb   Guenter Roeck   hwmon: (w83627ehf...
71
  	"w83667hg",
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
72
73
  	"nct6775",
  	"nct6776",
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
74
  };
67b671bce   Jean Delvare   hwmon: Let the us...
75
76
77
  static unsigned short force_id;
  module_param(force_id, ushort, 0);
  MODULE_PARM_DESC(force_id, "Override the detected device ID");
d42e869ac   Ian Dobson   hwmon: (w83627ehf...
78
79
80
  static unsigned short fan_debounce;
  module_param(fan_debounce, ushort, 0);
  MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
81
  #define DRVNAME "w83627ehf"
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
82

657c93b10   David Hubbard   hwmon/w83627ehf: ...
83
  /*
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
84
   * Super-I/O constants and functions
657c93b10   David Hubbard   hwmon/w83627ehf: ...
85
   */
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
86
87
  
  #define W83627EHF_LD_HWM	0x0b
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
88
  #define W83667HG_LD_VID		0x0d
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
89
90
91
  
  #define SIO_REG_LDSEL		0x07	/* Logical device select */
  #define SIO_REG_DEVID		0x20	/* Device ID (2 bytes) */
fc18d6c04   Jean Delvare   hwmon/w83627ehf: ...
92
  #define SIO_REG_EN_VRM10	0x2C	/* GPIO3, GPIO4 selection */
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
93
94
  #define SIO_REG_ENABLE		0x30	/* Logical device enable */
  #define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */
fc18d6c04   Jean Delvare   hwmon/w83627ehf: ...
95
96
  #define SIO_REG_VID_CTRL	0xF0	/* VID control */
  #define SIO_REG_VID_DATA	0xF1	/* VID data */
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
97

657c93b10   David Hubbard   hwmon/w83627ehf: ...
98
99
100
  #define SIO_W83627EHF_ID	0x8850
  #define SIO_W83627EHG_ID	0x8860
  #define SIO_W83627DHG_ID	0xa020
c1e48dce0   Jean Delvare   hwmon: (w83627ehf...
101
  #define SIO_W83627DHG_P_ID	0xb070
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
102
  #define SIO_W83627UHG_ID	0xa230
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
103
  #define SIO_W83667HG_ID		0xa510
c39aedafb   Guenter Roeck   hwmon: (w83627ehf...
104
  #define SIO_W83667HG_B_ID	0xb350
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
105
106
  #define SIO_NCT6775_ID		0xb470
  #define SIO_NCT6776_ID		0xc330
657c93b10   David Hubbard   hwmon/w83627ehf: ...
107
  #define SIO_ID_MASK		0xFFF0
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
108
109
  
  static inline void
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
110
  superio_outb(int ioreg, int reg, int val)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
111
  {
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
112
113
  	outb(reg, ioreg);
  	outb(val, ioreg + 1);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
114
115
116
  }
  
  static inline int
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
117
  superio_inb(int ioreg, int reg)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
118
  {
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
119
120
  	outb(reg, ioreg);
  	return inb(ioreg + 1);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
121
122
123
  }
  
  static inline void
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
124
  superio_select(int ioreg, int ld)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
125
  {
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
126
127
  	outb(SIO_REG_LDSEL, ioreg);
  	outb(ld, ioreg + 1);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
128
129
130
  }
  
  static inline void
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
131
  superio_enter(int ioreg)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
132
  {
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
133
134
  	outb(0x87, ioreg);
  	outb(0x87, ioreg);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
135
136
137
  }
  
  static inline void
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
138
  superio_exit(int ioreg)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
139
  {
022b75a3d   Jonas Jonsson   hwmon: (w83627ehf...
140
  	outb(0xaa, ioreg);
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
141
142
  	outb(0x02, ioreg);
  	outb(0x02, ioreg + 1);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
143
144
145
146
147
  }
  
  /*
   * ISA constants
   */
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
148
  #define IOREGION_ALIGNMENT	(~7)
1a641fceb   Jean Delvare   hwmon/w83627ehf: ...
149
150
  #define IOREGION_OFFSET		5
  #define IOREGION_LENGTH		2
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
151
152
  #define ADDR_REG_OFFSET		0
  #define DATA_REG_OFFSET		1
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
153
154
155
  
  #define W83627EHF_REG_BANK		0x4E
  #define W83627EHF_REG_CONFIG		0x40
657c93b10   David Hubbard   hwmon/w83627ehf: ...
156
157
158
159
160
161
  
  /* Not currently used:
   * REG_MAN_ID has the value 0x5ca3 for all supported chips.
   * REG_CHIP_ID == 0x88/0xa1/0xc1 depending on chip model.
   * REG_MAN_ID is at port 0x4f
   * REG_CHIP_ID is at port 0x58 */
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
162
163
164
  
  static const u16 W83627EHF_REG_FAN[] = { 0x28, 0x29, 0x2a, 0x3f, 0x553 };
  static const u16 W83627EHF_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d, 0x3e, 0x55c };
cf0676fe4   Rudolf Marek   [PATCH] w83627ehf...
165
166
167
168
169
170
171
  /* The W83627EHF registers for nr=7,8,9 are in bank 5 */
  #define W83627EHF_REG_IN_MAX(nr)	((nr < 7) ? (0x2b + (nr) * 2) : \
  					 (0x554 + (((nr) - 7) * 2)))
  #define W83627EHF_REG_IN_MIN(nr)	((nr < 7) ? (0x2c + (nr) * 2) : \
  					 (0x555 + (((nr) - 7) * 2)))
  #define W83627EHF_REG_IN(nr)		((nr < 7) ? (0x20 + (nr)) : \
  					 (0x550 + (nr) - 7))
d36cf32c9   Guenter Roeck   hwmon: (w83627ehf...
172
173
174
175
  static const u16 W83627EHF_REG_TEMP[] = { 0x27, 0x150, 0x250, 0x7e };
  static const u16 W83627EHF_REG_TEMP_HYST[] = { 0x3a, 0x153, 0x253, 0 };
  static const u16 W83627EHF_REG_TEMP_OVER[] = { 0x39, 0x155, 0x255, 0 };
  static const u16 W83627EHF_REG_TEMP_CONFIG[] = { 0, 0x152, 0x252, 0 };
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
176
177
178
179
180
181
182
  
  /* Fan clock dividers are spread over the following five registers */
  #define W83627EHF_REG_FANDIV1		0x47
  #define W83627EHF_REG_FANDIV2		0x4B
  #define W83627EHF_REG_VBAT		0x5D
  #define W83627EHF_REG_DIODE		0x59
  #define W83627EHF_REG_SMI_OVT		0x4C
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
183
184
185
  /* NCT6775F has its own fan divider registers */
  #define NCT6775_REG_FANDIV1		0x506
  #define NCT6775_REG_FANDIV2		0x507
d42e869ac   Ian Dobson   hwmon: (w83627ehf...
186
  #define NCT6775_REG_FAN_DEBOUNCE	0xf0
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
187

a4589dbb4   Jean Delvare   [PATCH] w83627ehf...
188
189
190
  #define W83627EHF_REG_ALARM1		0x459
  #define W83627EHF_REG_ALARM2		0x45A
  #define W83627EHF_REG_ALARM3		0x45B
363a12a49   Dmitry Artamonow   hwmon: (w83627ehf...
191
192
  #define W83627EHF_REG_CASEOPEN_DET	0x42 /* SMI STATUS #2 */
  #define W83627EHF_REG_CASEOPEN_CLR	0x46 /* SMI MASK #3 */
08c79950a   Rudolf Marek   hwmon: Add fan sp...
193
  /* SmartFan registers */
41e9a0623   Daniel J Blueman   hwmon: w83627ehf ...
194
195
  #define W83627EHF_REG_FAN_STEPUP_TIME 0x0f
  #define W83627EHF_REG_FAN_STEPDOWN_TIME 0x0e
08c79950a   Rudolf Marek   hwmon: Add fan sp...
196
197
198
199
200
  /* DC or PWM output fan configuration */
  static const u8 W83627EHF_REG_PWM_ENABLE[] = {
  	0x04,			/* SYS FAN0 output mode and PWM mode */
  	0x04,			/* CPU FAN0 output mode and PWM mode */
  	0x12,			/* AUX FAN mode */
41e9a0623   Daniel J Blueman   hwmon: w83627ehf ...
201
  	0x62,			/* CPU FAN1 mode */
08c79950a   Rudolf Marek   hwmon: Add fan sp...
202
203
204
205
206
207
  };
  
  static const u8 W83627EHF_PWM_MODE_SHIFT[] = { 0, 1, 0, 6 };
  static const u8 W83627EHF_PWM_ENABLE_SHIFT[] = { 2, 4, 1, 4 };
  
  /* FAN Duty Cycle, be used to control */
279af1a91   Guenter Roeck   hwmon: (w83627ehf...
208
209
  static const u16 W83627EHF_REG_PWM[] = { 0x01, 0x03, 0x11, 0x61 };
  static const u16 W83627EHF_REG_TARGET[] = { 0x05, 0x06, 0x13, 0x63 };
08c79950a   Rudolf Marek   hwmon: Add fan sp...
210
  static const u8 W83627EHF_REG_TOLERANCE[] = { 0x07, 0x07, 0x14, 0x62 };
08c79950a   Rudolf Marek   hwmon: Add fan sp...
211
  /* Advanced Fan control, some values are common for all fans */
279af1a91   Guenter Roeck   hwmon: (w83627ehf...
212
213
214
  static const u16 W83627EHF_REG_FAN_START_OUTPUT[] = { 0x0a, 0x0b, 0x16, 0x65 };
  static const u16 W83627EHF_REG_FAN_STOP_OUTPUT[] = { 0x08, 0x09, 0x15, 0x64 };
  static const u16 W83627EHF_REG_FAN_STOP_TIME[] = { 0x0c, 0x0d, 0x17, 0x66 };
c39aedafb   Guenter Roeck   hwmon: (w83627ehf...
215

279af1a91   Guenter Roeck   hwmon: (w83627ehf...
216
  static const u16 W83627EHF_REG_FAN_MAX_OUTPUT_COMMON[]
c39aedafb   Guenter Roeck   hwmon: (w83627ehf...
217
  						= { 0xff, 0x67, 0xff, 0x69 };
279af1a91   Guenter Roeck   hwmon: (w83627ehf...
218
  static const u16 W83627EHF_REG_FAN_STEP_OUTPUT_COMMON[]
c39aedafb   Guenter Roeck   hwmon: (w83627ehf...
219
  						= { 0xff, 0x68, 0xff, 0x6a };
279af1a91   Guenter Roeck   hwmon: (w83627ehf...
220
221
222
  static const u16 W83627EHF_REG_FAN_MAX_OUTPUT_W83667_B[] = { 0x67, 0x69, 0x6b };
  static const u16 W83627EHF_REG_FAN_STEP_OUTPUT_W83667_B[]
  						= { 0x68, 0x6a, 0x6c };
08c79950a   Rudolf Marek   hwmon: Add fan sp...
223

ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
224
225
226
227
228
229
230
231
  static const u16 NCT6775_REG_TARGET[] = { 0x101, 0x201, 0x301 };
  static const u16 NCT6775_REG_FAN_MODE[] = { 0x102, 0x202, 0x302 };
  static const u16 NCT6775_REG_FAN_STOP_OUTPUT[] = { 0x105, 0x205, 0x305 };
  static const u16 NCT6775_REG_FAN_START_OUTPUT[] = { 0x106, 0x206, 0x306 };
  static const u16 NCT6775_REG_FAN_STOP_TIME[] = { 0x107, 0x207, 0x307 };
  static const u16 NCT6775_REG_PWM[] = { 0x109, 0x209, 0x309 };
  static const u16 NCT6775_REG_FAN_MAX_OUTPUT[] = { 0x10a, 0x20a, 0x30a };
  static const u16 NCT6775_REG_FAN_STEP_OUTPUT[] = { 0x10b, 0x20b, 0x30b };
26bc440e3   Guenter Roeck   hwmon: (w83627ehf...
232
  static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 };
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
233
234
235
236
237
238
239
240
241
242
243
244
  static const u16 NCT6776_REG_FAN_MIN[] = { 0x63a, 0x63c, 0x63e, 0x640, 0x642};
  
  static const u16 NCT6775_REG_TEMP[]
  	= { 0x27, 0x150, 0x250, 0x73, 0x75, 0x77, 0x62b, 0x62c, 0x62d };
  static const u16 NCT6775_REG_TEMP_CONFIG[]
  	= { 0, 0x152, 0x252, 0, 0, 0, 0x628, 0x629, 0x62A };
  static const u16 NCT6775_REG_TEMP_HYST[]
  	= { 0x3a, 0x153, 0x253, 0, 0, 0, 0x673, 0x678, 0x67D };
  static const u16 NCT6775_REG_TEMP_OVER[]
  	= { 0x39, 0x155, 0x255, 0, 0, 0, 0x672, 0x677, 0x67C };
  static const u16 NCT6775_REG_TEMP_SOURCE[]
  	= { 0x621, 0x622, 0x623, 0x100, 0x200, 0x300, 0x624, 0x625, 0x626 };
d36cf32c9   Guenter Roeck   hwmon: (w83627ehf...
245
246
247
248
249
250
251
252
253
254
  static const char *const w83667hg_b_temp_label[] = {
  	"SYSTIN",
  	"CPUTIN",
  	"AUXTIN",
  	"AMDTSI",
  	"PECI Agent 1",
  	"PECI Agent 2",
  	"PECI Agent 3",
  	"PECI Agent 4"
  };
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
  static const char *const nct6775_temp_label[] = {
  	"",
  	"SYSTIN",
  	"CPUTIN",
  	"AUXTIN",
  	"AMD SB-TSI",
  	"PECI Agent 0",
  	"PECI Agent 1",
  	"PECI Agent 2",
  	"PECI Agent 3",
  	"PECI Agent 4",
  	"PECI Agent 5",
  	"PECI Agent 6",
  	"PECI Agent 7",
  	"PCH_CHIP_CPU_MAX_TEMP",
  	"PCH_CHIP_TEMP",
  	"PCH_CPU_TEMP",
  	"PCH_MCH_TEMP",
  	"PCH_DIM0_TEMP",
  	"PCH_DIM1_TEMP",
  	"PCH_DIM2_TEMP",
  	"PCH_DIM3_TEMP"
  };
  
  static const char *const nct6776_temp_label[] = {
  	"",
  	"SYSTIN",
  	"CPUTIN",
  	"AUXTIN",
  	"SMBUSMASTER 0",
  	"SMBUSMASTER 1",
  	"SMBUSMASTER 2",
  	"SMBUSMASTER 3",
  	"SMBUSMASTER 4",
  	"SMBUSMASTER 5",
  	"SMBUSMASTER 6",
  	"SMBUSMASTER 7",
  	"PECI Agent 0",
  	"PECI Agent 1",
  	"PCH_CHIP_CPU_MAX_TEMP",
  	"PCH_CHIP_TEMP",
  	"PCH_CPU_TEMP",
  	"PCH_MCH_TEMP",
  	"PCH_DIM0_TEMP",
  	"PCH_DIM1_TEMP",
  	"PCH_DIM2_TEMP",
  	"PCH_DIM3_TEMP",
  	"BYTE_TEMP"
  };
  
  #define NUM_REG_TEMP	ARRAY_SIZE(NCT6775_REG_TEMP)
d36cf32c9   Guenter Roeck   hwmon: (w83627ehf...
306

17296feb3   Jean Delvare   hwmon: (w83627ehf...
307
  static int is_word_sized(u16 reg)
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
308
  {
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
309
  	return ((((reg & 0xff00) == 0x100
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
310
311
312
  	      || (reg & 0xff00) == 0x200)
  	     && ((reg & 0x00ff) == 0x50
  	      || (reg & 0x00ff) == 0x53
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
313
314
315
316
317
318
319
  	      || (reg & 0x00ff) == 0x55))
  	     || (reg & 0xfff0) == 0x630
  	     || reg == 0x640 || reg == 0x642
  	     || ((reg & 0xfff0) == 0x650
  		 && (reg & 0x000f) >= 0x06)
  	     || reg == 0x73 || reg == 0x75 || reg == 0x77
  		);
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
320
  }
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
321
322
323
  /*
   * Conversions
   */
08c79950a   Rudolf Marek   hwmon: Add fan sp...
324
325
326
327
328
329
330
331
332
333
334
  /* 1 is PWM mode, output in ms */
  static inline unsigned int step_time_from_reg(u8 reg, u8 mode)
  {
  	return mode ? 100 * reg : 400 * reg;
  }
  
  static inline u8 step_time_to_reg(unsigned int msec, u8 mode)
  {
  	return SENSORS_LIMIT((mode ? (msec + 50) / 100 :
  						(msec + 200) / 400), 1, 255);
  }
26bc440e3   Guenter Roeck   hwmon: (w83627ehf...
335
  static unsigned int fan_from_reg8(u16 reg, unsigned int divreg)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
336
  {
26bc440e3   Guenter Roeck   hwmon: (w83627ehf...
337
  	if (reg == 0 || reg == 255)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
338
  		return 0;
26bc440e3   Guenter Roeck   hwmon: (w83627ehf...
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
  	return 1350000U / (reg << divreg);
  }
  
  static unsigned int fan_from_reg13(u16 reg, unsigned int divreg)
  {
  	if ((reg & 0xff1f) == 0xff1f)
  		return 0;
  
  	reg = (reg & 0x1f) | ((reg & 0xff00) >> 3);
  
  	if (reg == 0)
  		return 0;
  
  	return 1350000U / reg;
  }
  
  static unsigned int fan_from_reg16(u16 reg, unsigned int divreg)
  {
  	if (reg == 0 || reg == 0xffff)
  		return 0;
  
  	/*
  	 * Even though the registers are 16 bit wide, the fan divisor
  	 * still applies.
  	 */
  	return 1350000U / (reg << divreg);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
365
366
367
368
369
370
371
  }
  
  static inline unsigned int
  div_from_reg(u8 reg)
  {
  	return 1 << reg;
  }
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
372
373
374
375
376
377
378
379
  /* Some of the voltage inputs have internal scaling, the tables below
   * contain 8 (the ADC LSB in mV) * scaling factor * 100 */
  static const u16 scale_in_common[10] = {
  	800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 800
  };
  static const u16 scale_in_w83627uhg[9] = {
  	800, 800, 3328, 3424, 800, 800, 0, 3328, 3400
  };
cf0676fe4   Rudolf Marek   [PATCH] w83627ehf...
380

eff7687d4   Jean Delvare   hwmon: (w83627ehf...
381
  static inline long in_from_reg(u8 reg, u8 nr, const u16 *scale_in)
cf0676fe4   Rudolf Marek   [PATCH] w83627ehf...
382
  {
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
383
  	return DIV_ROUND_CLOSEST(reg * scale_in[nr], 100);
cf0676fe4   Rudolf Marek   [PATCH] w83627ehf...
384
  }
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
385
  static inline u8 in_to_reg(u32 val, u8 nr, const u16 *scale_in)
cf0676fe4   Rudolf Marek   [PATCH] w83627ehf...
386
  {
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
387
  	return SENSORS_LIMIT(DIV_ROUND_CLOSEST(val * 100, scale_in[nr]), 0,
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
388
  			     255);
cf0676fe4   Rudolf Marek   [PATCH] w83627ehf...
389
  }
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
390
391
392
393
394
  /*
   * Data structures and manipulation thereof
   */
  
  struct w83627ehf_data {
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
395
396
  	int addr;	/* IO base of hw monitor block */
  	const char *name;
1beeffe43   Tony Jones   hwmon: Convert fr...
397
  	struct device *hwmon_dev;
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
398
  	struct mutex lock;
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
399

ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
400
401
402
403
  	u16 reg_temp[NUM_REG_TEMP];
  	u16 reg_temp_over[NUM_REG_TEMP];
  	u16 reg_temp_hyst[NUM_REG_TEMP];
  	u16 reg_temp_config[NUM_REG_TEMP];
d36cf32c9   Guenter Roeck   hwmon: (w83627ehf...
404
405
  	u8 temp_src[NUM_REG_TEMP];
  	const char * const *temp_label;
279af1a91   Guenter Roeck   hwmon: (w83627ehf...
406
407
408
409
410
411
412
413
414
  	const u16 *REG_PWM;
  	const u16 *REG_TARGET;
  	const u16 *REG_FAN;
  	const u16 *REG_FAN_MIN;
  	const u16 *REG_FAN_START_OUTPUT;
  	const u16 *REG_FAN_STOP_OUTPUT;
  	const u16 *REG_FAN_STOP_TIME;
  	const u16 *REG_FAN_MAX_OUTPUT;
  	const u16 *REG_FAN_STEP_OUTPUT;
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
415
  	const u16 *scale_in;
da2e02559   Guenter Roeck   hwmon: (w83627ehf...
416

26bc440e3   Guenter Roeck   hwmon: (w83627ehf...
417
418
  	unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg);
  	unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg);
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
419
  	struct mutex update_lock;
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
420
421
422
423
  	char valid;		/* !=0 if following fields are valid */
  	unsigned long last_updated;	/* In jiffies */
  
  	/* Register values */
83cc8985b   Guenter Roeck   hwmon: (w83627ehf...
424
  	u8 bank;		/* current register bank */
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
425
  	u8 in_num;		/* number of in inputs we have */
cf0676fe4   Rudolf Marek   [PATCH] w83627ehf...
426
427
428
  	u8 in[10];		/* Register value */
  	u8 in_max[10];		/* Register value */
  	u8 in_min[10];		/* Register value */
3382a918d   Guenter Roeck   hwmon: (w83627ehf...
429
  	unsigned int rpm[5];
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
430
  	u16 fan_min[5];
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
431
432
  	u8 fan_div[5];
  	u8 has_fan;		/* some fan inputs can be disabled */
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
433
  	u8 has_fan_min;		/* some fans don't have min register */
26bc440e3   Guenter Roeck   hwmon: (w83627ehf...
434
  	bool has_fan_div;
da667365b   Jean Delvare   hwmon/w83627ehf: ...
435
  	u8 temp_type[3];
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
436
437
438
  	s16 temp[9];
  	s16 temp_max[9];
  	s16 temp_max_hyst[9];
a4589dbb4   Jean Delvare   [PATCH] w83627ehf...
439
  	u32 alarms;
363a12a49   Dmitry Artamonow   hwmon: (w83627ehf...
440
  	u8 caseopen;
08c79950a   Rudolf Marek   hwmon: Add fan sp...
441
442
443
  
  	u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */
  	u8 pwm_enable[4]; /* 1->manual
41e9a0623   Daniel J Blueman   hwmon: w83627ehf ...
444
445
  			     2->thermal cruise mode (also called SmartFan I)
  			     3->fan speed cruise mode
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
446
  			     4->variable thermal cruise (also called
b84bb5186   Guenter Roeck   hwmon: (w83627ehf...
447
448
449
450
  				SmartFan III)
  			     5->enhanced variable thermal cruise (also called
  				SmartFan IV) */
  	u8 pwm_enable_orig[4];	/* original value of pwm_enable */
237c8d2f5   Gong Jun   hwmon: (w83627ehf...
451
  	u8 pwm_num;		/* number of pwm */
08c79950a   Rudolf Marek   hwmon: Add fan sp...
452
453
454
  	u8 pwm[4];
  	u8 target_temp[4];
  	u8 tolerance[4];
41e9a0623   Daniel J Blueman   hwmon: w83627ehf ...
455
456
457
458
459
  	u8 fan_start_output[4]; /* minimum fan speed when spinning up */
  	u8 fan_stop_output[4]; /* minimum fan speed when spinning down */
  	u8 fan_stop_time[4]; /* time at minimum before disabling fan */
  	u8 fan_max_output[4]; /* maximum fan speed */
  	u8 fan_step_output[4]; /* rate of change output value */
fc18d6c04   Jean Delvare   hwmon/w83627ehf: ...
460
461
462
  
  	u8 vid;
  	u8 vrm;
a157d06d4   Gong Jun   hwmon: (w83627ehf...
463

ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
464
  	u16 have_temp;
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
465
466
  	u8 in6_skip:1;
  	u8 temp3_val_only:1;
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
467
  };
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
468
469
470
471
  struct w83627ehf_sio_data {
  	int sioreg;
  	enum kinds kind;
  };
83cc8985b   Guenter Roeck   hwmon: (w83627ehf...
472
473
474
475
476
477
  /*
   * On older chips, only registers 0x50-0x5f are banked.
   * On more recent chips, all registers are banked.
   * Assume that is the case and set the bank number for each access.
   * Cache the bank number so it only needs to be set if it changes.
   */
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
478
  static inline void w83627ehf_set_bank(struct w83627ehf_data *data, u16 reg)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
479
  {
83cc8985b   Guenter Roeck   hwmon: (w83627ehf...
480
481
  	u8 bank = reg >> 8;
  	if (data->bank != bank) {
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
482
  		outb_p(W83627EHF_REG_BANK, data->addr + ADDR_REG_OFFSET);
83cc8985b   Guenter Roeck   hwmon: (w83627ehf...
483
484
  		outb_p(bank, data->addr + DATA_REG_OFFSET);
  		data->bank = bank;
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
485
486
  	}
  }
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
487
  static u16 w83627ehf_read_value(struct w83627ehf_data *data, u16 reg)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
488
  {
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
489
  	int res, word_sized = is_word_sized(reg);
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
490
  	mutex_lock(&data->lock);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
491

1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
492
493
494
  	w83627ehf_set_bank(data, reg);
  	outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
  	res = inb_p(data->addr + DATA_REG_OFFSET);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
495
496
  	if (word_sized) {
  		outb_p((reg & 0xff) + 1,
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
497
498
  		       data->addr + ADDR_REG_OFFSET);
  		res = (res << 8) + inb_p(data->addr + DATA_REG_OFFSET);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
499
  	}
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
500

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
501
  	mutex_unlock(&data->lock);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
502
503
  	return res;
  }
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
504
505
  static int w83627ehf_write_value(struct w83627ehf_data *data, u16 reg,
  				 u16 value)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
506
  {
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
507
  	int word_sized = is_word_sized(reg);
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
508
  	mutex_lock(&data->lock);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
509

1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
510
511
  	w83627ehf_set_bank(data, reg);
  	outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
512
  	if (word_sized) {
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
513
  		outb_p(value >> 8, data->addr + DATA_REG_OFFSET);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
514
  		outb_p((reg & 0xff) + 1,
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
515
  		       data->addr + ADDR_REG_OFFSET);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
516
  	}
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
517
  	outb_p(value & 0xff, data->addr + DATA_REG_OFFSET);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
518

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
519
  	mutex_unlock(&data->lock);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
520
521
  	return 0;
  }
c5794cfac   Jean Delvare   hwmon: (w83627ehf...
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
  /* We left-align 8-bit temperature values to make the code simpler */
  static u16 w83627ehf_read_temp(struct w83627ehf_data *data, u16 reg)
  {
  	u16 res;
  
  	res = w83627ehf_read_value(data, reg);
  	if (!is_word_sized(reg))
  		res <<= 8;
  
  	return res;
  }
  
  static int w83627ehf_write_temp(struct w83627ehf_data *data, u16 reg,
  				       u16 value)
  {
  	if (!is_word_sized(reg))
  		value >>= 8;
  	return w83627ehf_write_value(data, reg, value);
  }
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
541
  /* This function assumes that the caller holds data->update_lock */
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
  static void nct6775_write_fan_div(struct w83627ehf_data *data, int nr)
  {
  	u8 reg;
  
  	switch (nr) {
  	case 0:
  		reg = (w83627ehf_read_value(data, NCT6775_REG_FANDIV1) & 0x70)
  		    | (data->fan_div[0] & 0x7);
  		w83627ehf_write_value(data, NCT6775_REG_FANDIV1, reg);
  		break;
  	case 1:
  		reg = (w83627ehf_read_value(data, NCT6775_REG_FANDIV1) & 0x7)
  		    | ((data->fan_div[1] << 4) & 0x70);
  		w83627ehf_write_value(data, NCT6775_REG_FANDIV1, reg);
  	case 2:
  		reg = (w83627ehf_read_value(data, NCT6775_REG_FANDIV2) & 0x70)
  		    | (data->fan_div[2] & 0x7);
  		w83627ehf_write_value(data, NCT6775_REG_FANDIV2, reg);
  		break;
  	case 3:
  		reg = (w83627ehf_read_value(data, NCT6775_REG_FANDIV2) & 0x7)
  		    | ((data->fan_div[3] << 4) & 0x70);
  		w83627ehf_write_value(data, NCT6775_REG_FANDIV2, reg);
  		break;
  	}
  }
  
  /* This function assumes that the caller holds data->update_lock */
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
570
  static void w83627ehf_write_fan_div(struct w83627ehf_data *data, int nr)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
571
  {
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
572
573
574
575
  	u8 reg;
  
  	switch (nr) {
  	case 0:
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
576
  		reg = (w83627ehf_read_value(data, W83627EHF_REG_FANDIV1) & 0xcf)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
577
  		    | ((data->fan_div[0] & 0x03) << 4);
14992c7ef   Rudolf Marek   w83627ehf: Fix th...
578
579
  		/* fan5 input control bit is write only, compute the value */
  		reg |= (data->has_fan & (1 << 4)) ? 1 : 0;
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
580
581
  		w83627ehf_write_value(data, W83627EHF_REG_FANDIV1, reg);
  		reg = (w83627ehf_read_value(data, W83627EHF_REG_VBAT) & 0xdf)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
582
  		    | ((data->fan_div[0] & 0x04) << 3);
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
583
  		w83627ehf_write_value(data, W83627EHF_REG_VBAT, reg);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
584
585
  		break;
  	case 1:
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
586
  		reg = (w83627ehf_read_value(data, W83627EHF_REG_FANDIV1) & 0x3f)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
587
  		    | ((data->fan_div[1] & 0x03) << 6);
14992c7ef   Rudolf Marek   w83627ehf: Fix th...
588
589
  		/* fan5 input control bit is write only, compute the value */
  		reg |= (data->has_fan & (1 << 4)) ? 1 : 0;
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
590
591
  		w83627ehf_write_value(data, W83627EHF_REG_FANDIV1, reg);
  		reg = (w83627ehf_read_value(data, W83627EHF_REG_VBAT) & 0xbf)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
592
  		    | ((data->fan_div[1] & 0x04) << 4);
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
593
  		w83627ehf_write_value(data, W83627EHF_REG_VBAT, reg);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
594
595
  		break;
  	case 2:
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
596
  		reg = (w83627ehf_read_value(data, W83627EHF_REG_FANDIV2) & 0x3f)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
597
  		    | ((data->fan_div[2] & 0x03) << 6);
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
598
599
  		w83627ehf_write_value(data, W83627EHF_REG_FANDIV2, reg);
  		reg = (w83627ehf_read_value(data, W83627EHF_REG_VBAT) & 0x7f)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
600
  		    | ((data->fan_div[2] & 0x04) << 5);
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
601
  		w83627ehf_write_value(data, W83627EHF_REG_VBAT, reg);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
602
603
  		break;
  	case 3:
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
604
  		reg = (w83627ehf_read_value(data, W83627EHF_REG_DIODE) & 0xfc)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
605
  		    | (data->fan_div[3] & 0x03);
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
606
607
  		w83627ehf_write_value(data, W83627EHF_REG_DIODE, reg);
  		reg = (w83627ehf_read_value(data, W83627EHF_REG_SMI_OVT) & 0x7f)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
608
  		    | ((data->fan_div[3] & 0x04) << 5);
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
609
  		w83627ehf_write_value(data, W83627EHF_REG_SMI_OVT, reg);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
610
611
  		break;
  	case 4:
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
612
  		reg = (w83627ehf_read_value(data, W83627EHF_REG_DIODE) & 0x73)
33725ad36   Jean Delvare   hwmon/w83627ehf: ...
613
  		    | ((data->fan_div[4] & 0x03) << 2)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
614
  		    | ((data->fan_div[4] & 0x04) << 5);
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
615
  		w83627ehf_write_value(data, W83627EHF_REG_DIODE, reg);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
616
617
618
  		break;
  	}
  }
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
  static void w83627ehf_write_fan_div_common(struct device *dev,
  					   struct w83627ehf_data *data, int nr)
  {
  	struct w83627ehf_sio_data *sio_data = dev->platform_data;
  
  	if (sio_data->kind == nct6776)
  		; /* no dividers, do nothing */
  	else if (sio_data->kind == nct6775)
  		nct6775_write_fan_div(data, nr);
  	else
  		w83627ehf_write_fan_div(data, nr);
  }
  
  static void nct6775_update_fan_div(struct w83627ehf_data *data)
  {
  	u8 i;
  
  	i = w83627ehf_read_value(data, NCT6775_REG_FANDIV1);
  	data->fan_div[0] = i & 0x7;
  	data->fan_div[1] = (i & 0x70) >> 4;
  	i = w83627ehf_read_value(data, NCT6775_REG_FANDIV2);
  	data->fan_div[2] = i & 0x7;
  	if (data->has_fan & (1<<3))
  		data->fan_div[3] = (i & 0x70) >> 4;
  }
ea7be66c4   Mark M. Hoffman   hwmon: (w83627ehf...
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
  static void w83627ehf_update_fan_div(struct w83627ehf_data *data)
  {
  	int i;
  
  	i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1);
  	data->fan_div[0] = (i >> 4) & 0x03;
  	data->fan_div[1] = (i >> 6) & 0x03;
  	i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV2);
  	data->fan_div[2] = (i >> 6) & 0x03;
  	i = w83627ehf_read_value(data, W83627EHF_REG_VBAT);
  	data->fan_div[0] |= (i >> 3) & 0x04;
  	data->fan_div[1] |= (i >> 4) & 0x04;
  	data->fan_div[2] |= (i >> 5) & 0x04;
  	if (data->has_fan & ((1 << 3) | (1 << 4))) {
  		i = w83627ehf_read_value(data, W83627EHF_REG_DIODE);
  		data->fan_div[3] = i & 0x03;
  		data->fan_div[4] = ((i >> 2) & 0x03)
  				 | ((i >> 5) & 0x04);
  	}
  	if (data->has_fan & (1 << 3)) {
  		i = w83627ehf_read_value(data, W83627EHF_REG_SMI_OVT);
  		data->fan_div[3] |= (i >> 5) & 0x04;
  	}
  }
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
  static void w83627ehf_update_fan_div_common(struct device *dev,
  					    struct w83627ehf_data *data)
  {
  	struct w83627ehf_sio_data *sio_data = dev->platform_data;
  
  	if (sio_data->kind == nct6776)
  		; /* no dividers, do nothing */
  	else if (sio_data->kind == nct6775)
  		nct6775_update_fan_div(data);
  	else
  		w83627ehf_update_fan_div(data);
  }
  
  static void nct6775_update_pwm(struct w83627ehf_data *data)
  {
  	int i;
  	int pwmcfg, fanmodecfg;
  
  	for (i = 0; i < data->pwm_num; i++) {
  		pwmcfg = w83627ehf_read_value(data,
  					      W83627EHF_REG_PWM_ENABLE[i]);
  		fanmodecfg = w83627ehf_read_value(data,
  						  NCT6775_REG_FAN_MODE[i]);
  		data->pwm_mode[i] =
  		  ((pwmcfg >> W83627EHF_PWM_MODE_SHIFT[i]) & 1) ? 0 : 1;
  		data->pwm_enable[i] = ((fanmodecfg >> 4) & 7) + 1;
  		data->tolerance[i] = fanmodecfg & 0x0f;
  		data->pwm[i] = w83627ehf_read_value(data, data->REG_PWM[i]);
  	}
  }
  
  static void w83627ehf_update_pwm(struct w83627ehf_data *data)
  {
  	int i;
  	int pwmcfg = 0, tolerance = 0; /* shut up the compiler */
  
  	for (i = 0; i < data->pwm_num; i++) {
  		if (!(data->has_fan & (1 << i)))
  			continue;
  
  		/* pwmcfg, tolerance mapped for i=0, i=1 to same reg */
  		if (i != 1) {
  			pwmcfg = w83627ehf_read_value(data,
  					W83627EHF_REG_PWM_ENABLE[i]);
  			tolerance = w83627ehf_read_value(data,
  					W83627EHF_REG_TOLERANCE[i]);
  		}
  		data->pwm_mode[i] =
  			((pwmcfg >> W83627EHF_PWM_MODE_SHIFT[i]) & 1) ? 0 : 1;
  		data->pwm_enable[i] = ((pwmcfg >> W83627EHF_PWM_ENABLE_SHIFT[i])
  				       & 3) + 1;
  		data->pwm[i] = w83627ehf_read_value(data, data->REG_PWM[i]);
  
  		data->tolerance[i] = (tolerance >> (i == 1 ? 4 : 0)) & 0x0f;
  	}
  }
  
  static void w83627ehf_update_pwm_common(struct device *dev,
  					struct w83627ehf_data *data)
  {
  	struct w83627ehf_sio_data *sio_data = dev->platform_data;
  
  	if (sio_data->kind == nct6775 || sio_data->kind == nct6776)
  		nct6775_update_pwm(data);
  	else
  		w83627ehf_update_pwm(data);
  }
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
735
736
  static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
  {
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
737
  	struct w83627ehf_data *data = dev_get_drvdata(dev);
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
738
  	struct w83627ehf_sio_data *sio_data = dev->platform_data;
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
739
  	int i;
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
740
  	mutex_lock(&data->update_lock);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
741

6b3e46458   Jean Delvare   hwmon/w83627ehf: ...
742
  	if (time_after(jiffies, data->last_updated + HZ + HZ/2)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
743
744
  	 || !data->valid) {
  		/* Fan clock dividers */
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
745
  		w83627ehf_update_fan_div_common(dev, data);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
746

cf0676fe4   Rudolf Marek   [PATCH] w83627ehf...
747
  		/* Measured voltages and limits */
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
748
  		for (i = 0; i < data->in_num; i++) {
389ef65d2   Jean Delvare   hwmon: (w83627ehf...
749
750
  			if ((i == 6) && data->in6_skip)
  				continue;
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
751
  			data->in[i] = w83627ehf_read_value(data,
cf0676fe4   Rudolf Marek   [PATCH] w83627ehf...
752
  				      W83627EHF_REG_IN(i));
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
753
  			data->in_min[i] = w83627ehf_read_value(data,
cf0676fe4   Rudolf Marek   [PATCH] w83627ehf...
754
  					  W83627EHF_REG_IN_MIN(i));
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
755
  			data->in_max[i] = w83627ehf_read_value(data,
cf0676fe4   Rudolf Marek   [PATCH] w83627ehf...
756
757
  					  W83627EHF_REG_IN_MAX(i));
  		}
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
758
759
  		/* Measured fan speeds and limits */
  		for (i = 0; i < 5; i++) {
3382a918d   Guenter Roeck   hwmon: (w83627ehf...
760
  			u16 reg;
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
761
762
  			if (!(data->has_fan & (1 << i)))
  				continue;
3382a918d   Guenter Roeck   hwmon: (w83627ehf...
763
764
765
  			reg = w83627ehf_read_value(data, data->REG_FAN[i]);
  			data->rpm[i] = data->fan_from_reg(reg,
  							  data->fan_div[i]);
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
766
767
768
  
  			if (data->has_fan_min & (1 << i))
  				data->fan_min[i] = w83627ehf_read_value(data,
279af1a91   Guenter Roeck   hwmon: (w83627ehf...
769
  					   data->REG_FAN_MIN[i]);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
770
771
772
773
  
  			/* If we failed to measure the fan speed and clock
  			   divider can be increased, let's try that for next
  			   time */
26bc440e3   Guenter Roeck   hwmon: (w83627ehf...
774
  			if (data->has_fan_div
3382a918d   Guenter Roeck   hwmon: (w83627ehf...
775
776
  			    && (reg >= 0xff || (sio_data->kind == nct6775
  						&& reg == 0x00))
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
777
  			    && data->fan_div[i] < 0x07) {
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
778
  				dev_dbg(dev, "Increasing fan%d "
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
779
780
  					"clock divider from %u to %u
  ",
33725ad36   Jean Delvare   hwmon/w83627ehf: ...
781
  					i + 1, div_from_reg(data->fan_div[i]),
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
782
783
  					div_from_reg(data->fan_div[i] + 1));
  				data->fan_div[i]++;
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
784
  				w83627ehf_write_fan_div_common(dev, data, i);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
785
  				/* Preserve min limit if possible */
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
786
787
  				if ((data->has_fan_min & (1 << i))
  				 && data->fan_min[i] >= 2
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
788
  				 && data->fan_min[i] != 255)
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
789
  					w83627ehf_write_value(data,
279af1a91   Guenter Roeck   hwmon: (w83627ehf...
790
  						data->REG_FAN_MIN[i],
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
791
792
793
  						(data->fan_min[i] /= 2));
  			}
  		}
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
794
  		w83627ehf_update_pwm_common(dev, data);
da2e02559   Guenter Roeck   hwmon: (w83627ehf...
795
796
797
  		for (i = 0; i < data->pwm_num; i++) {
  			if (!(data->has_fan & (1 << i)))
  				continue;
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
798
799
800
801
802
803
804
805
806
807
808
809
  			data->fan_start_output[i] =
  			  w83627ehf_read_value(data,
  					       data->REG_FAN_START_OUTPUT[i]);
  			data->fan_stop_output[i] =
  			  w83627ehf_read_value(data,
  					       data->REG_FAN_STOP_OUTPUT[i]);
  			data->fan_stop_time[i] =
  			  w83627ehf_read_value(data,
  					       data->REG_FAN_STOP_TIME[i]);
  
  			if (data->REG_FAN_MAX_OUTPUT &&
  			    data->REG_FAN_MAX_OUTPUT[i] != 0xff)
da2e02559   Guenter Roeck   hwmon: (w83627ehf...
810
811
  				data->fan_max_output[i] =
  				  w83627ehf_read_value(data,
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
812
  						data->REG_FAN_MAX_OUTPUT[i]);
da2e02559   Guenter Roeck   hwmon: (w83627ehf...
813

ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
814
815
  			if (data->REG_FAN_STEP_OUTPUT &&
  			    data->REG_FAN_STEP_OUTPUT[i] != 0xff)
da2e02559   Guenter Roeck   hwmon: (w83627ehf...
816
817
  				data->fan_step_output[i] =
  				  w83627ehf_read_value(data,
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
818
  						data->REG_FAN_STEP_OUTPUT[i]);
da2e02559   Guenter Roeck   hwmon: (w83627ehf...
819

08c79950a   Rudolf Marek   hwmon: Add fan sp...
820
  			data->target_temp[i] =
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
821
  				w83627ehf_read_value(data,
279af1a91   Guenter Roeck   hwmon: (w83627ehf...
822
  					data->REG_TARGET[i]) &
08c79950a   Rudolf Marek   hwmon: Add fan sp...
823
  					(data->pwm_mode[i] == 1 ? 0x7f : 0xff);
08c79950a   Rudolf Marek   hwmon: Add fan sp...
824
  		}
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
825
  		/* Measured temperatures and limits */
d36cf32c9   Guenter Roeck   hwmon: (w83627ehf...
826
827
828
  		for (i = 0; i < NUM_REG_TEMP; i++) {
  			if (!(data->have_temp & (1 << i)))
  				continue;
c5794cfac   Jean Delvare   hwmon: (w83627ehf...
829
  			data->temp[i] = w83627ehf_read_temp(data,
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
830
831
832
  						data->reg_temp[i]);
  			if (data->reg_temp_over[i])
  				data->temp_max[i]
c5794cfac   Jean Delvare   hwmon: (w83627ehf...
833
  				  = w83627ehf_read_temp(data,
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
834
835
836
  						data->reg_temp_over[i]);
  			if (data->reg_temp_hyst[i])
  				data->temp_max_hyst[i]
c5794cfac   Jean Delvare   hwmon: (w83627ehf...
837
  				  = w83627ehf_read_temp(data,
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
838
  						data->reg_temp_hyst[i]);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
839
  		}
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
840
  		data->alarms = w83627ehf_read_value(data,
a4589dbb4   Jean Delvare   [PATCH] w83627ehf...
841
  					W83627EHF_REG_ALARM1) |
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
842
  			       (w83627ehf_read_value(data,
a4589dbb4   Jean Delvare   [PATCH] w83627ehf...
843
  					W83627EHF_REG_ALARM2) << 8) |
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
844
  			       (w83627ehf_read_value(data,
a4589dbb4   Jean Delvare   [PATCH] w83627ehf...
845
  					W83627EHF_REG_ALARM3) << 16);
363a12a49   Dmitry Artamonow   hwmon: (w83627ehf...
846
847
  		data->caseopen = w83627ehf_read_value(data,
  						W83627EHF_REG_CASEOPEN_DET);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
848
849
850
  		data->last_updated = jiffies;
  		data->valid = 1;
  	}
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
851
  	mutex_unlock(&data->update_lock);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
852
853
854
855
856
857
  	return data;
  }
  
  /*
   * Sysfs callback functions
   */
cf0676fe4   Rudolf Marek   [PATCH] w83627ehf...
858
859
860
861
862
863
  #define show_in_reg(reg) \
  static ssize_t \
  show_##reg(struct device *dev, struct device_attribute *attr, \
  	   char *buf) \
  { \
  	struct w83627ehf_data *data = w83627ehf_update_device(dev); \
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
864
865
  	struct sensor_device_attribute *sensor_attr = \
  		to_sensor_dev_attr(attr); \
cf0676fe4   Rudolf Marek   [PATCH] w83627ehf...
866
  	int nr = sensor_attr->index; \
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
867
868
869
  	return sprintf(buf, "%ld
  ", in_from_reg(data->reg[nr], nr, \
  		       data->scale_in)); \
cf0676fe4   Rudolf Marek   [PATCH] w83627ehf...
870
871
872
873
874
875
876
  }
  show_in_reg(in)
  show_in_reg(in_min)
  show_in_reg(in_max)
  
  #define store_in_reg(REG, reg) \
  static ssize_t \
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
877
878
  store_in_##reg(struct device *dev, struct device_attribute *attr, \
  	       const char *buf, size_t count) \
cf0676fe4   Rudolf Marek   [PATCH] w83627ehf...
879
  { \
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
880
  	struct w83627ehf_data *data = dev_get_drvdata(dev); \
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
881
882
  	struct sensor_device_attribute *sensor_attr = \
  		to_sensor_dev_attr(attr); \
cf0676fe4   Rudolf Marek   [PATCH] w83627ehf...
883
  	int nr = sensor_attr->index; \
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
884
885
  	unsigned long val; \
  	int err; \
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
886
  	err = kstrtoul(buf, 10, &val); \
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
887
888
  	if (err < 0) \
  		return err; \
cf0676fe4   Rudolf Marek   [PATCH] w83627ehf...
889
  	mutex_lock(&data->update_lock); \
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
890
  	data->in_##reg[nr] = in_to_reg(val, nr, data->scale_in); \
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
891
  	w83627ehf_write_value(data, W83627EHF_REG_IN_##REG(nr), \
cf0676fe4   Rudolf Marek   [PATCH] w83627ehf...
892
893
894
895
896
897
898
  			      data->in_##reg[nr]); \
  	mutex_unlock(&data->update_lock); \
  	return count; \
  }
  
  store_in_reg(MIN, min)
  store_in_reg(MAX, max)
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
899
900
  static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
  			  char *buf)
a4589dbb4   Jean Delvare   [PATCH] w83627ehf...
901
902
903
904
905
906
907
  {
  	struct w83627ehf_data *data = w83627ehf_update_device(dev);
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
  	return sprintf(buf, "%u
  ", (data->alarms >> nr) & 0x01);
  }
cf0676fe4   Rudolf Marek   [PATCH] w83627ehf...
908
909
910
911
912
913
914
915
916
917
918
919
  static struct sensor_device_attribute sda_in_input[] = {
  	SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0),
  	SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1),
  	SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2),
  	SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3),
  	SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4),
  	SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5),
  	SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6),
  	SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7),
  	SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8),
  	SENSOR_ATTR(in9_input, S_IRUGO, show_in, NULL, 9),
  };
a4589dbb4   Jean Delvare   [PATCH] w83627ehf...
920
921
922
923
924
925
926
927
928
929
930
931
  static struct sensor_device_attribute sda_in_alarm[] = {
  	SENSOR_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0),
  	SENSOR_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1),
  	SENSOR_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2),
  	SENSOR_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3),
  	SENSOR_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8),
  	SENSOR_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 21),
  	SENSOR_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 20),
  	SENSOR_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 16),
  	SENSOR_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 17),
  	SENSOR_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, 19),
  };
cf0676fe4   Rudolf Marek   [PATCH] w83627ehf...
932
  static struct sensor_device_attribute sda_in_min[] = {
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
933
934
935
936
937
938
939
940
941
942
  	SENSOR_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 0),
  	SENSOR_ATTR(in1_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 1),
  	SENSOR_ATTR(in2_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 2),
  	SENSOR_ATTR(in3_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 3),
  	SENSOR_ATTR(in4_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 4),
  	SENSOR_ATTR(in5_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 5),
  	SENSOR_ATTR(in6_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 6),
  	SENSOR_ATTR(in7_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 7),
  	SENSOR_ATTR(in8_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 8),
  	SENSOR_ATTR(in9_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 9),
cf0676fe4   Rudolf Marek   [PATCH] w83627ehf...
943
944
945
  };
  
  static struct sensor_device_attribute sda_in_max[] = {
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
946
947
948
949
950
951
952
953
954
955
  	SENSOR_ATTR(in0_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 0),
  	SENSOR_ATTR(in1_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 1),
  	SENSOR_ATTR(in2_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 2),
  	SENSOR_ATTR(in3_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 3),
  	SENSOR_ATTR(in4_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 4),
  	SENSOR_ATTR(in5_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 5),
  	SENSOR_ATTR(in6_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 6),
  	SENSOR_ATTR(in7_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 7),
  	SENSOR_ATTR(in8_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 8),
  	SENSOR_ATTR(in9_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 9),
cf0676fe4   Rudolf Marek   [PATCH] w83627ehf...
956
  };
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
957
958
959
960
961
962
  static ssize_t
  show_fan(struct device *dev, struct device_attribute *attr, char *buf)
  {
  	struct w83627ehf_data *data = w83627ehf_update_device(dev);
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
3382a918d   Guenter Roeck   hwmon: (w83627ehf...
963
964
  	return sprintf(buf, "%d
  ", data->rpm[nr]);
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
965
966
967
968
969
970
971
972
973
974
  }
  
  static ssize_t
  show_fan_min(struct device *dev, struct device_attribute *attr, char *buf)
  {
  	struct w83627ehf_data *data = w83627ehf_update_device(dev);
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
  	return sprintf(buf, "%d
  ",
26bc440e3   Guenter Roeck   hwmon: (w83627ehf...
975
976
  		       data->fan_from_reg_min(data->fan_min[nr],
  					      data->fan_div[nr]));
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
977
  }
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
978
979
  
  static ssize_t
412fec821   Yuan Mu   [PATCH] w83627ehf...
980
981
  show_fan_div(struct device *dev, struct device_attribute *attr,
  	     char *buf)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
982
983
  {
  	struct w83627ehf_data *data = w83627ehf_update_device(dev);
412fec821   Yuan Mu   [PATCH] w83627ehf...
984
985
986
987
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
  	return sprintf(buf, "%u
  ", div_from_reg(data->fan_div[nr]));
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
988
989
990
  }
  
  static ssize_t
412fec821   Yuan Mu   [PATCH] w83627ehf...
991
992
  store_fan_min(struct device *dev, struct device_attribute *attr,
  	      const char *buf, size_t count)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
993
  {
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
994
  	struct w83627ehf_data *data = dev_get_drvdata(dev);
412fec821   Yuan Mu   [PATCH] w83627ehf...
995
996
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
997
998
  	unsigned long val;
  	int err;
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
999
1000
  	unsigned int reg;
  	u8 new_div;
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
1001
  	err = kstrtoul(buf, 10, &val);
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1002
1003
  	if (err < 0)
  		return err;
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
1004
  	mutex_lock(&data->update_lock);
26bc440e3   Guenter Roeck   hwmon: (w83627ehf...
1005
1006
1007
1008
1009
  	if (!data->has_fan_div) {
  		/*
  		 * Only NCT6776F for now, so we know that this is a 13 bit
  		 * register
  		 */
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
  		if (!val) {
  			val = 0xff1f;
  		} else {
  			if (val > 1350000U)
  				val = 135000U;
  			val = 1350000U / val;
  			val = (val & 0x1f) | ((val << 3) & 0xff00);
  		}
  		data->fan_min[nr] = val;
  		goto done;	/* Leave fan divider alone */
  	}
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
  	if (!val) {
  		/* No min limit, alarm disabled */
  		data->fan_min[nr] = 255;
  		new_div = data->fan_div[nr]; /* No change */
  		dev_info(dev, "fan%u low limit and alarm disabled
  ", nr + 1);
  	} else if ((reg = 1350000U / val) >= 128 * 255) {
  		/* Speed below this value cannot possibly be represented,
  		   even with the highest divider (128) */
  		data->fan_min[nr] = 254;
  		new_div = 7; /* 128 == (1 << 7) */
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1032
  		dev_warn(dev, "fan%u low limit %lu below minimum %u, set to "
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1033
1034
  			 "minimum
  ", nr + 1, val,
26bc440e3   Guenter Roeck   hwmon: (w83627ehf...
1035
  			 data->fan_from_reg_min(254, 7));
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1036
1037
1038
1039
1040
  	} else if (!reg) {
  		/* Speed above this value cannot possibly be represented,
  		   even with the lowest divider (1) */
  		data->fan_min[nr] = 1;
  		new_div = 0; /* 1 == (1 << 0) */
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1041
  		dev_warn(dev, "fan%u low limit %lu above maximum %u, set to "
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1042
1043
  			 "maximum
  ", nr + 1, val,
26bc440e3   Guenter Roeck   hwmon: (w83627ehf...
1044
  			 data->fan_from_reg_min(1, 0));
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
  	} else {
  		/* Automatically pick the best divider, i.e. the one such
  		   that the min limit will correspond to a register value
  		   in the 96..192 range */
  		new_div = 0;
  		while (reg > 192 && new_div < 7) {
  			reg >>= 1;
  			new_div++;
  		}
  		data->fan_min[nr] = reg;
  	}
  
  	/* Write both the fan clock divider (if it changed) and the new
  	   fan min (unconditionally) */
  	if (new_div != data->fan_div[nr]) {
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1060
1061
1062
1063
1064
  		dev_dbg(dev, "fan%u clock divider changed from %u to %u
  ",
  			nr + 1, div_from_reg(data->fan_div[nr]),
  			div_from_reg(new_div));
  		data->fan_div[nr] = new_div;
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1065
  		w83627ehf_write_fan_div_common(dev, data, nr);
6b3e46458   Jean Delvare   hwmon/w83627ehf: ...
1066
1067
  		/* Give the chip time to sample a new speed value */
  		data->last_updated = jiffies;
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1068
  	}
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1069
  done:
279af1a91   Guenter Roeck   hwmon: (w83627ehf...
1070
  	w83627ehf_write_value(data, data->REG_FAN_MIN[nr],
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1071
  			      data->fan_min[nr]);
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
1072
  	mutex_unlock(&data->update_lock);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1073
1074
1075
  
  	return count;
  }
412fec821   Yuan Mu   [PATCH] w83627ehf...
1076
1077
1078
1079
1080
1081
1082
  static struct sensor_device_attribute sda_fan_input[] = {
  	SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0),
  	SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1),
  	SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2),
  	SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3),
  	SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4),
  };
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1083

a4589dbb4   Jean Delvare   [PATCH] w83627ehf...
1084
1085
1086
1087
1088
1089
1090
  static struct sensor_device_attribute sda_fan_alarm[] = {
  	SENSOR_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6),
  	SENSOR_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7),
  	SENSOR_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11),
  	SENSOR_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 10),
  	SENSOR_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 23),
  };
412fec821   Yuan Mu   [PATCH] w83627ehf...
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
  static struct sensor_device_attribute sda_fan_min[] = {
  	SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min,
  		    store_fan_min, 0),
  	SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min,
  		    store_fan_min, 1),
  	SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min,
  		    store_fan_min, 2),
  	SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min,
  		    store_fan_min, 3),
  	SENSOR_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min,
  		    store_fan_min, 4),
  };
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1103

412fec821   Yuan Mu   [PATCH] w83627ehf...
1104
1105
1106
1107
1108
1109
1110
  static struct sensor_device_attribute sda_fan_div[] = {
  	SENSOR_ATTR(fan1_div, S_IRUGO, show_fan_div, NULL, 0),
  	SENSOR_ATTR(fan2_div, S_IRUGO, show_fan_div, NULL, 1),
  	SENSOR_ATTR(fan3_div, S_IRUGO, show_fan_div, NULL, 2),
  	SENSOR_ATTR(fan4_div, S_IRUGO, show_fan_div, NULL, 3),
  	SENSOR_ATTR(fan5_div, S_IRUGO, show_fan_div, NULL, 4),
  };
d36cf32c9   Guenter Roeck   hwmon: (w83627ehf...
1111
1112
1113
1114
1115
1116
1117
1118
1119
  static ssize_t
  show_temp_label(struct device *dev, struct device_attribute *attr, char *buf)
  {
  	struct w83627ehf_data *data = w83627ehf_update_device(dev);
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
  	return sprintf(buf, "%s
  ", data->temp_label[data->temp_src[nr]]);
  }
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1120
  #define show_temp_reg(addr, reg) \
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1121
  static ssize_t \
412fec821   Yuan Mu   [PATCH] w83627ehf...
1122
1123
  show_##reg(struct device *dev, struct device_attribute *attr, \
  	   char *buf) \
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1124
1125
  { \
  	struct w83627ehf_data *data = w83627ehf_update_device(dev); \
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
1126
1127
  	struct sensor_device_attribute *sensor_attr = \
  		to_sensor_dev_attr(attr); \
412fec821   Yuan Mu   [PATCH] w83627ehf...
1128
  	int nr = sensor_attr->index; \
c5794cfac   Jean Delvare   hwmon: (w83627ehf...
1129
1130
  	return sprintf(buf, "%d
  ", LM75_TEMP_FROM_REG(data->reg[nr])); \
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1131
  }
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1132
1133
1134
  show_temp_reg(reg_temp, temp);
  show_temp_reg(reg_temp_over, temp_max);
  show_temp_reg(reg_temp_hyst, temp_max_hyst);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1135

ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1136
  #define store_temp_reg(addr, reg) \
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1137
  static ssize_t \
412fec821   Yuan Mu   [PATCH] w83627ehf...
1138
1139
  store_##reg(struct device *dev, struct device_attribute *attr, \
  	    const char *buf, size_t count) \
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1140
  { \
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1141
  	struct w83627ehf_data *data = dev_get_drvdata(dev); \
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
1142
1143
  	struct sensor_device_attribute *sensor_attr = \
  		to_sensor_dev_attr(attr); \
412fec821   Yuan Mu   [PATCH] w83627ehf...
1144
  	int nr = sensor_attr->index; \
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1145
1146
  	int err; \
  	long val; \
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
1147
  	err = kstrtol(buf, 10, &val); \
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1148
1149
  	if (err < 0) \
  		return err; \
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
1150
  	mutex_lock(&data->update_lock); \
c5794cfac   Jean Delvare   hwmon: (w83627ehf...
1151
1152
  	data->reg[nr] = LM75_TEMP_TO_REG(val); \
  	w83627ehf_write_temp(data, data->addr[nr], data->reg[nr]); \
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
1153
  	mutex_unlock(&data->update_lock); \
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1154
1155
  	return count; \
  }
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1156
1157
  store_temp_reg(reg_temp_over, temp_max);
  store_temp_reg(reg_temp_hyst, temp_max_hyst);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1158

da667365b   Jean Delvare   hwmon/w83627ehf: ...
1159
1160
1161
1162
1163
1164
1165
1166
1167
  static ssize_t
  show_temp_type(struct device *dev, struct device_attribute *attr, char *buf)
  {
  	struct w83627ehf_data *data = w83627ehf_update_device(dev);
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
  	return sprintf(buf, "%d
  ", (int)data->temp_type[nr]);
  }
a157d06d4   Gong Jun   hwmon: (w83627ehf...
1168
  static struct sensor_device_attribute sda_temp_input[] = {
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1169
1170
1171
  	SENSOR_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0),
  	SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1),
  	SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2),
d36cf32c9   Guenter Roeck   hwmon: (w83627ehf...
1172
  	SENSOR_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3),
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1173
1174
1175
1176
1177
  	SENSOR_ATTR(temp5_input, S_IRUGO, show_temp, NULL, 4),
  	SENSOR_ATTR(temp6_input, S_IRUGO, show_temp, NULL, 5),
  	SENSOR_ATTR(temp7_input, S_IRUGO, show_temp, NULL, 6),
  	SENSOR_ATTR(temp8_input, S_IRUGO, show_temp, NULL, 7),
  	SENSOR_ATTR(temp9_input, S_IRUGO, show_temp, NULL, 8),
d36cf32c9   Guenter Roeck   hwmon: (w83627ehf...
1178
1179
1180
1181
1182
1183
1184
  };
  
  static struct sensor_device_attribute sda_temp_label[] = {
  	SENSOR_ATTR(temp1_label, S_IRUGO, show_temp_label, NULL, 0),
  	SENSOR_ATTR(temp2_label, S_IRUGO, show_temp_label, NULL, 1),
  	SENSOR_ATTR(temp3_label, S_IRUGO, show_temp_label, NULL, 2),
  	SENSOR_ATTR(temp4_label, S_IRUGO, show_temp_label, NULL, 3),
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1185
1186
1187
1188
1189
  	SENSOR_ATTR(temp5_label, S_IRUGO, show_temp_label, NULL, 4),
  	SENSOR_ATTR(temp6_label, S_IRUGO, show_temp_label, NULL, 5),
  	SENSOR_ATTR(temp7_label, S_IRUGO, show_temp_label, NULL, 6),
  	SENSOR_ATTR(temp8_label, S_IRUGO, show_temp_label, NULL, 7),
  	SENSOR_ATTR(temp9_label, S_IRUGO, show_temp_label, NULL, 8),
a157d06d4   Gong Jun   hwmon: (w83627ehf...
1190
1191
1192
  };
  
  static struct sensor_device_attribute sda_temp_max[] = {
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1193
  	SENSOR_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp_max,
412fec821   Yuan Mu   [PATCH] w83627ehf...
1194
  		    store_temp_max, 0),
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1195
  	SENSOR_ATTR(temp2_max, S_IRUGO | S_IWUSR, show_temp_max,
412fec821   Yuan Mu   [PATCH] w83627ehf...
1196
  		    store_temp_max, 1),
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1197
1198
  	SENSOR_ATTR(temp3_max, S_IRUGO | S_IWUSR, show_temp_max,
  		    store_temp_max, 2),
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
  	SENSOR_ATTR(temp4_max, S_IRUGO | S_IWUSR, show_temp_max,
  		    store_temp_max, 3),
  	SENSOR_ATTR(temp5_max, S_IRUGO | S_IWUSR, show_temp_max,
  		    store_temp_max, 4),
  	SENSOR_ATTR(temp6_max, S_IRUGO | S_IWUSR, show_temp_max,
  		    store_temp_max, 5),
  	SENSOR_ATTR(temp7_max, S_IRUGO | S_IWUSR, show_temp_max,
  		    store_temp_max, 6),
  	SENSOR_ATTR(temp8_max, S_IRUGO | S_IWUSR, show_temp_max,
  		    store_temp_max, 7),
  	SENSOR_ATTR(temp9_max, S_IRUGO | S_IWUSR, show_temp_max,
  		    store_temp_max, 8),
a157d06d4   Gong Jun   hwmon: (w83627ehf...
1211
1212
1213
  };
  
  static struct sensor_device_attribute sda_temp_max_hyst[] = {
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1214
  	SENSOR_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
412fec821   Yuan Mu   [PATCH] w83627ehf...
1215
  		    store_temp_max_hyst, 0),
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1216
  	SENSOR_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
412fec821   Yuan Mu   [PATCH] w83627ehf...
1217
  		    store_temp_max_hyst, 1),
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1218
1219
  	SENSOR_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
  		    store_temp_max_hyst, 2),
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
  	SENSOR_ATTR(temp4_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
  		    store_temp_max_hyst, 3),
  	SENSOR_ATTR(temp5_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
  		    store_temp_max_hyst, 4),
  	SENSOR_ATTR(temp6_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
  		    store_temp_max_hyst, 5),
  	SENSOR_ATTR(temp7_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
  		    store_temp_max_hyst, 6),
  	SENSOR_ATTR(temp8_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
  		    store_temp_max_hyst, 7),
  	SENSOR_ATTR(temp9_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
  		    store_temp_max_hyst, 8),
a157d06d4   Gong Jun   hwmon: (w83627ehf...
1232
1233
1234
  };
  
  static struct sensor_device_attribute sda_temp_alarm[] = {
a4589dbb4   Jean Delvare   [PATCH] w83627ehf...
1235
1236
1237
  	SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4),
  	SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5),
  	SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13),
a157d06d4   Gong Jun   hwmon: (w83627ehf...
1238
1239
1240
  };
  
  static struct sensor_device_attribute sda_temp_type[] = {
da667365b   Jean Delvare   hwmon/w83627ehf: ...
1241
1242
1243
  	SENSOR_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0),
  	SENSOR_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1),
  	SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2),
412fec821   Yuan Mu   [PATCH] w83627ehf...
1244
  };
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1245

08c79950a   Rudolf Marek   hwmon: Add fan sp...
1246
  #define show_pwm_reg(reg) \
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
1247
1248
  static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
  			  char *buf) \
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1249
1250
  { \
  	struct w83627ehf_data *data = w83627ehf_update_device(dev); \
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
1251
1252
  	struct sensor_device_attribute *sensor_attr = \
  		to_sensor_dev_attr(attr); \
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
  	int nr = sensor_attr->index; \
  	return sprintf(buf, "%d
  ", data->reg[nr]); \
  }
  
  show_pwm_reg(pwm_mode)
  show_pwm_reg(pwm_enable)
  show_pwm_reg(pwm)
  
  static ssize_t
  store_pwm_mode(struct device *dev, struct device_attribute *attr,
  			const char *buf, size_t count)
  {
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1266
  	struct w83627ehf_data *data = dev_get_drvdata(dev);
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1267
1268
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1269
1270
  	unsigned long val;
  	int err;
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1271
  	u16 reg;
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
1272
  	err = kstrtoul(buf, 10, &val);
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1273
1274
  	if (err < 0)
  		return err;
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1275
1276
1277
  	if (val > 1)
  		return -EINVAL;
  	mutex_lock(&data->update_lock);
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1278
  	reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]);
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1279
1280
1281
1282
  	data->pwm_mode[nr] = val;
  	reg &= ~(1 << W83627EHF_PWM_MODE_SHIFT[nr]);
  	if (!val)
  		reg |= 1 << W83627EHF_PWM_MODE_SHIFT[nr];
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1283
  	w83627ehf_write_value(data, W83627EHF_REG_PWM_ENABLE[nr], reg);
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1284
1285
1286
1287
1288
1289
1290
1291
  	mutex_unlock(&data->update_lock);
  	return count;
  }
  
  static ssize_t
  store_pwm(struct device *dev, struct device_attribute *attr,
  			const char *buf, size_t count)
  {
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1292
  	struct w83627ehf_data *data = dev_get_drvdata(dev);
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1293
1294
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1295
1296
  	unsigned long val;
  	int err;
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
1297
  	err = kstrtoul(buf, 10, &val);
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1298
1299
1300
1301
  	if (err < 0)
  		return err;
  
  	val = SENSORS_LIMIT(val, 0, 255);
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1302
1303
1304
  
  	mutex_lock(&data->update_lock);
  	data->pwm[nr] = val;
279af1a91   Guenter Roeck   hwmon: (w83627ehf...
1305
  	w83627ehf_write_value(data, data->REG_PWM[nr], val);
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1306
1307
1308
1309
1310
1311
1312
1313
  	mutex_unlock(&data->update_lock);
  	return count;
  }
  
  static ssize_t
  store_pwm_enable(struct device *dev, struct device_attribute *attr,
  			const char *buf, size_t count)
  {
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1314
  	struct w83627ehf_data *data = dev_get_drvdata(dev);
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1315
  	struct w83627ehf_sio_data *sio_data = dev->platform_data;
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1316
1317
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1318
1319
  	unsigned long val;
  	int err;
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1320
  	u16 reg;
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
1321
  	err = kstrtoul(buf, 10, &val);
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1322
1323
  	if (err < 0)
  		return err;
b84bb5186   Guenter Roeck   hwmon: (w83627ehf...
1324
  	if (!val || (val > 4 && val != data->pwm_enable_orig[nr]))
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1325
  		return -EINVAL;
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1326
1327
1328
  	/* SmartFan III mode is not supported on NCT6776F */
  	if (sio_data->kind == nct6776 && val == 4)
  		return -EINVAL;
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1329
  	mutex_lock(&data->update_lock);
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1330
  	data->pwm_enable[nr] = val;
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
  	if (sio_data->kind == nct6775 || sio_data->kind == nct6776) {
  		reg = w83627ehf_read_value(data,
  					   NCT6775_REG_FAN_MODE[nr]);
  		reg &= 0x0f;
  		reg |= (val - 1) << 4;
  		w83627ehf_write_value(data,
  				      NCT6775_REG_FAN_MODE[nr], reg);
  	} else {
  		reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]);
  		reg &= ~(0x03 << W83627EHF_PWM_ENABLE_SHIFT[nr]);
  		reg |= (val - 1) << W83627EHF_PWM_ENABLE_SHIFT[nr];
  		w83627ehf_write_value(data, W83627EHF_REG_PWM_ENABLE[nr], reg);
  	}
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
  	mutex_unlock(&data->update_lock);
  	return count;
  }
  
  
  #define show_tol_temp(reg) \
  static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
  				char *buf) \
  { \
  	struct w83627ehf_data *data = w83627ehf_update_device(dev); \
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
1354
1355
  	struct sensor_device_attribute *sensor_attr = \
  		to_sensor_dev_attr(attr); \
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1356
  	int nr = sensor_attr->index; \
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1357
1358
  	return sprintf(buf, "%d
  ", data->reg[nr] * 1000); \
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1359
1360
1361
1362
1363
1364
1365
1366
1367
  }
  
  show_tol_temp(tolerance)
  show_tol_temp(target_temp)
  
  static ssize_t
  store_target_temp(struct device *dev, struct device_attribute *attr,
  			const char *buf, size_t count)
  {
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1368
  	struct w83627ehf_data *data = dev_get_drvdata(dev);
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1369
1370
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1371
1372
  	long val;
  	int err;
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
1373
  	err = kstrtol(buf, 10, &val);
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1374
1375
1376
1377
  	if (err < 0)
  		return err;
  
  	val = SENSORS_LIMIT(DIV_ROUND_CLOSEST(val, 1000), 0, 127);
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1378
1379
1380
  
  	mutex_lock(&data->update_lock);
  	data->target_temp[nr] = val;
279af1a91   Guenter Roeck   hwmon: (w83627ehf...
1381
  	w83627ehf_write_value(data, data->REG_TARGET[nr], val);
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1382
1383
1384
1385
1386
1387
1388
1389
  	mutex_unlock(&data->update_lock);
  	return count;
  }
  
  static ssize_t
  store_tolerance(struct device *dev, struct device_attribute *attr,
  			const char *buf, size_t count)
  {
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1390
  	struct w83627ehf_data *data = dev_get_drvdata(dev);
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1391
  	struct w83627ehf_sio_data *sio_data = dev->platform_data;
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1392
1393
1394
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
  	u16 reg;
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1395
1396
  	long val;
  	int err;
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
1397
  	err = kstrtol(buf, 10, &val);
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1398
1399
  	if (err < 0)
  		return err;
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1400
  	/* Limit the temp to 0C - 15C */
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1401
  	val = SENSORS_LIMIT(DIV_ROUND_CLOSEST(val, 1000), 0, 15);
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1402
1403
  
  	mutex_lock(&data->update_lock);
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1404
1405
1406
1407
1408
  	if (sio_data->kind == nct6775 || sio_data->kind == nct6776) {
  		/* Limit tolerance further for NCT6776F */
  		if (sio_data->kind == nct6776 && val > 7)
  			val = 7;
  		reg = w83627ehf_read_value(data, NCT6775_REG_FAN_MODE[nr]);
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1409
  		reg = (reg & 0xf0) | val;
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
  		w83627ehf_write_value(data, NCT6775_REG_FAN_MODE[nr], reg);
  	} else {
  		reg = w83627ehf_read_value(data, W83627EHF_REG_TOLERANCE[nr]);
  		if (nr == 1)
  			reg = (reg & 0x0f) | (val << 4);
  		else
  			reg = (reg & 0xf0) | val;
  		w83627ehf_write_value(data, W83627EHF_REG_TOLERANCE[nr], reg);
  	}
  	data->tolerance[nr] = val;
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
  	mutex_unlock(&data->update_lock);
  	return count;
  }
  
  static struct sensor_device_attribute sda_pwm[] = {
  	SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0),
  	SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1),
  	SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2),
  	SENSOR_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 3),
  };
  
  static struct sensor_device_attribute sda_pwm_mode[] = {
  	SENSOR_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
  		    store_pwm_mode, 0),
  	SENSOR_ATTR(pwm2_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
  		    store_pwm_mode, 1),
  	SENSOR_ATTR(pwm3_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
  		    store_pwm_mode, 2),
  	SENSOR_ATTR(pwm4_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
  		    store_pwm_mode, 3),
  };
  
  static struct sensor_device_attribute sda_pwm_enable[] = {
  	SENSOR_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
  		    store_pwm_enable, 0),
  	SENSOR_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
  		    store_pwm_enable, 1),
  	SENSOR_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
  		    store_pwm_enable, 2),
  	SENSOR_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
  		    store_pwm_enable, 3),
  };
  
  static struct sensor_device_attribute sda_target_temp[] = {
  	SENSOR_ATTR(pwm1_target, S_IWUSR | S_IRUGO, show_target_temp,
  		    store_target_temp, 0),
  	SENSOR_ATTR(pwm2_target, S_IWUSR | S_IRUGO, show_target_temp,
  		    store_target_temp, 1),
  	SENSOR_ATTR(pwm3_target, S_IWUSR | S_IRUGO, show_target_temp,
  		    store_target_temp, 2),
  	SENSOR_ATTR(pwm4_target, S_IWUSR | S_IRUGO, show_target_temp,
  		    store_target_temp, 3),
  };
  
  static struct sensor_device_attribute sda_tolerance[] = {
  	SENSOR_ATTR(pwm1_tolerance, S_IWUSR | S_IRUGO, show_tolerance,
  		    store_tolerance, 0),
  	SENSOR_ATTR(pwm2_tolerance, S_IWUSR | S_IRUGO, show_tolerance,
  		    store_tolerance, 1),
  	SENSOR_ATTR(pwm3_tolerance, S_IWUSR | S_IRUGO, show_tolerance,
  		    store_tolerance, 2),
  	SENSOR_ATTR(pwm4_tolerance, S_IWUSR | S_IRUGO, show_tolerance,
  		    store_tolerance, 3),
  };
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1474
1475
1476
1477
1478
1479
1480
  /* Smart Fan registers */
  
  #define fan_functions(reg, REG) \
  static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
  		       char *buf) \
  { \
  	struct w83627ehf_data *data = w83627ehf_update_device(dev); \
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
1481
1482
  	struct sensor_device_attribute *sensor_attr = \
  		to_sensor_dev_attr(attr); \
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1483
1484
1485
  	int nr = sensor_attr->index; \
  	return sprintf(buf, "%d
  ", data->reg[nr]); \
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
1486
  } \
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1487
1488
1489
  static ssize_t \
  store_##reg(struct device *dev, struct device_attribute *attr, \
  			    const char *buf, size_t count) \
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
1490
  { \
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1491
  	struct w83627ehf_data *data = dev_get_drvdata(dev); \
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
1492
1493
  	struct sensor_device_attribute *sensor_attr = \
  		to_sensor_dev_attr(attr); \
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1494
  	int nr = sensor_attr->index; \
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1495
1496
  	unsigned long val; \
  	int err; \
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
1497
  	err = kstrtoul(buf, 10, &val); \
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1498
1499
1500
  	if (err < 0) \
  		return err; \
  	val = SENSORS_LIMIT(val, 1, 255); \
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1501
1502
  	mutex_lock(&data->update_lock); \
  	data->reg[nr] = val; \
da2e02559   Guenter Roeck   hwmon: (w83627ehf...
1503
  	w83627ehf_write_value(data, data->REG_##REG[nr], val); \
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1504
1505
1506
  	mutex_unlock(&data->update_lock); \
  	return count; \
  }
41e9a0623   Daniel J Blueman   hwmon: w83627ehf ...
1507
1508
1509
1510
  fan_functions(fan_start_output, FAN_START_OUTPUT)
  fan_functions(fan_stop_output, FAN_STOP_OUTPUT)
  fan_functions(fan_max_output, FAN_MAX_OUTPUT)
  fan_functions(fan_step_output, FAN_STEP_OUTPUT)
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1511
1512
1513
1514
1515
1516
  
  #define fan_time_functions(reg, REG) \
  static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
  				char *buf) \
  { \
  	struct w83627ehf_data *data = w83627ehf_update_device(dev); \
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
1517
1518
  	struct sensor_device_attribute *sensor_attr = \
  		to_sensor_dev_attr(attr); \
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1519
1520
1521
  	int nr = sensor_attr->index; \
  	return sprintf(buf, "%d
  ", \
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
1522
1523
  			step_time_from_reg(data->reg[nr], \
  					   data->pwm_mode[nr])); \
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1524
1525
1526
1527
1528
1529
  } \
  \
  static ssize_t \
  store_##reg(struct device *dev, struct device_attribute *attr, \
  			const char *buf, size_t count) \
  { \
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1530
  	struct w83627ehf_data *data = dev_get_drvdata(dev); \
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
1531
1532
  	struct sensor_device_attribute *sensor_attr = \
  		to_sensor_dev_attr(attr); \
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1533
  	int nr = sensor_attr->index; \
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1534
1535
  	unsigned long val; \
  	int err; \
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
1536
  	err = kstrtoul(buf, 10, &val); \
bce26c58d   Guenter Roeck   hwmon: (w83627ehf...
1537
1538
1539
  	if (err < 0) \
  		return err; \
  	val = step_time_to_reg(val, data->pwm_mode[nr]); \
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1540
1541
  	mutex_lock(&data->update_lock); \
  	data->reg[nr] = val; \
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1542
  	w83627ehf_write_value(data, W83627EHF_REG_##REG[nr], val); \
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1543
1544
1545
1546
1547
  	mutex_unlock(&data->update_lock); \
  	return count; \
  } \
  
  fan_time_functions(fan_stop_time, FAN_STOP_TIME)
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1548
1549
1550
1551
1552
1553
1554
1555
1556
  static ssize_t show_name(struct device *dev, struct device_attribute *attr,
  			 char *buf)
  {
  	struct w83627ehf_data *data = dev_get_drvdata(dev);
  
  	return sprintf(buf, "%s
  ", data->name);
  }
  static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1557
1558
1559
1560
  
  static struct sensor_device_attribute sda_sf3_arrays_fan4[] = {
  	SENSOR_ATTR(pwm4_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
  		    store_fan_stop_time, 3),
41e9a0623   Daniel J Blueman   hwmon: w83627ehf ...
1561
1562
1563
1564
1565
1566
1567
1568
  	SENSOR_ATTR(pwm4_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
  		    store_fan_start_output, 3),
  	SENSOR_ATTR(pwm4_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
  		    store_fan_stop_output, 3),
  	SENSOR_ATTR(pwm4_max_output, S_IWUSR | S_IRUGO, show_fan_max_output,
  		    store_fan_max_output, 3),
  	SENSOR_ATTR(pwm4_step_output, S_IWUSR | S_IRUGO, show_fan_step_output,
  		    store_fan_step_output, 3),
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1569
  };
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
1570
1571
1572
1573
1574
1575
1576
1577
  static struct sensor_device_attribute sda_sf3_arrays_fan3[] = {
  	SENSOR_ATTR(pwm3_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
  		    store_fan_stop_time, 2),
  	SENSOR_ATTR(pwm3_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
  		    store_fan_start_output, 2),
  	SENSOR_ATTR(pwm3_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
  		    store_fan_stop_output, 2),
  };
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1578
1579
1580
1581
1582
  static struct sensor_device_attribute sda_sf3_arrays[] = {
  	SENSOR_ATTR(pwm1_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
  		    store_fan_stop_time, 0),
  	SENSOR_ATTR(pwm2_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
  		    store_fan_stop_time, 1),
41e9a0623   Daniel J Blueman   hwmon: w83627ehf ...
1583
1584
1585
1586
  	SENSOR_ATTR(pwm1_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
  		    store_fan_start_output, 0),
  	SENSOR_ATTR(pwm2_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
  		    store_fan_start_output, 1),
41e9a0623   Daniel J Blueman   hwmon: w83627ehf ...
1587
1588
1589
1590
  	SENSOR_ATTR(pwm1_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
  		    store_fan_stop_output, 0),
  	SENSOR_ATTR(pwm2_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
  		    store_fan_stop_output, 1),
da2e02559   Guenter Roeck   hwmon: (w83627ehf...
1591
  };
41e9a0623   Daniel J Blueman   hwmon: w83627ehf ...
1592

da2e02559   Guenter Roeck   hwmon: (w83627ehf...
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
  
  /*
   * pwm1 and pwm3 don't support max and step settings on all chips.
   * Need to check support while generating/removing attribute files.
   */
  static struct sensor_device_attribute sda_sf3_max_step_arrays[] = {
  	SENSOR_ATTR(pwm1_max_output, S_IWUSR | S_IRUGO, show_fan_max_output,
  		    store_fan_max_output, 0),
  	SENSOR_ATTR(pwm1_step_output, S_IWUSR | S_IRUGO, show_fan_step_output,
  		    store_fan_step_output, 0),
41e9a0623   Daniel J Blueman   hwmon: w83627ehf ...
1603
1604
1605
1606
  	SENSOR_ATTR(pwm2_max_output, S_IWUSR | S_IRUGO, show_fan_max_output,
  		    store_fan_max_output, 1),
  	SENSOR_ATTR(pwm2_step_output, S_IWUSR | S_IRUGO, show_fan_step_output,
  		    store_fan_step_output, 1),
da2e02559   Guenter Roeck   hwmon: (w83627ehf...
1607
1608
1609
1610
  	SENSOR_ATTR(pwm3_max_output, S_IWUSR | S_IRUGO, show_fan_max_output,
  		    store_fan_max_output, 2),
  	SENSOR_ATTR(pwm3_step_output, S_IWUSR | S_IRUGO, show_fan_step_output,
  		    store_fan_step_output, 2),
08c79950a   Rudolf Marek   hwmon: Add fan sp...
1611
  };
fc18d6c04   Jean Delvare   hwmon/w83627ehf: ...
1612
1613
1614
1615
1616
1617
1618
1619
  static ssize_t
  show_vid(struct device *dev, struct device_attribute *attr, char *buf)
  {
  	struct w83627ehf_data *data = dev_get_drvdata(dev);
  	return sprintf(buf, "%d
  ", vid_from_reg(data->vid, data->vrm));
  }
  static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
363a12a49   Dmitry Artamonow   hwmon: (w83627ehf...
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
  
  /* Case open detection */
  
  static ssize_t
  show_caseopen(struct device *dev, struct device_attribute *attr, char *buf)
  {
  	struct w83627ehf_data *data = w83627ehf_update_device(dev);
  
  	return sprintf(buf, "%d
  ",
  		!!(data->caseopen & to_sensor_dev_attr_2(attr)->index));
  }
  
  static ssize_t
  clear_caseopen(struct device *dev, struct device_attribute *attr,
  			const char *buf, size_t count)
  {
  	struct w83627ehf_data *data = dev_get_drvdata(dev);
  	unsigned long val;
  	u16 reg, mask;
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
1640
  	if (kstrtoul(buf, 10, &val) || val != 0)
363a12a49   Dmitry Artamonow   hwmon: (w83627ehf...
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
  		return -EINVAL;
  
  	mask = to_sensor_dev_attr_2(attr)->nr;
  
  	mutex_lock(&data->update_lock);
  	reg = w83627ehf_read_value(data, W83627EHF_REG_CASEOPEN_CLR);
  	w83627ehf_write_value(data, W83627EHF_REG_CASEOPEN_CLR, reg | mask);
  	w83627ehf_write_value(data, W83627EHF_REG_CASEOPEN_CLR, reg & ~mask);
  	data->valid = 0;	/* Force cache refresh */
  	mutex_unlock(&data->update_lock);
  
  	return count;
  }
  
  static struct sensor_device_attribute_2 sda_caseopen[] = {
  	SENSOR_ATTR_2(intrusion0_alarm, S_IWUSR | S_IRUGO, show_caseopen,
  			clear_caseopen, 0x80, 0x10),
  	SENSOR_ATTR_2(intrusion1_alarm, S_IWUSR | S_IRUGO, show_caseopen,
  			clear_caseopen, 0x40, 0x40),
  };
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1661
  /*
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1662
   * Driver and device management
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1663
   */
c18beb5b9   David Hubbard   w83627ehf: Fix un...
1664
1665
1666
1667
1668
  static void w83627ehf_device_remove_files(struct device *dev)
  {
  	/* some entries in the following arrays may not have been used in
  	 * device_create_file(), but device_remove_file() will ignore them */
  	int i;
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1669
  	struct w83627ehf_data *data = dev_get_drvdata(dev);
c18beb5b9   David Hubbard   w83627ehf: Fix un...
1670
1671
1672
  
  	for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++)
  		device_remove_file(dev, &sda_sf3_arrays[i].dev_attr);
da2e02559   Guenter Roeck   hwmon: (w83627ehf...
1673
1674
1675
  	for (i = 0; i < ARRAY_SIZE(sda_sf3_max_step_arrays); i++) {
  		struct sensor_device_attribute *attr =
  		  &sda_sf3_max_step_arrays[i];
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1676
1677
  		if (data->REG_FAN_STEP_OUTPUT &&
  		    data->REG_FAN_STEP_OUTPUT[attr->index] != 0xff)
da2e02559   Guenter Roeck   hwmon: (w83627ehf...
1678
1679
  			device_remove_file(dev, &attr->dev_attr);
  	}
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
1680
1681
  	for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan3); i++)
  		device_remove_file(dev, &sda_sf3_arrays_fan3[i].dev_attr);
c18beb5b9   David Hubbard   w83627ehf: Fix un...
1682
1683
  	for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++)
  		device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr);
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1684
  	for (i = 0; i < data->in_num; i++) {
a157d06d4   Gong Jun   hwmon: (w83627ehf...
1685
1686
  		if ((i == 6) && data->in6_skip)
  			continue;
c18beb5b9   David Hubbard   w83627ehf: Fix un...
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
  		device_remove_file(dev, &sda_in_input[i].dev_attr);
  		device_remove_file(dev, &sda_in_alarm[i].dev_attr);
  		device_remove_file(dev, &sda_in_min[i].dev_attr);
  		device_remove_file(dev, &sda_in_max[i].dev_attr);
  	}
  	for (i = 0; i < 5; i++) {
  		device_remove_file(dev, &sda_fan_input[i].dev_attr);
  		device_remove_file(dev, &sda_fan_alarm[i].dev_attr);
  		device_remove_file(dev, &sda_fan_div[i].dev_attr);
  		device_remove_file(dev, &sda_fan_min[i].dev_attr);
  	}
237c8d2f5   Gong Jun   hwmon: (w83627ehf...
1698
  	for (i = 0; i < data->pwm_num; i++) {
c18beb5b9   David Hubbard   w83627ehf: Fix un...
1699
1700
1701
1702
1703
1704
  		device_remove_file(dev, &sda_pwm[i].dev_attr);
  		device_remove_file(dev, &sda_pwm_mode[i].dev_attr);
  		device_remove_file(dev, &sda_pwm_enable[i].dev_attr);
  		device_remove_file(dev, &sda_target_temp[i].dev_attr);
  		device_remove_file(dev, &sda_tolerance[i].dev_attr);
  	}
d36cf32c9   Guenter Roeck   hwmon: (w83627ehf...
1705
1706
  	for (i = 0; i < NUM_REG_TEMP; i++) {
  		if (!(data->have_temp & (1 << i)))
a157d06d4   Gong Jun   hwmon: (w83627ehf...
1707
1708
  			continue;
  		device_remove_file(dev, &sda_temp_input[i].dev_attr);
d36cf32c9   Guenter Roeck   hwmon: (w83627ehf...
1709
  		device_remove_file(dev, &sda_temp_label[i].dev_attr);
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
1710
1711
  		if (i == 2 && data->temp3_val_only)
  			continue;
a157d06d4   Gong Jun   hwmon: (w83627ehf...
1712
1713
  		device_remove_file(dev, &sda_temp_max[i].dev_attr);
  		device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr);
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1714
1715
  		if (i > 2)
  			continue;
a157d06d4   Gong Jun   hwmon: (w83627ehf...
1716
1717
1718
  		device_remove_file(dev, &sda_temp_alarm[i].dev_attr);
  		device_remove_file(dev, &sda_temp_type[i].dev_attr);
  	}
c18beb5b9   David Hubbard   w83627ehf: Fix un...
1719

363a12a49   Dmitry Artamonow   hwmon: (w83627ehf...
1720
1721
  	device_remove_file(dev, &sda_caseopen[0].dev_attr);
  	device_remove_file(dev, &sda_caseopen[1].dev_attr);
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1722
  	device_remove_file(dev, &dev_attr_name);
cbe311f2a   Jean Delvare   hwmon: (w83627ehf...
1723
  	device_remove_file(dev, &dev_attr_cpu0_vid);
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1724
  }
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1725

1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1726
  /* Get the monitoring functions started */
bf164c58e   Jean Delvare   hwmon: (w83627ehf...
1727
1728
  static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data,
  						   enum kinds kind)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1729
1730
  {
  	int i;
da667365b   Jean Delvare   hwmon/w83627ehf: ...
1731
  	u8 tmp, diode;
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1732
1733
  
  	/* Start monitoring is needed */
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1734
  	tmp = w83627ehf_read_value(data, W83627EHF_REG_CONFIG);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1735
  	if (!(tmp & 0x01))
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1736
  		w83627ehf_write_value(data, W83627EHF_REG_CONFIG,
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1737
  				      tmp | 0x01);
d36cf32c9   Guenter Roeck   hwmon: (w83627ehf...
1738
1739
1740
1741
  	/* Enable temperature sensors if needed */
  	for (i = 0; i < NUM_REG_TEMP; i++) {
  		if (!(data->have_temp & (1 << i)))
  			continue;
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1742
  		if (!data->reg_temp_config[i])
d36cf32c9   Guenter Roeck   hwmon: (w83627ehf...
1743
  			continue;
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1744
  		tmp = w83627ehf_read_value(data,
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1745
  					   data->reg_temp_config[i]);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1746
  		if (tmp & 0x01)
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1747
  			w83627ehf_write_value(data,
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1748
  					      data->reg_temp_config[i],
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1749
1750
  					      tmp & 0xfe);
  	}
d3130f0e3   Jean Delvare   hwmon/w83627ehf: ...
1751
1752
1753
1754
1755
  
  	/* Enable VBAT monitoring if needed */
  	tmp = w83627ehf_read_value(data, W83627EHF_REG_VBAT);
  	if (!(tmp & 0x01))
  		w83627ehf_write_value(data, W83627EHF_REG_VBAT, tmp | 0x01);
da667365b   Jean Delvare   hwmon/w83627ehf: ...
1756
1757
  
  	/* Get thermal sensor types */
bf164c58e   Jean Delvare   hwmon: (w83627ehf...
1758
1759
1760
1761
  	switch (kind) {
  	case w83627ehf:
  		diode = w83627ehf_read_value(data, W83627EHF_REG_DIODE);
  		break;
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
1762
1763
1764
  	case w83627uhg:
  		diode = 0x00;
  		break;
bf164c58e   Jean Delvare   hwmon: (w83627ehf...
1765
1766
1767
  	default:
  		diode = 0x70;
  	}
da667365b   Jean Delvare   hwmon/w83627ehf: ...
1768
  	for (i = 0; i < 3; i++) {
bfa02b0da   Guenter Roeck   hwmon: (w83627ehf...
1769
1770
1771
1772
  		const char *label = NULL;
  
  		if (data->temp_label)
  			label = data->temp_label[data->temp_src[i]];
2265cef27   Jean Delvare   hwmon: (w83627ehf...
1773
1774
  
  		/* Digital source overrides analog type */
bfa02b0da   Guenter Roeck   hwmon: (w83627ehf...
1775
  		if (label && strncmp(label, "PECI", 4) == 0)
2265cef27   Jean Delvare   hwmon: (w83627ehf...
1776
  			data->temp_type[i] = 6;
bfa02b0da   Guenter Roeck   hwmon: (w83627ehf...
1777
  		else if (label && strncmp(label, "AMD", 3) == 0)
2265cef27   Jean Delvare   hwmon: (w83627ehf...
1778
1779
  			data->temp_type[i] = 5;
  		else if ((tmp & (0x02 << i)))
bf164c58e   Jean Delvare   hwmon: (w83627ehf...
1780
  			data->temp_type[i] = (diode & (0x10 << i)) ? 1 : 3;
da667365b   Jean Delvare   hwmon/w83627ehf: ...
1781
1782
1783
  		else
  			data->temp_type[i] = 4; /* thermistor */
  	}
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1784
  }
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
  static void w82627ehf_swap_tempreg(struct w83627ehf_data *data,
  				   int r1, int r2)
  {
  	u16 tmp;
  
  	tmp = data->temp_src[r1];
  	data->temp_src[r1] = data->temp_src[r2];
  	data->temp_src[r2] = tmp;
  
  	tmp = data->reg_temp[r1];
  	data->reg_temp[r1] = data->reg_temp[r2];
  	data->reg_temp[r2] = tmp;
  
  	tmp = data->reg_temp_over[r1];
  	data->reg_temp_over[r1] = data->reg_temp_over[r2];
  	data->reg_temp_over[r2] = tmp;
  
  	tmp = data->reg_temp_hyst[r1];
  	data->reg_temp_hyst[r1] = data->reg_temp_hyst[r2];
  	data->reg_temp_hyst[r2] = tmp;
  
  	tmp = data->reg_temp_config[r1];
  	data->reg_temp_config[r1] = data->reg_temp_config[r2];
  	data->reg_temp_config[r2] = tmp;
  }
03f5de2bb   Jean Delvare   hwmon: (w83627ehf...
1810
  static void __devinit
6ba71de5f   Jean Delvare   hwmon: (w83627ehf...
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
  w83627ehf_set_temp_reg_ehf(struct w83627ehf_data *data, int n_temp)
  {
  	int i;
  
  	for (i = 0; i < n_temp; i++) {
  		data->reg_temp[i] = W83627EHF_REG_TEMP[i];
  		data->reg_temp_over[i] = W83627EHF_REG_TEMP_OVER[i];
  		data->reg_temp_hyst[i] = W83627EHF_REG_TEMP_HYST[i];
  		data->reg_temp_config[i] = W83627EHF_REG_TEMP_CONFIG[i];
  	}
  }
  
  static void __devinit
03f5de2bb   Jean Delvare   hwmon: (w83627ehf...
1824
1825
1826
1827
  w83627ehf_check_fan_inputs(const struct w83627ehf_sio_data *sio_data,
  			   struct w83627ehf_data *data)
  {
  	int fan3pin, fan4pin, fan4min, fan5pin, regval;
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
1828
1829
1830
1831
1832
1833
  	/* The W83627UHG is simple, only two fan inputs, no config */
  	if (sio_data->kind == w83627uhg) {
  		data->has_fan = 0x03; /* fan1 and fan2 */
  		data->has_fan_min = 0x03;
  		return;
  	}
03f5de2bb   Jean Delvare   hwmon: (w83627ehf...
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
  	superio_enter(sio_data->sioreg);
  
  	/* fan4 and fan5 share some pins with the GPIO and serial flash */
  	if (sio_data->kind == nct6775) {
  		/* On NCT6775, fan4 shares pins with the fdc interface */
  		fan3pin = 1;
  		fan4pin = !(superio_inb(sio_data->sioreg, 0x2A) & 0x80);
  		fan4min = 0;
  		fan5pin = 0;
  	} else if (sio_data->kind == nct6776) {
  		fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40);
  		fan4pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x01);
  		fan5pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x02);
  		fan4min = fan4pin;
  	} else if (sio_data->kind == w83667hg || sio_data->kind == w83667hg_b) {
  		fan3pin = 1;
  		fan4pin = superio_inb(sio_data->sioreg, 0x27) & 0x40;
  		fan5pin = superio_inb(sio_data->sioreg, 0x27) & 0x20;
  		fan4min = fan4pin;
  	} else {
  		fan3pin = 1;
  		fan4pin = !(superio_inb(sio_data->sioreg, 0x29) & 0x06);
  		fan5pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x02);
  		fan4min = fan4pin;
  	}
  
  	superio_exit(sio_data->sioreg);
  
  	data->has_fan = data->has_fan_min = 0x03; /* fan1 and fan2 */
  	data->has_fan |= (fan3pin << 2);
  	data->has_fan_min |= (fan3pin << 2);
  
  	if (sio_data->kind == nct6775 || sio_data->kind == nct6776) {
  		/*
  		 * NCT6775F and NCT6776F don't have the W83627EHF_REG_FANDIV1
  		 * register
  		 */
  		data->has_fan |= (fan4pin << 3) | (fan5pin << 4);
  		data->has_fan_min |= (fan4min << 3) | (fan5pin << 4);
  	} else {
  		/*
  		 * It looks like fan4 and fan5 pins can be alternatively used
  		 * as fan on/off switches, but fan5 control is write only :/
  		 * We assume that if the serial interface is disabled, designers
  		 * connected fan5 as input unless they are emitting log 1, which
  		 * is not the default.
  		 */
  		regval = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1);
  		if ((regval & (1 << 2)) && fan4pin) {
  			data->has_fan |= (1 << 3);
  			data->has_fan_min |= (1 << 3);
  		}
  		if (!(regval & (1 << 1)) && fan5pin) {
  			data->has_fan |= (1 << 4);
  			data->has_fan_min |= (1 << 4);
  		}
  	}
  }
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1892
  static int __devinit w83627ehf_probe(struct platform_device *pdev)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1893
  {
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1894
1895
  	struct device *dev = &pdev->dev;
  	struct w83627ehf_sio_data *sio_data = dev->platform_data;
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1896
  	struct w83627ehf_data *data;
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1897
  	struct resource *res;
03f5de2bb   Jean Delvare   hwmon: (w83627ehf...
1898
  	u8 en_vrm10;
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1899
  	int i, err = 0;
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1900
1901
  	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
  	if (!request_region(res->start, IOREGION_LENGTH, DRVNAME)) {
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1902
  		err = -EBUSY;
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1903
1904
1905
1906
  		dev_err(dev, "Failed to request region 0x%lx-0x%lx
  ",
  			(unsigned long)res->start,
  			(unsigned long)res->start + IOREGION_LENGTH - 1);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1907
1908
  		goto exit;
  	}
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
1909
1910
  	data = kzalloc(sizeof(struct w83627ehf_data), GFP_KERNEL);
  	if (!data) {
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1911
1912
1913
  		err = -ENOMEM;
  		goto exit_release;
  	}
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1914

1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1915
  	data->addr = res->start;
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
1916
  	mutex_init(&data->lock);
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
1917
  	mutex_init(&data->update_lock);
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
1918
1919
  	data->name = w83627ehf_device_names[sio_data->kind];
  	platform_set_drvdata(pdev, data);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1920

237c8d2f5   Gong Jun   hwmon: (w83627ehf...
1921
1922
  	/* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */
  	data->in_num = (sio_data->kind == w83627ehf) ? 10 : 9;
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
  	/* 667HG, NCT6775F, and NCT6776F have 3 pwms, and 627UHG has only 2 */
  	switch (sio_data->kind) {
  	default:
  		data->pwm_num = 4;
  		break;
  	case w83667hg:
  	case w83667hg_b:
  	case nct6775:
  	case nct6776:
  		data->pwm_num = 3;
  		break;
  	case w83627uhg:
  		data->pwm_num = 2;
  		break;
  	}
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
1938

6ba71de5f   Jean Delvare   hwmon: (w83627ehf...
1939
  	/* Default to 3 temperature inputs, code below will adjust as needed */
d36cf32c9   Guenter Roeck   hwmon: (w83627ehf...
1940
  	data->have_temp = 0x07;
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
  
  	/* Deal with temperature register setup first. */
  	if (sio_data->kind == nct6775 || sio_data->kind == nct6776) {
  		int mask = 0;
  
  		/*
  		 * Display temperature sensor output only if it monitors
  		 * a source other than one already reported. Always display
  		 * first three temperature registers, though.
  		 */
  		for (i = 0; i < NUM_REG_TEMP; i++) {
  			u8 src;
  
  			data->reg_temp[i] = NCT6775_REG_TEMP[i];
  			data->reg_temp_over[i] = NCT6775_REG_TEMP_OVER[i];
  			data->reg_temp_hyst[i] = NCT6775_REG_TEMP_HYST[i];
  			data->reg_temp_config[i] = NCT6775_REG_TEMP_CONFIG[i];
  
  			src = w83627ehf_read_value(data,
  						   NCT6775_REG_TEMP_SOURCE[i]);
  			src &= 0x1f;
  			if (src && !(mask & (1 << src))) {
  				data->have_temp |= 1 << i;
  				mask |= 1 << src;
  			}
  
  			data->temp_src[i] = src;
  
  			/*
  			 * Now do some register swapping if index 0..2 don't
  			 * point to SYSTIN(1), CPUIN(2), and AUXIN(3).
  			 * Idea is to have the first three attributes
  			 * report SYSTIN, CPUIN, and AUXIN if possible
  			 * without overriding the basic system configuration.
  			 */
  			if (i > 0 && data->temp_src[0] != 1
  			    && data->temp_src[i] == 1)
  				w82627ehf_swap_tempreg(data, 0, i);
  			if (i > 1 && data->temp_src[1] != 2
  			    && data->temp_src[i] == 2)
  				w82627ehf_swap_tempreg(data, 1, i);
  			if (i > 2 && data->temp_src[2] != 3
  			    && data->temp_src[i] == 3)
  				w82627ehf_swap_tempreg(data, 2, i);
  		}
  		if (sio_data->kind == nct6776) {
  			/*
  			 * On NCT6776, AUXTIN and VIN3 pins are shared.
  			 * Only way to detect it is to check if AUXTIN is used
  			 * as a temperature source, and if that source is
  			 * enabled.
  			 *
  			 * If that is the case, disable in6, which reports VIN3.
  			 * Otherwise disable temp3.
  			 */
  			if (data->temp_src[2] == 3) {
  				u8 reg;
  
  				if (data->reg_temp_config[2])
  					reg = w83627ehf_read_value(data,
  						data->reg_temp_config[2]);
  				else
  					reg = 0; /* Assume AUXTIN is used */
  
  				if (reg & 0x01)
  					data->have_temp &= ~(1 << 2);
  				else
  					data->in6_skip = 1;
  			}
02309ad2b   Guenter Roeck   hwmon: (w83627ehf...
2010
2011
2012
  			data->temp_label = nct6776_temp_label;
  		} else {
  			data->temp_label = nct6775_temp_label;
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
2013
  		}
d36cf32c9   Guenter Roeck   hwmon: (w83627ehf...
2014
2015
  	} else if (sio_data->kind == w83667hg_b) {
  		u8 reg;
6ba71de5f   Jean Delvare   hwmon: (w83627ehf...
2016
  		w83627ehf_set_temp_reg_ehf(data, 4);
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
2017
2018
2019
2020
  		/*
  		 * Temperature sources are selected with bank 0, registers 0x49
  		 * and 0x4a.
  		 */
d36cf32c9   Guenter Roeck   hwmon: (w83627ehf...
2021
2022
2023
2024
  		reg = w83627ehf_read_value(data, 0x4a);
  		data->temp_src[0] = reg >> 5;
  		reg = w83627ehf_read_value(data, 0x49);
  		data->temp_src[1] = reg & 0x07;
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
2025
  		data->temp_src[2] = (reg >> 4) & 0x07;
d36cf32c9   Guenter Roeck   hwmon: (w83627ehf...
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
  
  		/*
  		 * W83667HG-B has another temperature register at 0x7e.
  		 * The temperature source is selected with register 0x7d.
  		 * Support it if the source differs from already reported
  		 * sources.
  		 */
  		reg = w83627ehf_read_value(data, 0x7d);
  		reg &= 0x07;
  		if (reg != data->temp_src[0] && reg != data->temp_src[1]
  		    && reg != data->temp_src[2]) {
  			data->temp_src[3] = reg;
  			data->have_temp |= 1 << 3;
  		}
  
  		/*
  		 * Chip supports either AUXTIN or VIN3. Try to find out which
  		 * one.
  		 */
  		reg = w83627ehf_read_value(data, W83627EHF_REG_TEMP_CONFIG[2]);
  		if (data->temp_src[2] == 2 && (reg & 0x01))
  			data->have_temp &= ~(1 << 2);
  
  		if ((data->temp_src[2] == 2 && (data->have_temp & (1 << 2)))
  		    || (data->temp_src[3] == 2 && (data->have_temp & (1 << 3))))
  			data->in6_skip = 1;
  
  		data->temp_label = w83667hg_b_temp_label;
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
  	} else if (sio_data->kind == w83627uhg) {
  		u8 reg;
  
  		w83627ehf_set_temp_reg_ehf(data, 3);
  
  		/*
  		 * Temperature sources for temp1 and temp2 are selected with
  		 * bank 0, registers 0x49 and 0x4a.
  		 */
  		data->temp_src[0] = 0;	/* SYSTIN */
  		reg = w83627ehf_read_value(data, 0x49) & 0x07;
  		/* Adjust to have the same mapping as other source registers */
  		if (reg == 0)
  			data->temp_src[1]++;
  		else if (reg >= 2 && reg <= 5)
  			data->temp_src[1] += 2;
  		else	/* should never happen */
  			data->have_temp &= ~(1 << 1);
  		reg = w83627ehf_read_value(data, 0x4a);
  		data->temp_src[2] = reg >> 5;
  
  		/*
  		 * Skip temp3 if source is invalid or the same as temp1
  		 * or temp2.
  		 */
  		if (data->temp_src[2] == 2 || data->temp_src[2] == 3 ||
  		    data->temp_src[2] == data->temp_src[0] ||
  		    ((data->have_temp & (1 << 1)) &&
  		     data->temp_src[2] == data->temp_src[1]))
  			data->have_temp &= ~(1 << 2);
  		else
  			data->temp3_val_only = 1;	/* No limit regs */
  
  		data->in6_skip = 1;			/* No VIN3 */
  
  		data->temp_label = w83667hg_b_temp_label;
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
2090
  	} else {
6ba71de5f   Jean Delvare   hwmon: (w83627ehf...
2091
  		w83627ehf_set_temp_reg_ehf(data, 3);
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
2092
  		/* Temperature sources are fixed */
6ba71de5f   Jean Delvare   hwmon: (w83627ehf...
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
  
  		if (sio_data->kind == w83667hg) {
  			u8 reg;
  
  			/*
  			 * Chip supports either AUXTIN or VIN3. Try to find
  			 * out which one.
  			 */
  			reg = w83627ehf_read_value(data,
  						W83627EHF_REG_TEMP_CONFIG[2]);
  			if (reg & 0x01)
  				data->have_temp &= ~(1 << 2);
  			else
  				data->in6_skip = 1;
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
2107
  		}
a157d06d4   Gong Jun   hwmon: (w83627ehf...
2108
  	}
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
2109
  	if (sio_data->kind == nct6775) {
26bc440e3   Guenter Roeck   hwmon: (w83627ehf...
2110
2111
2112
  		data->has_fan_div = true;
  		data->fan_from_reg = fan_from_reg16;
  		data->fan_from_reg_min = fan_from_reg8;
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
2113
2114
  		data->REG_PWM = NCT6775_REG_PWM;
  		data->REG_TARGET = NCT6775_REG_TARGET;
26bc440e3   Guenter Roeck   hwmon: (w83627ehf...
2115
  		data->REG_FAN = NCT6775_REG_FAN;
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
2116
2117
2118
2119
2120
2121
2122
  		data->REG_FAN_MIN = W83627EHF_REG_FAN_MIN;
  		data->REG_FAN_START_OUTPUT = NCT6775_REG_FAN_START_OUTPUT;
  		data->REG_FAN_STOP_OUTPUT = NCT6775_REG_FAN_STOP_OUTPUT;
  		data->REG_FAN_STOP_TIME = NCT6775_REG_FAN_STOP_TIME;
  		data->REG_FAN_MAX_OUTPUT = NCT6775_REG_FAN_MAX_OUTPUT;
  		data->REG_FAN_STEP_OUTPUT = NCT6775_REG_FAN_STEP_OUTPUT;
  	} else if (sio_data->kind == nct6776) {
26bc440e3   Guenter Roeck   hwmon: (w83627ehf...
2123
2124
2125
  		data->has_fan_div = false;
  		data->fan_from_reg = fan_from_reg13;
  		data->fan_from_reg_min = fan_from_reg13;
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
2126
2127
  		data->REG_PWM = NCT6775_REG_PWM;
  		data->REG_TARGET = NCT6775_REG_TARGET;
26bc440e3   Guenter Roeck   hwmon: (w83627ehf...
2128
  		data->REG_FAN = NCT6775_REG_FAN;
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
2129
2130
2131
2132
2133
  		data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
  		data->REG_FAN_START_OUTPUT = NCT6775_REG_FAN_START_OUTPUT;
  		data->REG_FAN_STOP_OUTPUT = NCT6775_REG_FAN_STOP_OUTPUT;
  		data->REG_FAN_STOP_TIME = NCT6775_REG_FAN_STOP_TIME;
  	} else if (sio_data->kind == w83667hg_b) {
26bc440e3   Guenter Roeck   hwmon: (w83627ehf...
2134
2135
2136
  		data->has_fan_div = true;
  		data->fan_from_reg = fan_from_reg8;
  		data->fan_from_reg_min = fan_from_reg8;
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
2137
2138
2139
2140
2141
2142
2143
  		data->REG_PWM = W83627EHF_REG_PWM;
  		data->REG_TARGET = W83627EHF_REG_TARGET;
  		data->REG_FAN = W83627EHF_REG_FAN;
  		data->REG_FAN_MIN = W83627EHF_REG_FAN_MIN;
  		data->REG_FAN_START_OUTPUT = W83627EHF_REG_FAN_START_OUTPUT;
  		data->REG_FAN_STOP_OUTPUT = W83627EHF_REG_FAN_STOP_OUTPUT;
  		data->REG_FAN_STOP_TIME = W83627EHF_REG_FAN_STOP_TIME;
c39aedafb   Guenter Roeck   hwmon: (w83627ehf...
2144
2145
2146
2147
2148
  		data->REG_FAN_MAX_OUTPUT =
  		  W83627EHF_REG_FAN_MAX_OUTPUT_W83667_B;
  		data->REG_FAN_STEP_OUTPUT =
  		  W83627EHF_REG_FAN_STEP_OUTPUT_W83667_B;
  	} else {
26bc440e3   Guenter Roeck   hwmon: (w83627ehf...
2149
2150
2151
  		data->has_fan_div = true;
  		data->fan_from_reg = fan_from_reg8;
  		data->fan_from_reg_min = fan_from_reg8;
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
2152
2153
2154
2155
2156
2157
2158
  		data->REG_PWM = W83627EHF_REG_PWM;
  		data->REG_TARGET = W83627EHF_REG_TARGET;
  		data->REG_FAN = W83627EHF_REG_FAN;
  		data->REG_FAN_MIN = W83627EHF_REG_FAN_MIN;
  		data->REG_FAN_START_OUTPUT = W83627EHF_REG_FAN_START_OUTPUT;
  		data->REG_FAN_STOP_OUTPUT = W83627EHF_REG_FAN_STOP_OUTPUT;
  		data->REG_FAN_STOP_TIME = W83627EHF_REG_FAN_STOP_TIME;
c39aedafb   Guenter Roeck   hwmon: (w83627ehf...
2159
2160
2161
2162
2163
  		data->REG_FAN_MAX_OUTPUT =
  		  W83627EHF_REG_FAN_MAX_OUTPUT_COMMON;
  		data->REG_FAN_STEP_OUTPUT =
  		  W83627EHF_REG_FAN_STEP_OUTPUT_COMMON;
  	}
da2e02559   Guenter Roeck   hwmon: (w83627ehf...
2164

eff7687d4   Jean Delvare   hwmon: (w83627ehf...
2165
2166
2167
2168
2169
  	/* Setup input voltage scaling factors */
  	if (sio_data->kind == w83627uhg)
  		data->scale_in = scale_in_w83627uhg;
  	else
  		data->scale_in = scale_in_common;
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2170
  	/* Initialize the chip */
bf164c58e   Jean Delvare   hwmon: (w83627ehf...
2171
  	w83627ehf_init_device(data, sio_data->kind);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2172

fc18d6c04   Jean Delvare   hwmon/w83627ehf: ...
2173
2174
  	data->vrm = vid_which_vrm();
  	superio_enter(sio_data->sioreg);
fc18d6c04   Jean Delvare   hwmon/w83627ehf: ...
2175
  	/* Read VID value */
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
2176
2177
  	if (sio_data->kind == w83667hg || sio_data->kind == w83667hg_b ||
  	    sio_data->kind == nct6775 || sio_data->kind == nct6776) {
237c8d2f5   Gong Jun   hwmon: (w83627ehf...
2178
2179
2180
2181
2182
  		/* W83667HG has different pins for VID input and output, so
  		we can get the VID input values directly at logical device D
  		0xe3. */
  		superio_select(sio_data->sioreg, W83667HG_LD_VID);
  		data->vid = superio_inb(sio_data->sioreg, 0xe3);
cbe311f2a   Jean Delvare   hwmon: (w83627ehf...
2183
2184
2185
  		err = device_create_file(dev, &dev_attr_cpu0_vid);
  		if (err)
  			goto exit_release;
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
2186
  	} else if (sio_data->kind != w83627uhg) {
237c8d2f5   Gong Jun   hwmon: (w83627ehf...
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
  		superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
  		if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) {
  			/* Set VID input sensibility if needed. In theory the
  			   BIOS should have set it, but in practice it's not
  			   always the case. We only do it for the W83627EHF/EHG
  			   because the W83627DHG is more complex in this
  			   respect. */
  			if (sio_data->kind == w83627ehf) {
  				en_vrm10 = superio_inb(sio_data->sioreg,
  						       SIO_REG_EN_VRM10);
  				if ((en_vrm10 & 0x08) && data->vrm == 90) {
  					dev_warn(dev, "Setting VID input "
  						 "voltage to TTL
  ");
  					superio_outb(sio_data->sioreg,
  						     SIO_REG_EN_VRM10,
  						     en_vrm10 & ~0x08);
  				} else if (!(en_vrm10 & 0x08)
  					   && data->vrm == 100) {
  					dev_warn(dev, "Setting VID input "
  						 "voltage to VRM10
  ");
  					superio_outb(sio_data->sioreg,
  						     SIO_REG_EN_VRM10,
  						     en_vrm10 | 0x08);
  				}
  			}
  
  			data->vid = superio_inb(sio_data->sioreg,
  						SIO_REG_VID_DATA);
  			if (sio_data->kind == w83627ehf) /* 6 VID pins only */
  				data->vid &= 0x3f;
  
  			err = device_create_file(dev, &dev_attr_cpu0_vid);
  			if (err)
  				goto exit_release;
  		} else {
  			dev_info(dev, "VID pins in output mode, CPU VID not "
  				 "available
  ");
  		}
fc18d6c04   Jean Delvare   hwmon/w83627ehf: ...
2228
  	}
d42e869ac   Ian Dobson   hwmon: (w83627ehf...
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
  	if (fan_debounce &&
  	    (sio_data->kind == nct6775 || sio_data->kind == nct6776)) {
  		u8 tmp;
  
  		superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
  		tmp = superio_inb(sio_data->sioreg, NCT6775_REG_FAN_DEBOUNCE);
  		if (sio_data->kind == nct6776)
  			superio_outb(sio_data->sioreg, NCT6775_REG_FAN_DEBOUNCE,
  				     0x3e | tmp);
  		else
  			superio_outb(sio_data->sioreg, NCT6775_REG_FAN_DEBOUNCE,
  				     0x1e | tmp);
  		pr_info("Enabled fan debounce for chip %s
  ", data->name);
  	}
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2244
  	superio_exit(sio_data->sioreg);
08c79950a   Rudolf Marek   hwmon: Add fan sp...
2245

03f5de2bb   Jean Delvare   hwmon: (w83627ehf...
2246
  	w83627ehf_check_fan_inputs(sio_data, data);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2247

ea7be66c4   Mark M. Hoffman   hwmon: (w83627ehf...
2248
  	/* Read fan clock dividers immediately */
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
2249
2250
2251
2252
2253
2254
  	w83627ehf_update_fan_div_common(dev, data);
  
  	/* Read pwm data to save original values */
  	w83627ehf_update_pwm_common(dev, data);
  	for (i = 0; i < data->pwm_num; i++)
  		data->pwm_enable_orig[i] = data->pwm_enable[i];
ea7be66c4   Mark M. Hoffman   hwmon: (w83627ehf...
2255

b84bb5186   Guenter Roeck   hwmon: (w83627ehf...
2256
2257
2258
2259
  	/* Read pwm data to save original values */
  	w83627ehf_update_pwm_common(dev, data);
  	for (i = 0; i < data->pwm_num; i++)
  		data->pwm_enable_orig[i] = data->pwm_enable[i];
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2260
  	/* Register sysfs hooks */
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
2261
2262
2263
  	for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) {
  		err = device_create_file(dev, &sda_sf3_arrays[i].dev_attr);
  		if (err)
c18beb5b9   David Hubbard   w83627ehf: Fix un...
2264
  			goto exit_remove;
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
2265
  	}
08c79950a   Rudolf Marek   hwmon: Add fan sp...
2266

da2e02559   Guenter Roeck   hwmon: (w83627ehf...
2267
2268
2269
  	for (i = 0; i < ARRAY_SIZE(sda_sf3_max_step_arrays); i++) {
  		struct sensor_device_attribute *attr =
  		  &sda_sf3_max_step_arrays[i];
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
2270
2271
  		if (data->REG_FAN_STEP_OUTPUT &&
  		    data->REG_FAN_STEP_OUTPUT[attr->index] != 0xff) {
da2e02559   Guenter Roeck   hwmon: (w83627ehf...
2272
2273
2274
2275
2276
  			err = device_create_file(dev, &attr->dev_attr);
  			if (err)
  				goto exit_remove;
  		}
  	}
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
2277
2278
2279
2280
2281
2282
2283
2284
  	/* if fan3 and fan4 are enabled create the sf3 files for them */
  	if ((data->has_fan & (1 << 2)) && data->pwm_num >= 3)
  		for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan3); i++) {
  			err = device_create_file(dev,
  					&sda_sf3_arrays_fan3[i].dev_attr);
  			if (err)
  				goto exit_remove;
  		}
237c8d2f5   Gong Jun   hwmon: (w83627ehf...
2285
  	if ((data->has_fan & (1 << 3)) && data->pwm_num >= 4)
c18beb5b9   David Hubbard   w83627ehf: Fix un...
2286
  		for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) {
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
2287
2288
2289
  			err = device_create_file(dev,
  					&sda_sf3_arrays_fan4[i].dev_attr);
  			if (err)
c18beb5b9   David Hubbard   w83627ehf: Fix un...
2290
2291
  				goto exit_remove;
  		}
08c79950a   Rudolf Marek   hwmon: Add fan sp...
2292

a157d06d4   Gong Jun   hwmon: (w83627ehf...
2293
2294
2295
  	for (i = 0; i < data->in_num; i++) {
  		if ((i == 6) && data->in6_skip)
  			continue;
c18beb5b9   David Hubbard   w83627ehf: Fix un...
2296
2297
2298
2299
2300
2301
2302
2303
  		if ((err = device_create_file(dev, &sda_in_input[i].dev_attr))
  			|| (err = device_create_file(dev,
  				&sda_in_alarm[i].dev_attr))
  			|| (err = device_create_file(dev,
  				&sda_in_min[i].dev_attr))
  			|| (err = device_create_file(dev,
  				&sda_in_max[i].dev_attr)))
  			goto exit_remove;
a157d06d4   Gong Jun   hwmon: (w83627ehf...
2304
  	}
cf0676fe4   Rudolf Marek   [PATCH] w83627ehf...
2305

412fec821   Yuan Mu   [PATCH] w83627ehf...
2306
  	for (i = 0; i < 5; i++) {
08c79950a   Rudolf Marek   hwmon: Add fan sp...
2307
  		if (data->has_fan & (1 << i)) {
c18beb5b9   David Hubbard   w83627ehf: Fix un...
2308
2309
2310
  			if ((err = device_create_file(dev,
  					&sda_fan_input[i].dev_attr))
  				|| (err = device_create_file(dev,
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
2311
  					&sda_fan_alarm[i].dev_attr)))
c18beb5b9   David Hubbard   w83627ehf: Fix un...
2312
  				goto exit_remove;
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
  			if (sio_data->kind != nct6776) {
  				err = device_create_file(dev,
  						&sda_fan_div[i].dev_attr);
  				if (err)
  					goto exit_remove;
  			}
  			if (data->has_fan_min & (1 << i)) {
  				err = device_create_file(dev,
  						&sda_fan_min[i].dev_attr);
  				if (err)
  					goto exit_remove;
  			}
237c8d2f5   Gong Jun   hwmon: (w83627ehf...
2325
  			if (i < data->pwm_num &&
c18beb5b9   David Hubbard   w83627ehf: Fix un...
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
  				((err = device_create_file(dev,
  					&sda_pwm[i].dev_attr))
  				|| (err = device_create_file(dev,
  					&sda_pwm_mode[i].dev_attr))
  				|| (err = device_create_file(dev,
  					&sda_pwm_enable[i].dev_attr))
  				|| (err = device_create_file(dev,
  					&sda_target_temp[i].dev_attr))
  				|| (err = device_create_file(dev,
  					&sda_tolerance[i].dev_attr))))
  				goto exit_remove;
08c79950a   Rudolf Marek   hwmon: Add fan sp...
2337
  		}
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2338
  	}
08c79950a   Rudolf Marek   hwmon: Add fan sp...
2339

d36cf32c9   Guenter Roeck   hwmon: (w83627ehf...
2340
2341
  	for (i = 0; i < NUM_REG_TEMP; i++) {
  		if (!(data->have_temp & (1 << i)))
a157d06d4   Gong Jun   hwmon: (w83627ehf...
2342
  			continue;
d36cf32c9   Guenter Roeck   hwmon: (w83627ehf...
2343
2344
2345
2346
2347
2348
2349
2350
2351
  		err = device_create_file(dev, &sda_temp_input[i].dev_attr);
  		if (err)
  			goto exit_remove;
  		if (data->temp_label) {
  			err = device_create_file(dev,
  						 &sda_temp_label[i].dev_attr);
  			if (err)
  				goto exit_remove;
  		}
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
2352
2353
  		if (i == 2 && data->temp3_val_only)
  			continue;
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
  		if (data->reg_temp_over[i]) {
  			err = device_create_file(dev,
  				&sda_temp_max[i].dev_attr);
  			if (err)
  				goto exit_remove;
  		}
  		if (data->reg_temp_hyst[i]) {
  			err = device_create_file(dev,
  				&sda_temp_max_hyst[i].dev_attr);
  			if (err)
  				goto exit_remove;
  		}
d36cf32c9   Guenter Roeck   hwmon: (w83627ehf...
2366
  		if (i > 2)
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
2367
2368
  			continue;
  		if ((err = device_create_file(dev,
a157d06d4   Gong Jun   hwmon: (w83627ehf...
2369
2370
2371
  				&sda_temp_alarm[i].dev_attr))
  			|| (err = device_create_file(dev,
  				&sda_temp_type[i].dev_attr)))
c18beb5b9   David Hubbard   w83627ehf: Fix un...
2372
  			goto exit_remove;
a157d06d4   Gong Jun   hwmon: (w83627ehf...
2373
  	}
c18beb5b9   David Hubbard   w83627ehf: Fix un...
2374

363a12a49   Dmitry Artamonow   hwmon: (w83627ehf...
2375
2376
2377
2378
2379
2380
2381
2382
2383
  	err = device_create_file(dev, &sda_caseopen[0].dev_attr);
  	if (err)
  		goto exit_remove;
  
  	if (sio_data->kind == nct6776) {
  		err = device_create_file(dev, &sda_caseopen[1].dev_attr);
  		if (err)
  			goto exit_remove;
  	}
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2384
2385
2386
  	err = device_create_file(dev, &dev_attr_name);
  	if (err)
  		goto exit_remove;
1beeffe43   Tony Jones   hwmon: Convert fr...
2387
2388
2389
  	data->hwmon_dev = hwmon_device_register(dev);
  	if (IS_ERR(data->hwmon_dev)) {
  		err = PTR_ERR(data->hwmon_dev);
c18beb5b9   David Hubbard   w83627ehf: Fix un...
2390
2391
  		goto exit_remove;
  	}
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2392
2393
  
  	return 0;
c18beb5b9   David Hubbard   w83627ehf: Fix un...
2394
2395
  exit_remove:
  	w83627ehf_device_remove_files(dev);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2396
  	kfree(data);
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2397
  	platform_set_drvdata(pdev, NULL);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2398
  exit_release:
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2399
  	release_region(res->start, IOREGION_LENGTH);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2400
2401
2402
  exit:
  	return err;
  }
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2403
  static int __devexit w83627ehf_remove(struct platform_device *pdev)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2404
  {
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2405
  	struct w83627ehf_data *data = platform_get_drvdata(pdev);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2406

1beeffe43   Tony Jones   hwmon: Convert fr...
2407
  	hwmon_device_unregister(data->hwmon_dev);
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2408
2409
2410
  	w83627ehf_device_remove_files(&pdev->dev);
  	release_region(data->addr, IOREGION_LENGTH);
  	platform_set_drvdata(pdev, NULL);
943b0830c   Mark M. Hoffman   [PATCH] I2C hwmon...
2411
  	kfree(data);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2412
2413
2414
  
  	return 0;
  }
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2415
  static struct platform_driver w83627ehf_driver = {
cdaf79349   Laurent Riffard   [PATCH] i2c: Drop...
2416
  	.driver = {
872188420   Jean Delvare   i2c-isa: Restore ...
2417
  		.owner	= THIS_MODULE,
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2418
  		.name	= DRVNAME,
cdaf79349   Laurent Riffard   [PATCH] i2c: Drop...
2419
  	},
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2420
2421
  	.probe		= w83627ehf_probe,
  	.remove		= __devexit_p(w83627ehf_remove),
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2422
  };
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2423
2424
2425
  /* w83627ehf_find() looks for a '627 in the Super-I/O config space */
  static int __init w83627ehf_find(int sioaddr, unsigned short *addr,
  				 struct w83627ehf_sio_data *sio_data)
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2426
  {
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2427
2428
2429
  	static const char __initdata sio_name_W83627EHF[] = "W83627EHF";
  	static const char __initdata sio_name_W83627EHG[] = "W83627EHG";
  	static const char __initdata sio_name_W83627DHG[] = "W83627DHG";
c1e48dce0   Jean Delvare   hwmon: (w83627ehf...
2430
  	static const char __initdata sio_name_W83627DHG_P[] = "W83627DHG-P";
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
2431
  	static const char __initdata sio_name_W83627UHG[] = "W83627UHG";
237c8d2f5   Gong Jun   hwmon: (w83627ehf...
2432
  	static const char __initdata sio_name_W83667HG[] = "W83667HG";
c39aedafb   Guenter Roeck   hwmon: (w83627ehf...
2433
  	static const char __initdata sio_name_W83667HG_B[] = "W83667HG-B";
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
2434
2435
  	static const char __initdata sio_name_NCT6775[] = "NCT6775F";
  	static const char __initdata sio_name_NCT6776[] = "NCT6776F";
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2436

08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2437
  	u16 val;
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2438
  	const char *sio_name;
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2439

1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2440
  	superio_enter(sioaddr);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2441

67b671bce   Jean Delvare   hwmon: Let the us...
2442
2443
2444
2445
2446
  	if (force_id)
  		val = force_id;
  	else
  		val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8)
  		    | superio_inb(sioaddr, SIO_REG_DEVID + 1);
657c93b10   David Hubbard   hwmon/w83627ehf: ...
2447
  	switch (val & SIO_ID_MASK) {
657c93b10   David Hubbard   hwmon/w83627ehf: ...
2448
  	case SIO_W83627EHF_ID:
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2449
2450
2451
  		sio_data->kind = w83627ehf;
  		sio_name = sio_name_W83627EHF;
  		break;
657c93b10   David Hubbard   hwmon/w83627ehf: ...
2452
  	case SIO_W83627EHG_ID:
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2453
2454
2455
2456
2457
2458
  		sio_data->kind = w83627ehf;
  		sio_name = sio_name_W83627EHG;
  		break;
  	case SIO_W83627DHG_ID:
  		sio_data->kind = w83627dhg;
  		sio_name = sio_name_W83627DHG;
657c93b10   David Hubbard   hwmon/w83627ehf: ...
2459
  		break;
c1e48dce0   Jean Delvare   hwmon: (w83627ehf...
2460
2461
2462
2463
  	case SIO_W83627DHG_P_ID:
  		sio_data->kind = w83627dhg_p;
  		sio_name = sio_name_W83627DHG_P;
  		break;
eff7687d4   Jean Delvare   hwmon: (w83627ehf...
2464
2465
2466
2467
  	case SIO_W83627UHG_ID:
  		sio_data->kind = w83627uhg;
  		sio_name = sio_name_W83627UHG;
  		break;
237c8d2f5   Gong Jun   hwmon: (w83627ehf...
2468
2469
2470
2471
  	case SIO_W83667HG_ID:
  		sio_data->kind = w83667hg;
  		sio_name = sio_name_W83667HG;
  		break;
c39aedafb   Guenter Roeck   hwmon: (w83627ehf...
2472
2473
2474
2475
  	case SIO_W83667HG_B_ID:
  		sio_data->kind = w83667hg_b;
  		sio_name = sio_name_W83667HG_B;
  		break;
ec3e5a164   Guenter Roeck   hwmon: (w83627ehf...
2476
2477
2478
2479
2480
2481
2482
2483
  	case SIO_NCT6775_ID:
  		sio_data->kind = nct6775;
  		sio_name = sio_name_NCT6775;
  		break;
  	case SIO_NCT6776_ID:
  		sio_data->kind = nct6776;
  		sio_name = sio_name_NCT6776;
  		break;
657c93b10   David Hubbard   hwmon/w83627ehf: ...
2484
  	default:
9f66036b4   Jean Delvare   hwmon/w83627ehf: ...
2485
  		if (val != 0xffff)
abdc6fd18   Joe Perches   hwmon: (w83627ehf...
2486
2487
  			pr_debug("unsupported chip ID: 0x%04x
  ", val);
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2488
  		superio_exit(sioaddr);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2489
2490
  		return -ENODEV;
  	}
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2491
2492
2493
2494
  	/* We have a known chip, find the HWM I/O address */
  	superio_select(sioaddr, W83627EHF_LD_HWM);
  	val = (superio_inb(sioaddr, SIO_REG_ADDR) << 8)
  	    | superio_inb(sioaddr, SIO_REG_ADDR + 1);
1a641fceb   Jean Delvare   hwmon/w83627ehf: ...
2495
  	*addr = val & IOREGION_ALIGNMENT;
2d8672c5a   Jean Delvare   [PATCH] I2C: Sepa...
2496
  	if (*addr == 0) {
abdc6fd18   Joe Perches   hwmon: (w83627ehf...
2497
2498
  		pr_err("Refusing to enable a Super-I/O device with a base I/O port 0
  ");
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2499
  		superio_exit(sioaddr);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2500
2501
2502
2503
  		return -ENODEV;
  	}
  
  	/* Activate logical device if needed */
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2504
  	val = superio_inb(sioaddr, SIO_REG_ENABLE);
475ef8551   David Hubbard   hwmon/w83627ehf: ...
2505
  	if (!(val & 0x01)) {
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
2506
2507
2508
  		pr_warn("Forcibly enabling Super-I/O. "
  			"Sensor is probably unusable.
  ");
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2509
  		superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01);
475ef8551   David Hubbard   hwmon/w83627ehf: ...
2510
  	}
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2511
2512
  
  	superio_exit(sioaddr);
abdc6fd18   Joe Perches   hwmon: (w83627ehf...
2513
2514
  	pr_info("Found %s chip at %#x
  ", sio_name, *addr);
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2515
  	sio_data->sioreg = sioaddr;
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2516

08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2517
2518
  	return 0;
  }
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2519
2520
2521
2522
2523
  /* when Super-I/O functions move to a separate file, the Super-I/O
   * bus will manage the lifetime of the device and this module will only keep
   * track of the w83627ehf driver. But since we platform_device_alloc(), we
   * must keep track of the device */
  static struct platform_device *pdev;
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2524
2525
  static int __init sensors_w83627ehf_init(void)
  {
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
  	int err;
  	unsigned short address;
  	struct resource res;
  	struct w83627ehf_sio_data sio_data;
  
  	/* initialize sio_data->kind and sio_data->sioreg.
  	 *
  	 * when Super-I/O functions move to a separate file, the Super-I/O
  	 * driver will probe 0x2e and 0x4e and auto-detect the presence of a
  	 * w83627ehf hardware monitor, and call probe() */
  	if (w83627ehf_find(0x2e, &address, &sio_data) &&
  	    w83627ehf_find(0x4e, &address, &sio_data))
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2538
  		return -ENODEV;
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2539
2540
2541
  	err = platform_driver_register(&w83627ehf_driver);
  	if (err)
  		goto exit;
e7e1ca6ef   Guenter Roeck   hwmon: (w83627ehf...
2542
2543
  	pdev = platform_device_alloc(DRVNAME, address);
  	if (!pdev) {
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2544
  		err = -ENOMEM;
abdc6fd18   Joe Perches   hwmon: (w83627ehf...
2545
2546
  		pr_err("Device allocation failed
  ");
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2547
2548
2549
2550
2551
2552
  		goto exit_unregister;
  	}
  
  	err = platform_device_add_data(pdev, &sio_data,
  				       sizeof(struct w83627ehf_sio_data));
  	if (err) {
abdc6fd18   Joe Perches   hwmon: (w83627ehf...
2553
2554
  		pr_err("Platform data allocation failed
  ");
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2555
2556
2557
2558
2559
2560
2561
2562
  		goto exit_device_put;
  	}
  
  	memset(&res, 0, sizeof(res));
  	res.name = DRVNAME;
  	res.start = address + IOREGION_OFFSET;
  	res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
  	res.flags = IORESOURCE_IO;
b9acb64a3   Jean Delvare   hwmon: Check for ...
2563
2564
2565
  
  	err = acpi_check_resource_conflict(&res);
  	if (err)
18632f84f   Hans de Goede   hwmon: Fix ACPI r...
2566
  		goto exit_device_put;
b9acb64a3   Jean Delvare   hwmon: Check for ...
2567

1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2568
2569
  	err = platform_device_add_resources(pdev, &res, 1);
  	if (err) {
abdc6fd18   Joe Perches   hwmon: (w83627ehf...
2570
2571
  		pr_err("Device resource addition failed (%d)
  ", err);
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2572
2573
2574
2575
2576
2577
  		goto exit_device_put;
  	}
  
  	/* platform_device_add calls probe() */
  	err = platform_device_add(pdev);
  	if (err) {
abdc6fd18   Joe Perches   hwmon: (w83627ehf...
2578
2579
  		pr_err("Device addition failed (%d)
  ", err);
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
  		goto exit_device_put;
  	}
  
  	return 0;
  
  exit_device_put:
  	platform_device_put(pdev);
  exit_unregister:
  	platform_driver_unregister(&w83627ehf_driver);
  exit:
  	return err;
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2591
2592
2593
2594
  }
  
  static void __exit sensors_w83627ehf_exit(void)
  {
1ea6dd384   David Hubbard   hwmon/w83627ehf: ...
2595
2596
  	platform_device_unregister(pdev);
  	platform_driver_unregister(&w83627ehf_driver);
08e7e2789   Jean Delvare   [PATCH] I2C: New ...
2597
2598
2599
2600
2601
2602
2603
2604
  }
  
  MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
  MODULE_DESCRIPTION("W83627EHF driver");
  MODULE_LICENSE("GPL");
  
  module_init(sensors_w83627ehf_init);
  module_exit(sensors_w83627ehf_exit);