Blame view

drivers/hwmon/w83627hf.c 55.6 KB
74ba9207e   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
  /*
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
3
4
5
6
7
8
   * w83627hf.c - Part of lm_sensors, Linux kernel modules for hardware
   *		monitoring
   * Copyright (c) 1998 - 2003  Frodo Looijaard <frodol@dds.nl>,
   *			      Philip Edelbrock <phil@netroedge.com>,
   *			      and Mark Studebaker <mdsxyz123@yahoo.com>
   * Ported to 2.6 by Bernhard C. Schrenk <clemy@clemy.org>
7c81c60f3   Jean Delvare   Update Jean Delva...
9
   * Copyright (c) 2007 - 1012  Jean Delvare <jdelvare@suse.de>
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
10
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
11
12
  
  /*
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
13
14
   * Supports following chips:
   *
4101ece3a   Jean Delvare   hwmon: Fix chip f...
15
   * Chip		#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
16
17
18
19
20
21
22
23
24
25
26
27
   * w83627hf	9	3	2	3	0x20	0x5ca3	no	yes(LPC)
   * w83627thf	7	3	3	3	0x90	0x5ca3	no	yes(LPC)
   * w83637hf	7	3	3	3	0x80	0x5ca3	no	yes(LPC)
   * w83687thf	7	3	3	3	0x90	0x5ca3	no	yes(LPC)
   * w83697hf	8	2	2	2	0x60	0x5ca3	no	yes(LPC)
   *
   * For other winbond chips, and for i2c support in the above chips,
   * use w83781d.c.
   *
   * Note: automatic ("cruise") fan control for 697, 637 & 627thf not
   * supported yet.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28

18de030f1   Joe Perches   hwmon: (w83627hf)...
29
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
31
32
33
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/slab.h>
  #include <linux/jiffies.h>
787c72b10   Jean Delvare   hwmon/w83627hf: C...
34
  #include <linux/platform_device.h>
943b0830c   Mark M. Hoffman   [PATCH] I2C hwmon...
35
  #include <linux/hwmon.h>
07584c762   Jim Cromie   hwmon: (w83627hf)...
36
  #include <linux/hwmon-sysfs.h>
303760b44   Jean Delvare   [PATCH] hwmon: hw...
37
  #include <linux/hwmon-vid.h>
943b0830c   Mark M. Hoffman   [PATCH] I2C hwmon...
38
  #include <linux/err.h>
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
39
  #include <linux/mutex.h>
d27c37c0b   Jean Delvare   hwmon/w83627hf: P...
40
  #include <linux/ioport.h>
b9acb64a3   Jean Delvare   hwmon: Check for ...
41
  #include <linux/acpi.h>
6055fae8a   H Hartley Sweeten   hwmon: Include <l...
42
  #include <linux/io.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43
  #include "lm75.h"
787c72b10   Jean Delvare   hwmon/w83627hf: C...
44
  static struct platform_device *pdev;
d27c37c0b   Jean Delvare   hwmon/w83627hf: P...
45
46
47
  
  #define DRVNAME "w83627hf"
  enum chips { w83627hf, w83627thf, w83697hf, w83637hf, w83687thf };
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
48
49
50
51
  struct w83627hf_sio_data {
  	enum chips type;
  	int sioaddr;
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
52
53
54
55
  static u8 force_i2c = 0x1f;
  module_param(force_i2c, byte, 0);
  MODULE_PARM_DESC(force_i2c,
  		 "Initialize the i2c address of the sensors");
90ab5ee94   Rusty Russell   module_param: mak...
56
  static bool init = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
58
  module_param(init, bool, 0);
  MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization");
67b671bce   Jean Delvare   hwmon: Let the us...
59
60
61
  static unsigned short force_id;
  module_param(force_id, ushort, 0);
  MODULE_PARM_DESC(force_id, "Override the detected device ID");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
62
  /* modified from kernel/include/traps.c */
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
63
  #define DEV			0x07 /* Register: Logical device select */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
  
  /* logical device numbers for superio_select (below) */
  #define W83627HF_LD_FDC		0x00
  #define W83627HF_LD_PRT		0x01
  #define W83627HF_LD_UART1	0x02
  #define W83627HF_LD_UART2	0x03
  #define W83627HF_LD_KBC		0x05
  #define W83627HF_LD_CIR		0x06 /* w83627hf only */
  #define W83627HF_LD_GAME	0x07
  #define W83627HF_LD_MIDI	0x07
  #define W83627HF_LD_GPIO1	0x07
  #define W83627HF_LD_GPIO5	0x07 /* w83627thf only */
  #define W83627HF_LD_GPIO2	0x08
  #define W83627HF_LD_GPIO3	0x09
  #define W83627HF_LD_GPIO4	0x09 /* w83627thf only */
  #define W83627HF_LD_ACPI	0x0a
  #define W83627HF_LD_HWM		0x0b
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
81
  #define DEVID			0x20 /* Register: Device ID */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
82
83
84
85
  
  #define W83627THF_GPIO5_EN	0x30 /* w83627thf only */
  #define W83627THF_GPIO5_IOSR	0xf3 /* w83627thf only */
  #define W83627THF_GPIO5_DR	0xf4 /* w83627thf only */
c2db6ce14   Jean Delvare   [PATCH] hwmon: Ad...
86
87
88
  #define W83687THF_VID_EN	0x29 /* w83687thf only */
  #define W83687THF_VID_CFG	0xF0 /* w83687thf only */
  #define W83687THF_VID_DATA	0xF1 /* w83687thf only */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
89
  static inline void
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
90
  superio_outb(struct w83627hf_sio_data *sio, int reg, int val)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
91
  {
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
92
93
  	outb(reg, sio->sioaddr);
  	outb(val, sio->sioaddr + 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
95
96
  }
  
  static inline int
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
97
  superio_inb(struct w83627hf_sio_data *sio, int reg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
98
  {
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
99
100
  	outb(reg, sio->sioaddr);
  	return inb(sio->sioaddr + 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
102
103
  }
  
  static inline void
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
104
  superio_select(struct w83627hf_sio_data *sio, int ld)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
105
  {
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
106
107
  	outb(DEV, sio->sioaddr);
  	outb(ld,  sio->sioaddr + 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
108
  }
e95fd518d   Guenter Roeck   hwmon: (w83627hf)...
109
  static inline int
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
110
  superio_enter(struct w83627hf_sio_data *sio)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
111
  {
e95fd518d   Guenter Roeck   hwmon: (w83627hf)...
112
113
  	if (!request_muxed_region(sio->sioaddr, 2, DRVNAME))
  		return -EBUSY;
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
114
115
  	outb(0x87, sio->sioaddr);
  	outb(0x87, sio->sioaddr);
e95fd518d   Guenter Roeck   hwmon: (w83627hf)...
116
117
  
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
118
119
120
  }
  
  static inline void
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
121
  superio_exit(struct w83627hf_sio_data *sio)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
122
  {
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
123
  	outb(0xAA, sio->sioaddr);
e95fd518d   Guenter Roeck   hwmon: (w83627hf)...
124
  	release_region(sio->sioaddr, 2);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
125
126
127
128
129
130
  }
  
  #define W627_DEVID 0x52
  #define W627THF_DEVID 0x82
  #define W697_DEVID 0x60
  #define W637_DEVID 0x70
c2db6ce14   Jean Delvare   [PATCH] hwmon: Ad...
131
  #define W687THF_DEVID 0x85
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
132
133
134
  #define WINB_ACT_REG 0x30
  #define WINB_BASE_REG 0x60
  /* Constants specified below */
ada0c2f8f   Petr Vandrovec   [PATCH] hwmon: Fi...
135
136
  /* Alignment of the base address */
  #define WINB_ALIGNMENT		~7
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
137

ada0c2f8f   Petr Vandrovec   [PATCH] hwmon: Fi...
138
139
140
  /* Offset & size of I/O region we are interested in */
  #define WINB_REGION_OFFSET	5
  #define WINB_REGION_SIZE	2
787c72b10   Jean Delvare   hwmon/w83627hf: C...
141
142
143
  /* Where are the sensors address/data registers relative to the region offset */
  #define W83781D_ADDR_REG_OFFSET 0
  #define W83781D_DATA_REG_OFFSET 1
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
144
145
146
147
148
149
150
151
152
  
  /* The W83781D registers */
  /* The W83782D registers for nr=7,8 are in bank 5 */
  #define W83781D_REG_IN_MAX(nr) ((nr < 7) ? (0x2b + (nr) * 2) : \
  					   (0x554 + (((nr) - 7) * 2)))
  #define W83781D_REG_IN_MIN(nr) ((nr < 7) ? (0x2c + (nr) * 2) : \
  					   (0x555 + (((nr) - 7) * 2)))
  #define W83781D_REG_IN(nr)     ((nr < 7) ? (0x20 + (nr)) : \
  					   (0x550 + (nr) - 7))
2ca2fcd12   Jim Cromie   hwmon: (w83627hf)...
153
154
155
  /* nr:0-2 for fans:1-3 */
  #define W83627HF_REG_FAN_MIN(nr)	(0x3b + (nr))
  #define W83627HF_REG_FAN(nr)		(0x28 + (nr))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156

df48ed804   Jim Cromie   hwmon: (w83627hf)...
157
158
159
160
161
162
  #define W83627HF_REG_TEMP2_CONFIG 0x152
  #define W83627HF_REG_TEMP3_CONFIG 0x252
  /* these are zero-based, unlike config constants above */
  static const u16 w83627hf_reg_temp[]		= { 0x27, 0x150, 0x250 };
  static const u16 w83627hf_reg_temp_hyst[]	= { 0x3A, 0x153, 0x253 };
  static const u16 w83627hf_reg_temp_over[]	= { 0x39, 0x155, 0x255 };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
163
164
165
166
  
  #define W83781D_REG_BANK 0x4E
  
  #define W83781D_REG_CONFIG 0x40
4a1c4447e   Yuan Mu   [PATCH] hwmon: Fi...
167
168
169
  #define W83781D_REG_ALARM1 0x459
  #define W83781D_REG_ALARM2 0x45A
  #define W83781D_REG_ALARM3 0x45B
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
170

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
  #define W83781D_REG_BEEP_CONFIG 0x4D
  #define W83781D_REG_BEEP_INTS1 0x56
  #define W83781D_REG_BEEP_INTS2 0x57
  #define W83781D_REG_BEEP_INTS3 0x453
  
  #define W83781D_REG_VID_FANDIV 0x47
  
  #define W83781D_REG_CHIPID 0x49
  #define W83781D_REG_WCHIPID 0x58
  #define W83781D_REG_CHIPMAN 0x4F
  #define W83781D_REG_PIN 0x4B
  
  #define W83781D_REG_VBAT 0x5D
  
  #define W83627HF_REG_PWM1 0x5A
  #define W83627HF_REG_PWM2 0x5B
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
187

a95a5ed85   Dominik Geyer   hwmon: (w83627hf)...
188
189
190
191
192
193
  static const u8 W83627THF_REG_PWM_ENABLE[] = {
  	0x04,		/* FAN 1 mode */
  	0x04,		/* FAN 2 mode */
  	0x12,		/* FAN AUX mode */
  };
  static const u8 W83627THF_PWM_ENABLE_SHIFT[] = { 2, 4, 1 };
c2db6ce14   Jean Delvare   [PATCH] hwmon: Ad...
194
195
196
  #define W83627THF_REG_PWM1		0x01	/* 697HF/637HF/687THF too */
  #define W83627THF_REG_PWM2		0x03	/* 697HF/637HF/687THF too */
  #define W83627THF_REG_PWM3		0x11	/* 637HF/687THF too */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
197

c2db6ce14   Jean Delvare   [PATCH] hwmon: Ad...
198
  #define W83627THF_REG_VRM_OVT_CFG 	0x18	/* 637HF/687THF too */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
199
200
201
202
203
  
  static const u8 regpwm_627hf[] = { W83627HF_REG_PWM1, W83627HF_REG_PWM2 };
  static const u8 regpwm[] = { W83627THF_REG_PWM1, W83627THF_REG_PWM2,
                               W83627THF_REG_PWM3 };
  #define W836X7HF_REG_PWM(type, nr) (((type) == w83627hf) ? \
07584c762   Jim Cromie   hwmon: (w83627hf)...
204
  				    regpwm_627hf[nr] : regpwm[nr])
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
205

1550cb6d7   Carlos Olalla Martinez   hwmon/w83627hf: A...
206
207
208
209
210
211
212
213
214
215
216
  #define W83627HF_REG_PWM_FREQ		0x5C	/* Only for the 627HF */
  
  #define W83637HF_REG_PWM_FREQ1		0x00	/* 697HF/687THF too */
  #define W83637HF_REG_PWM_FREQ2		0x02	/* 697HF/687THF too */
  #define W83637HF_REG_PWM_FREQ3		0x10	/* 687THF too */
  
  static const u8 W83637HF_REG_PWM_FREQ[] = { W83637HF_REG_PWM_FREQ1,
  					W83637HF_REG_PWM_FREQ2,
  					W83637HF_REG_PWM_FREQ3 };
  
  #define W83627HF_BASE_PWM_FREQ	46870
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
217
218
219
220
221
222
223
224
225
  #define W83781D_REG_I2C_ADDR 0x48
  #define W83781D_REG_I2C_SUBADDR 0x4A
  
  /* Sensor selection */
  #define W83781D_REG_SCFG1 0x5D
  static const u8 BIT_SCFG1[] = { 0x02, 0x04, 0x08 };
  #define W83781D_REG_SCFG2 0x59
  static const u8 BIT_SCFG2[] = { 0x10, 0x20, 0x40 };
  #define W83781D_DEFAULT_BETA 3435
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
226
227
228
229
230
231
  /*
   * Conversions. Limit checking is only done on the TO_REG
   * variants. Note that you should be a bit careful with which arguments
   * these macros are called: arguments may be evaluated more than once.
   * Fixing this is just not worth it.
   */
2a844c148   Guenter Roeck   hwmon: Replace SE...
232
  #define IN_TO_REG(val)  (clamp_val((((val) + 8) / 16), 0, 255))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
