Blame view

drivers/hwmon/vt8231.c 30.5 KB
74ba9207e   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
2
  /*
61ba03184   Guenter Roeck   hwmon: (vt8231) F...
3
4
5
6
7
8
   * vt8231.c - Part of lm_sensors, Linux kernel modules
   *	      for hardware monitoring
   *
   * Copyright (c) 2005 Roger Lucas <vt8231@hiddenengine.co.uk>
   * Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
   *		      Aaron M. Marsh <amarsh@sdf.lonestar.org>
61ba03184   Guenter Roeck   hwmon: (vt8231) F...
9
   */
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
10

61ba03184   Guenter Roeck   hwmon: (vt8231) F...
11
12
13
  /*
   * Supports VIA VT8231 South Bridge embedded sensors
   */
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
14

9d72be0da   Joe Perches   hwmon: (vt8231) U...
15
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
16
17
18
19
20
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/slab.h>
  #include <linux/pci.h>
  #include <linux/jiffies.h>
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
21
  #include <linux/platform_device.h>
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
22
23
24
25
  #include <linux/hwmon.h>
  #include <linux/hwmon-sysfs.h>
  #include <linux/hwmon-vid.h>
  #include <linux/err.h>
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
26
  #include <linux/mutex.h>
b9acb64a3   Jean Delvare   hwmon: Check for ...
27
  #include <linux/acpi.h>
6055fae8a   H Hartley Sweeten   hwmon: Include <l...
28
  #include <linux/io.h>
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
29
30
31
32
  
  static int force_addr;
  module_param(force_addr, int, 0);
  MODULE_PARM_DESC(force_addr, "Initialize the base address of the sensors");
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
33
  static struct platform_device *pdev;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
34
35
36
37
  
  #define VT8231_EXTENT 0x80
  #define VT8231_BASE_REG 0x70
  #define VT8231_ENABLE_REG 0x74
61ba03184   Guenter Roeck   hwmon: (vt8231) F...
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
  /*
   * The VT8231 registers
   *
   * The reset value for the input channel configuration is used (Reg 0x4A=0x07)
   * which sets the selected inputs marked with '*' below if multiple options are
   * possible:
   *
   *		    Voltage Mode	  Temperature Mode
   *	Sensor	      Linux Id	      Linux Id	      VIA Id
   *	--------      --------	      --------	      ------
   *	CPU Diode	N/A		temp1		0
   *	UIC1		in0		temp2 *		1
   *	UIC2		in1 *		temp3		2
   *	UIC3		in2 *		temp4		3
   *	UIC4		in3 *		temp5		4
   *	UIC5		in4 *		temp6		5
   *	3.3V		in5		N/A
   *
   * Note that the BIOS may set the configuration register to a different value
   * to match the motherboard configuration.
   */
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
59
60
61
62
63
64
65
66
67
68
  
  /* fans numbered 0-1 */
  #define VT8231_REG_FAN_MIN(nr)	(0x3b + (nr))
  #define VT8231_REG_FAN(nr)	(0x29 + (nr))
  
  /* Voltage inputs numbered 0-5 */
  
  static const u8 regvolt[]    = { 0x21, 0x22, 0x23, 0x24, 0x25, 0x26 };
  static const u8 regvoltmax[] = { 0x3d, 0x2b, 0x2d, 0x2f, 0x31, 0x33 };
  static const u8 regvoltmin[] = { 0x3e, 0x2c, 0x2e, 0x30, 0x32, 0x34 };
61ba03184   Guenter Roeck   hwmon: (vt8231) F...
69
70
71
72
73
74
75
76
  /*
   * Temperatures are numbered 1-6 according to the Linux kernel specification.
   *
   * In the VIA datasheet, however, the temperatures are numbered from zero.
   * Since it is important that this driver can easily be compared to the VIA
   * datasheet, we will use the VIA numbering within this driver and map the
   * kernel sysfs device name to the VIA number in the sysfs callback.
   */
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
  
  #define VT8231_REG_TEMP_LOW01	0x49
  #define VT8231_REG_TEMP_LOW25	0x4d
  
  static const u8 regtemp[]    = { 0x1f, 0x21, 0x22, 0x23, 0x24, 0x25 };
  static const u8 regtempmax[] = { 0x39, 0x3d, 0x2b, 0x2d, 0x2f, 0x31 };
  static const u8 regtempmin[] = { 0x3a, 0x3e, 0x2c, 0x2e, 0x30, 0x32 };
  
  #define TEMP_FROM_REG(reg)		(((253 * 4 - (reg)) * 550 + 105) / 210)
  #define TEMP_MAXMIN_FROM_REG(reg)	(((253 - (reg)) * 2200 + 105) / 210)
  #define TEMP_MAXMIN_TO_REG(val)		(253 - ((val) * 210 + 1100) / 2200)
  
  #define VT8231_REG_CONFIG 0x40
  #define VT8231_REG_ALARM1 0x41
  #define VT8231_REG_ALARM2 0x42
  #define VT8231_REG_FANDIV 0x47
  #define VT8231_REG_UCH_CONFIG 0x4a
  #define VT8231_REG_TEMP1_CONFIG 0x4b
  #define VT8231_REG_TEMP2_CONFIG 0x4c
61ba03184   Guenter Roeck   hwmon: (vt8231) F...
96
97
98
99
  /*
   * temps 0-5 as numbered in VIA datasheet - see later for mapping to Linux
   * numbering
   */
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
100
101
102
103
104
105
106
  #define ISTEMP(i, ch_config) ((i) == 0 ? 1 : \
  			      ((ch_config) >> ((i)+1)) & 0x01)
  /* voltages 0-5 */
  #define ISVOLT(i, ch_config) ((i) == 5 ? 1 : \
  			      !(((ch_config) >> ((i)+2)) & 0x01))
  
  #define DIV_FROM_REG(val) (1 << (val))
61ba03184   Guenter Roeck   hwmon: (vt8231) F...
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
  /*
   * NB  The values returned here are NOT temperatures.  The calibration curves
   *     for the thermistor curves are board-specific and must go in the
   *     sensors.conf file.  Temperature sensors are actually ten bits, but the
   *     VIA datasheet only considers the 8 MSBs obtained from the regtemp[]
   *     register.  The temperature value returned should have a magnitude of 3,
   *     so we use the VIA scaling as the "true" scaling and use the remaining 2
   *     LSBs as fractional precision.
   *
   *     All the on-chip hardware temperature comparisons for the alarms are only
   *     8-bits wide, and compare against the 8 MSBs of the temperature.  The bits
   *     in the registers VT8231_REG_TEMP_LOW01 and VT8231_REG_TEMP_LOW25 are
   *     ignored.
   */
  
  /*
   ****** FAN RPM CONVERSIONS ********
   * This chip saturates back at 0, not at 255 like many the other chips.
   * So, 0 means 0 RPM
   */
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
127
128
  static inline u8 FAN_TO_REG(long rpm, int div)
  {
3806b45ba   Dan Carpenter   hwmon: Prevent so...
129
  	if (rpm <= 0 || rpm > 1310720)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
130
  		return 0;
2a844c148   Guenter Roeck   hwmon: Replace SE...
131
  	return clamp_val(1310720 / (rpm * div), 1, 255);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
132
133
134
135
136
  }
  
  #define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : 1310720 / ((val) * (div)))
  
  struct vt8231_data {
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
137
138
  	unsigned short addr;
  	const char *name;
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
139
  	struct mutex update_lock;
1beeffe43   Tony Jones   hwmon: Convert fr...
140
  	struct device *hwmon_dev;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
  	char valid;		/* !=0 if following fields are valid */
  	unsigned long last_updated;	/* In jiffies */
  
  	u8 in[6];		/* Register value */
  	u8 in_max[6];		/* Register value */
  	u8 in_min[6];		/* Register value */
  	u16 temp[6];		/* Register value 10 bit, right aligned */
  	u8 temp_max[6];		/* Register value */
  	u8 temp_min[6];		/* Register value */
  	u8 fan[2];		/* Register value */
  	u8 fan_min[2];		/* Register value */
  	u8 fan_div[2];		/* Register encoding, shifted right */
  	u16 alarms;		/* Register encoding */
  	u8 uch_config;
  };
  
  static struct pci_dev *s_bridge;
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
158
  static int vt8231_probe(struct platform_device *pdev);
281dfd0b6   Bill Pemberton   hwmon: remove use...
159
  static int vt8231_remove(struct platform_device *pdev);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
160
  static struct vt8231_data *vt8231_update_device(struct device *dev);
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
161
  static void vt8231_init_device(struct vt8231_data *data);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
162

ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
163
  static inline int vt8231_read_value(struct vt8231_data *data, u8 reg)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
164
  {
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
165
  	return inb_p(data->addr + reg);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
166
  }
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
167
  static inline void vt8231_write_value(struct vt8231_data *data, u8 reg,
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
168
169
  					u8 value)
  {
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
170
  	outb_p(value, data->addr + reg);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
171
172
173
  }
  
  /* following are the sysfs callback functions */
08ea5a874   Guenter Roeck   hwmon: (vt8231) U...
174
175
  static ssize_t in_show(struct device *dev, struct device_attribute *attr,
  		       char *buf)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