233
234
235
236
237
238
  #define IN_FROM_REG(val) ((val) * 16)
  
  static inline u8 FAN_TO_REG(long rpm, int div)
  {
  	if (rpm == 0)
  		return 255;
2a844c148   Guenter Roeck   hwmon: Replace SE...
239
240
  	rpm = clamp_val(rpm, 1, 1000000);
  	return clamp_val((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
241
242
243
244
  }
  
  #define TEMP_MIN (-128000)
  #define TEMP_MAX ( 127000)
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
245
246
247
248
  /*
   * TEMP: 0.001C/bit (-128C to +127C)
   * REG: 1C/bit, two's complement
   */
5bfedac04   Christian Hohnstaedt   hwmon: Allow writ...
249
  static u8 TEMP_TO_REG(long temp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
250
  {
2a844c148   Guenter Roeck   hwmon: Replace SE...
251
252
253
  	int ntemp = clamp_val(temp, TEMP_MIN, TEMP_MAX);
  	ntemp += (ntemp < 0 ? -500 : 500);
  	return (u8)(ntemp / 1000);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
254
255
256
257
258
259
260
261
  }
  
  static int TEMP_FROM_REG(u8 reg)
  {
          return (s8)reg * 1000;
  }
  
  #define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div)))
2a844c148   Guenter Roeck   hwmon: Replace SE...
262
  #define PWM_TO_REG(val) (clamp_val((val), 0, 255))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
263

1550cb6d7   Carlos Olalla Martinez   hwmon/w83627hf: A...
264
265
266
267
268
269
270
271
272
  static inline unsigned long pwm_freq_from_reg_627hf(u8 reg)
  {
  	unsigned long freq;
  	freq = W83627HF_BASE_PWM_FREQ >> reg;
  	return freq;
  }
  static inline u8 pwm_freq_to_reg_627hf(unsigned long val)
  {
  	u8 i;
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
273
274
275
276
  	/*
  	 * Only 5 dividers (1 2 4 8 16)
  	 * Search for the nearest available frequency
  	 */
1550cb6d7   Carlos Olalla Martinez   hwmon/w83627hf: A...
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
  	for (i = 0; i < 4; i++) {
  		if (val > (((W83627HF_BASE_PWM_FREQ >> i) +
  			    (W83627HF_BASE_PWM_FREQ >> (i+1))) / 2))
  			break;
  	}
  	return i;
  }
  
  static inline unsigned long pwm_freq_from_reg(u8 reg)
  {
  	/* Clock bit 8 -> 180 kHz or 24 MHz */
  	unsigned long clock = (reg & 0x80) ? 180000UL : 24000000UL;
  
  	reg &= 0x7f;
  	/* This should not happen but anyway... */
  	if (reg == 0)
  		reg++;
7fe83ad87   Frans Meulenbroeks   hwmon: remove () ...
294
  	return clock / (reg << 8);
1550cb6d7   Carlos Olalla Martinez   hwmon/w83627hf: A...
295
296
297
298
299
300
301
  }
  static inline u8 pwm_freq_to_reg(unsigned long val)
  {
  	/* Minimum divider value is 0x01 and maximum is 0x7F */
  	if (val >= 93750)	/* The highest we can do */
  		return 0x01;
  	if (val >= 720)	/* Use 24 MHz clock */
7fe83ad87   Frans Meulenbroeks   hwmon: remove () ...
302
  		return 24000000UL / (val << 8);
1550cb6d7   Carlos Olalla Martinez   hwmon/w83627hf: A...
303
304
305
  	if (val < 6)		/* The lowest we can do */
  		return 0xFF;
  	else			/* Use 180 kHz clock */
7fe83ad87   Frans Meulenbroeks   hwmon: remove () ...
306
  		return 0x80 | (180000UL / (val << 8));
1550cb6d7   Carlos Olalla Martinez   hwmon/w83627hf: A...
307
  }
1c1381076   Jean Delvare   hwmon: (w83627hf)...
308
309
  #define BEEP_MASK_FROM_REG(val)		((val) & 0xff7fff)
  #define BEEP_MASK_TO_REG(val)		((val) & 0xff7fff)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
310
311
312
313
314
315
  
  #define DIV_FROM_REG(val) (1 << (val))
  
  static inline u8 DIV_TO_REG(long val)
  {
  	int i;
2a844c148   Guenter Roeck   hwmon: Replace SE...
316
  	val = clamp_val(val, 1, 128) >> 1;
abc019224   Grant Coady   [PATCH] I2C: Sett...
317
  	for (i = 0; i < 7; i++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
318
319
320
321
  		if (val == 0)
  			break;
  		val >>= 1;
  	}
7fe83ad87   Frans Meulenbroeks   hwmon: remove () ...
322
  	return (u8)i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
323
  }
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
324
325
326
327
  /*
   * For each registered chip, we need to keep some data in memory.
   * The structure is dynamically allocated.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
328
  struct w83627hf_data {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
329
330
  	unsigned short addr;
  	const char *name;
1beeffe43   Tony Jones   hwmon: Convert fr...
331
  	struct device *hwmon_dev;
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
332
  	struct mutex lock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
333
  	enum chips type;
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
334
  	struct mutex update_lock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
335
336
  	char valid;		/* !=0 if following fields are valid */
  	unsigned long last_updated;	/* In jiffies */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
337
338
339
340
341
  	u8 in[9];		/* Register value */
  	u8 in_max[9];		/* Register value */
  	u8 in_min[9];		/* Register value */
  	u8 fan[3];		/* Register value */
  	u8 fan_min[3];		/* Register value */
df48ed804   Jim Cromie   hwmon: (w83627hf)...
342
343
344
  	u16 temp[3];		/* Register value */
  	u16 temp_max[3];	/* Register value */
  	u16 temp_max_hyst[3];	/* Register value */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
345
346
347
348
  	u8 fan_div[3];		/* Register encoding, shifted right */
  	u8 vid;			/* Register encoding, combined */
  	u32 alarms;		/* Register encoding, combined */
  	u32 beep_mask;		/* Register encoding, combined */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
349
  	u8 pwm[3];		/* Register value */
a95a5ed85   Dominik Geyer   hwmon: (w83627hf)...
350
  	u8 pwm_enable[3];	/* 1 = manual
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
351
352
353
  				 * 2 = thermal cruise (also called SmartFan I)
  				 * 3 = fan speed cruise
  				 */
1550cb6d7   Carlos Olalla Martinez   hwmon/w83627hf: A...
354
  	u8 pwm_freq[3];		/* Register value */
b26f93309   Jean Delvare   hwmon: Don't expo...
355
  	u16 sens[3];		/* 1 = pentium diode; 2 = 3904 diode;
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
356
357
  				 * 4 = thermistor
  				 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
358
  	u8 vrm;
c2db6ce14   Jean Delvare   [PATCH] hwmon: Ad...
359
  	u8 vrm_ovt;		/* Register value, 627THF/637HF/687THF only */
275b7d6eb   Jean Delvare   hwmon: (w83627hf)...
360
361
362
363
364
365
  
  #ifdef CONFIG_PM
  	/* Remember extra register values over suspend/resume */
  	u8 scfg1;
  	u8 scfg2;
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
366
  };
787c72b10   Jean Delvare   hwmon/w83627hf: C...
367
  static int w83627hf_probe(struct platform_device *pdev);
281dfd0b6   Bill Pemberton   hwmon: remove use...
368
  static int w83627hf_remove(struct platform_device *pdev);
787c72b10   Jean Delvare   hwmon/w83627hf: C...
369
370
371
  
  static int w83627hf_read_value(struct w83627hf_data *data, u16 reg);
  static int w83627hf_write_value(struct w83627hf_data *data, u16 reg, u16 value);
c09c5184a   Jean Delvare   hwmon: (w83627hf)...
372
  static void w83627hf_update_fan_div(struct w83627hf_data *data);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
373
  static struct w83627hf_data *w83627hf_update_device(struct device *dev);
787c72b10   Jean Delvare   hwmon/w83627hf: C...
374
  static void w83627hf_init_device(struct platform_device *pdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
375

275b7d6eb   Jean Delvare   hwmon: (w83627hf)...
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
  #ifdef CONFIG_PM
  static int w83627hf_suspend(struct device *dev)
  {
  	struct w83627hf_data *data = w83627hf_update_device(dev);
  
  	mutex_lock(&data->update_lock);
  	data->scfg1 = w83627hf_read_value(data, W83781D_REG_SCFG1);
  	data->scfg2 = w83627hf_read_value(data, W83781D_REG_SCFG2);
  	mutex_unlock(&data->update_lock);
  
  	return 0;
  }
  
  static int w83627hf_resume(struct device *dev)
  {
  	struct w83627hf_data *data = dev_get_drvdata(dev);
  	int i, num_temps = (data->type == w83697hf) ? 2 : 3;
  
  	/* Restore limits */
  	mutex_lock(&data->update_lock);
  	for (i = 0; i <= 8; i++) {
  		/* skip missing sensors */
  		if (((data->type == w83697hf) && (i == 1)) ||
  		    ((data->type != w83627hf && data->type != w83697hf)
  		    && (i == 5 || i == 6)))
  			continue;
  		w83627hf_write_value(data, W83781D_REG_IN_MAX(i),
  				     data->in_max[i]);
  		w83627hf_write_value(data, W83781D_REG_IN_MIN(i),
  				     data->in_min[i]);
  	}
  	for (i = 0; i <= 2; i++)
  		w83627hf_write_value(data, W83627HF_REG_FAN_MIN(i),
  				     data->fan_min[i]);
  	for (i = 0; i < num_temps; i++) {
  		w83627hf_write_value(data, w83627hf_reg_temp_over[i],
  				     data->temp_max[i]);
  		w83627hf_write_value(data, w83627hf_reg_temp_hyst[i],
  				     data->temp_max_hyst[i]);
  	}
  
  	/* Fixup BIOS bugs */
  	if (data->type == w83627thf || data->type == w83637hf ||
  	    data->type == w83687thf)
  		w83627hf_write_value(data, W83627THF_REG_VRM_OVT_CFG,
  				     data->vrm_ovt);
  	w83627hf_write_value(data, W83781D_REG_SCFG1, data->scfg1);
  	w83627hf_write_value(data, W83781D_REG_SCFG2, data->scfg2);
  
  	/* Force re-reading all values */
  	data->valid = 0;
  	mutex_unlock(&data->update_lock);
  
  	return 0;
  }
  
  static const struct dev_pm_ops w83627hf_dev_pm_ops = {
  	.suspend = w83627hf_suspend,
  	.resume = w83627hf_resume,
  };
  
  #define W83627HF_DEV_PM_OPS	(&w83627hf_dev_pm_ops)
  #else
  #define W83627HF_DEV_PM_OPS	NULL
  #endif /* CONFIG_PM */
787c72b10   Jean Delvare   hwmon/w83627hf: C...
441
  static struct platform_driver w83627hf_driver = {
cdaf79349   Laurent Riffard   [PATCH] i2c: Drop...
442
  	.driver = {
d27c37c0b   Jean Delvare   hwmon/w83627hf: P...
443
  		.name	= DRVNAME,
275b7d6eb   Jean Delvare   hwmon: (w83627hf)...
444
  		.pm	= W83627HF_DEV_PM_OPS,
cdaf79349   Laurent Riffard   [PATCH] i2c: Drop...
445
  	},
787c72b10   Jean Delvare   hwmon/w83627hf: C...
446
  	.probe		= w83627hf_probe,
9e5e9b7a9   Bill Pemberton   hwmon: remove use...
447
  	.remove		= w83627hf_remove,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
448
  };
07584c762   Jim Cromie   hwmon: (w83627hf)...
449
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
450
  in_input_show(struct device *dev, struct device_attribute *devattr, char *buf)
07584c762   Jim Cromie   hwmon: (w83627hf)...
451
452
453
454
455
  {
  	int nr = to_sensor_dev_attr(devattr)->index;
  	struct w83627hf_data *data = w83627hf_update_device(dev);
  	return sprintf(buf, "%ld
  ", (long)IN_FROM_REG(data->in[nr]));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
456
  }
07584c762   Jim Cromie   hwmon: (w83627hf)...
457
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
458
  in_min_show(struct device *dev, struct device_attribute *devattr, char *buf)
07584c762   Jim Cromie   hwmon: (w83627hf)...
459
460
461
462
463
464
465
  {
  	int nr = to_sensor_dev_attr(devattr)->index;
  	struct w83627hf_data *data = w83627hf_update_device(dev);
  	return sprintf(buf, "%ld
  ", (long)IN_FROM_REG(data->in_min[nr]));
  }
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
466
  in_max_show(struct device *dev, struct device_attribute *devattr, char *buf)
07584c762   Jim Cromie   hwmon: (w83627hf)...
467
468
469
470
471
  {
  	int nr = to_sensor_dev_attr(devattr)->index;
  	struct w83627hf_data *data = w83627hf_update_device(dev);
  	return sprintf(buf, "%ld
  ", (long)IN_FROM_REG(data->in_max[nr]));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
472
  }
07584c762   Jim Cromie   hwmon: (w83627hf)...
473
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
474
  in_min_store(struct device *dev, struct device_attribute *devattr,
07584c762   Jim Cromie   hwmon: (w83627hf)...
475
476
477
478
  	     const char *buf, size_t count)
  {
  	int nr = to_sensor_dev_attr(devattr)->index;
  	struct w83627hf_data *data = dev_get_drvdata(dev);
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
479
480
481
482
483
484
  	long val;
  	int err;
  
  	err = kstrtol(buf, 10, &val);
  	if (err)
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
485

07584c762   Jim Cromie   hwmon: (w83627hf)...
486
487
488
489
490
491
492
  	mutex_lock(&data->update_lock);
  	data->in_min[nr] = IN_TO_REG(val);
  	w83627hf_write_value(data, W83781D_REG_IN_MIN(nr), data->in_min[nr]);
  	mutex_unlock(&data->update_lock);
  	return count;
  }
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
493
  in_max_store(struct device *dev, struct device_attribute *devattr,
07584c762   Jim Cromie   hwmon: (w83627hf)...
494
495
496
497
  	     const char *buf, size_t count)
  {
  	int nr = to_sensor_dev_attr(devattr)->index;
  	struct w83627hf_data *data = dev_get_drvdata(dev);
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
498
499
500
501
502
503
  	long val;
  	int err;
  
  	err = kstrtol(buf, 10, &val);
  	if (err)
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
504

07584c762   Jim Cromie   hwmon: (w83627hf)...
505
506
507
508
509
510
  	mutex_lock(&data->update_lock);
  	data->in_max[nr] = IN_TO_REG(val);
  	w83627hf_write_value(data, W83781D_REG_IN_MAX(nr), data->in_max[nr]);
  	mutex_unlock(&data->update_lock);
  	return count;
  }
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
  
  static SENSOR_DEVICE_ATTR_RO(in1_input, in_input, 1);
  static SENSOR_DEVICE_ATTR_RW(in1_min, in_min, 1);
  static SENSOR_DEVICE_ATTR_RW(in1_max, in_max, 1);
  static SENSOR_DEVICE_ATTR_RO(in2_input, in_input, 2);
  static SENSOR_DEVICE_ATTR_RW(in2_min, in_min, 2);
  static SENSOR_DEVICE_ATTR_RW(in2_max, in_max, 2);
  static SENSOR_DEVICE_ATTR_RO(in3_input, in_input, 3);
  static SENSOR_DEVICE_ATTR_RW(in3_min, in_min, 3);
  static SENSOR_DEVICE_ATTR_RW(in3_max, in_max, 3);
  static SENSOR_DEVICE_ATTR_RO(in4_input, in_input, 4);
  static SENSOR_DEVICE_ATTR_RW(in4_min, in_min, 4);
  static SENSOR_DEVICE_ATTR_RW(in4_max, in_max, 4);
  static SENSOR_DEVICE_ATTR_RO(in5_input, in_input, 5);
  static SENSOR_DEVICE_ATTR_RW(in5_min, in_min, 5);
  static SENSOR_DEVICE_ATTR_RW(in5_max, in_max, 5);
  static SENSOR_DEVICE_ATTR_RO(in6_input, in_input, 6);
  static SENSOR_DEVICE_ATTR_RW(in6_min, in_min, 6);
  static SENSOR_DEVICE_ATTR_RW(in6_max, in_max, 6);
  static SENSOR_DEVICE_ATTR_RO(in7_input, in_input, 7);
  static SENSOR_DEVICE_ATTR_RW(in7_min, in_min, 7);
  static SENSOR_DEVICE_ATTR_RW(in7_max, in_max, 7);
  static SENSOR_DEVICE_ATTR_RO(in8_input, in_input, 8);
  static SENSOR_DEVICE_ATTR_RW(in8_min, in_min, 8);
  static SENSOR_DEVICE_ATTR_RW(in8_max, in_max, 8);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
536
537
538
539
540
541
542
  
  /* use a different set of functions for in0 */
  static ssize_t show_in_0(struct w83627hf_data *data, char *buf, u8 reg)
  {
  	long in0;
  
  	if ((data->vrm_ovt & 0x01) &&
c2db6ce14   Jean Delvare   [PATCH] hwmon: Ad...
543
544
  		(w83627thf == data->type || w83637hf == data->type
  		 || w83687thf == data->type))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
545
546
547
548
549
550
551
552
553
554
  
  		/* use VRM9 calculation */
  		in0 = (long)((reg * 488 + 70000 + 50) / 100);
  	else
  		/* use VRM8 (standard) calculation */
  		in0 = (long)IN_FROM_REG(reg);
  
  	return sprintf(buf,"%ld
  ", in0);
  }
8dfcdfc1e   Julia Lawall   hwmon: (w83627hf)...
555
556
  static ssize_t in0_input_show(struct device *dev,
  			      struct device_attribute *attr, char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
557
558
559
560
  {
  	struct w83627hf_data *data = w83627hf_update_device(dev);
  	return show_in_0(data, buf, data->in[0]);
  }
8dfcdfc1e   Julia Lawall   hwmon: (w83627hf)...
561
562
  static ssize_t in0_min_show(struct device *dev, struct device_attribute *attr,
  			    char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
563
564
565
566
  {
  	struct w83627hf_data *data = w83627hf_update_device(dev);
  	return show_in_0(data, buf, data->in_min[0]);
  }
8dfcdfc1e   Julia Lawall   hwmon: (w83627hf)...
567
568
  static ssize_t in0_max_show(struct device *dev, struct device_attribute *attr,
  			    char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
569
570
571
572
  {
  	struct w83627hf_data *data = w83627hf_update_device(dev);
  	return show_in_0(data, buf, data->in_max[0]);
  }
8dfcdfc1e   Julia Lawall   hwmon: (w83627hf)...
573
574
575
  static ssize_t in0_min_store(struct device *dev,
  			     struct device_attribute *attr, const char *buf,
  			     size_t count)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
576
  {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
577
  	struct w83627hf_data *data = dev_get_drvdata(dev);
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
578
579
  	unsigned long val;
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
580

27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
581
582
583
  	err = kstrtoul(buf, 10, &val);
  	if (err)
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
584

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
585
  	mutex_lock(&data->update_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
586
587
  	
  	if ((data->vrm_ovt & 0x01) &&
c2db6ce14   Jean Delvare   [PATCH] hwmon: Ad...
588
589
  		(w83627thf == data->type || w83637hf == data->type
  		 || w83687thf == data->type))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
590
591
  
  		/* use VRM9 calculation */
2723ab91c   Yuan Mu   [PATCH] hwmon: Fi...
592
  		data->in_min[0] =
2a844c148   Guenter Roeck   hwmon: Replace SE...
593
  			clamp_val(((val * 100) - 70000 + 244) / 488, 0, 255);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
594
595
596
  	else
  		/* use VRM8 (standard) calculation */
  		data->in_min[0] = IN_TO_REG(val);
787c72b10   Jean Delvare   hwmon/w83627hf: C...
597
  	w83627hf_write_value(data, W83781D_REG_IN_MIN(0), data->in_min[0]);
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
598
  	mutex_unlock(&data->update_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
599
600
  	return count;
  }
8dfcdfc1e   Julia Lawall   hwmon: (w83627hf)...
601
602
603
  static ssize_t in0_max_store(struct device *dev,
  			     struct device_attribute *attr, const char *buf,
  			     size_t count)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
604
  {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
605
  	struct w83627hf_data *data = dev_get_drvdata(dev);
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
606
607
  	unsigned long val;
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
608

27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
609
610
611
  	err = kstrtoul(buf, 10, &val);
  	if (err)
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
612

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
613
  	mutex_lock(&data->update_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
614
615
  
  	if ((data->vrm_ovt & 0x01) &&
c2db6ce14   Jean Delvare   [PATCH] hwmon: Ad...
616
617
  		(w83627thf == data->type || w83637hf == data->type
  		 || w83687thf == data->type))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
618
619
  		
  		/* use VRM9 calculation */
2723ab91c   Yuan Mu   [PATCH] hwmon: Fi...
620
  		data->in_max[0] =
2a844c148   Guenter Roeck   hwmon: Replace SE...
621
  			clamp_val(((val * 100) - 70000 + 244) / 488, 0, 255);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
622
623
624
  	else
  		/* use VRM8 (standard) calculation */
  		data->in_max[0] = IN_TO_REG(val);
787c72b10   Jean Delvare   hwmon/w83627hf: C...
625
  	w83627hf_write_value(data, W83781D_REG_IN_MAX(0), data->in_max[0]);
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
626
  	mutex_unlock(&data->update_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
627
628
  	return count;
  }
8dfcdfc1e   Julia Lawall   hwmon: (w83627hf)...
629
630
631
  static DEVICE_ATTR_RO(in0_input);
  static DEVICE_ATTR_RW(in0_min);
  static DEVICE_ATTR_RW(in0_max);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
632

07584c762   Jim Cromie   hwmon: (w83627hf)...
633
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
634
635
  fan_input_show(struct device *dev, struct device_attribute *devattr,
  	       char *buf)
07584c762   Jim Cromie   hwmon: (w83627hf)...
636
637
638
639
640
641
642
643
  {
  	int nr = to_sensor_dev_attr(devattr)->index;
  	struct w83627hf_data *data = w83627hf_update_device(dev);
  	return sprintf(buf, "%ld
  ", FAN_FROM_REG(data->fan[nr],
  				(long)DIV_FROM_REG(data->fan_div[nr])));
  }
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
644
  fan_min_show(struct device *dev, struct device_attribute *devattr, char *buf)
07584c762   Jim Cromie   hwmon: (w83627hf)...
645
646
647
648
649
650
  {
  	int nr = to_sensor_dev_attr(devattr)->index;
  	struct w83627hf_data *data = w83627hf_update_device(dev);
  	return sprintf(buf, "%ld
  ", FAN_FROM_REG(data->fan_min[nr],
  				(long)DIV_FROM_REG(data->fan_div[nr])));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
651
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
652
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
653
  fan_min_store(struct device *dev, struct device_attribute *devattr,
07584c762   Jim Cromie   hwmon: (w83627hf)...
654
  	      const char *buf, size_t count)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
655
  {
07584c762   Jim Cromie   hwmon: (w83627hf)...
656
  	int nr = to_sensor_dev_attr(devattr)->index;
787c72b10   Jean Delvare   hwmon/w83627hf: C...
657
  	struct w83627hf_data *data = dev_get_drvdata(dev);
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
658
659
660
661
662
663
  	unsigned long val;
  	int err;
  
  	err = kstrtoul(buf, 10, &val);
  	if (err)
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
664

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
665
  	mutex_lock(&data->update_lock);
07584c762   Jim Cromie   hwmon: (w83627hf)...
666
  	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
2ca2fcd12   Jim Cromie   hwmon: (w83627hf)...
667
  	w83627hf_write_value(data, W83627HF_REG_FAN_MIN(nr),
07584c762   Jim Cromie   hwmon: (w83627hf)...
668
  			     data->fan_min[nr]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
669

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
670
  	mutex_unlock(&data->update_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
671
672
  	return count;
  }
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
673
674
675
676
677
678
  static SENSOR_DEVICE_ATTR_RO(fan1_input, fan_input, 0);
  static SENSOR_DEVICE_ATTR_RW(fan1_min, fan_min, 0);
  static SENSOR_DEVICE_ATTR_RO(fan2_input, fan_input, 1);
  static SENSOR_DEVICE_ATTR_RW(fan2_min, fan_min, 1);
  static SENSOR_DEVICE_ATTR_RO(fan3_input, fan_input, 2);
  static SENSOR_DEVICE_ATTR_RW(fan3_min, fan_min, 2);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
679

07584c762   Jim Cromie   hwmon: (w83627hf)...
680
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
681
  temp_show(struct device *dev, struct device_attribute *devattr, char *buf)
07584c762   Jim Cromie   hwmon: (w83627hf)...
682
683
684
  {
  	int nr = to_sensor_dev_attr(devattr)->index;
  	struct w83627hf_data *data = w83627hf_update_device(dev);
df48ed804   Jim Cromie   hwmon: (w83627hf)...
685
686
687
688
689
  
  	u16 tmp = data->temp[nr];
  	return sprintf(buf, "%ld
  ", (nr) ? (long) LM75_TEMP_FROM_REG(tmp)
  					  : (long) TEMP_FROM_REG(tmp));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
690
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
691

07584c762   Jim Cromie   hwmon: (w83627hf)...
692
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
693
  temp_max_show(struct device *dev, struct device_attribute *devattr, char *buf)
07584c762   Jim Cromie   hwmon: (w83627hf)...
694
695
696
  {
  	int nr = to_sensor_dev_attr(devattr)->index;
  	struct w83627hf_data *data = w83627hf_update_device(dev);
df48ed804   Jim Cromie   hwmon: (w83627hf)...
697
698
699
700
701
  
  	u16 tmp = data->temp_max[nr];
  	return sprintf(buf, "%ld
  ", (nr) ? (long) LM75_TEMP_FROM_REG(tmp)
  					  : (long) TEMP_FROM_REG(tmp));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
702
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
703

07584c762   Jim Cromie   hwmon: (w83627hf)...
704
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
705
  temp_max_hyst_show(struct device *dev, struct device_attribute *devattr,
07584c762   Jim Cromie   hwmon: (w83627hf)...
706
707
708
709
  		   char *buf)
  {
  	int nr = to_sensor_dev_attr(devattr)->index;
  	struct w83627hf_data *data = w83627hf_update_device(dev);
df48ed804   Jim Cromie   hwmon: (w83627hf)...
710
711
712
713
714
  
  	u16 tmp = data->temp_max_hyst[nr];
  	return sprintf(buf, "%ld
  ", (nr) ? (long) LM75_TEMP_FROM_REG(tmp)
  					  : (long) TEMP_FROM_REG(tmp));
07584c762   Jim Cromie   hwmon: (w83627hf)...
715
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
716

07584c762   Jim Cromie   hwmon: (w83627hf)...
717
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
718
  temp_max_store(struct device *dev, struct device_attribute *devattr,
07584c762   Jim Cromie   hwmon: (w83627hf)...
719
720
721
722
  	       const char *buf, size_t count)
  {
  	int nr = to_sensor_dev_attr(devattr)->index;
  	struct w83627hf_data *data = dev_get_drvdata(dev);
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
723
724
725
  	u16 tmp;
  	long val;
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
726

27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
727
728
729
730
731
  	err = kstrtol(buf, 10, &val);
  	if (err)
  		return err;
  
  	tmp = (nr) ? LM75_TEMP_TO_REG(val) : TEMP_TO_REG(val);
07584c762   Jim Cromie   hwmon: (w83627hf)...
732
  	mutex_lock(&data->update_lock);
df48ed804   Jim Cromie   hwmon: (w83627hf)...
733
734
  	data->temp_max[nr] = tmp;
  	w83627hf_write_value(data, w83627hf_reg_temp_over[nr], tmp);
07584c762   Jim Cromie   hwmon: (w83627hf)...
735
736
737
738
739
  	mutex_unlock(&data->update_lock);
  	return count;
  }
  
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
740
  temp_max_hyst_store(struct device *dev, struct device_attribute *devattr,
07584c762   Jim Cromie   hwmon: (w83627hf)...
741
742
743
744
  		    const char *buf, size_t count)
  {
  	int nr = to_sensor_dev_attr(devattr)->index;
  	struct w83627hf_data *data = dev_get_drvdata(dev);
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
745
746
747
748
749
750
751
  	u16 tmp;
  	long val;
  	int err;
  
  	err = kstrtol(buf, 10, &val);
  	if (err)
  		return err;
07584c762   Jim Cromie   hwmon: (w83627hf)...
752

27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
753
  	tmp = (nr) ? LM75_TEMP_TO_REG(val) : TEMP_TO_REG(val);
07584c762   Jim Cromie   hwmon: (w83627hf)...
754
  	mutex_lock(&data->update_lock);
df48ed804   Jim Cromie   hwmon: (w83627hf)...
755
756
  	data->temp_max_hyst[nr] = tmp;
  	w83627hf_write_value(data, w83627hf_reg_temp_hyst[nr], tmp);
07584c762   Jim Cromie   hwmon: (w83627hf)...
757
758
759
  	mutex_unlock(&data->update_lock);
  	return count;
  }
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
760
761
762
763
764
765
766
767
768
  static SENSOR_DEVICE_ATTR_RO(temp1_input, temp, 0);
  static SENSOR_DEVICE_ATTR_RW(temp1_max, temp_max, 0);
  static SENSOR_DEVICE_ATTR_RW(temp1_max_hyst, temp_max_hyst, 0);
  static SENSOR_DEVICE_ATTR_RO(temp2_input, temp, 1);
  static SENSOR_DEVICE_ATTR_RW(temp2_max, temp_max, 1);
  static SENSOR_DEVICE_ATTR_RW(temp2_max_hyst, temp_max_hyst, 1);
  static SENSOR_DEVICE_ATTR_RO(temp3_input, temp, 2);
  static SENSOR_DEVICE_ATTR_RW(temp3_max, temp_max, 2);
  static SENSOR_DEVICE_ATTR_RW(temp3_max_hyst, temp_max_hyst, 2);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
769

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
770
  static ssize_t
8dfcdfc1e   Julia Lawall   hwmon: (w83627hf)...
771
  cpu0_vid_show(struct device *dev, struct device_attribute *attr, char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
772
773
774
775
776
  {
  	struct w83627hf_data *data = w83627hf_update_device(dev);
  	return sprintf(buf, "%ld
  ", (long) vid_from_reg(data->vid, data->vrm));
  }
8dfcdfc1e   Julia Lawall   hwmon: (w83627hf)...
777
  static DEVICE_ATTR_RO(cpu0_vid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
778
779
  
  static ssize_t
8dfcdfc1e   Julia Lawall   hwmon: (w83627hf)...
780
  vrm_show(struct device *dev, struct device_attribute *attr, char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
781
  {
90d6619a9   Jean Delvare   hwmon: VRM is not...
782
  	struct w83627hf_data *data = dev_get_drvdata(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
783
784
785
786
  	return sprintf(buf, "%ld
  ", (long) data->vrm);
  }
  static ssize_t
8dfcdfc1e   Julia Lawall   hwmon: (w83627hf)...
787
788
  vrm_store(struct device *dev, struct device_attribute *attr, const char *buf,
  	  size_t count)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
789
  {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
790
  	struct w83627hf_data *data = dev_get_drvdata(dev);
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
791
792
  	unsigned long val;
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
793

27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
794
795
796
  	err = kstrtoul(buf, 10, &val);
  	if (err)
  		return err;
970255b75   Axel Lin   hwmon: (w83627hf)...
797
798
799
  
  	if (val > 255)
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
800
801
802
803
  	data->vrm = val;
  
  	return count;
  }
8dfcdfc1e   Julia Lawall   hwmon: (w83627hf)...
804
  static DEVICE_ATTR_RW(vrm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
805
806
  
  static ssize_t
8dfcdfc1e   Julia Lawall   hwmon: (w83627hf)...
807
  alarms_show(struct device *dev, struct device_attribute *attr, char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
808
809
810
811
812
  {
  	struct w83627hf_data *data = w83627hf_update_device(dev);
  	return sprintf(buf, "%ld
  ", (long) data->alarms);
  }
8dfcdfc1e   Julia Lawall   hwmon: (w83627hf)...
813
  static DEVICE_ATTR_RO(alarms);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
814

e3604c626   Jean Delvare   hwmon: (w83627hf)...
815
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
816
  alarm_show(struct device *dev, struct device_attribute *attr, char *buf)
e3604c626   Jean Delvare   hwmon: (w83627hf)...
817
818
819
820
821
822
  {
  	struct w83627hf_data *data = w83627hf_update_device(dev);
  	int bitnr = to_sensor_dev_attr(attr)->index;
  	return sprintf(buf, "%u
  ", (data->alarms >> bitnr) & 1);
  }
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
  static SENSOR_DEVICE_ATTR_RO(in0_alarm, alarm, 0);
  static SENSOR_DEVICE_ATTR_RO(in1_alarm, alarm, 1);
  static SENSOR_DEVICE_ATTR_RO(in2_alarm, alarm, 2);
  static SENSOR_DEVICE_ATTR_RO(in3_alarm, alarm, 3);
  static SENSOR_DEVICE_ATTR_RO(in4_alarm, alarm, 8);
  static SENSOR_DEVICE_ATTR_RO(in5_alarm, alarm, 9);
  static SENSOR_DEVICE_ATTR_RO(in6_alarm, alarm, 10);
  static SENSOR_DEVICE_ATTR_RO(in7_alarm, alarm, 16);
  static SENSOR_DEVICE_ATTR_RO(in8_alarm, alarm, 17);
  static SENSOR_DEVICE_ATTR_RO(fan1_alarm, alarm, 6);
  static SENSOR_DEVICE_ATTR_RO(fan2_alarm, alarm, 7);
  static SENSOR_DEVICE_ATTR_RO(fan3_alarm, alarm, 11);
  static SENSOR_DEVICE_ATTR_RO(temp1_alarm, alarm, 4);
  static SENSOR_DEVICE_ATTR_RO(temp2_alarm, alarm, 5);
  static SENSOR_DEVICE_ATTR_RO(temp3_alarm, alarm, 13);
e3604c626   Jean Delvare   hwmon: (w83627hf)...
838

1c1381076   Jean Delvare   hwmon: (w83627hf)...
839
  static ssize_t
8dfcdfc1e   Julia Lawall   hwmon: (w83627hf)...
840
  beep_mask_show(struct device *dev, struct device_attribute *attr, char *buf)
1c1381076   Jean Delvare   hwmon: (w83627hf)...
841
842
843
844
845
  {
  	struct w83627hf_data *data = w83627hf_update_device(dev);
  	return sprintf(buf, "%ld
  ",
  		      (long)BEEP_MASK_FROM_REG(data->beep_mask));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
846
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
847
848
  
  static ssize_t
8dfcdfc1e   Julia Lawall   hwmon: (w83627hf)...
849
  beep_mask_store(struct device *dev, struct device_attribute *attr,
1c1381076   Jean Delvare   hwmon: (w83627hf)...
850
  		const char *buf, size_t count)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
851
  {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
852
  	struct w83627hf_data *data = dev_get_drvdata(dev);
1c1381076   Jean Delvare   hwmon: (w83627hf)...
853
  	unsigned long val;
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
854
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
855

27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
856
857
858
  	err = kstrtoul(buf, 10, &val);
  	if (err)
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
859

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
860
  	mutex_lock(&data->update_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
861

1c1381076   Jean Delvare   hwmon: (w83627hf)...
862
863
864
865
866
867
868
  	/* preserve beep enable */
  	data->beep_mask = (data->beep_mask & 0x8000)
  			| BEEP_MASK_TO_REG(val);
  	w83627hf_write_value(data, W83781D_REG_BEEP_INTS1,
  			    data->beep_mask & 0xff);
  	w83627hf_write_value(data, W83781D_REG_BEEP_INTS3,
  			    ((data->beep_mask) >> 16) & 0xff);
787c72b10   Jean Delvare   hwmon/w83627hf: C...
869
  	w83627hf_write_value(data, W83781D_REG_BEEP_INTS2,
1c1381076   Jean Delvare   hwmon: (w83627hf)...
870
  			    (data->beep_mask >> 8) & 0xff);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
871

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
872
  	mutex_unlock(&data->update_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
873
874
  	return count;
  }
8dfcdfc1e   Julia Lawall   hwmon: (w83627hf)...
875
  static DEVICE_ATTR_RW(beep_mask);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
876

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
877
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
878
  beep_show(struct device *dev, struct device_attribute *attr, char *buf)
e3604c626   Jean Delvare   hwmon: (w83627hf)...
879
880
881
882
883
884
885
886
  {
  	struct w83627hf_data *data = w83627hf_update_device(dev);
  	int bitnr = to_sensor_dev_attr(attr)->index;
  	return sprintf(buf, "%u
  ", (data->beep_mask >> bitnr) & 1);
  }
  
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
887
888
  beep_store(struct device *dev, struct device_attribute *attr, const char *buf,
  	   size_t count)
e3604c626   Jean Delvare   hwmon: (w83627hf)...
889
890
891
  {
  	struct w83627hf_data *data = dev_get_drvdata(dev);
  	int bitnr = to_sensor_dev_attr(attr)->index;
e3604c626   Jean Delvare   hwmon: (w83627hf)...
892
  	u8 reg;
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
893
894
895
896
897
898
  	unsigned long bit;
  	int err;
  
  	err = kstrtoul(buf, 10, &bit);
  	if (err)
  		return err;
e3604c626   Jean Delvare   hwmon: (w83627hf)...
899

e3604c626   Jean Delvare   hwmon: (w83627hf)...
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
  	if (bit & ~1)
  		return -EINVAL;
  
  	mutex_lock(&data->update_lock);
  	if (bit)
  		data->beep_mask |= (1 << bitnr);
  	else
  		data->beep_mask &= ~(1 << bitnr);
  
  	if (bitnr < 8) {
  		reg = w83627hf_read_value(data, W83781D_REG_BEEP_INTS1);
  		if (bit)
  			reg |= (1 << bitnr);
  		else
  			reg &= ~(1 << bitnr);
  		w83627hf_write_value(data, W83781D_REG_BEEP_INTS1, reg);
  	} else if (bitnr < 16) {
  		reg = w83627hf_read_value(data, W83781D_REG_BEEP_INTS2);
  		if (bit)
  			reg |= (1 << (bitnr - 8));
  		else
  			reg &= ~(1 << (bitnr - 8));
  		w83627hf_write_value(data, W83781D_REG_BEEP_INTS2, reg);
  	} else {
  		reg = w83627hf_read_value(data, W83781D_REG_BEEP_INTS3);
  		if (bit)
  			reg |= (1 << (bitnr - 16));
  		else
  			reg &= ~(1 << (bitnr - 16));
  		w83627hf_write_value(data, W83781D_REG_BEEP_INTS3, reg);
  	}
  	mutex_unlock(&data->update_lock);
  
  	return count;
  }
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
  static SENSOR_DEVICE_ATTR_RW(in0_beep, beep, 0);
  static SENSOR_DEVICE_ATTR_RW(in1_beep, beep, 1);
  static SENSOR_DEVICE_ATTR_RW(in2_beep, beep, 2);
  static SENSOR_DEVICE_ATTR_RW(in3_beep, beep, 3);
  static SENSOR_DEVICE_ATTR_RW(in4_beep, beep, 8);
  static SENSOR_DEVICE_ATTR_RW(in5_beep, beep, 9);
  static SENSOR_DEVICE_ATTR_RW(in6_beep, beep, 10);
  static SENSOR_DEVICE_ATTR_RW(in7_beep, beep, 16);
  static SENSOR_DEVICE_ATTR_RW(in8_beep, beep, 17);
  static SENSOR_DEVICE_ATTR_RW(fan1_beep, beep, 6);
  static SENSOR_DEVICE_ATTR_RW(fan2_beep, beep, 7);
  static SENSOR_DEVICE_ATTR_RW(fan3_beep, beep, 11);
  static SENSOR_DEVICE_ATTR_RW(temp1_beep, beep, 4);
  static SENSOR_DEVICE_ATTR_RW(temp2_beep, beep, 5);
  static SENSOR_DEVICE_ATTR_RW(temp3_beep, beep, 13);
  static SENSOR_DEVICE_ATTR_RW(beep_enable, beep, 15);
e3604c626   Jean Delvare   hwmon: (w83627hf)...
951
952
  
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
953
  fan_div_show(struct device *dev, struct device_attribute *devattr, char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
954
  {
07584c762   Jim Cromie   hwmon: (w83627hf)...
955
  	int nr = to_sensor_dev_attr(devattr)->index;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
956
957
958
  	struct w83627hf_data *data = w83627hf_update_device(dev);
  	return sprintf(buf, "%ld
  ",
07584c762   Jim Cromie   hwmon: (w83627hf)...
959
  		       (long) DIV_FROM_REG(data->fan_div[nr]));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
960
  }
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
961
962
963
964
965
966
  /*
   * Note: we save and restore the fan minimum here, because its value is
   * determined in part by the fan divisor.  This follows the principle of
   * least surprise; the user doesn't expect the fan minimum to change just
   * because the divisor changed.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
967
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
968
  fan_div_store(struct device *dev, struct device_attribute *devattr,
07584c762   Jim Cromie   hwmon: (w83627hf)...
969
  	      const char *buf, size_t count)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
970
  {
07584c762   Jim Cromie   hwmon: (w83627hf)...
971
  	int nr = to_sensor_dev_attr(devattr)->index;
787c72b10   Jean Delvare   hwmon/w83627hf: C...
972
  	struct w83627hf_data *data = dev_get_drvdata(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
973
974
  	unsigned long min;
  	u8 reg;
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
975
976
977
978
979
980
  	unsigned long val;
  	int err;
  
  	err = kstrtoul(buf, 10, &val);
  	if (err)
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
981

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
982
  	mutex_lock(&data->update_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
983
984
985
986
987
988
  
  	/* Save fan_min */
  	min = FAN_FROM_REG(data->fan_min[nr],
  			   DIV_FROM_REG(data->fan_div[nr]));
  
  	data->fan_div[nr] = DIV_TO_REG(val);
787c72b10   Jean Delvare   hwmon/w83627hf: C...
989
  	reg = (w83627hf_read_value(data, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
990
991
  	       & (nr==0 ? 0xcf : 0x3f))
  	    | ((data->fan_div[nr] & 0x03) << (nr==0 ? 4 : 6));
787c72b10   Jean Delvare   hwmon/w83627hf: C...
992
  	w83627hf_write_value(data, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
993

787c72b10   Jean Delvare   hwmon/w83627hf: C...
994
  	reg = (w83627hf_read_value(data, W83781D_REG_VBAT)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
995
996
  	       & ~(1 << (5 + nr)))
  	    | ((data->fan_div[nr] & 0x04) << (3 + nr));
787c72b10   Jean Delvare   hwmon/w83627hf: C...
997
  	w83627hf_write_value(data, W83781D_REG_VBAT, reg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
998
999
1000
  
  	/* Restore fan_min */
  	data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
2ca2fcd12   Jim Cromie   hwmon: (w83627hf)...
1001
  	w83627hf_write_value(data, W83627HF_REG_FAN_MIN(nr), data->fan_min[nr]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1002

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
1003
  	mutex_unlock(&data->update_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1004
1005
  	return count;
  }
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
1006
1007
1008
  static SENSOR_DEVICE_ATTR_RW(fan1_div, fan_div, 0);
  static SENSOR_DEVICE_ATTR_RW(fan2_div, fan_div, 1);
  static SENSOR_DEVICE_ATTR_RW(fan3_div, fan_div, 2);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1009

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1010
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
1011
  pwm_show(struct device *dev, struct device_attribute *devattr, char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1012
  {
07584c762   Jim Cromie   hwmon: (w83627hf)...
1013
  	int nr = to_sensor_dev_attr(devattr)->index;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1014
  	struct w83627hf_data *data = w83627hf_update_device(dev);
07584c762   Jim Cromie   hwmon: (w83627hf)...
1015
1016
  	return sprintf(buf, "%ld
  ", (long) data->pwm[nr]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1017
1018
1019
  }
  
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
1020
  pwm_store(struct device *dev, struct device_attribute *devattr,
07584c762   Jim Cromie   hwmon: (w83627hf)...
1021
  	  const char *buf, size_t count)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1022
  {
07584c762   Jim Cromie   hwmon: (w83627hf)...
1023
  	int nr = to_sensor_dev_attr(devattr)->index;
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1024
  	struct w83627hf_data *data = dev_get_drvdata(dev);
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
1025
1026
1027
1028
1029
1030
  	unsigned long val;
  	int err;
  
  	err = kstrtoul(buf, 10, &val);
  	if (err)
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1031

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
1032
  	mutex_lock(&data->update_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1033
1034
1035
  
  	if (data->type == w83627thf) {
  		/* bits 0-3 are reserved  in 627THF */
07584c762   Jim Cromie   hwmon: (w83627hf)...
1036
  		data->pwm[nr] = PWM_TO_REG(val) & 0xf0;
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1037
  		w83627hf_write_value(data,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1038
  				     W836X7HF_REG_PWM(data->type, nr),
07584c762   Jim Cromie   hwmon: (w83627hf)...
1039
  				     data->pwm[nr] |
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1040
  				     (w83627hf_read_value(data,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1041
1042
  				     W836X7HF_REG_PWM(data->type, nr)) & 0x0f));
  	} else {
07584c762   Jim Cromie   hwmon: (w83627hf)...
1043
  		data->pwm[nr] = PWM_TO_REG(val);
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1044
  		w83627hf_write_value(data,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1045
  				     W836X7HF_REG_PWM(data->type, nr),
07584c762   Jim Cromie   hwmon: (w83627hf)...
1046
  				     data->pwm[nr]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1047
  	}
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
1048
  	mutex_unlock(&data->update_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1049
1050
  	return count;
  }
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
1051
1052
1053
  static SENSOR_DEVICE_ATTR_RW(pwm1, pwm, 0);
  static SENSOR_DEVICE_ATTR_RW(pwm2, pwm, 1);
  static SENSOR_DEVICE_ATTR_RW(pwm3, pwm, 2);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1054

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1055
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
1056
1057
  pwm_enable_show(struct device *dev, struct device_attribute *devattr,
  		char *buf)
a95a5ed85   Dominik Geyer   hwmon: (w83627hf)...
1058
1059
1060
1061
1062
1063
1064
1065
  {
  	int nr = to_sensor_dev_attr(devattr)->index;
  	struct w83627hf_data *data = w83627hf_update_device(dev);
  	return sprintf(buf, "%d
  ", data->pwm_enable[nr]);
  }
  
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
1066
1067
  pwm_enable_store(struct device *dev, struct device_attribute *devattr,
  		 const char *buf, size_t count)
a95a5ed85   Dominik Geyer   hwmon: (w83627hf)...
1068
1069
1070
  {
  	int nr = to_sensor_dev_attr(devattr)->index;
  	struct w83627hf_data *data = dev_get_drvdata(dev);
a95a5ed85   Dominik Geyer   hwmon: (w83627hf)...
1071
  	u8 reg;
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
1072
1073
  	unsigned long val;
  	int err;
a95a5ed85   Dominik Geyer   hwmon: (w83627hf)...
1074

27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
1075
1076
1077
1078
1079
  	err = kstrtoul(buf, 10, &val);
  	if (err)
  		return err;
  
  	if (!val || val > 3)	/* modes 1, 2 and 3 are supported */
a95a5ed85   Dominik Geyer   hwmon: (w83627hf)...
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
  		return -EINVAL;
  	mutex_lock(&data->update_lock);
  	data->pwm_enable[nr] = val;
  	reg = w83627hf_read_value(data, W83627THF_REG_PWM_ENABLE[nr]);
  	reg &= ~(0x03 << W83627THF_PWM_ENABLE_SHIFT[nr]);
  	reg |= (val - 1) << W83627THF_PWM_ENABLE_SHIFT[nr];
  	w83627hf_write_value(data, W83627THF_REG_PWM_ENABLE[nr], reg);
  	mutex_unlock(&data->update_lock);
  	return count;
  }
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
1090
1091
1092
  static SENSOR_DEVICE_ATTR_RW(pwm1_enable, pwm_enable, 0);
  static SENSOR_DEVICE_ATTR_RW(pwm2_enable, pwm_enable, 1);
  static SENSOR_DEVICE_ATTR_RW(pwm3_enable, pwm_enable, 2);
a95a5ed85   Dominik Geyer   hwmon: (w83627hf)...
1093
1094
  
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
1095
  pwm_freq_show(struct device *dev, struct device_attribute *devattr, char *buf)
1550cb6d7   Carlos Olalla Martinez   hwmon/w83627hf: A...
1096
  {
07584c762   Jim Cromie   hwmon: (w83627hf)...
1097
  	int nr = to_sensor_dev_attr(devattr)->index;
1550cb6d7   Carlos Olalla Martinez   hwmon/w83627hf: A...
1098
1099
1100
1101
  	struct w83627hf_data *data = w83627hf_update_device(dev);
  	if (data->type == w83627hf)
  		return sprintf(buf, "%ld
  ",
07584c762   Jim Cromie   hwmon: (w83627hf)...
1102
  			pwm_freq_from_reg_627hf(data->pwm_freq[nr]));
1550cb6d7   Carlos Olalla Martinez   hwmon/w83627hf: A...
1103
1104
1105
  	else
  		return sprintf(buf, "%ld
  ",
07584c762   Jim Cromie   hwmon: (w83627hf)...
1106
  			pwm_freq_from_reg(data->pwm_freq[nr]));
1550cb6d7   Carlos Olalla Martinez   hwmon/w83627hf: A...
1107
1108
1109
  }
  
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
1110
  pwm_freq_store(struct device *dev, struct device_attribute *devattr,
07584c762   Jim Cromie   hwmon: (w83627hf)...
1111
  	       const char *buf, size_t count)
1550cb6d7   Carlos Olalla Martinez   hwmon/w83627hf: A...
1112
  {
07584c762   Jim Cromie   hwmon: (w83627hf)...
1113
  	int nr = to_sensor_dev_attr(devattr)->index;
1550cb6d7   Carlos Olalla Martinez   hwmon/w83627hf: A...
1114
1115
  	struct w83627hf_data *data = dev_get_drvdata(dev);
  	static const u8 mask[]={0xF8, 0x8F};
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
1116
1117
  	unsigned long val;
  	int err;
1550cb6d7   Carlos Olalla Martinez   hwmon/w83627hf: A...
1118

27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
1119
1120
1121
  	err = kstrtoul(buf, 10, &val);
  	if (err)
  		return err;
1550cb6d7   Carlos Olalla Martinez   hwmon/w83627hf: A...
1122
1123
1124
1125
  
  	mutex_lock(&data->update_lock);
  
  	if (data->type == w83627hf) {
07584c762   Jim Cromie   hwmon: (w83627hf)...
1126
  		data->pwm_freq[nr] = pwm_freq_to_reg_627hf(val);
1550cb6d7   Carlos Olalla Martinez   hwmon/w83627hf: A...
1127
  		w83627hf_write_value(data, W83627HF_REG_PWM_FREQ,
07584c762   Jim Cromie   hwmon: (w83627hf)...
1128
  				(data->pwm_freq[nr] << (nr*4)) |
1550cb6d7   Carlos Olalla Martinez   hwmon/w83627hf: A...
1129
  				(w83627hf_read_value(data,
07584c762   Jim Cromie   hwmon: (w83627hf)...
1130
  				W83627HF_REG_PWM_FREQ) & mask[nr]));
1550cb6d7   Carlos Olalla Martinez   hwmon/w83627hf: A...
1131
  	} else {
07584c762   Jim Cromie   hwmon: (w83627hf)...
1132
1133
1134
  		data->pwm_freq[nr] = pwm_freq_to_reg(val);
  		w83627hf_write_value(data, W83637HF_REG_PWM_FREQ[nr],
  				data->pwm_freq[nr]);
1550cb6d7   Carlos Olalla Martinez   hwmon/w83627hf: A...
1135
1136
1137
1138
1139
  	}
  
  	mutex_unlock(&data->update_lock);
  	return count;
  }
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
1140
1141
1142
  static SENSOR_DEVICE_ATTR_RW(pwm1_freq, pwm_freq, 0);
  static SENSOR_DEVICE_ATTR_RW(pwm2_freq, pwm_freq, 1);
  static SENSOR_DEVICE_ATTR_RW(pwm3_freq, pwm_freq, 2);
1550cb6d7   Carlos Olalla Martinez   hwmon/w83627hf: A...
1143
1144
  
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
1145
  temp_type_show(struct device *dev, struct device_attribute *devattr,
07584c762   Jim Cromie   hwmon: (w83627hf)...
1146
  	       char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1147
  {
07584c762   Jim Cromie   hwmon: (w83627hf)...
1148
  	int nr = to_sensor_dev_attr(devattr)->index;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1149
  	struct w83627hf_data *data = w83627hf_update_device(dev);
07584c762   Jim Cromie   hwmon: (w83627hf)...
1150
1151
  	return sprintf(buf, "%ld
  ", (long) data->sens[nr]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1152
1153
1154
  }
  
  static ssize_t
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
1155
  temp_type_store(struct device *dev, struct device_attribute *devattr,
07584c762   Jim Cromie   hwmon: (w83627hf)...
1156
  		const char *buf, size_t count)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1157
  {
07584c762   Jim Cromie   hwmon: (w83627hf)...
1158
  	int nr = to_sensor_dev_attr(devattr)->index;
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1159
  	struct w83627hf_data *data = dev_get_drvdata(dev);
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
1160
1161
1162
  	unsigned long val;
  	u32 tmp;
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1163

27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
1164
1165
1166
  	err = kstrtoul(buf, 10, &val);
  	if (err)
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1167

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
1168
  	mutex_lock(&data->update_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1169
1170
1171
  
  	switch (val) {
  	case 1:		/* PII/Celeron diode */
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1172
1173
  		tmp = w83627hf_read_value(data, W83781D_REG_SCFG1);
  		w83627hf_write_value(data, W83781D_REG_SCFG1,
07584c762   Jim Cromie   hwmon: (w83627hf)...
1174
  				    tmp | BIT_SCFG1[nr]);
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1175
1176
  		tmp = w83627hf_read_value(data, W83781D_REG_SCFG2);
  		w83627hf_write_value(data, W83781D_REG_SCFG2,
07584c762   Jim Cromie   hwmon: (w83627hf)...
1177
1178
  				    tmp | BIT_SCFG2[nr]);
  		data->sens[nr] = val;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1179
1180
  		break;
  	case 2:		/* 3904 */
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1181
1182
  		tmp = w83627hf_read_value(data, W83781D_REG_SCFG1);
  		w83627hf_write_value(data, W83781D_REG_SCFG1,
07584c762   Jim Cromie   hwmon: (w83627hf)...
1183
  				    tmp | BIT_SCFG1[nr]);
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1184
1185
  		tmp = w83627hf_read_value(data, W83781D_REG_SCFG2);
  		w83627hf_write_value(data, W83781D_REG_SCFG2,
07584c762   Jim Cromie   hwmon: (w83627hf)...
1186
1187
  				    tmp & ~BIT_SCFG2[nr]);
  		data->sens[nr] = val;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1188
  		break;
b26f93309   Jean Delvare   hwmon: Don't expo...
1189
1190
1191
1192
  	case W83781D_DEFAULT_BETA:
  		dev_warn(dev, "Sensor type %d is deprecated, please use 4 "
  			 "instead
  ", W83781D_DEFAULT_BETA);
df561f668   Gustavo A. R. Silva   treewide: Use fal...
1193
  		fallthrough;
b26f93309   Jean Delvare   hwmon: Don't expo...
1194
  	case 4:		/* thermistor */
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1195
1196
  		tmp = w83627hf_read_value(data, W83781D_REG_SCFG1);
  		w83627hf_write_value(data, W83781D_REG_SCFG1,
07584c762   Jim Cromie   hwmon: (w83627hf)...
1197
1198
  				    tmp & ~BIT_SCFG1[nr]);
  		data->sens[nr] = val;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1199
1200
  		break;
  	default:
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1201
  		dev_err(dev,
b26f93309   Jean Delvare   hwmon: Don't expo...
1202
1203
1204
  		       "Invalid sensor type %ld; must be 1, 2, or 4
  ",
  		       (long) val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1205
1206
  		break;
  	}
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
1207
  	mutex_unlock(&data->update_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1208
1209
  	return count;
  }
502a92ff2   Guenter Roeck   hwmon: (w83627hf)...
1210
1211
1212
  static SENSOR_DEVICE_ATTR_RW(temp1_type, temp_type, 0);
  static SENSOR_DEVICE_ATTR_RW(temp2_type, temp_type, 1);
  static SENSOR_DEVICE_ATTR_RW(temp3_type, temp_type, 2);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1213

07584c762   Jim Cromie   hwmon: (w83627hf)...
1214
  static ssize_t
8dfcdfc1e   Julia Lawall   hwmon: (w83627hf)...
1215
  name_show(struct device *dev, struct device_attribute *devattr, char *buf)
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1216
1217
1218
1219
1220
1221
  {
  	struct w83627hf_data *data = dev_get_drvdata(dev);
  
  	return sprintf(buf, "%s
  ", data->name);
  }
8dfcdfc1e   Julia Lawall   hwmon: (w83627hf)...
1222
  static DEVICE_ATTR_RO(name);
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1223
1224
1225
  
  static int __init w83627hf_find(int sioaddr, unsigned short *addr,
  				struct w83627hf_sio_data *sio_data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1226
  {
e95fd518d   Guenter Roeck   hwmon: (w83627hf)...
1227
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1228
  	u16 val;
64f503076   Andi Kleen   sections: Fix sec...
1229
  	static __initconst char *const names[] = {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1230
1231
1232
1233
1234
1235
  		"W83627HF",
  		"W83627THF",
  		"W83697HF",
  		"W83637HF",
  		"W83687THF",
  	};
c46c0e918   Christian Schulte   hwmon: (w83627hf)...
1236
  	sio_data->sioaddr = sioaddr;
e95fd518d   Guenter Roeck   hwmon: (w83627hf)...
1237
1238
1239
1240
1241
  	err = superio_enter(sio_data);
  	if (err)
  		return err;
  
  	err = -ENODEV;
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
1242
  	val = force_id ? force_id : superio_inb(sio_data, DEVID);
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
  	switch (val) {
  	case W627_DEVID:
  		sio_data->type = w83627hf;
  		break;
  	case W627THF_DEVID:
  		sio_data->type = w83627thf;
  		break;
  	case W697_DEVID:
  		sio_data->type = w83697hf;
  		break;
  	case W637_DEVID:
  		sio_data->type = w83637hf;
  		break;
  	case W687THF_DEVID:
  		sio_data->type = w83687thf;
  		break;
e142e2a30   Jean Delvare   hwmon/w83627hf: B...
1259
1260
  	case 0xff:	/* No device at all */
  		goto exit;
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1261
  	default:
e142e2a30   Jean Delvare   hwmon/w83627hf: B...
1262
1263
  		pr_debug(DRVNAME ": Unsupported chip (DEVID=0x%02x)
  ", val);
d27c37c0b   Jean Delvare   hwmon/w83627hf: P...
1264
  		goto exit;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1265
  	}
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
1266
1267
1268
  	superio_select(sio_data, W83627HF_LD_HWM);
  	val = (superio_inb(sio_data, WINB_BASE_REG) << 8) |
  	       superio_inb(sio_data, WINB_BASE_REG + 1);
ada0c2f8f   Petr Vandrovec   [PATCH] hwmon: Fi...
1269
  	*addr = val & WINB_ALIGNMENT;
d27c37c0b   Jean Delvare   hwmon/w83627hf: P...
1270
  	if (*addr == 0) {
18de030f1   Joe Perches   hwmon: (w83627hf)...
1271
1272
  		pr_warn("Base address not set, skipping
  ");
d27c37c0b   Jean Delvare   hwmon/w83627hf: P...
1273
  		goto exit;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1274
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1275

b72656dbc   Jean Delvare   hwmon: (w83627hf)...
1276
  	val = superio_inb(sio_data, WINB_ACT_REG);
d27c37c0b   Jean Delvare   hwmon/w83627hf: P...
1277
  	if (!(val & 0x01)) {
18de030f1   Joe Perches   hwmon: (w83627hf)...
1278
1279
  		pr_warn("Enabling HWM logical device
  ");
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
1280
  		superio_outb(sio_data, WINB_ACT_REG, val | 0x01);
d27c37c0b   Jean Delvare   hwmon/w83627hf: P...
1281
1282
1283
  	}
  
  	err = 0;
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1284
1285
1286
  	pr_info(DRVNAME ": Found %s chip at %#x
  ",
  		names[sio_data->type], *addr);
d27c37c0b   Jean Delvare   hwmon/w83627hf: P...
1287
1288
  
   exit:
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
1289
  	superio_exit(sio_data);
d27c37c0b   Jean Delvare   hwmon/w83627hf: P...
1290
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1291
  }
07584c762   Jim Cromie   hwmon: (w83627hf)...
1292
1293
1294
  #define VIN_UNIT_ATTRS(_X_)	\
  	&sensor_dev_attr_in##_X_##_input.dev_attr.attr,		\
  	&sensor_dev_attr_in##_X_##_min.dev_attr.attr,		\
e3604c626   Jean Delvare   hwmon: (w83627hf)...
1295
1296
1297
  	&sensor_dev_attr_in##_X_##_max.dev_attr.attr,		\
  	&sensor_dev_attr_in##_X_##_alarm.dev_attr.attr,		\
  	&sensor_dev_attr_in##_X_##_beep.dev_attr.attr
07584c762   Jim Cromie   hwmon: (w83627hf)...
1298
1299
1300
1301
  
  #define FAN_UNIT_ATTRS(_X_)	\
  	&sensor_dev_attr_fan##_X_##_input.dev_attr.attr,	\
  	&sensor_dev_attr_fan##_X_##_min.dev_attr.attr,		\
e3604c626   Jean Delvare   hwmon: (w83627hf)...
1302
1303
1304
  	&sensor_dev_attr_fan##_X_##_div.dev_attr.attr,		\
  	&sensor_dev_attr_fan##_X_##_alarm.dev_attr.attr,	\
  	&sensor_dev_attr_fan##_X_##_beep.dev_attr.attr
07584c762   Jim Cromie   hwmon: (w83627hf)...
1305
1306
1307
1308
1309
  
  #define TEMP_UNIT_ATTRS(_X_)	\
  	&sensor_dev_attr_temp##_X_##_input.dev_attr.attr,	\
  	&sensor_dev_attr_temp##_X_##_max.dev_attr.attr,		\
  	&sensor_dev_attr_temp##_X_##_max_hyst.dev_attr.attr,	\
e3604c626   Jean Delvare   hwmon: (w83627hf)...
1310
1311
1312
  	&sensor_dev_attr_temp##_X_##_type.dev_attr.attr,	\
  	&sensor_dev_attr_temp##_X_##_alarm.dev_attr.attr,	\
  	&sensor_dev_attr_temp##_X_##_beep.dev_attr.attr
07584c762   Jim Cromie   hwmon: (w83627hf)...
1313

c1685f61b   Mark M. Hoffman   hwmon: Fix unchec...
1314
1315
1316
1317
  static struct attribute *w83627hf_attributes[] = {
  	&dev_attr_in0_input.attr,
  	&dev_attr_in0_min.attr,
  	&dev_attr_in0_max.attr,
e3604c626   Jean Delvare   hwmon: (w83627hf)...
1318
1319
  	&sensor_dev_attr_in0_alarm.dev_attr.attr,
  	&sensor_dev_attr_in0_beep.dev_attr.attr,
07584c762   Jim Cromie   hwmon: (w83627hf)...
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
  	VIN_UNIT_ATTRS(2),
  	VIN_UNIT_ATTRS(3),
  	VIN_UNIT_ATTRS(4),
  	VIN_UNIT_ATTRS(7),
  	VIN_UNIT_ATTRS(8),
  
  	FAN_UNIT_ATTRS(1),
  	FAN_UNIT_ATTRS(2),
  
  	TEMP_UNIT_ATTRS(1),
  	TEMP_UNIT_ATTRS(2),
c1685f61b   Mark M. Hoffman   hwmon: Fix unchec...
1331
1332
  
  	&dev_attr_alarms.attr,
1c1381076   Jean Delvare   hwmon: (w83627hf)...
1333
  	&sensor_dev_attr_beep_enable.dev_attr.attr,
c1685f61b   Mark M. Hoffman   hwmon: Fix unchec...
1334
  	&dev_attr_beep_mask.attr,
07584c762   Jim Cromie   hwmon: (w83627hf)...
1335
1336
  	&sensor_dev_attr_pwm1.dev_attr.attr,
  	&sensor_dev_attr_pwm2.dev_attr.attr,
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1337
  	&dev_attr_name.attr,
c1685f61b   Mark M. Hoffman   hwmon: Fix unchec...
1338
1339
1340
1341
1342
1343
1344
1345
  	NULL
  };
  
  static const struct attribute_group w83627hf_group = {
  	.attrs = w83627hf_attributes,
  };
  
  static struct attribute *w83627hf_attributes_opt[] = {
07584c762   Jim Cromie   hwmon: (w83627hf)...
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
  	VIN_UNIT_ATTRS(1),
  	VIN_UNIT_ATTRS(5),
  	VIN_UNIT_ATTRS(6),
  
  	FAN_UNIT_ATTRS(3),
  	TEMP_UNIT_ATTRS(3),
  	&sensor_dev_attr_pwm3.dev_attr.attr,
  
  	&sensor_dev_attr_pwm1_freq.dev_attr.attr,
  	&sensor_dev_attr_pwm2_freq.dev_attr.attr,
  	&sensor_dev_attr_pwm3_freq.dev_attr.attr,
a95a5ed85   Dominik Geyer   hwmon: (w83627hf)...
1357
1358
1359
1360
  
  	&sensor_dev_attr_pwm1_enable.dev_attr.attr,
  	&sensor_dev_attr_pwm2_enable.dev_attr.attr,
  	&sensor_dev_attr_pwm3_enable.dev_attr.attr,
c1685f61b   Mark M. Hoffman   hwmon: Fix unchec...
1361
1362
1363
1364
1365
1366
  	NULL
  };
  
  static const struct attribute_group w83627hf_group_opt = {
  	.attrs = w83627hf_attributes_opt,
  };
6c931ae1c   Bill Pemberton   hwmon: remove use...
1367
  static int w83627hf_probe(struct platform_device *pdev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1368
  {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1369
  	struct device *dev = &pdev->dev;
a8b3a3a53   Jingoo Han   hwmon: use dev_ge...
1370
  	struct w83627hf_sio_data *sio_data = dev_get_platdata(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1371
  	struct w83627hf_data *data;
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1372
  	struct resource *res;
2ca2fcd12   Jim Cromie   hwmon: (w83627hf)...
1373
  	int err, i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1374

787c72b10   Jean Delvare   hwmon/w83627hf: C...
1375
1376
1377
1378
1379
1380
1381
1382
1383
  	static const char *names[] = {
  		"w83627hf",
  		"w83627thf",
  		"w83697hf",
  		"w83637hf",
  		"w83687thf",
  	};
  
  	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
0cf469972   Guenter Roeck   hwmon: (w83627hf)...
1384
  	if (!devm_request_region(dev, res->start, WINB_REGION_SIZE, DRVNAME)) {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1385
1386
1387
1388
  		dev_err(dev, "Failed to request region 0x%lx-0x%lx
  ",
  			(unsigned long)res->start,
  			(unsigned long)(res->start + WINB_REGION_SIZE - 1));
0cf469972   Guenter Roeck   hwmon: (w83627hf)...
1389
  		return -EBUSY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1390
  	}
0cf469972   Guenter Roeck   hwmon: (w83627hf)...
1391
1392
1393
  	data = devm_kzalloc(dev, sizeof(struct w83627hf_data), GFP_KERNEL);
  	if (!data)
  		return -ENOMEM;
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1394
1395
1396
  	data->addr = res->start;
  	data->type = sio_data->type;
  	data->name = names[sio_data->type];
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
1397
  	mutex_init(&data->lock);
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
1398
  	mutex_init(&data->update_lock);
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1399
  	platform_set_drvdata(pdev, data);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1400

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1401
  	/* Initialize the chip */
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1402
  	w83627hf_init_device(pdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1403
1404
  
  	/* A few vars need to be filled upon startup */
2ca2fcd12   Jim Cromie   hwmon: (w83627hf)...
1405
1406
1407
  	for (i = 0; i <= 2; i++)
  		data->fan_min[i] = w83627hf_read_value(
  					data, W83627HF_REG_FAN_MIN(i));
c09c5184a   Jean Delvare   hwmon: (w83627hf)...
1408
  	w83627hf_update_fan_div(data);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1409

c1685f61b   Mark M. Hoffman   hwmon: Fix unchec...
1410
  	/* Register common device attributes */
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
1411
1412
  	err = sysfs_create_group(&dev->kobj, &w83627hf_group);
  	if (err)
0cf469972   Guenter Roeck   hwmon: (w83627hf)...
1413
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1414

c1685f61b   Mark M. Hoffman   hwmon: Fix unchec...
1415
  	/* Register chip-specific device attributes */
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1416
  	if (data->type == w83627hf || data->type == w83697hf)
07584c762   Jim Cromie   hwmon: (w83627hf)...
1417
1418
1419
1420
1421
1422
1423
  		if ((err = device_create_file(dev,
  				&sensor_dev_attr_in5_input.dev_attr))
  		 || (err = device_create_file(dev,
  				&sensor_dev_attr_in5_min.dev_attr))
  		 || (err = device_create_file(dev,
  				&sensor_dev_attr_in5_max.dev_attr))
  		 || (err = device_create_file(dev,
e3604c626   Jean Delvare   hwmon: (w83627hf)...
1424
1425
1426
1427
  				&sensor_dev_attr_in5_alarm.dev_attr))
  		 || (err = device_create_file(dev,
  				&sensor_dev_attr_in5_beep.dev_attr))
  		 || (err = device_create_file(dev,
07584c762   Jim Cromie   hwmon: (w83627hf)...
1428
1429
1430
1431
1432
1433
  				&sensor_dev_attr_in6_input.dev_attr))
  		 || (err = device_create_file(dev,
  				&sensor_dev_attr_in6_min.dev_attr))
  		 || (err = device_create_file(dev,
  				&sensor_dev_attr_in6_max.dev_attr))
  		 || (err = device_create_file(dev,
e3604c626   Jean Delvare   hwmon: (w83627hf)...
1434
1435
1436
1437
  				&sensor_dev_attr_in6_alarm.dev_attr))
  		 || (err = device_create_file(dev,
  				&sensor_dev_attr_in6_beep.dev_attr))
  		 || (err = device_create_file(dev,
07584c762   Jim Cromie   hwmon: (w83627hf)...
1438
1439
1440
  				&sensor_dev_attr_pwm1_freq.dev_attr))
  		 || (err = device_create_file(dev,
  				&sensor_dev_attr_pwm2_freq.dev_attr)))
0cf469972   Guenter Roeck   hwmon: (w83627hf)...
1441
  			goto error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1442

787c72b10   Jean Delvare   hwmon/w83627hf: C...
1443
  	if (data->type != w83697hf)
07584c762   Jim Cromie   hwmon: (w83627hf)...
1444
1445
1446
1447
1448
1449
1450
  		if ((err = device_create_file(dev,
  				&sensor_dev_attr_in1_input.dev_attr))
  		 || (err = device_create_file(dev,
  				&sensor_dev_attr_in1_min.dev_attr))
  		 || (err = device_create_file(dev,
  				&sensor_dev_attr_in1_max.dev_attr))
  		 || (err = device_create_file(dev,
e3604c626   Jean Delvare   hwmon: (w83627hf)...
1451
1452
1453
1454
  				&sensor_dev_attr_in1_alarm.dev_attr))
  		 || (err = device_create_file(dev,
  				&sensor_dev_attr_in1_beep.dev_attr))
  		 || (err = device_create_file(dev,
07584c762   Jim Cromie   hwmon: (w83627hf)...
1455
1456
1457
1458
1459
1460
  				&sensor_dev_attr_fan3_input.dev_attr))
  		 || (err = device_create_file(dev,
  				&sensor_dev_attr_fan3_min.dev_attr))
  		 || (err = device_create_file(dev,
  				&sensor_dev_attr_fan3_div.dev_attr))
  		 || (err = device_create_file(dev,
e3604c626   Jean Delvare   hwmon: (w83627hf)...
1461
1462
1463
1464
  				&sensor_dev_attr_fan3_alarm.dev_attr))
  		 || (err = device_create_file(dev,
  				&sensor_dev_attr_fan3_beep.dev_attr))
  		 || (err = device_create_file(dev,
07584c762   Jim Cromie   hwmon: (w83627hf)...
1465
1466
1467
1468
1469
1470
  				&sensor_dev_attr_temp3_input.dev_attr))
  		 || (err = device_create_file(dev,
  				&sensor_dev_attr_temp3_max.dev_attr))
  		 || (err = device_create_file(dev,
  				&sensor_dev_attr_temp3_max_hyst.dev_attr))
  		 || (err = device_create_file(dev,
e3604c626   Jean Delvare   hwmon: (w83627hf)...
1471
1472
1473
1474
  				&sensor_dev_attr_temp3_alarm.dev_attr))
  		 || (err = device_create_file(dev,
  				&sensor_dev_attr_temp3_beep.dev_attr))
  		 || (err = device_create_file(dev,
07584c762   Jim Cromie   hwmon: (w83627hf)...
1475
  				&sensor_dev_attr_temp3_type.dev_attr)))
0cf469972   Guenter Roeck   hwmon: (w83627hf)...
1476
  			goto error;
c1685f61b   Mark M. Hoffman   hwmon: Fix unchec...
1477

787c72b10   Jean Delvare   hwmon/w83627hf: C...
1478
  	if (data->type != w83697hf && data->vid != 0xff) {
8a665a055   Jean Delvare   hwmon: Only call ...
1479
1480
  		/* Convert VID to voltage based on VRM */
  		data->vrm = vid_which_vrm();
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1481
1482
  		if ((err = device_create_file(dev, &dev_attr_cpu0_vid))
  		 || (err = device_create_file(dev, &dev_attr_vrm)))
0cf469972   Guenter Roeck   hwmon: (w83627hf)...
1483
  			goto error;
8a665a055   Jean Delvare   hwmon: Only call ...
1484
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1485

787c72b10   Jean Delvare   hwmon/w83627hf: C...
1486
  	if (data->type == w83627thf || data->type == w83637hf
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
1487
1488
1489
  	    || data->type == w83687thf) {
  		err = device_create_file(dev, &sensor_dev_attr_pwm3.dev_attr);
  		if (err)
0cf469972   Guenter Roeck   hwmon: (w83627hf)...
1490
  			goto error;
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
1491
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1492

1550cb6d7   Carlos Olalla Martinez   hwmon/w83627hf: A...
1493
  	if (data->type == w83637hf || data->type == w83687thf)
07584c762   Jim Cromie   hwmon: (w83627hf)...
1494
1495
1496
1497
1498
1499
  		if ((err = device_create_file(dev,
  				&sensor_dev_attr_pwm1_freq.dev_attr))
  		 || (err = device_create_file(dev,
  				&sensor_dev_attr_pwm2_freq.dev_attr))
  		 || (err = device_create_file(dev,
  				&sensor_dev_attr_pwm3_freq.dev_attr)))
0cf469972   Guenter Roeck   hwmon: (w83627hf)...
1500
  			goto error;
1550cb6d7   Carlos Olalla Martinez   hwmon/w83627hf: A...
1501

a95a5ed85   Dominik Geyer   hwmon: (w83627hf)...
1502
1503
1504
1505
1506
  	if (data->type != w83627hf)
  		if ((err = device_create_file(dev,
  				&sensor_dev_attr_pwm1_enable.dev_attr))
  		 || (err = device_create_file(dev,
  				&sensor_dev_attr_pwm2_enable.dev_attr)))
0cf469972   Guenter Roeck   hwmon: (w83627hf)...
1507
  			goto error;
a95a5ed85   Dominik Geyer   hwmon: (w83627hf)...
1508
1509
  
  	if (data->type == w83627thf || data->type == w83637hf
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
1510
1511
1512
1513
  	    || data->type == w83687thf) {
  		err = device_create_file(dev,
  					 &sensor_dev_attr_pwm3_enable.dev_attr);
  		if (err)
0cf469972   Guenter Roeck   hwmon: (w83627hf)...
1514
  			goto error;
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
1515
  	}
a95a5ed85   Dominik Geyer   hwmon: (w83627hf)...
1516

1beeffe43   Tony Jones   hwmon: Convert fr...
1517
1518
1519
  	data->hwmon_dev = hwmon_device_register(dev);
  	if (IS_ERR(data->hwmon_dev)) {
  		err = PTR_ERR(data->hwmon_dev);
0cf469972   Guenter Roeck   hwmon: (w83627hf)...
1520
  		goto error;
c1685f61b   Mark M. Hoffman   hwmon: Fix unchec...
1521
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1522
1523
  
  	return 0;
0cf469972   Guenter Roeck   hwmon: (w83627hf)...
1524
   error:
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1525
1526
  	sysfs_remove_group(&dev->kobj, &w83627hf_group);
  	sysfs_remove_group(&dev->kobj, &w83627hf_group_opt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1527
1528
  	return err;
  }
281dfd0b6   Bill Pemberton   hwmon: remove use...
1529
  static int w83627hf_remove(struct platform_device *pdev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1530
  {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1531
  	struct w83627hf_data *data = platform_get_drvdata(pdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1532

1beeffe43   Tony Jones   hwmon: Convert fr...
1533
  	hwmon_device_unregister(data->hwmon_dev);
943b0830c   Mark M. Hoffman   [PATCH] I2C hwmon...
1534

787c72b10   Jean Delvare   hwmon/w83627hf: C...
1535
1536
  	sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group);
  	sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group_opt);
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1537

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1538
1539
  	return 0;
  }
d58df9cd7   Jean Delvare   hwmon: (w83627hf)...
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
  /* Registers 0x50-0x5f are banked */
  static inline void w83627hf_set_bank(struct w83627hf_data *data, u16 reg)
  {
  	if ((reg & 0x00f0) == 0x50) {
  		outb_p(W83781D_REG_BANK, data->addr + W83781D_ADDR_REG_OFFSET);
  		outb_p(reg >> 8, data->addr + W83781D_DATA_REG_OFFSET);
  	}
  }
  
  /* Not strictly necessary, but play it safe for now */
  static inline void w83627hf_reset_bank(struct w83627hf_data *data, u16 reg)
  {
  	if (reg & 0xff00) {
  		outb_p(W83781D_REG_BANK, data->addr + W83781D_ADDR_REG_OFFSET);
  		outb_p(0, data->addr + W83781D_DATA_REG_OFFSET);
  	}
  }
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1557
  static int w83627hf_read_value(struct w83627hf_data *data, u16 reg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1558
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1559
  	int res, word_sized;
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
1560
  	mutex_lock(&data->lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1561
1562
1563
1564
1565
  	word_sized = (((reg & 0xff00) == 0x100)
  		   || ((reg & 0xff00) == 0x200))
  		  && (((reg & 0x00ff) == 0x50)
  		   || ((reg & 0x00ff) == 0x53)
  		   || ((reg & 0x00ff) == 0x55));
d58df9cd7   Jean Delvare   hwmon: (w83627hf)...
1566
  	w83627hf_set_bank(data, reg);
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1567
1568
  	outb_p(reg & 0xff, data->addr + W83781D_ADDR_REG_OFFSET);
  	res = inb_p(data->addr + W83781D_DATA_REG_OFFSET);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1569
1570
  	if (word_sized) {
  		outb_p((reg & 0xff) + 1,
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1571
  		       data->addr + W83781D_ADDR_REG_OFFSET);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1572
  		res =
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1573
  		    (res << 8) + inb_p(data->addr +
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1574
1575
  				       W83781D_DATA_REG_OFFSET);
  	}
d58df9cd7   Jean Delvare   hwmon: (w83627hf)...
1576
  	w83627hf_reset_bank(data, reg);
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
1577
  	mutex_unlock(&data->lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1578
1579
  	return res;
  }
6c931ae1c   Bill Pemberton   hwmon: remove use...
1580
  static int w83627thf_read_gpio5(struct platform_device *pdev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1581
  {
a8b3a3a53   Jingoo Han   hwmon: use dev_ge...
1582
  	struct w83627hf_sio_data *sio_data = dev_get_platdata(&pdev->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1583
  	int res = 0xff, sel;
e95fd518d   Guenter Roeck   hwmon: (w83627hf)...
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
  	if (superio_enter(sio_data)) {
  		/*
  		 * Some other driver reserved the address space for itself.
  		 * We don't want to fail driver instantiation because of that,
  		 * so display a warning and keep going.
  		 */
  		dev_warn(&pdev->dev,
  			 "Can not read VID data: Failed to enable SuperIO access
  ");
  		return res;
  	}
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
1595
  	superio_select(sio_data, W83627HF_LD_GPIO5);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1596

e95fd518d   Guenter Roeck   hwmon: (w83627hf)...
1597
  	res = 0xff;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1598
  	/* Make sure these GPIO pins are enabled */
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
1599
  	if (!(superio_inb(sio_data, W83627THF_GPIO5_EN) & (1<<3))) {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1600
1601
  		dev_dbg(&pdev->dev, "GPIO5 disabled, no VID function
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1602
1603
  		goto exit;
  	}
27b9de3c4   Guenter Roeck   hwmon: (w83627hf)...
1604
1605
1606
1607
  	/*
  	 * Make sure the pins are configured for input
  	 * There must be at least five (VRM 9), and possibly 6 (VRM 10)
  	 */
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
1608
  	sel = superio_inb(sio_data, W83627THF_GPIO5_IOSR) & 0x3f;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1609
  	if ((sel & 0x1f) != 0x1f) {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1610
  		dev_dbg(&pdev->dev, "GPIO5 not configured for VID "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1611
1612
1613
1614
  			"function
  ");
  		goto exit;
  	}
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1615
1616
  	dev_info(&pdev->dev, "Reading VID from GPIO5
  ");
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
1617
  	res = superio_inb(sio_data, W83627THF_GPIO5_DR) & sel;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1618
1619
  
  exit:
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
1620
  	superio_exit(sio_data);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1621
1622
  	return res;
  }
6c931ae1c   Bill Pemberton   hwmon: remove use...
1623
  static int w83687thf_read_vid(struct platform_device *pdev)
c2db6ce14   Jean Delvare   [PATCH] hwmon: Ad...
1624
  {
a8b3a3a53   Jingoo Han   hwmon: use dev_ge...
1625
  	struct w83627hf_sio_data *sio_data = dev_get_platdata(&pdev->dev);
c2db6ce14   Jean Delvare   [PATCH] hwmon: Ad...
1626
  	int res = 0xff;
e95fd518d   Guenter Roeck   hwmon: (w83627hf)...
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
  	if (superio_enter(sio_data)) {
  		/*
  		 * Some other driver reserved the address space for itself.
  		 * We don't want to fail driver instantiation because of that,
  		 * so display a warning and keep going.
  		 */
  		dev_warn(&pdev->dev,
  			 "Can not read VID data: Failed to enable SuperIO access
  ");
  		return res;
  	}
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
1638
  	superio_select(sio_data, W83627HF_LD_HWM);
c2db6ce14   Jean Delvare   [PATCH] hwmon: Ad...
1639
1640
  
  	/* Make sure these GPIO pins are enabled */
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
1641
  	if (!(superio_inb(sio_data, W83687THF_VID_EN) & (1 << 2))) {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1642
1643
  		dev_dbg(&pdev->dev, "VID disabled, no VID function
  ");
c2db6ce14   Jean Delvare   [PATCH] hwmon: Ad...
1644
1645
1646
1647
  		goto exit;
  	}
  
  	/* Make sure the pins are configured for input */
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
1648
  	if (!(superio_inb(sio_data, W83687THF_VID_CFG) & (1 << 4))) {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1649
  		dev_dbg(&pdev->dev, "VID configured as output, "
c2db6ce14   Jean Delvare   [PATCH] hwmon: Ad...
1650
1651
1652
1653
  			"no VID function
  ");
  		goto exit;
  	}
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
1654
  	res = superio_inb(sio_data, W83687THF_VID_DATA) & 0x3f;
c2db6ce14   Jean Delvare   [PATCH] hwmon: Ad...
1655
1656
  
  exit:
b72656dbc   Jean Delvare   hwmon: (w83627hf)...
1657
  	superio_exit(sio_data);
c2db6ce14   Jean Delvare   [PATCH] hwmon: Ad...
1658
1659
  	return res;
  }
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1660
  static int w83627hf_write_value(struct w83627hf_data *data, u16 reg, u16 value)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1661
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1662
  	int word_sized;
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
1663
  	mutex_lock(&data->lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1664
1665
1666
1667
  	word_sized = (((reg & 0xff00) == 0x100)
  		   || ((reg & 0xff00) == 0x200))
  		  && (((reg & 0x00ff) == 0x53)
  		   || ((reg & 0x00ff) == 0x55));
d58df9cd7   Jean Delvare   hwmon: (w83627hf)...
1668
  	w83627hf_set_bank(data, reg);
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1669
  	outb_p(reg & 0xff, data->addr + W83781D_ADDR_REG_OFFSET);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1670
1671
  	if (word_sized) {
  		outb_p(value >> 8,
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1672
  		       data->addr + W83781D_DATA_REG_OFFSET);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1673
  		outb_p((reg & 0xff) + 1,
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1674
  		       data->addr + W83781D_ADDR_REG_OFFSET);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1675
1676
  	}
  	outb_p(value & 0xff,
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1677
  	       data->addr + W83781D_DATA_REG_OFFSET);
d58df9cd7   Jean Delvare   hwmon: (w83627hf)...
1678
  	w83627hf_reset_bank(data, reg);
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
1679
  	mutex_unlock(&data->lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1680
1681
  	return 0;
  }
6c931ae1c   Bill Pemberton   hwmon: remove use...
1682
  static void w83627hf_init_device(struct platform_device *pdev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1683
  {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1684
  	struct w83627hf_data *data = platform_get_drvdata(pdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1685
  	int i;
d27c37c0b   Jean Delvare   hwmon/w83627hf: P...
1686
  	enum chips type = data->type;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1687
  	u8 tmp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1688
1689
1690
  	/* Minimize conflicts with other winbond i2c-only clients...  */
  	/* disable i2c subclients... how to disable main i2c client?? */
  	/* force i2c address to relatively uncommon address */
8f3c7c547   Jean Delvare   hwmon: (w83627hf)...
1691
1692
1693
1694
  	if (type == w83627hf) {
  		w83627hf_write_value(data, W83781D_REG_I2C_SUBADDR, 0x89);
  		w83627hf_write_value(data, W83781D_REG_I2C_ADDR, force_i2c);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1695
1696
  
  	/* Read VID only once */
d27c37c0b   Jean Delvare   hwmon/w83627hf: P...
1697
  	if (type == w83627hf || type == w83637hf) {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1698
1699
  		int lo = w83627hf_read_value(data, W83781D_REG_VID_FANDIV);
  		int hi = w83627hf_read_value(data, W83781D_REG_CHIPID);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1700
  		data->vid = (lo & 0x0f) | ((hi & 0x01) << 4);
d27c37c0b   Jean Delvare   hwmon/w83627hf: P...
1701
  	} else if (type == w83627thf) {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1702
  		data->vid = w83627thf_read_gpio5(pdev);
d27c37c0b   Jean Delvare   hwmon/w83627hf: P...
1703
  	} else if (type == w83687thf) {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1704
  		data->vid = w83687thf_read_vid(pdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1705
1706
1707
  	}
  
  	/* Read VRM & OVT Config only once */
d27c37c0b   Jean Delvare   hwmon/w83627hf: P...
1708
  	if (type == w83627thf || type == w83637hf || type == w83687thf) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1709
  		data->vrm_ovt = 
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1710
  			w83627hf_read_value(data, W83627THF_REG_VRM_OVT_CFG);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1711
  	}
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1712
  	tmp = w83627hf_read_value(data, W83781D_REG_SCFG1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1713
1714
  	for (i = 1; i <= 3; i++) {
  		if (!(tmp & BIT_SCFG1[i - 1])) {
b26f93309   Jean Delvare   hwmon: Don't expo...
1715
  			data->sens[i - 1] = 4;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1716
1717
  		} else {
  			if (w83627hf_read_value
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1718
  			    (data,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
  			     W83781D_REG_SCFG2) & BIT_SCFG2[i - 1])
  				data->sens[i - 1] = 1;
  			else
  				data->sens[i - 1] = 2;
  		}
  		if ((type == w83697hf) && (i == 2))
  			break;
  	}
  
  	if(init) {
  		/* Enable temp2 */
df48ed804   Jim Cromie   hwmon: (w83627hf)...
1730
  		tmp = w83627hf_read_value(data, W83627HF_REG_TEMP2_CONFIG);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1731
  		if (tmp & 0x01) {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1732
  			dev_warn(&pdev->dev, "Enabling temp2, readings "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1733
1734
  				 "might not make sense
  ");
df48ed804   Jim Cromie   hwmon: (w83627hf)...
1735
  			w83627hf_write_value(data, W83627HF_REG_TEMP2_CONFIG,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1736
1737
1738
1739
1740
  				tmp & 0xfe);
  		}
  
  		/* Enable temp3 */
  		if (type != w83697hf) {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1741
  			tmp = w83627hf_read_value(data,
df48ed804   Jim Cromie   hwmon: (w83627hf)...
1742
  				W83627HF_REG_TEMP3_CONFIG);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1743
  			if (tmp & 0x01) {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1744
  				dev_warn(&pdev->dev, "Enabling temp3, "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1745
1746
  					 "readings might not make sense
  ");
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1747
  				w83627hf_write_value(data,
df48ed804   Jim Cromie   hwmon: (w83627hf)...
1748
  					W83627HF_REG_TEMP3_CONFIG, tmp & 0xfe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1749
1750
  			}
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1751
1752
1753
  	}
  
  	/* Start monitoring */
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1754
1755
  	w83627hf_write_value(data, W83781D_REG_CONFIG,
  			    (w83627hf_read_value(data,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1756
1757
  						W83781D_REG_CONFIG) & 0xf7)
  			    | 0x01);
ef878b11b   Jean Delvare   hwmon: (w83627hf)...
1758
1759
1760
1761
1762
  
  	/* Enable VBAT monitoring if needed */
  	tmp = w83627hf_read_value(data, W83781D_REG_VBAT);
  	if (!(tmp & 0x01))
  		w83627hf_write_value(data, W83781D_REG_VBAT, tmp | 0x01);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1763
  }
c09c5184a   Jean Delvare   hwmon: (w83627hf)...
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
  static void w83627hf_update_fan_div(struct w83627hf_data *data)
  {
  	int reg;
  
  	reg = w83627hf_read_value(data, W83781D_REG_VID_FANDIV);
  	data->fan_div[0] = (reg >> 4) & 0x03;
  	data->fan_div[1] = (reg >> 6) & 0x03;
  	if (data->type != w83697hf) {
  		data->fan_div[2] = (w83627hf_read_value(data,
  				       W83781D_REG_PIN) >> 6) & 0x03;
  	}
  	reg = w83627hf_read_value(data, W83781D_REG_VBAT);
  	data->fan_div[0] |= (reg >> 3) & 0x04;
  	data->fan_div[1] |= (reg >> 4) & 0x04;
  	if (data->type != w83697hf)
  		data->fan_div[2] |= (reg >> 5) & 0x04;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1781
1782
  static struct w83627hf_data *w83627hf_update_device(struct device *dev)
  {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1783
  	struct w83627hf_data *data = dev_get_drvdata(dev);
df48ed804   Jim Cromie   hwmon: (w83627hf)...
1784
  	int i, num_temps = (data->type == w83697hf) ? 2 : 3;
a95a5ed85   Dominik Geyer   hwmon: (w83627hf)...
1785
  	int num_pwms = (data->type == w83697hf) ? 2 : 3;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1786

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
1787
  	mutex_lock(&data->update_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1788
1789
1790
1791
1792
1793
  
  	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
  	    || !data->valid) {
  		for (i = 0; i <= 8; i++) {
  			/* skip missing sensors */
  			if (((data->type == w83697hf) && (i == 1)) ||
c2db6ce14   Jean Delvare   [PATCH] hwmon: Ad...
1794
  			    ((data->type != w83627hf && data->type != w83697hf)
4a1c4447e   Yuan Mu   [PATCH] hwmon: Fi...
1795
  			    && (i == 5 || i == 6)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1796
1797
  				continue;
  			data->in[i] =
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1798
  			    w83627hf_read_value(data, W83781D_REG_IN(i));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1799
  			data->in_min[i] =
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1800
  			    w83627hf_read_value(data,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1801
1802
  					       W83781D_REG_IN_MIN(i));
  			data->in_max[i] =
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1803
  			    w83627hf_read_value(data,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1804
1805
  					       W83781D_REG_IN_MAX(i));
  		}
2ca2fcd12   Jim Cromie   hwmon: (w83627hf)...
1806
1807
1808
1809
  		for (i = 0; i <= 2; i++) {
  			data->fan[i] =
  			    w83627hf_read_value(data, W83627HF_REG_FAN(i));
  			data->fan_min[i] =
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1810
  			    w83627hf_read_value(data,
2ca2fcd12   Jim Cromie   hwmon: (w83627hf)...
1811
  					       W83627HF_REG_FAN_MIN(i));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1812
  		}
07584c762   Jim Cromie   hwmon: (w83627hf)...
1813
  		for (i = 0; i <= 2; i++) {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1814
  			u8 tmp = w83627hf_read_value(data,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1815
1816
1817
1818
  				W836X7HF_REG_PWM(data->type, i));
   			/* bits 0-3 are reserved  in 627THF */
   			if (data->type == w83627thf)
  				tmp &= 0xf0;
07584c762   Jim Cromie   hwmon: (w83627hf)...
1819
1820
1821
  			data->pwm[i] = tmp;
  			if (i == 1 &&
  			    (data->type == w83627hf || data->type == w83697hf))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1822
1823
  				break;
  		}
1550cb6d7   Carlos Olalla Martinez   hwmon/w83627hf: A...
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
  		if (data->type == w83627hf) {
  				u8 tmp = w83627hf_read_value(data,
  						W83627HF_REG_PWM_FREQ);
  				data->pwm_freq[0] = tmp & 0x07;
  				data->pwm_freq[1] = (tmp >> 4) & 0x07;
  		} else if (data->type != w83627thf) {
  			for (i = 1; i <= 3; i++) {
  				data->pwm_freq[i - 1] =
  					w83627hf_read_value(data,
  						W83637HF_REG_PWM_FREQ[i - 1]);
  				if (i == 2 && (data->type == w83697hf))
  					break;
  			}
  		}
a95a5ed85   Dominik Geyer   hwmon: (w83627hf)...
1838
1839
1840
1841
1842
1843
1844
1845
1846
  		if (data->type != w83627hf) {
  			for (i = 0; i < num_pwms; i++) {
  				u8 tmp = w83627hf_read_value(data,
  					W83627THF_REG_PWM_ENABLE[i]);
  				data->pwm_enable[i] =
  					((tmp >> W83627THF_PWM_ENABLE_SHIFT[i])
  					& 0x03) + 1;
  			}
  		}
df48ed804   Jim Cromie   hwmon: (w83627hf)...
1847
1848
1849
1850
1851
1852
1853
  		for (i = 0; i < num_temps; i++) {
  			data->temp[i] = w83627hf_read_value(
  						data, w83627hf_reg_temp[i]);
  			data->temp_max[i] = w83627hf_read_value(
  						data, w83627hf_reg_temp_over[i]);
  			data->temp_max_hyst[i] = w83627hf_read_value(
  						data, w83627hf_reg_temp_hyst[i]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1854
  		}
c09c5184a   Jean Delvare   hwmon: (w83627hf)...
1855
  		w83627hf_update_fan_div(data);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1856
  		data->alarms =
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1857
1858
1859
1860
  		    w83627hf_read_value(data, W83781D_REG_ALARM1) |
  		    (w83627hf_read_value(data, W83781D_REG_ALARM2) << 8) |
  		    (w83627hf_read_value(data, W83781D_REG_ALARM3) << 16);
  		i = w83627hf_read_value(data, W83781D_REG_BEEP_INTS2);
1c1381076   Jean Delvare   hwmon: (w83627hf)...
1861
  		data->beep_mask = (i << 8) |
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1862
1863
  		    w83627hf_read_value(data, W83781D_REG_BEEP_INTS1) |
  		    w83627hf_read_value(data, W83781D_REG_BEEP_INTS3) << 16;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1864
1865
1866
  		data->last_updated = jiffies;
  		data->valid = 1;
  	}
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
1867
  	mutex_unlock(&data->update_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1868
1869
1870
  
  	return data;
  }
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
  static int __init w83627hf_device_add(unsigned short address,
  				      const struct w83627hf_sio_data *sio_data)
  {
  	struct resource res = {
  		.start	= address + WINB_REGION_OFFSET,
  		.end	= address + WINB_REGION_OFFSET + WINB_REGION_SIZE - 1,
  		.name	= DRVNAME,
  		.flags	= IORESOURCE_IO,
  	};
  	int err;
b9acb64a3   Jean Delvare   hwmon: Check for ...
1881
1882
1883
  	err = acpi_check_resource_conflict(&res);
  	if (err)
  		goto exit;
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1884
1885
1886
  	pdev = platform_device_alloc(DRVNAME, address);
  	if (!pdev) {
  		err = -ENOMEM;
18de030f1   Joe Perches   hwmon: (w83627hf)...
1887
1888
  		pr_err("Device allocation failed
  ");
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1889
1890
1891
1892
1893
  		goto exit;
  	}
  
  	err = platform_device_add_resources(pdev, &res, 1);
  	if (err) {
18de030f1   Joe Perches   hwmon: (w83627hf)...
1894
1895
  		pr_err("Device resource addition failed (%d)
  ", err);
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1896
1897
  		goto exit_device_put;
  	}
2df6d8115   Jean Delvare   hwmon: Use platfo...
1898
1899
1900
  	err = platform_device_add_data(pdev, sio_data,
  				       sizeof(struct w83627hf_sio_data));
  	if (err) {
18de030f1   Joe Perches   hwmon: (w83627hf)...
1901
1902
  		pr_err("Platform data allocation failed
  ");
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1903
1904
  		goto exit_device_put;
  	}
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1905
1906
1907
  
  	err = platform_device_add(pdev);
  	if (err) {
18de030f1   Joe Perches   hwmon: (w83627hf)...
1908
1909
  		pr_err("Device addition failed (%d)
  ", err);
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
  		goto exit_device_put;
  	}
  
  	return 0;
  
  exit_device_put:
  	platform_device_put(pdev);
  exit:
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1920
1921
  static int __init sensors_w83627hf_init(void)
  {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1922
1923
1924
1925
1926
1927
  	int err;
  	unsigned short address;
  	struct w83627hf_sio_data sio_data;
  
  	if (w83627hf_find(0x2e, &address, &sio_data)
  	 && w83627hf_find(0x4e, &address, &sio_data))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1928
  		return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1929

787c72b10   Jean Delvare   hwmon/w83627hf: C...
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
  	err = platform_driver_register(&w83627hf_driver);
  	if (err)
  		goto exit;
  
  	/* Sets global pdev as a side effect */
  	err = w83627hf_device_add(address, &sio_data);
  	if (err)
  		goto exit_driver;
  
  	return 0;
  
  exit_driver:
  	platform_driver_unregister(&w83627hf_driver);
  exit:
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1945
1946
1947
1948
  }
  
  static void __exit sensors_w83627hf_exit(void)
  {
787c72b10   Jean Delvare   hwmon/w83627hf: C...
1949
1950
  	platform_device_unregister(pdev);
  	platform_driver_unregister(&w83627hf_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
  }
  
  MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
  	      "Philip Edelbrock <phil@netroedge.com>, "
  	      "and Mark Studebaker <mdsxyz123@yahoo.com>");
  MODULE_DESCRIPTION("W83627HF driver");
  MODULE_LICENSE("GPL");
  
  module_init(sensors_w83627hf_init);
  module_exit(sensors_w83627hf_exit);