176
177
178
179
180
181
182
183
  {
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
  	struct vt8231_data *data = vt8231_update_device(dev);
  
  	return sprintf(buf, "%d
  ", ((data->in[nr] - 3) * 10000) / 958);
  }
08ea5a874   Guenter Roeck   hwmon: (vt8231) U...
184
185
  static ssize_t in_min_show(struct device *dev, struct device_attribute *attr,
  			   char *buf)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
186
187
188
189
190
191
192
193
  {
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
  	struct vt8231_data *data = vt8231_update_device(dev);
  
  	return sprintf(buf, "%d
  ", ((data->in_min[nr] - 3) * 10000) / 958);
  }
08ea5a874   Guenter Roeck   hwmon: (vt8231) U...
194
195
  static ssize_t in_max_show(struct device *dev, struct device_attribute *attr,
  			   char *buf)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
196
197
198
199
200
201
202
203
  {
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
  	struct vt8231_data *data = vt8231_update_device(dev);
  
  	return sprintf(buf, "%d
  ", (((data->in_max[nr] - 3) * 10000) / 958));
  }
08ea5a874   Guenter Roeck   hwmon: (vt8231) U...
204
205
  static ssize_t in_min_store(struct device *dev, struct device_attribute *attr,
  			    const char *buf, size_t count)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
206
207
208
  {
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
209
  	struct vt8231_data *data = dev_get_drvdata(dev);
65fe5c795   Guenter Roeck   hwmon: (vt8231) F...
210
211
212
213
214
215
  	unsigned long val;
  	int err;
  
  	err = kstrtoul(buf, 10, &val);
  	if (err)
  		return err;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
216

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
217
  	mutex_lock(&data->update_lock);
2a844c148   Guenter Roeck   hwmon: Replace SE...
218
  	data->in_min[nr] = clamp_val(((val * 958) / 10000) + 3, 0, 255);
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
219
  	vt8231_write_value(data, regvoltmin[nr], data->in_min[nr]);
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
220
  	mutex_unlock(&data->update_lock);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
221
222
  	return count;
  }
08ea5a874   Guenter Roeck   hwmon: (vt8231) U...
223
224
  static ssize_t in_max_store(struct device *dev, struct device_attribute *attr,
  			    const char *buf, size_t count)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
225
226
227
  {
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
228
  	struct vt8231_data *data = dev_get_drvdata(dev);
65fe5c795   Guenter Roeck   hwmon: (vt8231) F...
229
230
231
232
233
234
  	unsigned long val;
  	int err;
  
  	err = kstrtoul(buf, 10, &val);
  	if (err)
  		return err;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
235

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
236
  	mutex_lock(&data->update_lock);
2a844c148   Guenter Roeck   hwmon: Replace SE...
237
  	data->in_max[nr] = clamp_val(((val * 958) / 10000) + 3, 0, 255);
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
238
  	vt8231_write_value(data, regvoltmax[nr], data->in_max[nr]);
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
239
  	mutex_unlock(&data->update_lock);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
240
241
242
243
  	return count;
  }
  
  /* Special case for input 5 as this has 3.3V scaling built into the chip */
d5034db6c   Julia Lawall   hwmon: (vt8231) u...
244
245
  static ssize_t in5_input_show(struct device *dev,
  			      struct device_attribute *attr, char *buf)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
246
247
248
249
250
251
252
  {
  	struct vt8231_data *data = vt8231_update_device(dev);
  
  	return sprintf(buf, "%d
  ",
  		(((data->in[5] - 3) * 10000 * 54) / (958 * 34)));
  }
d5034db6c   Julia Lawall   hwmon: (vt8231) u...
253
  static ssize_t in5_min_show(struct device *dev, struct device_attribute *attr,
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
254
255
256
257
258
259
260
261
  		char *buf)
  {
  	struct vt8231_data *data = vt8231_update_device(dev);
  
  	return sprintf(buf, "%d
  ",
  		(((data->in_min[5] - 3) * 10000 * 54) / (958 * 34)));
  }
d5034db6c   Julia Lawall   hwmon: (vt8231) u...
262
  static ssize_t in5_max_show(struct device *dev, struct device_attribute *attr,
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
263
264
265
266
267
268
269
270
  		char *buf)
  {
  	struct vt8231_data *data = vt8231_update_device(dev);
  
  	return sprintf(buf, "%d
  ",
  		(((data->in_max[5] - 3) * 10000 * 54) / (958 * 34)));
  }
d5034db6c   Julia Lawall   hwmon: (vt8231) u...
271
272
273
  static ssize_t in5_min_store(struct device *dev,
  			     struct device_attribute *attr, const char *buf,
  			     size_t count)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
274
  {
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
275
  	struct vt8231_data *data = dev_get_drvdata(dev);
65fe5c795   Guenter Roeck   hwmon: (vt8231) F...
276
277
278
279
280
281
  	unsigned long val;
  	int err;
  
  	err = kstrtoul(buf, 10, &val);
  	if (err)
  		return err;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
282

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
283
  	mutex_lock(&data->update_lock);
2a844c148   Guenter Roeck   hwmon: Replace SE...
284
285
  	data->in_min[5] = clamp_val(((val * 958 * 34) / (10000 * 54)) + 3,
  				    0, 255);
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
286
  	vt8231_write_value(data, regvoltmin[5], data->in_min[5]);
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
287
  	mutex_unlock(&data->update_lock);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
288
289
  	return count;
  }
d5034db6c   Julia Lawall   hwmon: (vt8231) u...
290
291
292
  static ssize_t in5_max_store(struct device *dev,
  			     struct device_attribute *attr, const char *buf,
  			     size_t count)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
293
  {
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
294
  	struct vt8231_data *data = dev_get_drvdata(dev);
65fe5c795   Guenter Roeck   hwmon: (vt8231) F...
295
296
297
298
299
300
  	unsigned long val;
  	int err;
  
  	err = kstrtoul(buf, 10, &val);
  	if (err)
  		return err;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
301

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
302
  	mutex_lock(&data->update_lock);
2a844c148   Guenter Roeck   hwmon: Replace SE...
303
304
  	data->in_max[5] = clamp_val(((val * 958 * 34) / (10000 * 54)) + 3,
  				    0, 255);
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
305
  	vt8231_write_value(data, regvoltmax[5], data->in_max[5]);
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
306
  	mutex_unlock(&data->update_lock);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
307
308
  	return count;
  }
08ea5a874   Guenter Roeck   hwmon: (vt8231) U...
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
  static SENSOR_DEVICE_ATTR_RO(in0_input, in, 0);
  static SENSOR_DEVICE_ATTR_RW(in0_min, in_min, 0);
  static SENSOR_DEVICE_ATTR_RW(in0_max, in_max, 0);
  static SENSOR_DEVICE_ATTR_RO(in1_input, in, 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, 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, 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, 4);
  static SENSOR_DEVICE_ATTR_RW(in4_min, in_min, 4);
  static SENSOR_DEVICE_ATTR_RW(in4_max, in_max, 4);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
324

d5034db6c   Julia Lawall   hwmon: (vt8231) u...
325
326
327
  static DEVICE_ATTR_RO(in5_input);
  static DEVICE_ATTR_RW(in5_min);
  static DEVICE_ATTR_RW(in5_max);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
328
329
  
  /* Temperatures */
d5034db6c   Julia Lawall   hwmon: (vt8231) u...
330
331
  static ssize_t temp1_input_show(struct device *dev,
  				struct device_attribute *attr, char *buf)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
332
333
334
335
336
  {
  	struct vt8231_data *data = vt8231_update_device(dev);
  	return sprintf(buf, "%d
  ", data->temp[0] * 250);
  }
d5034db6c   Julia Lawall   hwmon: (vt8231) u...
337
  static ssize_t temp1_max_show(struct device *dev, struct device_attribute *attr,
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
338
339
340
341
342
343
  		char *buf)
  {
  	struct vt8231_data *data = vt8231_update_device(dev);
  	return sprintf(buf, "%d
  ", data->temp_max[0] * 1000);
  }
d5034db6c   Julia Lawall   hwmon: (vt8231) u...
344
345
  static ssize_t temp1_max_hyst_show(struct device *dev,
  				   struct device_attribute *attr, char *buf)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
346
347
348
349
350
  {
  	struct vt8231_data *data = vt8231_update_device(dev);
  	return sprintf(buf, "%d
  ", data->temp_min[0] * 1000);
  }
d5034db6c   Julia Lawall   hwmon: (vt8231) u...
351
352
353
  static ssize_t temp1_max_store(struct device *dev,
  			       struct device_attribute *attr, const char *buf,
  			       size_t count)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
354
  {
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
355
  	struct vt8231_data *data = dev_get_drvdata(dev);
65fe5c795   Guenter Roeck   hwmon: (vt8231) F...
356
357
358
359
360
361
  	long val;
  	int err;
  
  	err = kstrtol(buf, 10, &val);
  	if (err)
  		return err;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
362

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
363
  	mutex_lock(&data->update_lock);
2a844c148   Guenter Roeck   hwmon: Replace SE...
364
  	data->temp_max[0] = clamp_val((val + 500) / 1000, 0, 255);
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
365
  	vt8231_write_value(data, regtempmax[0], data->temp_max[0]);
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
366
  	mutex_unlock(&data->update_lock);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
367
368
  	return count;
  }
d5034db6c   Julia Lawall   hwmon: (vt8231) u...
369
370
371
  static ssize_t temp1_max_hyst_store(struct device *dev,
  				    struct device_attribute *attr,
  				    const char *buf, size_t count)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
372
  {
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
373
  	struct vt8231_data *data = dev_get_drvdata(dev);
65fe5c795   Guenter Roeck   hwmon: (vt8231) F...
374
375
376
377
378
379
  	long val;
  	int err;
  
  	err = kstrtol(buf, 10, &val);
  	if (err)
  		return err;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
380

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
381
  	mutex_lock(&data->update_lock);
2a844c148   Guenter Roeck   hwmon: Replace SE...
382
  	data->temp_min[0] = clamp_val((val + 500) / 1000, 0, 255);
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
383
  	vt8231_write_value(data, regtempmin[0], data->temp_min[0]);
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
384
  	mutex_unlock(&data->update_lock);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
385
386
  	return count;
  }
08ea5a874   Guenter Roeck   hwmon: (vt8231) U...
387
388
  static ssize_t temp_show(struct device *dev, struct device_attribute *attr,
  			 char *buf)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
389
390
391
392
393
394
395
  {
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
  	struct vt8231_data *data = vt8231_update_device(dev);
  	return sprintf(buf, "%d
  ", TEMP_FROM_REG(data->temp[nr]));
  }
08ea5a874   Guenter Roeck   hwmon: (vt8231) U...
396
397
  static ssize_t temp_max_show(struct device *dev,
  			     struct device_attribute *attr, char *buf)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
398
399
400
401
402
403
404
  {
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
  	struct vt8231_data *data = vt8231_update_device(dev);
  	return sprintf(buf, "%d
  ", TEMP_MAXMIN_FROM_REG(data->temp_max[nr]));
  }
08ea5a874   Guenter Roeck   hwmon: (vt8231) U...
405
406
  static ssize_t temp_min_show(struct device *dev,
  			     struct device_attribute *attr, char *buf)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
407
408
409
410
411
412
413
  {
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
  	struct vt8231_data *data = vt8231_update_device(dev);
  	return sprintf(buf, "%d
  ", TEMP_MAXMIN_FROM_REG(data->temp_min[nr]));
  }
08ea5a874   Guenter Roeck   hwmon: (vt8231) U...
414
415
416
  static ssize_t temp_max_store(struct device *dev,
  			      struct device_attribute *attr, const char *buf,
  			      size_t count)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
417
418
419
  {
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
420
  	struct vt8231_data *data = dev_get_drvdata(dev);
65fe5c795   Guenter Roeck   hwmon: (vt8231) F...
421
422
423
424
425
426
  	long val;
  	int err;
  
  	err = kstrtol(buf, 10, &val);
  	if (err)
  		return err;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
427

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
428
  	mutex_lock(&data->update_lock);
2a844c148   Guenter Roeck   hwmon: Replace SE...
429
  	data->temp_max[nr] = clamp_val(TEMP_MAXMIN_TO_REG(val), 0, 255);
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
430
  	vt8231_write_value(data, regtempmax[nr], data->temp_max[nr]);
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
431
  	mutex_unlock(&data->update_lock);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
432
433
  	return count;
  }
08ea5a874   Guenter Roeck   hwmon: (vt8231) U...
434
435
436
  static ssize_t temp_min_store(struct device *dev,
  			      struct device_attribute *attr, const char *buf,
  			      size_t count)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
437
438
439
  {
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
440
  	struct vt8231_data *data = dev_get_drvdata(dev);
65fe5c795   Guenter Roeck   hwmon: (vt8231) F...
441
442
443
444
445
446
  	long val;
  	int err;
  
  	err = kstrtol(buf, 10, &val);
  	if (err)
  		return err;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
447

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
448
  	mutex_lock(&data->update_lock);
2a844c148   Guenter Roeck   hwmon: Replace SE...
449
  	data->temp_min[nr] = clamp_val(TEMP_MAXMIN_TO_REG(val), 0, 255);
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
450
  	vt8231_write_value(data, regtempmin[nr], data->temp_min[nr]);
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
451
  	mutex_unlock(&data->update_lock);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
452
453
  	return count;
  }
61ba03184   Guenter Roeck   hwmon: (vt8231) F...
454
455
456
457
  /*
   * Note that these map the Linux temperature sensor numbering (1-6) to the VIA
   * temperature sensor numbering (0-5)
   */
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
458

d5034db6c   Julia Lawall   hwmon: (vt8231) u...
459
460
461
  static DEVICE_ATTR_RO(temp1_input);
  static DEVICE_ATTR_RW(temp1_max);
  static DEVICE_ATTR_RW(temp1_max_hyst);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
462

08ea5a874   Guenter Roeck   hwmon: (vt8231) U...
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
  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_min, 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_min, 2);
  static SENSOR_DEVICE_ATTR_RO(temp4_input, temp, 3);
  static SENSOR_DEVICE_ATTR_RW(temp4_max, temp_max, 3);
  static SENSOR_DEVICE_ATTR_RW(temp4_max_hyst, temp_min, 3);
  static SENSOR_DEVICE_ATTR_RO(temp5_input, temp, 4);
  static SENSOR_DEVICE_ATTR_RW(temp5_max, temp_max, 4);
  static SENSOR_DEVICE_ATTR_RW(temp5_max_hyst, temp_min, 4);
  static SENSOR_DEVICE_ATTR_RO(temp6_input, temp, 5);
  static SENSOR_DEVICE_ATTR_RW(temp6_max, temp_max, 5);
  static SENSOR_DEVICE_ATTR_RW(temp6_max_hyst, temp_min, 5);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
478

1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
479
  /* Fans */
08ea5a874   Guenter Roeck   hwmon: (vt8231) U...
480
481
  static ssize_t fan_show(struct device *dev, struct device_attribute *attr,
  			char *buf)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
482
483
484
485
486
487
488
489
  {
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
  	struct vt8231_data *data = vt8231_update_device(dev);
  	return sprintf(buf, "%d
  ", FAN_FROM_REG(data->fan[nr],
  				DIV_FROM_REG(data->fan_div[nr])));
  }
08ea5a874   Guenter Roeck   hwmon: (vt8231) U...
490
491
  static ssize_t fan_min_show(struct device *dev, struct device_attribute *attr,
  			    char *buf)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
492
493
494
495
496
497
498
499
  {
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
  	struct vt8231_data *data = vt8231_update_device(dev);
  	return sprintf(buf, "%d
  ", FAN_FROM_REG(data->fan_min[nr],
  			DIV_FROM_REG(data->fan_div[nr])));
  }
08ea5a874   Guenter Roeck   hwmon: (vt8231) U...
500
501
  static ssize_t fan_div_show(struct device *dev, struct device_attribute *attr,
  			    char *buf)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
502
503
504
505
506
507
508
  {
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
  	struct vt8231_data *data = vt8231_update_device(dev);
  	return sprintf(buf, "%d
  ", DIV_FROM_REG(data->fan_div[nr]));
  }
08ea5a874   Guenter Roeck   hwmon: (vt8231) U...
509
510
511
  static ssize_t fan_min_store(struct device *dev,
  			     struct device_attribute *attr, const char *buf,
  			     size_t count)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
512
513
514
  {
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  	int nr = sensor_attr->index;
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
515
  	struct vt8231_data *data = dev_get_drvdata(dev);
65fe5c795   Guenter Roeck   hwmon: (vt8231) F...
516
517
518
519
520
521
  	unsigned long val;
  	int err;
  
  	err = kstrtoul(buf, 10, &val);
  	if (err)
  		return err;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
522

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
523
  	mutex_lock(&data->update_lock);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
524
  	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
525
  	vt8231_write_value(data, VT8231_REG_FAN_MIN(nr), data->fan_min[nr]);
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
526
  	mutex_unlock(&data->update_lock);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
527
528
  	return count;
  }
08ea5a874   Guenter Roeck   hwmon: (vt8231) U...
529
530
531
  static ssize_t fan_div_store(struct device *dev,
  			     struct device_attribute *attr, const char *buf,
  			     size_t count)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
532
  {
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
533
  	struct vt8231_data *data = dev_get_drvdata(dev);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
534
  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
65fe5c795   Guenter Roeck   hwmon: (vt8231) F...
535
  	unsigned long val;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
536
  	int nr = sensor_attr->index;
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
537
  	int old = vt8231_read_value(data, VT8231_REG_FANDIV);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
538
539
  	long min = FAN_FROM_REG(data->fan_min[nr],
  				 DIV_FROM_REG(data->fan_div[nr]));
65fe5c795   Guenter Roeck   hwmon: (vt8231) F...
540
541
542
543
544
  	int err;
  
  	err = kstrtoul(buf, 10, &val);
  	if (err)
  		return err;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
545

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
546
  	mutex_lock(&data->update_lock);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
547
  	switch (val) {
65fe5c795   Guenter Roeck   hwmon: (vt8231) F...
548
549
550
551
552
553
554
555
556
557
558
559
  	case 1:
  		data->fan_div[nr] = 0;
  		break;
  	case 2:
  		data->fan_div[nr] = 1;
  		break;
  	case 4:
  		data->fan_div[nr] = 2;
  		break;
  	case 8:
  		data->fan_div[nr] = 3;
  		break;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
560
  	default:
b55f37572   Guenter Roeck   hwmon: Fix checkp...
561
562
563
564
  		dev_err(dev,
  			"fan_div value %ld not supported. Choose one of 1, 2, 4 or 8!
  ",
  			val);
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
565
  		mutex_unlock(&data->update_lock);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
566
567
568
569
570
  		return -EINVAL;
  	}
  
  	/* Correct the fan minimum speed */
  	data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
571
  	vt8231_write_value(data, VT8231_REG_FAN_MIN(nr), data->fan_min[nr]);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
572
573
  
  	old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4);
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
574
  	vt8231_write_value(data, VT8231_REG_FANDIV, old);
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
575
  	mutex_unlock(&data->update_lock);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
576
577
  	return count;
  }
08ea5a874   Guenter Roeck   hwmon: (vt8231) U...
578
579
580
581
582
583
  static SENSOR_DEVICE_ATTR_RO(fan1_input, fan, 0);
  static SENSOR_DEVICE_ATTR_RW(fan1_min, fan_min, 0);
  static SENSOR_DEVICE_ATTR_RW(fan1_div, fan_div, 0);
  static SENSOR_DEVICE_ATTR_RO(fan2_input, fan, 1);
  static SENSOR_DEVICE_ATTR_RW(fan2_min, fan_min, 1);
  static SENSOR_DEVICE_ATTR_RW(fan2_div, fan_div, 1);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
584
585
  
  /* Alarms */
d5034db6c   Julia Lawall   hwmon: (vt8231) u...
586
  static ssize_t alarms_show(struct device *dev, struct device_attribute *attr,
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
587
588
589
590
591
592
  			   char *buf)
  {
  	struct vt8231_data *data = vt8231_update_device(dev);
  	return sprintf(buf, "%d
  ", data->alarms);
  }
d5034db6c   Julia Lawall   hwmon: (vt8231) u...
593
  static DEVICE_ATTR_RO(alarms);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
594

08ea5a874   Guenter Roeck   hwmon: (vt8231) U...
595
  static ssize_t alarm_show(struct device *dev, struct device_attribute *attr,
2d1374cad   Jean Delvare   hwmon: (vt8231) A...
596
597
598
599
600
601
602
  			  char *buf)
  {
  	int bitnr = to_sensor_dev_attr(attr)->index;
  	struct vt8231_data *data = vt8231_update_device(dev);
  	return sprintf(buf, "%u
  ", (data->alarms >> bitnr) & 1);
  }
08ea5a874   Guenter Roeck   hwmon: (vt8231) U...
603
604
605
606
607
608
609
610
611
612
613
614
615
616
  static SENSOR_DEVICE_ATTR_RO(temp1_alarm, alarm, 4);
  static SENSOR_DEVICE_ATTR_RO(temp2_alarm, alarm, 11);
  static SENSOR_DEVICE_ATTR_RO(temp3_alarm, alarm, 0);
  static SENSOR_DEVICE_ATTR_RO(temp4_alarm, alarm, 1);
  static SENSOR_DEVICE_ATTR_RO(temp5_alarm, alarm, 3);
  static SENSOR_DEVICE_ATTR_RO(temp6_alarm, alarm, 8);
  static SENSOR_DEVICE_ATTR_RO(in0_alarm, alarm, 11);
  static SENSOR_DEVICE_ATTR_RO(in1_alarm, alarm, 0);
  static SENSOR_DEVICE_ATTR_RO(in2_alarm, alarm, 1);
  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, 2);
  static SENSOR_DEVICE_ATTR_RO(fan1_alarm, alarm, 6);
  static SENSOR_DEVICE_ATTR_RO(fan2_alarm, alarm, 7);
2d1374cad   Jean Delvare   hwmon: (vt8231) A...
617

d5034db6c   Julia Lawall   hwmon: (vt8231) u...
618
  static ssize_t name_show(struct device *dev, struct device_attribute
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
619
620
621
622
623
624
  			 *devattr, char *buf)
  {
  	struct vt8231_data *data = dev_get_drvdata(dev);
  	return sprintf(buf, "%s
  ", data->name);
  }
d5034db6c   Julia Lawall   hwmon: (vt8231) u...
625
  static DEVICE_ATTR_RO(name);
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
626

2d1374cad   Jean Delvare   hwmon: (vt8231) A...
627
  static struct attribute *vt8231_attributes_temps[6][5] = {
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
628
629
630
631
  	{
  		&dev_attr_temp1_input.attr,
  		&dev_attr_temp1_max_hyst.attr,
  		&dev_attr_temp1_max.attr,
2d1374cad   Jean Delvare   hwmon: (vt8231) A...
632
  		&sensor_dev_attr_temp1_alarm.dev_attr.attr,
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
633
634
635
636
637
  		NULL
  	}, {
  		&sensor_dev_attr_temp2_input.dev_attr.attr,
  		&sensor_dev_attr_temp2_max_hyst.dev_attr.attr,
  		&sensor_dev_attr_temp2_max.dev_attr.attr,
2d1374cad   Jean Delvare   hwmon: (vt8231) A...
638
  		&sensor_dev_attr_temp2_alarm.dev_attr.attr,
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
639
640
641
642
643
  		NULL
  	}, {
  		&sensor_dev_attr_temp3_input.dev_attr.attr,
  		&sensor_dev_attr_temp3_max_hyst.dev_attr.attr,
  		&sensor_dev_attr_temp3_max.dev_attr.attr,
2d1374cad   Jean Delvare   hwmon: (vt8231) A...
644
  		&sensor_dev_attr_temp3_alarm.dev_attr.attr,
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
645
646
647
648
649
  		NULL
  	}, {
  		&sensor_dev_attr_temp4_input.dev_attr.attr,
  		&sensor_dev_attr_temp4_max_hyst.dev_attr.attr,
  		&sensor_dev_attr_temp4_max.dev_attr.attr,
2d1374cad   Jean Delvare   hwmon: (vt8231) A...
650
  		&sensor_dev_attr_temp4_alarm.dev_attr.attr,
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
651
652
653
654
655
  		NULL
  	}, {
  		&sensor_dev_attr_temp5_input.dev_attr.attr,
  		&sensor_dev_attr_temp5_max_hyst.dev_attr.attr,
  		&sensor_dev_attr_temp5_max.dev_attr.attr,
2d1374cad   Jean Delvare   hwmon: (vt8231) A...
656
  		&sensor_dev_attr_temp5_alarm.dev_attr.attr,
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
657
658
659
660
661
  		NULL
  	}, {
  		&sensor_dev_attr_temp6_input.dev_attr.attr,
  		&sensor_dev_attr_temp6_max_hyst.dev_attr.attr,
  		&sensor_dev_attr_temp6_max.dev_attr.attr,
2d1374cad   Jean Delvare   hwmon: (vt8231) A...
662
  		&sensor_dev_attr_temp6_alarm.dev_attr.attr,
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
663
664
665
666
667
668
669
670
671
672
673
674
  		NULL
  	}
  };
  
  static const struct attribute_group vt8231_group_temps[6] = {
  	{ .attrs = vt8231_attributes_temps[0] },
  	{ .attrs = vt8231_attributes_temps[1] },
  	{ .attrs = vt8231_attributes_temps[2] },
  	{ .attrs = vt8231_attributes_temps[3] },
  	{ .attrs = vt8231_attributes_temps[4] },
  	{ .attrs = vt8231_attributes_temps[5] },
  };
2d1374cad   Jean Delvare   hwmon: (vt8231) A...
675
  static struct attribute *vt8231_attributes_volts[6][5] = {
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
676
677
678
679
  	{
  		&sensor_dev_attr_in0_input.dev_attr.attr,
  		&sensor_dev_attr_in0_min.dev_attr.attr,
  		&sensor_dev_attr_in0_max.dev_attr.attr,
2d1374cad   Jean Delvare   hwmon: (vt8231) A...
680
  		&sensor_dev_attr_in0_alarm.dev_attr.attr,
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
681
682
683
684
685
  		NULL
  	}, {
  		&sensor_dev_attr_in1_input.dev_attr.attr,
  		&sensor_dev_attr_in1_min.dev_attr.attr,
  		&sensor_dev_attr_in1_max.dev_attr.attr,
2d1374cad   Jean Delvare   hwmon: (vt8231) A...
686
  		&sensor_dev_attr_in1_alarm.dev_attr.attr,
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
687
688
689
690
691
  		NULL
  	}, {
  		&sensor_dev_attr_in2_input.dev_attr.attr,
  		&sensor_dev_attr_in2_min.dev_attr.attr,
  		&sensor_dev_attr_in2_max.dev_attr.attr,
2d1374cad   Jean Delvare   hwmon: (vt8231) A...
692
  		&sensor_dev_attr_in2_alarm.dev_attr.attr,
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
693
694
695
696
697
  		NULL
  	}, {
  		&sensor_dev_attr_in3_input.dev_attr.attr,
  		&sensor_dev_attr_in3_min.dev_attr.attr,
  		&sensor_dev_attr_in3_max.dev_attr.attr,
2d1374cad   Jean Delvare   hwmon: (vt8231) A...
698
  		&sensor_dev_attr_in3_alarm.dev_attr.attr,
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
699
700
701
702
703
  		NULL
  	}, {
  		&sensor_dev_attr_in4_input.dev_attr.attr,
  		&sensor_dev_attr_in4_min.dev_attr.attr,
  		&sensor_dev_attr_in4_max.dev_attr.attr,
2d1374cad   Jean Delvare   hwmon: (vt8231) A...
704
  		&sensor_dev_attr_in4_alarm.dev_attr.attr,
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
705
706
707
708
709
  		NULL
  	}, {
  		&dev_attr_in5_input.attr,
  		&dev_attr_in5_min.attr,
  		&dev_attr_in5_max.attr,
2d1374cad   Jean Delvare   hwmon: (vt8231) A...
710
  		&sensor_dev_attr_in5_alarm.dev_attr.attr,
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
  		NULL
  	}
  };
  
  static const struct attribute_group vt8231_group_volts[6] = {
  	{ .attrs = vt8231_attributes_volts[0] },
  	{ .attrs = vt8231_attributes_volts[1] },
  	{ .attrs = vt8231_attributes_volts[2] },
  	{ .attrs = vt8231_attributes_volts[3] },
  	{ .attrs = vt8231_attributes_volts[4] },
  	{ .attrs = vt8231_attributes_volts[5] },
  };
  
  static struct attribute *vt8231_attributes[] = {
  	&sensor_dev_attr_fan1_input.dev_attr.attr,
  	&sensor_dev_attr_fan2_input.dev_attr.attr,
  	&sensor_dev_attr_fan1_min.dev_attr.attr,
  	&sensor_dev_attr_fan2_min.dev_attr.attr,
  	&sensor_dev_attr_fan1_div.dev_attr.attr,
  	&sensor_dev_attr_fan2_div.dev_attr.attr,
2d1374cad   Jean Delvare   hwmon: (vt8231) A...
731
732
  	&sensor_dev_attr_fan1_alarm.dev_attr.attr,
  	&sensor_dev_attr_fan2_alarm.dev_attr.attr,
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
733
  	&dev_attr_alarms.attr,
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
734
  	&dev_attr_name.attr,
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
735
736
737
738
739
740
  	NULL
  };
  
  static const struct attribute_group vt8231_group = {
  	.attrs = vt8231_attributes,
  };
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
741
  static struct platform_driver vt8231_driver = {
cdaf79349   Laurent Riffard   [PATCH] i2c: Drop...
742
  	.driver = {
cdaf79349   Laurent Riffard   [PATCH] i2c: Drop...
743
744
  		.name	= "vt8231",
  	},
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
745
  	.probe	= vt8231_probe,
9e5e9b7a9   Bill Pemberton   hwmon: remove use...
746
  	.remove	= vt8231_remove,
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
747
  };
cd9bb0564   Jingoo Han   hwmon: remove DEF...
748
  static const struct pci_device_id vt8231_pci_ids[] = {
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
749
750
751
752
753
  	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
  	{ 0, }
  };
  
  MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
6c931ae1c   Bill Pemberton   hwmon: remove use...
754
  static int vt8231_pci_probe(struct pci_dev *dev,
65fe5c795   Guenter Roeck   hwmon: (vt8231) F...
755
  				      const struct pci_device_id *id);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
756
757
758
759
760
761
  
  static struct pci_driver vt8231_pci_driver = {
  	.name		= "vt8231",
  	.id_table	= vt8231_pci_ids,
  	.probe		= vt8231_pci_probe,
  };
a022fef5a   Mark M. Hoffman   hwmon: (vt8231) f...
762
  static int vt8231_probe(struct platform_device *pdev)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
763
  {
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
764
  	struct resource *res;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
765
766
  	struct vt8231_data *data;
  	int err = 0, i;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
767
768
  
  	/* Reserve the ISA region */
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
769
  	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
7711f1bd0   Guenter Roeck   hwmon: (vt8231) C...
770
771
  	if (!devm_request_region(&pdev->dev, res->start, VT8231_EXTENT,
  				 vt8231_driver.driver.name)) {
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
772
773
774
  		dev_err(&pdev->dev, "Region 0x%lx-0x%lx already in use!
  ",
  			(unsigned long)res->start, (unsigned long)res->end);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
775
776
  		return -ENODEV;
  	}
7711f1bd0   Guenter Roeck   hwmon: (vt8231) C...
777
778
779
  	data = devm_kzalloc(&pdev->dev, sizeof(struct vt8231_data), GFP_KERNEL);
  	if (!data)
  		return -ENOMEM;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
780

ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
781
782
783
  	platform_set_drvdata(pdev, data);
  	data->addr = res->start;
  	data->name = "vt8231";
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
784

9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
785
  	mutex_init(&data->update_lock);
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
786
  	vt8231_init_device(data);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
787
788
  
  	/* Register sysfs hooks */
65fe5c795   Guenter Roeck   hwmon: (vt8231) F...
789
790
  	err = sysfs_create_group(&pdev->dev.kobj, &vt8231_group);
  	if (err)
7711f1bd0   Guenter Roeck   hwmon: (vt8231) C...
791
  		return err;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
792
793
  
  	/* Must update device information to find out the config field */
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
794
  	data->uch_config = vt8231_read_value(data, VT8231_REG_UCH_CONFIG);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
795

cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
796
  	for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++) {
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
797
  		if (ISTEMP(i, data->uch_config)) {
65fe5c795   Guenter Roeck   hwmon: (vt8231) F...
798
799
800
  			err = sysfs_create_group(&pdev->dev.kobj,
  						 &vt8231_group_temps[i]);
  			if (err)
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
801
  				goto exit_remove_files;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
802
803
  		}
  	}
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
804
  	for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) {
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
805
  		if (ISVOLT(i, data->uch_config)) {
65fe5c795   Guenter Roeck   hwmon: (vt8231) F...
806
807
808
  			err = sysfs_create_group(&pdev->dev.kobj,
  						 &vt8231_group_volts[i]);
  			if (err)
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
809
  				goto exit_remove_files;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
810
811
  		}
  	}
1beeffe43   Tony Jones   hwmon: Convert fr...
812
813
814
  	data->hwmon_dev = hwmon_device_register(&pdev->dev);
  	if (IS_ERR(data->hwmon_dev)) {
  		err = PTR_ERR(data->hwmon_dev);
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
815
816
  		goto exit_remove_files;
  	}
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
817
  	return 0;
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
818
819
  exit_remove_files:
  	for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++)
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
820
  		sysfs_remove_group(&pdev->dev.kobj, &vt8231_group_volts[i]);
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
821
822
  
  	for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++)
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
823
824
825
  		sysfs_remove_group(&pdev->dev.kobj, &vt8231_group_temps[i]);
  
  	sysfs_remove_group(&pdev->dev.kobj, &vt8231_group);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
826
827
  	return err;
  }
281dfd0b6   Bill Pemberton   hwmon: remove use...
828
  static int vt8231_remove(struct platform_device *pdev)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
829
  {
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
830
831
  	struct vt8231_data *data = platform_get_drvdata(pdev);
  	int i;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
832

1beeffe43   Tony Jones   hwmon: Convert fr...
833
  	hwmon_device_unregister(data->hwmon_dev);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
834

cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
835
  	for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++)
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
836
  		sysfs_remove_group(&pdev->dev.kobj, &vt8231_group_volts[i]);
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
837
838
  
  	for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++)
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
839
  		sysfs_remove_group(&pdev->dev.kobj, &vt8231_group_temps[i]);
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
840

ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
841
  	sysfs_remove_group(&pdev->dev.kobj, &vt8231_group);
cbeeb5b7c   Roger Lucas   vt8231: Fix unche...
842

1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
843
844
  	return 0;
  }
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
845
  static void vt8231_init_device(struct vt8231_data *data)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
846
  {
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
847
848
  	vt8231_write_value(data, VT8231_REG_TEMP1_CONFIG, 0);
  	vt8231_write_value(data, VT8231_REG_TEMP2_CONFIG, 0);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
849
850
851
852
  }
  
  static struct vt8231_data *vt8231_update_device(struct device *dev)
  {
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
853
  	struct vt8231_data *data = dev_get_drvdata(dev);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
854
855
  	int i;
  	u16 low;
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
856
  	mutex_lock(&data->update_lock);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
857
858
859
860
861
  
  	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
  	    || !data->valid) {
  		for (i = 0; i < 6; i++) {
  			if (ISVOLT(i, data->uch_config)) {
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
862
  				data->in[i] = vt8231_read_value(data,
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
863
  						regvolt[i]);
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
864
  				data->in_min[i] = vt8231_read_value(data,
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
865
  						regvoltmin[i]);
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
866
  				data->in_max[i] = vt8231_read_value(data,
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
867
868
869
870
  						regvoltmax[i]);
  			}
  		}
  		for (i = 0; i < 2; i++) {
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
871
  			data->fan[i] = vt8231_read_value(data,
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
872
  						VT8231_REG_FAN(i));
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
873
  			data->fan_min[i] = vt8231_read_value(data,
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
874
875
  						VT8231_REG_FAN_MIN(i));
  		}
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
876
  		low = vt8231_read_value(data, VT8231_REG_TEMP_LOW01);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
877
  		low = (low >> 6) | ((low & 0x30) >> 2)
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
878
  		    | (vt8231_read_value(data, VT8231_REG_TEMP_LOW25) << 4);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
879
880
  		for (i = 0; i < 6; i++) {
  			if (ISTEMP(i, data->uch_config)) {
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
881
  				data->temp[i] = (vt8231_read_value(data,
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
882
883
  						       regtemp[i]) << 2)
  						| ((low >> (2 * i)) & 0x03);
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
884
  				data->temp_max[i] = vt8231_read_value(data,
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
885
  						      regtempmax[i]);
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
886
  				data->temp_min[i] = vt8231_read_value(data,
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
887
888
889
  						      regtempmin[i]);
  			}
  		}
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
890
  		i = vt8231_read_value(data, VT8231_REG_FANDIV);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
891
892
  		data->fan_div[0] = (i >> 4) & 0x03;
  		data->fan_div[1] = i >> 6;
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
893
894
  		data->alarms = vt8231_read_value(data, VT8231_REG_ALARM1) |
  			(vt8231_read_value(data, VT8231_REG_ALARM2) << 8);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
895
896
  
  		/* Set alarm flags correctly */
65fe5c795   Guenter Roeck   hwmon: (vt8231) F...
897
  		if (!data->fan[0] && data->fan_min[0])
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
898
  			data->alarms |= 0x40;
65fe5c795   Guenter Roeck   hwmon: (vt8231) F...
899
  		else if (data->fan[0] && !data->fan_min[0])
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
900
  			data->alarms &= ~0x40;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
901

65fe5c795   Guenter Roeck   hwmon: (vt8231) F...
902
  		if (!data->fan[1] && data->fan_min[1])
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
903
  			data->alarms |= 0x80;
65fe5c795   Guenter Roeck   hwmon: (vt8231) F...
904
  		else if (data->fan[1] && !data->fan_min[1])
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
905
  			data->alarms &= ~0x80;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
906
907
908
909
  
  		data->last_updated = jiffies;
  		data->valid = 1;
  	}
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
910
  	mutex_unlock(&data->update_lock);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
911
912
913
  
  	return data;
  }
6c931ae1c   Bill Pemberton   hwmon: remove use...
914
  static int vt8231_device_add(unsigned short address)
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
915
916
917
918
919
920
921
922
  {
  	struct resource res = {
  		.start	= address,
  		.end	= address + VT8231_EXTENT - 1,
  		.name	= "vt8231",
  		.flags	= IORESOURCE_IO,
  	};
  	int err;
b9acb64a3   Jean Delvare   hwmon: Check for ...
923
924
925
  	err = acpi_check_resource_conflict(&res);
  	if (err)
  		goto exit;
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
926
927
928
  	pdev = platform_device_alloc("vt8231", address);
  	if (!pdev) {
  		err = -ENOMEM;
9d72be0da   Joe Perches   hwmon: (vt8231) U...
929
930
  		pr_err("Device allocation failed
  ");
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
931
932
933
934
935
  		goto exit;
  	}
  
  	err = platform_device_add_resources(pdev, &res, 1);
  	if (err) {
9d72be0da   Joe Perches   hwmon: (vt8231) U...
936
937
  		pr_err("Device resource addition failed (%d)
  ", err);
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
938
939
940
941
942
  		goto exit_device_put;
  	}
  
  	err = platform_device_add(pdev);
  	if (err) {
9d72be0da   Joe Perches   hwmon: (vt8231) U...
943
944
  		pr_err("Device addition failed (%d)
  ", err);
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
945
946
947
948
949
950
951
952
953
954
  		goto exit_device_put;
  	}
  
  	return 0;
  
  exit_device_put:
  	platform_device_put(pdev);
  exit:
  	return err;
  }
6c931ae1c   Bill Pemberton   hwmon: remove use...
955
  static int vt8231_pci_probe(struct pci_dev *dev,
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
956
957
  				const struct pci_device_id *id)
  {
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
958
959
960
961
962
963
964
965
966
967
968
  	u16 address, val;
  	if (force_addr) {
  		address = force_addr & 0xff00;
  		dev_warn(&dev->dev, "Forcing ISA address 0x%x
  ",
  			 address);
  
  		if (PCIBIOS_SUCCESSFUL !=
  		    pci_write_config_word(dev, VT8231_BASE_REG, address | 1))
  			return -ENODEV;
  	}
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
969

2207515db   Saheed O. Bolarinwa   hwmon: (i5k_amb, ...
970
971
  	pci_read_config_word(dev, VT8231_BASE_REG, &val);
  	if (val == (u16)~0)
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
972
  		return -ENODEV;
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
973
974
  	address = val & ~(VT8231_EXTENT - 1);
  	if (address == 0) {
4cae78784   Joe Perches   drivers/hwmon/vt8...
975
976
  		dev_err(&dev->dev, "base address not set - upgrade BIOS or use force_addr=0xaddr
  ");
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
977
978
  		return -ENODEV;
  	}
2207515db   Saheed O. Bolarinwa   hwmon: (i5k_amb, ...
979
980
  	pci_read_config_word(dev, VT8231_ENABLE_REG, &val);
  	if (val == (u16)~0)
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
981
  		return -ENODEV;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
982

ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
983
984
985
986
987
988
989
  	if (!(val & 0x0001)) {
  		dev_warn(&dev->dev, "enabling sensors
  ");
  		if (PCIBIOS_SUCCESSFUL !=
  			pci_write_config_word(dev, VT8231_ENABLE_REG,
  							val | 0x0001))
  			return -ENODEV;
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
990
  	}
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
991
992
993
994
995
996
  	if (platform_driver_register(&vt8231_driver))
  		goto exit;
  
  	/* Sets global pdev as a side effect */
  	if (vt8231_device_add(address))
  		goto exit_unregister;
61ba03184   Guenter Roeck   hwmon: (vt8231) F...
997
998
  	/*
  	 * Always return failure here.  This is to allow other drivers to bind
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
999
1000
1001
  	 * to this pci device.  We don't really want to have control over the
  	 * pci device, we only wanted to read as few register values from it.
  	 */
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
1002

61ba03184   Guenter Roeck   hwmon: (vt8231) F...
1003
1004
1005
1006
  	/*
  	 * We do, however, mark ourselves as using the PCI device to stop it
  	 * getting unloaded.
  	 */
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
1007
1008
1009
1010
1011
1012
  	s_bridge = pci_dev_get(dev);
  	return -ENODEV;
  
  exit_unregister:
  	platform_driver_unregister(&vt8231_driver);
  exit:
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
1013
1014
1015
1016
1017
  	return -ENODEV;
  }
  
  static int __init sm_vt8231_init(void)
  {
93b47684f   Richard Knutsson   [PATCH] drivers/*...
1018
  	return pci_register_driver(&vt8231_pci_driver);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
1019
1020
1021
1022
1023
1024
  }
  
  static void __exit sm_vt8231_exit(void)
  {
  	pci_unregister_driver(&vt8231_pci_driver);
  	if (s_bridge != NULL) {
ec5e1a4b8   Roger Lucas   hwmon: Convert vt...
1025
1026
  		platform_device_unregister(pdev);
  		platform_driver_unregister(&vt8231_driver);
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
1027
1028
1029
1030
  		pci_dev_put(s_bridge);
  		s_bridge = NULL;
  	}
  }
af865765a   Roger Lucas   hwmon: (vt8231) U...
1031
  MODULE_AUTHOR("Roger Lucas <vt8231@hiddenengine.co.uk>");
1de9e371b   Roger Lucas   [PATCH] hwmon: Ne...
1032
1033
1034
1035
1036
  MODULE_DESCRIPTION("VT8231 sensors");
  MODULE_LICENSE("GPL");
  
  module_init(sm_vt8231_init);
  module_exit(sm_vt8231_exit);