Blame view

drivers/hwmon/dme1737.c 77.4 KB
74ba9207e   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2
  /*
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
3
4
5
6
   * dme1737.c - Driver for the SMSC DME1737, Asus A8000, SMSC SCH311x, SCH5027,
   *             and SCH5127 Super-I/O chips integrated hardware monitoring
   *             features.
   * Copyright (c) 2007, 2008, 2009, 2010 Juerg Haefliger <juergh@gmail.com>
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
7
   *
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
8
   * This driver is an I2C/ISA hybrid, meaning that it uses the I2C bus to access
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
9
   * the chip registers if a DME1737, A8000, or SCH5027 is found and the ISA bus
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
10
11
12
   * if a SCH311x or SCH5127 chip is found. Both types of chips have very
   * similar hardware monitoring capabilities but differ in the way they can be
   * accessed.
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
13
   */
9c6e13b41   Joe Perches   hwmon: (dme1737) ...
14
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
15
16
17
18
19
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/slab.h>
  #include <linux/jiffies.h>
  #include <linux/i2c.h>
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
20
  #include <linux/platform_device.h>
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
21
22
23
24
25
  #include <linux/hwmon.h>
  #include <linux/hwmon-sysfs.h>
  #include <linux/hwmon-vid.h>
  #include <linux/err.h>
  #include <linux/mutex.h>
b9acb64a3   Jean Delvare   hwmon: Check for ...
26
  #include <linux/acpi.h>
6055fae8a   H Hartley Sweeten   hwmon: Include <l...
27
  #include <linux/io.h>
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
28

e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
29
30
  /* ISA device, if found */
  static struct platform_device *pdev;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
31
  /* Module load parameters */
90ab5ee94   Rusty Russell   module_param: mak...
32
  static bool force_start;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
33
34
  module_param(force_start, bool, 0);
  MODULE_PARM_DESC(force_start, "Force the chip to start monitoring inputs");
67b671bce   Jean Delvare   hwmon: Let the us...
35
36
37
  static unsigned short force_id;
  module_param(force_id, ushort, 0);
  MODULE_PARM_DESC(force_id, "Override the detected device ID");
90ab5ee94   Rusty Russell   module_param: mak...
38
  static bool probe_all_addr;
92430b6fe   Juerg Haefliger   hwmon: (dme1737) ...
39
  module_param(probe_all_addr, bool, 0);
b55f37572   Guenter Roeck   hwmon: Fix checkp...
40
41
  MODULE_PARM_DESC(probe_all_addr,
  		 "Include probing of non-standard LPC addresses");
92430b6fe   Juerg Haefliger   hwmon: (dme1737) ...
42

9431996f5   Juerg Haefliger   hwmon: New SMSC D...
43
  /* Addresses to scan */
25e9c86d5   Mark M. Hoffman   hwmon: normal_i2c...
44
  static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END};
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
45

ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
46
  enum chips { dme1737, sch5027, sch311x, sch5127 };
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
47

b55f37572   Guenter Roeck   hwmon: Fix checkp...
48
  #define	DO_REPORT "Please report to the driver maintainer."
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
49
50
51
52
53
54
55
56
57
58
59
60
61
62
  /* ---------------------------------------------------------------------
   * Registers
   *
   * The sensors are defined as follows:
   *
   * Voltages                          Temperatures
   * --------                          ------------
   * in0   +5VTR (+5V stdby)           temp1   Remote diode 1
   * in1   Vccp  (proc core)           temp2   Internal temp
   * in2   VCC   (internal +3.3V)      temp3   Remote diode 2
   * in3   +5V
   * in4   +12V
   * in5   VTR   (+3.3V stby)
   * in6   Vbat
d4b94e1fa   Juerg Haefliger   hwmon: (dme1737) ...
63
   * in7   Vtrip (sch5127 only)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
64
65
   *
   * --------------------------------------------------------------------- */
d4b94e1fa   Juerg Haefliger   hwmon: (dme1737) ...
66
  /* Voltages (in) numbered 0-7 (ix) */
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
67
  #define DME1737_REG_IN(ix)		((ix) < 5 ? 0x20 + (ix) : \
d4b94e1fa   Juerg Haefliger   hwmon: (dme1737) ...
68
69
  					 (ix) < 7 ? 0x94 + (ix) : \
  						    0x1f)
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
70
  #define DME1737_REG_IN_MIN(ix)		((ix) < 5 ? 0x44 + (ix) * 2 \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
71
  						  : 0x91 + (ix) * 2)
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
72
  #define DME1737_REG_IN_MAX(ix)		((ix) < 5 ? 0x45 + (ix) * 2 \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
73
74
75
76
77
78
79
80
  						  : 0x92 + (ix) * 2)
  
  /* Temperatures (temp) numbered 0-2 (ix) */
  #define DME1737_REG_TEMP(ix)		(0x25 + (ix))
  #define DME1737_REG_TEMP_MIN(ix)	(0x4e + (ix) * 2)
  #define DME1737_REG_TEMP_MAX(ix)	(0x4f + (ix) * 2)
  #define DME1737_REG_TEMP_OFFSET(ix)	((ix) == 0 ? 0x1f \
  						   : 0x1c + (ix))
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
81
82
  /*
   * Voltage and temperature LSBs
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
83
84
85
86
87
   * The LSBs (4 bits each) are stored in 5 registers with the following layouts:
   *    IN_TEMP_LSB(0) = [in5, in6]
   *    IN_TEMP_LSB(1) = [temp3, temp1]
   *    IN_TEMP_LSB(2) = [in4, temp2]
   *    IN_TEMP_LSB(3) = [in3, in0]
d4b94e1fa   Juerg Haefliger   hwmon: (dme1737) ...
88
   *    IN_TEMP_LSB(4) = [in2, in1]
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
89
90
   *    IN_TEMP_LSB(5) = [res, in7]
   */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
91
  #define DME1737_REG_IN_TEMP_LSB(ix)	(0x84 + (ix))
d4b94e1fa   Juerg Haefliger   hwmon: (dme1737) ...
92
93
  static const u8 DME1737_REG_IN_LSB[] = {3, 4, 4, 3, 2, 0, 0, 5};
  static const u8 DME1737_REG_IN_LSB_SHL[] = {4, 4, 0, 0, 0, 0, 4, 4};
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
  static const u8 DME1737_REG_TEMP_LSB[] = {1, 2, 1};
  static const u8 DME1737_REG_TEMP_LSB_SHL[] = {4, 4, 0};
  
  /* Fans numbered 0-5 (ix) */
  #define DME1737_REG_FAN(ix)		((ix) < 4 ? 0x28 + (ix) * 2 \
  						  : 0xa1 + (ix) * 2)
  #define DME1737_REG_FAN_MIN(ix)		((ix) < 4 ? 0x54 + (ix) * 2 \
  						  : 0xa5 + (ix) * 2)
  #define DME1737_REG_FAN_OPT(ix)		((ix) < 4 ? 0x90 + (ix) \
  						  : 0xb2 + (ix))
  #define DME1737_REG_FAN_MAX(ix)		(0xb4 + (ix)) /* only for fan[4-5] */
  
  /* PWMs numbered 0-2, 4-5 (ix) */
  #define DME1737_REG_PWM(ix)		((ix) < 3 ? 0x30 + (ix) \
  						  : 0xa1 + (ix))
  #define DME1737_REG_PWM_CONFIG(ix)	(0x5c + (ix)) /* only for pwm[0-2] */
  #define DME1737_REG_PWM_MIN(ix)		(0x64 + (ix)) /* only for pwm[0-2] */
  #define DME1737_REG_PWM_FREQ(ix)	((ix) < 3 ? 0x5f + (ix) \
  						  : 0xa3 + (ix))
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
113
114
  /*
   * The layout of the ramp rate registers is different from the other pwm
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
115
116
   * registers. The bits for the 3 PWMs are stored in 2 registers:
   *    PWM_RR(0) = [OFF3, OFF2,  OFF1,  RES,   RR1E, RR1-2, RR1-1, RR1-0]
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
117
118
   *    PWM_RR(1) = [RR2E, RR2-2, RR2-1, RR2-0, RR3E, RR3-2, RR3-1, RR3-0]
   */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
119
120
121
122
123
  #define DME1737_REG_PWM_RR(ix)		(0x62 + (ix)) /* only for pwm[0-2] */
  
  /* Thermal zones 0-2 */
  #define DME1737_REG_ZONE_LOW(ix)	(0x67 + (ix))
  #define DME1737_REG_ZONE_ABS(ix)	(0x6a + (ix))
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
124
125
  /*
   * The layout of the hysteresis registers is different from the other zone
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
126
127
   * registers. The bits for the 3 zones are stored in 2 registers:
   *    ZONE_HYST(0) = [H1-3,  H1-2,  H1-1, H1-0, H2-3, H2-2, H2-1, H2-0]
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
128
129
   *    ZONE_HYST(1) = [H3-3,  H3-2,  H3-1, H3-0, RES,  RES,  RES,  RES]
   */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
130
  #define DME1737_REG_ZONE_HYST(ix)	(0x6d + (ix))
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
131
132
  /*
   * Alarm registers and bit mapping
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
133
   * The 3 8-bit alarm registers will be concatenated to a single 32-bit
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
134
135
   * alarm value [0, ALARM3, ALARM2, ALARM1].
   */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
136
137
138
  #define DME1737_REG_ALARM1		0x41
  #define DME1737_REG_ALARM2		0x42
  #define DME1737_REG_ALARM3		0x83
d4b94e1fa   Juerg Haefliger   hwmon: (dme1737) ...
139
  static const u8 DME1737_BIT_ALARM_IN[] = {0, 1, 2, 3, 8, 16, 17, 18};
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
140
141
142
143
  static const u8 DME1737_BIT_ALARM_TEMP[] = {4, 5, 6};
  static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23};
  
  /* Miscellaneous registers */
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
144
  #define DME1737_REG_DEVICE		0x3d
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
  #define DME1737_REG_COMPANY		0x3e
  #define DME1737_REG_VERSTEP		0x3f
  #define DME1737_REG_CONFIG		0x40
  #define DME1737_REG_CONFIG2		0x7f
  #define DME1737_REG_VID			0x43
  #define DME1737_REG_TACH_PWM		0x81
  
  /* ---------------------------------------------------------------------
   * Misc defines
   * --------------------------------------------------------------------- */
  
  /* Chip identification */
  #define DME1737_COMPANY_SMSC	0x5c
  #define DME1737_VERSTEP		0x88
  #define DME1737_VERSTEP_MASK	0xf8
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
160
  #define SCH311X_DEVICE		0x8c
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
161
  #define SCH5027_VERSTEP		0x69
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
162
163
164
165
166
167
168
169
170
171
  #define SCH5127_DEVICE		0x8e
  
  /* Device ID values (global configuration register index 0x20) */
  #define DME1737_ID_1	0x77
  #define DME1737_ID_2	0x78
  #define SCH3112_ID	0x7c
  #define SCH3114_ID	0x7d
  #define SCH3116_ID	0x7f
  #define SCH5027_ID	0x89
  #define SCH5127_ID	0x86
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
172
173
174
  
  /* Length of ISA address segment */
  #define DME1737_EXTENT	2
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
175

ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
176
177
178
179
180
181
182
183
  /* chip-dependent features */
  #define HAS_TEMP_OFFSET		(1 << 0)		/* bit 0 */
  #define HAS_VID			(1 << 1)		/* bit 1 */
  #define HAS_ZONE3		(1 << 2)		/* bit 2 */
  #define HAS_ZONE_HYST		(1 << 3)		/* bit 3 */
  #define HAS_PWM_MIN		(1 << 4)		/* bit 4 */
  #define HAS_FAN(ix)		(1 << ((ix) + 5))	/* bits 5-10 */
  #define HAS_PWM(ix)		(1 << ((ix) + 11))	/* bits 11-16 */
d4b94e1fa   Juerg Haefliger   hwmon: (dme1737) ...
184
  #define HAS_IN7			(1 << 17)		/* bit 17 */
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
185

9431996f5   Juerg Haefliger   hwmon: New SMSC D...
186
187
188
189
190
  /* ---------------------------------------------------------------------
   * Data structures and manipulation thereof
   * --------------------------------------------------------------------- */
  
  struct dme1737_data {
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
191
  	struct i2c_client *client;	/* for I2C devices only */
1beeffe43   Tony Jones   hwmon: Convert fr...
192
  	struct device *hwmon_dev;
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
193
194
  	const char *name;
  	unsigned int addr;		/* for ISA devices only */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
195
196
197
198
199
  
  	struct mutex update_lock;
  	int valid;			/* !=0 if following fields are valid */
  	unsigned long last_update;	/* in jiffies */
  	unsigned long last_vbat;	/* in jiffies */
f994fb23d   Juerg Haefliger   hwmon: (dme1737) ...
200
  	enum chips type;
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
201
  	const int *in_nominal;		/* pointer to IN_NOMINAL array */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
202
203
204
  
  	u8 vid;
  	u8 pwm_rr_en;
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
205
  	u32 has_features;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
206
207
  
  	/* Register values */
d4b94e1fa   Juerg Haefliger   hwmon: (dme1737) ...
208
209
210
  	u16 in[8];
  	u8  in_min[8];
  	u8  in_max[8];
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
  	s16 temp[3];
  	s8  temp_min[3];
  	s8  temp_max[3];
  	s8  temp_offset[3];
  	u8  config;
  	u8  config2;
  	u8  vrm;
  	u16 fan[6];
  	u16 fan_min[6];
  	u8  fan_max[2];
  	u8  fan_opt[6];
  	u8  pwm[6];
  	u8  pwm_min[3];
  	u8  pwm_config[3];
  	u8  pwm_acz[3];
  	u8  pwm_freq[6];
  	u8  pwm_rr[2];
d58e47d78   Axel Lin   hwmon: (dme1737) ...
228
229
  	s8  zone_low[3];
  	s8  zone_abs[3];
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
230
231
232
233
234
  	u8  zone_hyst[2];
  	u32 alarms;
  };
  
  /* Nominal voltage values */
f994fb23d   Juerg Haefliger   hwmon: (dme1737) ...
235
236
237
238
  static const int IN_NOMINAL_DME1737[] = {5000, 2250, 3300, 5000, 12000, 3300,
  					 3300};
  static const int IN_NOMINAL_SCH311x[] = {2500, 1500, 3300, 5000, 12000, 3300,
  					 3300};
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
239
240
  static const int IN_NOMINAL_SCH5027[] = {5000, 2250, 3300, 1125, 1125, 3300,
  					 3300};
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
241
  static const int IN_NOMINAL_SCH5127[] = {2500, 2250, 3300, 1125, 1125, 3300,
d4b94e1fa   Juerg Haefliger   hwmon: (dme1737) ...
242
  					 3300, 1500};
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
243
244
  #define IN_NOMINAL(type)	((type) == sch311x ? IN_NOMINAL_SCH311x : \
  				 (type) == sch5027 ? IN_NOMINAL_SCH5027 : \
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
245
  				 (type) == sch5127 ? IN_NOMINAL_SCH5127 : \
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
246
  				 IN_NOMINAL_DME1737)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
247

c8de83624   Guenter Roeck   hwmon: (dme1737) ...
248
249
  /*
   * Voltage input
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
250
   * Voltage inputs have 16 bits resolution, limit values have 8 bits
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
251
252
   * resolution.
   */
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
253
  static inline int IN_FROM_REG(int reg, int nominal, int res)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
254
  {
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
255
  	return (reg * nominal + (3 << (res - 3))) / (3 << (res - 2));
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
256
  }
d58e47d78   Axel Lin   hwmon: (dme1737) ...
257
  static inline int IN_TO_REG(long val, int nominal)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
258
  {
07cc189d1   Guenter Roeck   hwmon: (dme1737) ...
259
260
  	val = clamp_val(val, 0, 255 * nominal / 192);
  	return DIV_ROUND_CLOSEST(val * 192, nominal);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
261
  }
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
262
263
  /*
   * Temperature input
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
264
265
   * The register values represent temperatures in 2's complement notation from
   * -127 degrees C to +127 degrees C. Temp inputs have 16 bits resolution, limit
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
266
267
   * values have 8 bits resolution.
   */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
268
269
270
271
  static inline int TEMP_FROM_REG(int reg, int res)
  {
  	return (reg * 1000) >> (res - 8);
  }
d58e47d78   Axel Lin   hwmon: (dme1737) ...
272
  static inline int TEMP_TO_REG(long val)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
273
  {
07cc189d1   Guenter Roeck   hwmon: (dme1737) ...
274
275
  	val = clamp_val(val, -128000, 127000);
  	return DIV_ROUND_CLOSEST(val, 1000);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
276
277
278
279
280
281
282
283
284
285
286
  }
  
  /* Temperature range */
  static const int TEMP_RANGE[] = {2000, 2500, 3333, 4000, 5000, 6666, 8000,
  				 10000, 13333, 16000, 20000, 26666, 32000,
  				 40000, 53333, 80000};
  
  static inline int TEMP_RANGE_FROM_REG(int reg)
  {
  	return TEMP_RANGE[(reg >> 4) & 0x0f];
  }
d58e47d78   Axel Lin   hwmon: (dme1737) ...
287
  static int TEMP_RANGE_TO_REG(long val, int reg)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
288
289
290
291
  {
  	int i;
  
  	for (i = 15; i > 0; i--) {
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
292
  		if (val > (TEMP_RANGE[i] + TEMP_RANGE[i - 1] + 1) / 2)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
293
  			break;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
294
295
296
297
  	}
  
  	return (reg & 0x0f) | (i << 4);
  }
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
298
299
  /*
   * Temperature hysteresis
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
300
301
   * Register layout:
   *    reg[0] = [H1-3, H1-2, H1-1, H1-0, H2-3, H2-2, H2-1, H2-0]
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
302
303
   *    reg[1] = [H3-3, H3-2, H3-1, H3-0, xxxx, xxxx, xxxx, xxxx]
   */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
304
305
306
307
  static inline int TEMP_HYST_FROM_REG(int reg, int ix)
  {
  	return (((ix == 1) ? reg : reg >> 4) & 0x0f) * 1000;
  }
07cc189d1   Guenter Roeck   hwmon: (dme1737) ...
308
  static inline int TEMP_HYST_TO_REG(int temp, long hyst, int ix, int reg)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
309
  {
07cc189d1   Guenter Roeck   hwmon: (dme1737) ...
310
311
  	hyst = clamp_val(hyst, temp - 15000, temp);
  	hyst = DIV_ROUND_CLOSEST(temp - hyst, 1000);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
312
313
314
315
316
317
318
  
  	return (ix == 1) ? (reg & 0xf0) | hyst : (reg & 0x0f) | (hyst << 4);
  }
  
  /* Fan input RPM */
  static inline int FAN_FROM_REG(int reg, int tpc)
  {
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
319
  	if (tpc)
ff8421f73   Juerg Haefliger   hwmon: (dme1737) ...
320
  		return tpc * reg;
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
321
  	else
ff8421f73   Juerg Haefliger   hwmon: (dme1737) ...
322
  		return (reg == 0 || reg == 0xffff) ? 0 : 90000 * 60 / reg;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
323
  }
d58e47d78   Axel Lin   hwmon: (dme1737) ...
324
  static inline int FAN_TO_REG(long val, int tpc)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
325
  {
ff8421f73   Juerg Haefliger   hwmon: (dme1737) ...
326
  	if (tpc) {
2a844c148   Guenter Roeck   hwmon: Replace SE...
327
  		return clamp_val(val / tpc, 0, 0xffff);
ff8421f73   Juerg Haefliger   hwmon: (dme1737) ...
328
329
  	} else {
  		return (val <= 0) ? 0xffff :
2a844c148   Guenter Roeck   hwmon: Replace SE...
330
  			clamp_val(90000 * 60 / val, 0, 0xfffe);
ff8421f73   Juerg Haefliger   hwmon: (dme1737) ...
331
  	}
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
332
  }
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
333
334
  /*
   * Fan TPC (tach pulse count)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
335
   * Converts a register value to a TPC multiplier or returns 0 if the tachometer
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
336
337
   * is configured in legacy (non-tpc) mode
   */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
338
339
340
341
  static inline int FAN_TPC_FROM_REG(int reg)
  {
  	return (reg & 0x20) ? 0 : 60 >> (reg & 0x03);
  }
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
342
343
  /*
   * Fan type
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
344
   * The type of a fan is expressed in number of pulses-per-revolution that it
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
345
346
   * emits
   */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
347
348
349
350
351
352
  static inline int FAN_TYPE_FROM_REG(int reg)
  {
  	int edge = (reg >> 1) & 0x03;
  
  	return (edge > 0) ? 1 << (edge - 1) : 0;
  }
d58e47d78   Axel Lin   hwmon: (dme1737) ...
353
  static inline int FAN_TYPE_TO_REG(long val, int reg)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
  {
  	int edge = (val == 4) ? 3 : val;
  
  	return (reg & 0xf9) | (edge << 1);
  }
  
  /* Fan max RPM */
  static const int FAN_MAX[] = {0x54, 0x38, 0x2a, 0x21, 0x1c, 0x18, 0x15, 0x12,
  			      0x11, 0x0f, 0x0e};
  
  static int FAN_MAX_FROM_REG(int reg)
  {
  	int i;
  
  	for (i = 10; i > 0; i--) {
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
369
  		if (reg == FAN_MAX[i])
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
370
  			break;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
371
372
373
374
  	}
  
  	return 1000 + i * 500;
  }
d58e47d78   Axel Lin   hwmon: (dme1737) ...
375
  static int FAN_MAX_TO_REG(long val)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
376
377
378
379
  {
  	int i;
  
  	for (i = 10; i > 0; i--) {
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
380
  		if (val > (1000 + (i - 1) * 500))
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
381
  			break;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
382
383
384
385
  	}
  
  	return FAN_MAX[i];
  }
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
386
387
  /*
   * PWM enable
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
388
389
390
391
392
393
394
395
   * Register to enable mapping:
   * 000:  2  fan on zone 1 auto
   * 001:  2  fan on zone 2 auto
   * 010:  2  fan on zone 3 auto
   * 011:  0  fan full on
   * 100: -1  fan disabled
   * 101:  2  fan on hottest of zones 2,3 auto
   * 110:  2  fan on hottest of zones 1,2,3 auto
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
396
397
   * 111:  1  fan in manual mode
   */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
398
399
400
401
402
403
404
405
406
407
408
409
410
  static inline int PWM_EN_FROM_REG(int reg)
  {
  	static const int en[] = {2, 2, 2, 0, -1, 2, 2, 1};
  
  	return en[(reg >> 5) & 0x07];
  }
  
  static inline int PWM_EN_TO_REG(int val, int reg)
  {
  	int en = (val == 1) ? 7 : 3;
  
  	return (reg & 0x1f) | ((en & 0x07) << 5);
  }
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
411
412
  /*
   * PWM auto channels zone
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
413
414
415
416
417
418
419
420
421
   * Register to auto channels zone mapping (ACZ is a bitfield with bit x
   * corresponding to zone x+1):
   * 000: 001  fan on zone 1 auto
   * 001: 010  fan on zone 2 auto
   * 010: 100  fan on zone 3 auto
   * 011: 000  fan full on
   * 100: 000  fan disabled
   * 101: 110  fan on hottest of zones 2,3 auto
   * 110: 111  fan on hottest of zones 1,2,3 auto
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
422
423
   * 111: 000  fan in manual mode
   */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
424
425
426
427
428
429
  static inline int PWM_ACZ_FROM_REG(int reg)
  {
  	static const int acz[] = {1, 2, 4, 0, 0, 6, 7, 0};
  
  	return acz[(reg >> 5) & 0x07];
  }
d58e47d78   Axel Lin   hwmon: (dme1737) ...
430
  static inline int PWM_ACZ_TO_REG(long val, int reg)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
431
432
433
434
435
436
437
438
439
440
441
442
443
444
  {
  	int acz = (val == 4) ? 2 : val - 1;
  
  	return (reg & 0x1f) | ((acz & 0x07) << 5);
  }
  
  /* PWM frequency */
  static const int PWM_FREQ[] = {11, 15, 22, 29, 35, 44, 59, 88,
  			       15000, 20000, 30000, 25000, 0, 0, 0, 0};
  
  static inline int PWM_FREQ_FROM_REG(int reg)
  {
  	return PWM_FREQ[reg & 0x0f];
  }
d58e47d78   Axel Lin   hwmon: (dme1737) ...
445
  static int PWM_FREQ_TO_REG(long val, int reg)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
446
447
448
449
450
451
452
453
454
455
  {
  	int i;
  
  	/* the first two cases are special - stupid chip design! */
  	if (val > 27500) {
  		i = 10;
  	} else if (val > 22500) {
  		i = 11;
  	} else {
  		for (i = 9; i > 0; i--) {
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
456
  			if (val > (PWM_FREQ[i] + PWM_FREQ[i - 1] + 1) / 2)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
457
  				break;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
458
459
460
461
462
  		}
  	}
  
  	return (reg & 0xf0) | i;
  }
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
463
464
  /*
   * PWM ramp rate
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
465
466
   * Register layout:
   *    reg[0] = [OFF3,  OFF2,  OFF1,  RES,   RR1-E, RR1-2, RR1-1, RR1-0]
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
467
468
   *    reg[1] = [RR2-E, RR2-2, RR2-1, RR2-0, RR3-E, RR3-2, RR3-1, RR3-0]
   */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
469
470
471
472
473
474
475
476
  static const u8 PWM_RR[] = {206, 104, 69, 41, 26, 18, 10, 5};
  
  static inline int PWM_RR_FROM_REG(int reg, int ix)
  {
  	int rr = (ix == 1) ? reg >> 4 : reg;
  
  	return (rr & 0x08) ? PWM_RR[rr & 0x07] : 0;
  }
d58e47d78   Axel Lin   hwmon: (dme1737) ...
477
  static int PWM_RR_TO_REG(long val, int ix, int reg)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
478
479
480
481
  {
  	int i;
  
  	for (i = 0; i < 7; i++) {
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
482
  		if (val > (PWM_RR[i] + PWM_RR[i + 1] + 1) / 2)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
483
  			break;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
484
485
486
487
488
489
490
491
492
493
  	}
  
  	return (ix == 1) ? (reg & 0x8f) | (i << 4) : (reg & 0xf8) | i;
  }
  
  /* PWM ramp rate enable */
  static inline int PWM_RR_EN_FROM_REG(int reg, int ix)
  {
  	return PWM_RR_FROM_REG(reg, ix) ? 1 : 0;
  }
d58e47d78   Axel Lin   hwmon: (dme1737) ...
494
  static inline int PWM_RR_EN_TO_REG(long val, int ix, int reg)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
495
496
497
498
499
  {
  	int en = (ix == 1) ? 0x80 : 0x08;
  
  	return val ? reg | en : reg & ~en;
  }
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
500
501
  /*
   * PWM min/off
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
502
   * The PWM min/off bits are part of the PMW ramp rate register 0 (see above for
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
503
504
   * the register layout).
   */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
505
506
507
508
509
510
511
512
513
514
515
516
  static inline int PWM_OFF_FROM_REG(int reg, int ix)
  {
  	return (reg >> (ix + 5)) & 0x01;
  }
  
  static inline int PWM_OFF_TO_REG(int val, int ix, int reg)
  {
  	return (reg & ~(1 << (ix + 5))) | ((val & 0x01) << (ix + 5));
  }
  
  /* ---------------------------------------------------------------------
   * Device I/O access
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
517
518
519
520
521
   *
   * ISA access is performed through an index/data register pair and needs to
   * be protected by a mutex during runtime (not required for initialization).
   * We use data->update_lock for this and need to ensure that we acquire it
   * before calling dme1737_read or dme1737_write.
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
522
   * --------------------------------------------------------------------- */
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
523
  static u8 dme1737_read(const struct dme1737_data *data, u8 reg)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
524
  {
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
525
  	struct i2c_client *client = data->client;
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
526
  	s32 val;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
527

dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
528
  	if (client) { /* I2C device */
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
529
530
531
  		val = i2c_smbus_read_byte_data(client, reg);
  
  		if (val < 0) {
b55f37572   Guenter Roeck   hwmon: Fix checkp...
532
533
534
535
  			dev_warn(&client->dev,
  				 "Read from register 0x%02x failed! %s
  ",
  				 reg, DO_REPORT);
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
536
537
  		}
  	} else { /* ISA device */
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
538
539
  		outb(reg, data->addr);
  		val = inb(data->addr + 1);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
540
541
542
543
  	}
  
  	return val;
  }
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
544
  static s32 dme1737_write(const struct dme1737_data *data, u8 reg, u8 val)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
545
  {
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
546
  	struct i2c_client *client = data->client;
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
547
  	s32 res = 0;
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
548
  	if (client) { /* I2C device */
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
549
  		res = i2c_smbus_write_byte_data(client, reg, val);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
550

e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
551
  		if (res < 0) {
b55f37572   Guenter Roeck   hwmon: Fix checkp...
552
553
554
555
  			dev_warn(&client->dev,
  				 "Write to register 0x%02x failed! %s
  ",
  				 reg, DO_REPORT);
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
556
557
  		}
  	} else { /* ISA device */
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
558
559
  		outb(reg, data->addr);
  		outb(val, data->addr + 1);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
560
561
562
563
564
565
566
  	}
  
  	return res;
  }
  
  static struct dme1737_data *dme1737_update_device(struct device *dev)
  {
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
567
  	struct dme1737_data *data = dev_get_drvdata(dev);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
568
  	int ix;
d4b94e1fa   Juerg Haefliger   hwmon: (dme1737) ...
569
  	u8 lsb[6];
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
570
571
572
573
574
  
  	mutex_lock(&data->update_lock);
  
  	/* Enable a Vbat monitoring cycle every 10 mins */
  	if (time_after(jiffies, data->last_vbat + 600 * HZ) || !data->valid) {
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
575
  		dme1737_write(data, DME1737_REG_CONFIG, dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
576
577
578
579
580
581
  						DME1737_REG_CONFIG) | 0x10);
  		data->last_vbat = jiffies;
  	}
  
  	/* Sample register contents every 1 sec */
  	if (time_after(jiffies, data->last_update + HZ) || !data->valid) {
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
582
  		if (data->has_features & HAS_VID) {
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
583
  			data->vid = dme1737_read(data, DME1737_REG_VID) &
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
584
585
  				0x3f;
  		}
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
586
587
588
  
  		/* In (voltage) registers */
  		for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) {
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
589
590
  			/*
  			 * Voltage inputs are stored as 16 bit values even
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
591
  			 * though they have only 12 bits resolution. This is
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
592
593
594
  			 * to make it consistent with the temp inputs.
  			 */
  			if (ix == 7 && !(data->has_features & HAS_IN7))
d4b94e1fa   Juerg Haefliger   hwmon: (dme1737) ...
595
  				continue;
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
596
  			data->in[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
597
  					DME1737_REG_IN(ix)) << 8;
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
598
  			data->in_min[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
599
  					DME1737_REG_IN_MIN(ix));
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
600
  			data->in_max[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
601
602
603
604
605
  					DME1737_REG_IN_MAX(ix));
  		}
  
  		/* Temp registers */
  		for (ix = 0; ix < ARRAY_SIZE(data->temp); ix++) {
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
606
607
  			/*
  			 * Temp inputs are stored as 16 bit values even
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
608
609
610
  			 * though they have only 12 bits resolution. This is
  			 * to take advantage of implicit conversions between
  			 * register values (2's complement) and temp values
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
611
612
  			 * (signed decimal).
  			 */
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
613
  			data->temp[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
614
  					DME1737_REG_TEMP(ix)) << 8;
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
615
  			data->temp_min[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
616
  					DME1737_REG_TEMP_MIN(ix));
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
617
  			data->temp_max[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
618
  					DME1737_REG_TEMP_MAX(ix));
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
619
  			if (data->has_features & HAS_TEMP_OFFSET) {
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
620
  				data->temp_offset[ix] = dme1737_read(data,
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
621
622
  						DME1737_REG_TEMP_OFFSET(ix));
  			}
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
623
  		}
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
624
625
  		/*
  		 * In and temp LSB registers
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
626
627
  		 * The LSBs are latched when the MSBs are read, so the order in
  		 * which the registers are read (MSB first, then LSB) is
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
628
629
  		 * important!
  		 */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
630
  		for (ix = 0; ix < ARRAY_SIZE(lsb); ix++) {
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
631
  			if (ix == 5 && !(data->has_features & HAS_IN7))
d4b94e1fa   Juerg Haefliger   hwmon: (dme1737) ...
632
  				continue;
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
633
  			lsb[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
634
635
636
  					DME1737_REG_IN_TEMP_LSB(ix));
  		}
  		for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) {
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
637
  			if (ix == 7 && !(data->has_features & HAS_IN7))
d4b94e1fa   Juerg Haefliger   hwmon: (dme1737) ...
638
  				continue;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
639
640
641
642
643
644
645
646
647
648
  			data->in[ix] |= (lsb[DME1737_REG_IN_LSB[ix]] <<
  					DME1737_REG_IN_LSB_SHL[ix]) & 0xf0;
  		}
  		for (ix = 0; ix < ARRAY_SIZE(data->temp); ix++) {
  			data->temp[ix] |= (lsb[DME1737_REG_TEMP_LSB[ix]] <<
  					DME1737_REG_TEMP_LSB_SHL[ix]) & 0xf0;
  		}
  
  		/* Fan registers */
  		for (ix = 0; ix < ARRAY_SIZE(data->fan); ix++) {
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
649
650
651
652
653
  			/*
  			 * Skip reading registers if optional fans are not
  			 * present
  			 */
  			if (!(data->has_features & HAS_FAN(ix)))
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
654
  				continue;
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
655
  			data->fan[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
656
  					DME1737_REG_FAN(ix));
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
657
  			data->fan[ix] |= dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
658
  					DME1737_REG_FAN(ix) + 1) << 8;
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
659
  			data->fan_min[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
660
  					DME1737_REG_FAN_MIN(ix));
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
661
  			data->fan_min[ix] |= dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
662
  					DME1737_REG_FAN_MIN(ix) + 1) << 8;
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
663
  			data->fan_opt[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
664
665
666
  					DME1737_REG_FAN_OPT(ix));
  			/* fan_max exists only for fan[5-6] */
  			if (ix > 3) {
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
667
  				data->fan_max[ix - 4] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
668
669
670
671
672
673
  					DME1737_REG_FAN_MAX(ix));
  			}
  		}
  
  		/* PWM registers */
  		for (ix = 0; ix < ARRAY_SIZE(data->pwm); ix++) {
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
674
675
676
677
678
  			/*
  			 * Skip reading registers if optional PWMs are not
  			 * present
  			 */
  			if (!(data->has_features & HAS_PWM(ix)))
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
679
  				continue;
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
680
  			data->pwm[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
681
  					DME1737_REG_PWM(ix));
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
682
  			data->pwm_freq[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
683
684
685
  					DME1737_REG_PWM_FREQ(ix));
  			/* pwm_config and pwm_min exist only for pwm[1-3] */
  			if (ix < 3) {
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
686
  				data->pwm_config[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
687
  						DME1737_REG_PWM_CONFIG(ix));
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
688
  				data->pwm_min[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
689
690
691
692
  						DME1737_REG_PWM_MIN(ix));
  			}
  		}
  		for (ix = 0; ix < ARRAY_SIZE(data->pwm_rr); ix++) {
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
693
  			data->pwm_rr[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
694
695
696
697
698
  						DME1737_REG_PWM_RR(ix));
  		}
  
  		/* Thermal zone registers */
  		for (ix = 0; ix < ARRAY_SIZE(data->zone_low); ix++) {
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
699
  			/* Skip reading registers if zone3 is not present */
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
700
  			if ((ix == 2) && !(data->has_features & HAS_ZONE3))
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
701
  				continue;
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
702
703
704
705
706
707
708
709
710
711
712
713
  			/* sch5127 zone2 registers are special */
  			if ((ix == 1) && (data->type == sch5127)) {
  				data->zone_low[1] = dme1737_read(data,
  						DME1737_REG_ZONE_LOW(2));
  				data->zone_abs[1] = dme1737_read(data,
  						DME1737_REG_ZONE_ABS(2));
  			} else {
  				data->zone_low[ix] = dme1737_read(data,
  						DME1737_REG_ZONE_LOW(ix));
  				data->zone_abs[ix] = dme1737_read(data,
  						DME1737_REG_ZONE_ABS(ix));
  			}
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
714
  		}
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
715
  		if (data->has_features & HAS_ZONE_HYST) {
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
716
  			for (ix = 0; ix < ARRAY_SIZE(data->zone_hyst); ix++) {
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
717
  				data->zone_hyst[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
718
  						DME1737_REG_ZONE_HYST(ix));
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
719
  			}
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
720
721
722
  		}
  
  		/* Alarm registers */
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
723
  		data->alarms = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
724
  						DME1737_REG_ALARM1);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
725
726
727
728
  		/*
  		 * Bit 7 tells us if the other alarm registers are non-zero and
  		 * therefore also need to be read
  		 */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
729
  		if (data->alarms & 0x80) {
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
730
  			data->alarms |= dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
731
  						DME1737_REG_ALARM2) << 8;
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
732
  			data->alarms |= dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
733
734
  						DME1737_REG_ALARM3) << 16;
  		}
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
735
736
  		/*
  		 * The ISA chips require explicit clearing of alarm bits.
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
737
  		 * Don't worry, an alarm will come back if the condition
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
738
739
  		 * that causes it still exists
  		 */
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
740
  		if (!data->client) {
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
741
742
743
744
745
746
  			if (data->alarms & 0xff0000)
  				dme1737_write(data, DME1737_REG_ALARM3, 0xff);
  			if (data->alarms & 0xff00)
  				dme1737_write(data, DME1737_REG_ALARM2, 0xff);
  			if (data->alarms & 0xff)
  				dme1737_write(data, DME1737_REG_ALARM1, 0xff);
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
747
  		}
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
748
749
750
751
752
753
754
755
756
757
758
  		data->last_update = jiffies;
  		data->valid = 1;
  	}
  
  	mutex_unlock(&data->update_lock);
  
  	return data;
  }
  
  /* ---------------------------------------------------------------------
   * Voltage sysfs attributes
d4b94e1fa   Juerg Haefliger   hwmon: (dme1737) ...
759
   * ix = [0-7]
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
   * --------------------------------------------------------------------- */
  
  #define SYS_IN_INPUT	0
  #define SYS_IN_MIN	1
  #define SYS_IN_MAX	2
  #define SYS_IN_ALARM	3
  
  static ssize_t show_in(struct device *dev, struct device_attribute *attr,
  		       char *buf)
  {
  	struct dme1737_data *data = dme1737_update_device(dev);
  	struct sensor_device_attribute_2
  		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
  	int ix = sensor_attr_2->index;
  	int fn = sensor_attr_2->nr;
  	int res;
  
  	switch (fn) {
  	case SYS_IN_INPUT:
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
779
  		res = IN_FROM_REG(data->in[ix], data->in_nominal[ix], 16);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
780
781
  		break;
  	case SYS_IN_MIN:
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
782
  		res = IN_FROM_REG(data->in_min[ix], data->in_nominal[ix], 8);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
783
784
  		break;
  	case SYS_IN_MAX:
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
785
  		res = IN_FROM_REG(data->in_max[ix], data->in_nominal[ix], 8);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
786
787
788
789
790
791
  		break;
  	case SYS_IN_ALARM:
  		res = (data->alarms >> DME1737_BIT_ALARM_IN[ix]) & 0x01;
  		break;
  	default:
  		res = 0;
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
792
793
  		dev_dbg(dev, "Unknown function %d.
  ", fn);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
794
795
796
797
798
799
800
801
802
  	}
  
  	return sprintf(buf, "%d
  ", res);
  }
  
  static ssize_t set_in(struct device *dev, struct device_attribute *attr,
  		      const char *buf, size_t count)
  {
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
803
  	struct dme1737_data *data = dev_get_drvdata(dev);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
804
805
806
807
  	struct sensor_device_attribute_2
  		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
  	int ix = sensor_attr_2->index;
  	int fn = sensor_attr_2->nr;
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
808
809
810
811
812
813
  	long val;
  	int err;
  
  	err = kstrtol(buf, 10, &val);
  	if (err)
  		return err;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
814
815
816
817
  
  	mutex_lock(&data->update_lock);
  	switch (fn) {
  	case SYS_IN_MIN:
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
818
  		data->in_min[ix] = IN_TO_REG(val, data->in_nominal[ix]);
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
819
  		dme1737_write(data, DME1737_REG_IN_MIN(ix),
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
820
821
822
  			      data->in_min[ix]);
  		break;
  	case SYS_IN_MAX:
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
823
  		data->in_max[ix] = IN_TO_REG(val, data->in_nominal[ix]);
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
824
  		dme1737_write(data, DME1737_REG_IN_MAX(ix),
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
825
826
827
  			      data->in_max[ix]);
  		break;
  	default:
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
828
829
  		dev_dbg(dev, "Unknown function %d.
  ", fn);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
  	}
  	mutex_unlock(&data->update_lock);
  
  	return count;
  }
  
  /* ---------------------------------------------------------------------
   * Temperature sysfs attributes
   * ix = [0-2]
   * --------------------------------------------------------------------- */
  
  #define SYS_TEMP_INPUT			0
  #define SYS_TEMP_MIN			1
  #define SYS_TEMP_MAX			2
  #define SYS_TEMP_OFFSET			3
  #define SYS_TEMP_ALARM			4
  #define SYS_TEMP_FAULT			5
  
  static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
  			 char *buf)
  {
  	struct dme1737_data *data = dme1737_update_device(dev);
  	struct sensor_device_attribute_2
  		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
  	int ix = sensor_attr_2->index;
  	int fn = sensor_attr_2->nr;
  	int res;
  
  	switch (fn) {
  	case SYS_TEMP_INPUT:
  		res = TEMP_FROM_REG(data->temp[ix], 16);
  		break;
  	case SYS_TEMP_MIN:
  		res = TEMP_FROM_REG(data->temp_min[ix], 8);
  		break;
  	case SYS_TEMP_MAX:
  		res = TEMP_FROM_REG(data->temp_max[ix], 8);
  		break;
  	case SYS_TEMP_OFFSET:
  		res = TEMP_FROM_REG(data->temp_offset[ix], 8);
  		break;
  	case SYS_TEMP_ALARM:
  		res = (data->alarms >> DME1737_BIT_ALARM_TEMP[ix]) & 0x01;
  		break;
  	case SYS_TEMP_FAULT:
c0f31403f   Juerg Haefliger   hwmon: fix dme173...
875
  		res = (((u16)data->temp[ix] & 0xff00) == 0x8000);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
876
877
878
  		break;
  	default:
  		res = 0;
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
879
880
  		dev_dbg(dev, "Unknown function %d.
  ", fn);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
881
882
883
884
885
886
887
888
889
  	}
  
  	return sprintf(buf, "%d
  ", res);
  }
  
  static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
  			const char *buf, size_t count)
  {
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
890
  	struct dme1737_data *data = dev_get_drvdata(dev);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
891
892
893
894
  	struct sensor_device_attribute_2
  		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
  	int ix = sensor_attr_2->index;
  	int fn = sensor_attr_2->nr;
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
895
896
897
898
899
900
  	long val;
  	int err;
  
  	err = kstrtol(buf, 10, &val);
  	if (err)
  		return err;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
901
902
903
904
905
  
  	mutex_lock(&data->update_lock);
  	switch (fn) {
  	case SYS_TEMP_MIN:
  		data->temp_min[ix] = TEMP_TO_REG(val);
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
906
  		dme1737_write(data, DME1737_REG_TEMP_MIN(ix),
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
907
908
909
910
  			      data->temp_min[ix]);
  		break;
  	case SYS_TEMP_MAX:
  		data->temp_max[ix] = TEMP_TO_REG(val);
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
911
  		dme1737_write(data, DME1737_REG_TEMP_MAX(ix),
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
912
913
914
915
  			      data->temp_max[ix]);
  		break;
  	case SYS_TEMP_OFFSET:
  		data->temp_offset[ix] = TEMP_TO_REG(val);
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
916
  		dme1737_write(data, DME1737_REG_TEMP_OFFSET(ix),
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
917
918
919
  			      data->temp_offset[ix]);
  		break;
  	default:
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
920
921
  		dev_dbg(dev, "Unknown function %d.
  ", fn);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
  	}
  	mutex_unlock(&data->update_lock);
  
  	return count;
  }
  
  /* ---------------------------------------------------------------------
   * Zone sysfs attributes
   * ix = [0-2]
   * --------------------------------------------------------------------- */
  
  #define SYS_ZONE_AUTO_CHANNELS_TEMP	0
  #define SYS_ZONE_AUTO_POINT1_TEMP_HYST	1
  #define SYS_ZONE_AUTO_POINT1_TEMP	2
  #define SYS_ZONE_AUTO_POINT2_TEMP	3
  #define SYS_ZONE_AUTO_POINT3_TEMP	4
  
  static ssize_t show_zone(struct device *dev, struct device_attribute *attr,
  			 char *buf)
  {
  	struct dme1737_data *data = dme1737_update_device(dev);
  	struct sensor_device_attribute_2
  		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
  	int ix = sensor_attr_2->index;
  	int fn = sensor_attr_2->nr;
  	int res;
  
  	switch (fn) {
  	case SYS_ZONE_AUTO_CHANNELS_TEMP:
  		/* check config2 for non-standard temp-to-zone mapping */
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
952
  		if ((ix == 1) && (data->config2 & 0x02))
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
953
  			res = 4;
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
954
  		else
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
955
  			res = 1 << ix;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
  		break;
  	case SYS_ZONE_AUTO_POINT1_TEMP_HYST:
  		res = TEMP_FROM_REG(data->zone_low[ix], 8) -
  		      TEMP_HYST_FROM_REG(data->zone_hyst[ix == 2], ix);
  		break;
  	case SYS_ZONE_AUTO_POINT1_TEMP:
  		res = TEMP_FROM_REG(data->zone_low[ix], 8);
  		break;
  	case SYS_ZONE_AUTO_POINT2_TEMP:
  		/* pwm_freq holds the temp range bits in the upper nibble */
  		res = TEMP_FROM_REG(data->zone_low[ix], 8) +
  		      TEMP_RANGE_FROM_REG(data->pwm_freq[ix]);
  		break;
  	case SYS_ZONE_AUTO_POINT3_TEMP:
  		res = TEMP_FROM_REG(data->zone_abs[ix], 8);
  		break;
  	default:
  		res = 0;
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
974
975
  		dev_dbg(dev, "Unknown function %d.
  ", fn);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
976
977
978
979
980
981
982
983
984
  	}
  
  	return sprintf(buf, "%d
  ", res);
  }
  
  static ssize_t set_zone(struct device *dev, struct device_attribute *attr,
  			const char *buf, size_t count)
  {
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
985
  	struct dme1737_data *data = dev_get_drvdata(dev);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
986
987
988
989
  	struct sensor_device_attribute_2
  		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
  	int ix = sensor_attr_2->index;
  	int fn = sensor_attr_2->nr;
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
990
  	long val;
07cc189d1   Guenter Roeck   hwmon: (dme1737) ...
991
  	int temp;
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
992
  	int err;
07cc189d1   Guenter Roeck   hwmon: (dme1737) ...
993
  	u8 reg;
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
994
995
996
997
  
  	err = kstrtol(buf, 10, &val);
  	if (err)
  		return err;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
998
999
1000
1001
1002
  
  	mutex_lock(&data->update_lock);
  	switch (fn) {
  	case SYS_ZONE_AUTO_POINT1_TEMP_HYST:
  		/* Refresh the cache */
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1003
  		data->zone_low[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1004
1005
  						  DME1737_REG_ZONE_LOW(ix));
  		/* Modify the temp hyst value */
07cc189d1   Guenter Roeck   hwmon: (dme1737) ...
1006
1007
1008
  		temp = TEMP_FROM_REG(data->zone_low[ix], 8);
  		reg = dme1737_read(data, DME1737_REG_ZONE_HYST(ix == 2));
  		data->zone_hyst[ix == 2] = TEMP_HYST_TO_REG(temp, val, ix, reg);
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1009
  		dme1737_write(data, DME1737_REG_ZONE_HYST(ix == 2),
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1010
1011
1012
1013
  			      data->zone_hyst[ix == 2]);
  		break;
  	case SYS_ZONE_AUTO_POINT1_TEMP:
  		data->zone_low[ix] = TEMP_TO_REG(val);
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1014
  		dme1737_write(data, DME1737_REG_ZONE_LOW(ix),
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1015
1016
1017
1018
  			      data->zone_low[ix]);
  		break;
  	case SYS_ZONE_AUTO_POINT2_TEMP:
  		/* Refresh the cache */
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1019
  		data->zone_low[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1020
  						  DME1737_REG_ZONE_LOW(ix));
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1021
1022
1023
1024
  		/*
  		 * Modify the temp range value (which is stored in the upper
  		 * nibble of the pwm_freq register)
  		 */
07cc189d1   Guenter Roeck   hwmon: (dme1737) ...
1025
1026
1027
1028
  		temp = TEMP_FROM_REG(data->zone_low[ix], 8);
  		val = clamp_val(val, temp, temp + 80000);
  		reg = dme1737_read(data, DME1737_REG_PWM_FREQ(ix));
  		data->pwm_freq[ix] = TEMP_RANGE_TO_REG(val - temp, reg);
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1029
  		dme1737_write(data, DME1737_REG_PWM_FREQ(ix),
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1030
1031
1032
1033
  			      data->pwm_freq[ix]);
  		break;
  	case SYS_ZONE_AUTO_POINT3_TEMP:
  		data->zone_abs[ix] = TEMP_TO_REG(val);
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1034
  		dme1737_write(data, DME1737_REG_ZONE_ABS(ix),
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1035
1036
1037
  			      data->zone_abs[ix]);
  		break;
  	default:
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1038
1039
  		dev_dbg(dev, "Unknown function %d.
  ", fn);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
  	}
  	mutex_unlock(&data->update_lock);
  
  	return count;
  }
  
  /* ---------------------------------------------------------------------
   * Fan sysfs attributes
   * ix = [0-5]
   * --------------------------------------------------------------------- */
  
  #define SYS_FAN_INPUT	0
  #define SYS_FAN_MIN	1
  #define SYS_FAN_MAX	2
  #define SYS_FAN_ALARM	3
  #define SYS_FAN_TYPE	4
  
  static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
  			char *buf)
  {
  	struct dme1737_data *data = dme1737_update_device(dev);
  	struct sensor_device_attribute_2
  		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
  	int ix = sensor_attr_2->index;
  	int fn = sensor_attr_2->nr;
  	int res;
  
  	switch (fn) {
  	case SYS_FAN_INPUT:
  		res = FAN_FROM_REG(data->fan[ix],
  				   ix < 4 ? 0 :
  				   FAN_TPC_FROM_REG(data->fan_opt[ix]));
  		break;
  	case SYS_FAN_MIN:
  		res = FAN_FROM_REG(data->fan_min[ix],
  				   ix < 4 ? 0 :
  				   FAN_TPC_FROM_REG(data->fan_opt[ix]));
  		break;
  	case SYS_FAN_MAX:
  		/* only valid for fan[5-6] */
  		res = FAN_MAX_FROM_REG(data->fan_max[ix - 4]);
  		break;
  	case SYS_FAN_ALARM:
  		res = (data->alarms >> DME1737_BIT_ALARM_FAN[ix]) & 0x01;
  		break;
  	case SYS_FAN_TYPE:
  		/* only valid for fan[1-4] */
  		res = FAN_TYPE_FROM_REG(data->fan_opt[ix]);
  		break;
  	default:
  		res = 0;
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1091
1092
  		dev_dbg(dev, "Unknown function %d.
  ", fn);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1093
1094
1095
1096
1097
1098
1099
1100
1101
  	}
  
  	return sprintf(buf, "%d
  ", res);
  }
  
  static ssize_t set_fan(struct device *dev, struct device_attribute *attr,
  		       const char *buf, size_t count)
  {
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1102
  	struct dme1737_data *data = dev_get_drvdata(dev);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1103
1104
1105
1106
  	struct sensor_device_attribute_2
  		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
  	int ix = sensor_attr_2->index;
  	int fn = sensor_attr_2->nr;
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1107
1108
1109
1110
1111
1112
  	long val;
  	int err;
  
  	err = kstrtol(buf, 10, &val);
  	if (err)
  		return err;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1113
1114
1115
1116
1117
1118
1119
1120
  
  	mutex_lock(&data->update_lock);
  	switch (fn) {
  	case SYS_FAN_MIN:
  		if (ix < 4) {
  			data->fan_min[ix] = FAN_TO_REG(val, 0);
  		} else {
  			/* Refresh the cache */
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1121
  			data->fan_opt[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1122
1123
1124
1125
1126
  						DME1737_REG_FAN_OPT(ix));
  			/* Modify the fan min value */
  			data->fan_min[ix] = FAN_TO_REG(val,
  					FAN_TPC_FROM_REG(data->fan_opt[ix]));
  		}
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1127
  		dme1737_write(data, DME1737_REG_FAN_MIN(ix),
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1128
  			      data->fan_min[ix] & 0xff);
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1129
  		dme1737_write(data, DME1737_REG_FAN_MIN(ix) + 1,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1130
1131
1132
1133
1134
  			      data->fan_min[ix] >> 8);
  		break;
  	case SYS_FAN_MAX:
  		/* Only valid for fan[5-6] */
  		data->fan_max[ix - 4] = FAN_MAX_TO_REG(val);
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1135
  		dme1737_write(data, DME1737_REG_FAN_MAX(ix),
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1136
1137
1138
1139
1140
1141
  			      data->fan_max[ix - 4]);
  		break;
  	case SYS_FAN_TYPE:
  		/* Only valid for fan[1-4] */
  		if (!(val == 1 || val == 2 || val == 4)) {
  			count = -EINVAL;
b55f37572   Guenter Roeck   hwmon: Fix checkp...
1142
1143
1144
  			dev_warn(dev,
  				 "Fan type value %ld not supported. Choose one of 1, 2, or 4.
  ",
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1145
1146
1147
  				 val);
  			goto exit;
  		}
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1148
  		data->fan_opt[ix] = FAN_TYPE_TO_REG(val, dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1149
  					DME1737_REG_FAN_OPT(ix)));
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1150
  		dme1737_write(data, DME1737_REG_FAN_OPT(ix),
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1151
1152
1153
  			      data->fan_opt[ix]);
  		break;
  	default:
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1154
1155
  		dev_dbg(dev, "Unknown function %d.
  ", fn);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
  	}
  exit:
  	mutex_unlock(&data->update_lock);
  
  	return count;
  }
  
  /* ---------------------------------------------------------------------
   * PWM sysfs attributes
   * ix = [0-4]
   * --------------------------------------------------------------------- */
  
  #define SYS_PWM				0
  #define SYS_PWM_FREQ			1
  #define SYS_PWM_ENABLE			2
  #define SYS_PWM_RAMP_RATE		3
  #define SYS_PWM_AUTO_CHANNELS_ZONE	4
  #define SYS_PWM_AUTO_PWM_MIN		5
  #define SYS_PWM_AUTO_POINT1_PWM		6
  #define SYS_PWM_AUTO_POINT2_PWM		7
  
  static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
  			char *buf)
  {
  	struct dme1737_data *data = dme1737_update_device(dev);
  	struct sensor_device_attribute_2
  		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
  	int ix = sensor_attr_2->index;
  	int fn = sensor_attr_2->nr;
  	int res;
  
  	switch (fn) {
  	case SYS_PWM:
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1189
  		if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 0)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1190
  			res = 255;
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1191
  		else
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1192
  			res = data->pwm[ix];
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1193
1194
1195
1196
1197
  		break;
  	case SYS_PWM_FREQ:
  		res = PWM_FREQ_FROM_REG(data->pwm_freq[ix]);
  		break;
  	case SYS_PWM_ENABLE:
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1198
  		if (ix >= 3)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1199
  			res = 1; /* pwm[5-6] hard-wired to manual mode */
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1200
  		else
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1201
  			res = PWM_EN_FROM_REG(data->pwm_config[ix]);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1202
1203
1204
1205
1206
1207
1208
  		break;
  	case SYS_PWM_RAMP_RATE:
  		/* Only valid for pwm[1-3] */
  		res = PWM_RR_FROM_REG(data->pwm_rr[ix > 0], ix);
  		break;
  	case SYS_PWM_AUTO_CHANNELS_ZONE:
  		/* Only valid for pwm[1-3] */
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1209
  		if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1210
  			res = PWM_ACZ_FROM_REG(data->pwm_config[ix]);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1211
  		else
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1212
  			res = data->pwm_acz[ix];
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1213
1214
1215
  		break;
  	case SYS_PWM_AUTO_PWM_MIN:
  		/* Only valid for pwm[1-3] */
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1216
  		if (PWM_OFF_FROM_REG(data->pwm_rr[0], ix))
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1217
  			res = data->pwm_min[ix];
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1218
  		else
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1219
  			res = 0;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
  		break;
  	case SYS_PWM_AUTO_POINT1_PWM:
  		/* Only valid for pwm[1-3] */
  		res = data->pwm_min[ix];
  		break;
  	case SYS_PWM_AUTO_POINT2_PWM:
  		/* Only valid for pwm[1-3] */
  		res = 255; /* hard-wired */
  		break;
  	default:
  		res = 0;
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1231
1232
  		dev_dbg(dev, "Unknown function %d.
  ", fn);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1233
1234
1235
1236
1237
  	}
  
  	return sprintf(buf, "%d
  ", res);
  }
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1238
  static struct attribute *dme1737_pwm_chmod_attr[];
48176a973   Al Viro   switch sysfs_chmo...
1239
  static void dme1737_chmod_file(struct device*, struct attribute*, umode_t);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1240
1241
1242
1243
  
  static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
  		       const char *buf, size_t count)
  {
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1244
  	struct dme1737_data *data = dev_get_drvdata(dev);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1245
1246
1247
1248
  	struct sensor_device_attribute_2
  		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
  	int ix = sensor_attr_2->index;
  	int fn = sensor_attr_2->nr;
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1249
1250
1251
1252
1253
1254
  	long val;
  	int err;
  
  	err = kstrtol(buf, 10, &val);
  	if (err)
  		return err;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1255
1256
1257
1258
  
  	mutex_lock(&data->update_lock);
  	switch (fn) {
  	case SYS_PWM:
2a844c148   Guenter Roeck   hwmon: Replace SE...
1259
  		data->pwm[ix] = clamp_val(val, 0, 255);
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1260
  		dme1737_write(data, DME1737_REG_PWM(ix), data->pwm[ix]);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1261
1262
  		break;
  	case SYS_PWM_FREQ:
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1263
  		data->pwm_freq[ix] = PWM_FREQ_TO_REG(val, dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1264
  						DME1737_REG_PWM_FREQ(ix)));
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1265
  		dme1737_write(data, DME1737_REG_PWM_FREQ(ix),
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1266
1267
1268
1269
1270
1271
  			      data->pwm_freq[ix]);
  		break;
  	case SYS_PWM_ENABLE:
  		/* Only valid for pwm[1-3] */
  		if (val < 0 || val > 2) {
  			count = -EINVAL;
b55f37572   Guenter Roeck   hwmon: Fix checkp...
1272
1273
1274
  			dev_warn(dev,
  				 "PWM enable %ld not supported. Choose one of 0, 1, or 2.
  ",
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1275
1276
1277
1278
  				 val);
  			goto exit;
  		}
  		/* Refresh the cache */
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1279
  		data->pwm_config[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
  						DME1737_REG_PWM_CONFIG(ix));
  		if (val == PWM_EN_FROM_REG(data->pwm_config[ix])) {
  			/* Bail out if no change */
  			goto exit;
  		}
  		/* Do some housekeeping if we are currently in auto mode */
  		if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) {
  			/* Save the current zone channel assignment */
  			data->pwm_acz[ix] = PWM_ACZ_FROM_REG(
  							data->pwm_config[ix]);
  			/* Save the current ramp rate state and disable it */
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1291
  			data->pwm_rr[ix > 0] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1292
1293
1294
1295
1296
1297
  						DME1737_REG_PWM_RR(ix > 0));
  			data->pwm_rr_en &= ~(1 << ix);
  			if (PWM_RR_EN_FROM_REG(data->pwm_rr[ix > 0], ix)) {
  				data->pwm_rr_en |= (1 << ix);
  				data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(0, ix,
  							data->pwm_rr[ix > 0]);
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1298
  				dme1737_write(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1299
1300
1301
1302
1303
1304
1305
1306
  					      DME1737_REG_PWM_RR(ix > 0),
  					      data->pwm_rr[ix > 0]);
  			}
  		}
  		/* Set the new PWM mode */
  		switch (val) {
  		case 0:
  			/* Change permissions of pwm[ix] to read-only */
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1307
  			dme1737_chmod_file(dev, dme1737_pwm_chmod_attr[ix],
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1308
1309
1310
1311
  					   S_IRUGO);
  			/* Turn fan fully on */
  			data->pwm_config[ix] = PWM_EN_TO_REG(0,
  							data->pwm_config[ix]);
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1312
  			dme1737_write(data, DME1737_REG_PWM_CONFIG(ix),
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1313
1314
1315
1316
1317
1318
  				      data->pwm_config[ix]);
  			break;
  		case 1:
  			/* Turn on manual mode */
  			data->pwm_config[ix] = PWM_EN_TO_REG(1,
  							data->pwm_config[ix]);
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1319
  			dme1737_write(data, DME1737_REG_PWM_CONFIG(ix),
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1320
1321
  				      data->pwm_config[ix]);
  			/* Change permissions of pwm[ix] to read-writeable */
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1322
  			dme1737_chmod_file(dev, dme1737_pwm_chmod_attr[ix],
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1323
1324
1325
1326
  					   S_IRUGO | S_IWUSR);
  			break;
  		case 2:
  			/* Change permissions of pwm[ix] to read-only */
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1327
  			dme1737_chmod_file(dev, dme1737_pwm_chmod_attr[ix],
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1328
  					   S_IRUGO);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1329
1330
1331
1332
  			/*
  			 * Turn on auto mode using the saved zone channel
  			 * assignment
  			 */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1333
1334
1335
  			data->pwm_config[ix] = PWM_ACZ_TO_REG(
  							data->pwm_acz[ix],
  							data->pwm_config[ix]);
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1336
  			dme1737_write(data, DME1737_REG_PWM_CONFIG(ix),
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1337
1338
1339
1340
  				      data->pwm_config[ix]);
  			/* Enable PWM ramp rate if previously enabled */
  			if (data->pwm_rr_en & (1 << ix)) {
  				data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(1, ix,
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1341
  						dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1342
  						DME1737_REG_PWM_RR(ix > 0)));
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1343
  				dme1737_write(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1344
1345
1346
1347
1348
1349
1350
1351
1352
  					      DME1737_REG_PWM_RR(ix > 0),
  					      data->pwm_rr[ix > 0]);
  			}
  			break;
  		}
  		break;
  	case SYS_PWM_RAMP_RATE:
  		/* Only valid for pwm[1-3] */
  		/* Refresh the cache */
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1353
  		data->pwm_config[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1354
  						DME1737_REG_PWM_CONFIG(ix));
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1355
  		data->pwm_rr[ix > 0] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1356
1357
1358
1359
1360
1361
  						DME1737_REG_PWM_RR(ix > 0));
  		/* Set the ramp rate value */
  		if (val > 0) {
  			data->pwm_rr[ix > 0] = PWM_RR_TO_REG(val, ix,
  							data->pwm_rr[ix > 0]);
  		}
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1362
1363
1364
1365
  		/*
  		 * Enable/disable the feature only if the associated PWM
  		 * output is in automatic mode.
  		 */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1366
1367
1368
1369
  		if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) {
  			data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(val > 0, ix,
  							data->pwm_rr[ix > 0]);
  		}
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1370
  		dme1737_write(data, DME1737_REG_PWM_RR(ix > 0),
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1371
1372
1373
1374
1375
1376
1377
  			      data->pwm_rr[ix > 0]);
  		break;
  	case SYS_PWM_AUTO_CHANNELS_ZONE:
  		/* Only valid for pwm[1-3] */
  		if (!(val == 1 || val == 2 || val == 4 ||
  		      val == 6 || val == 7)) {
  			count = -EINVAL;
b55f37572   Guenter Roeck   hwmon: Fix checkp...
1378
1379
  			dev_warn(dev,
  				 "PWM auto channels zone %ld not supported. Choose one of 1, 2, 4, 6, "
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1380
1381
1382
1383
1384
  				 "or 7.
  ", val);
  			goto exit;
  		}
  		/* Refresh the cache */
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1385
  		data->pwm_config[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1386
1387
  						DME1737_REG_PWM_CONFIG(ix));
  		if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) {
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1388
1389
1390
1391
  			/*
  			 * PWM is already in auto mode so update the temp
  			 * channel assignment
  			 */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1392
1393
  			data->pwm_config[ix] = PWM_ACZ_TO_REG(val,
  						data->pwm_config[ix]);
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1394
  			dme1737_write(data, DME1737_REG_PWM_CONFIG(ix),
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1395
1396
  				      data->pwm_config[ix]);
  		} else {
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1397
1398
1399
1400
  			/*
  			 * PWM is not in auto mode so we save the temp
  			 * channel assignment for later use
  			 */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1401
1402
1403
1404
1405
1406
  			data->pwm_acz[ix] = val;
  		}
  		break;
  	case SYS_PWM_AUTO_PWM_MIN:
  		/* Only valid for pwm[1-3] */
  		/* Refresh the cache */
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1407
  		data->pwm_min[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1408
  						DME1737_REG_PWM_MIN(ix));
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1409
1410
  		/*
  		 * There are only 2 values supported for the auto_pwm_min
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1411
1412
  		 * value: 0 or auto_point1_pwm. So if the temperature drops
  		 * below the auto_point1_temp_hyst value, the fan either turns
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1413
1414
  		 * off or runs at auto_point1_pwm duty-cycle.
  		 */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1415
1416
  		if (val > ((data->pwm_min[ix] + 1) / 2)) {
  			data->pwm_rr[0] = PWM_OFF_TO_REG(1, ix,
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1417
  						dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1418
  						DME1737_REG_PWM_RR(0)));
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1419
1420
  		} else {
  			data->pwm_rr[0] = PWM_OFF_TO_REG(0, ix,
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1421
  						dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1422
  						DME1737_REG_PWM_RR(0)));
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1423
  		}
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1424
  		dme1737_write(data, DME1737_REG_PWM_RR(0),
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1425
1426
1427
1428
  			      data->pwm_rr[0]);
  		break;
  	case SYS_PWM_AUTO_POINT1_PWM:
  		/* Only valid for pwm[1-3] */
2a844c148   Guenter Roeck   hwmon: Replace SE...
1429
  		data->pwm_min[ix] = clamp_val(val, 0, 255);
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1430
  		dme1737_write(data, DME1737_REG_PWM_MIN(ix),
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1431
1432
1433
  			      data->pwm_min[ix]);
  		break;
  	default:
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1434
1435
  		dev_dbg(dev, "Unknown function %d.
  ", fn);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
  	}
  exit:
  	mutex_unlock(&data->update_lock);
  
  	return count;
  }
  
  /* ---------------------------------------------------------------------
   * Miscellaneous sysfs attributes
   * --------------------------------------------------------------------- */
fd5ddb813   Julia Lawall   hwmon: (dme1737) ...
1446
  static ssize_t vrm_show(struct device *dev, struct device_attribute *attr,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1447
1448
1449
1450
1451
1452
1453
1454
  			char *buf)
  {
  	struct i2c_client *client = to_i2c_client(dev);
  	struct dme1737_data *data = i2c_get_clientdata(client);
  
  	return sprintf(buf, "%d
  ", data->vrm);
  }
fd5ddb813   Julia Lawall   hwmon: (dme1737) ...
1455
1456
  static ssize_t vrm_store(struct device *dev, struct device_attribute *attr,
  			 const char *buf, size_t count)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1457
  {
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1458
  	struct dme1737_data *data = dev_get_drvdata(dev);
d58e47d78   Axel Lin   hwmon: (dme1737) ...
1459
  	unsigned long val;
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1460
  	int err;
d58e47d78   Axel Lin   hwmon: (dme1737) ...
1461
  	err = kstrtoul(buf, 10, &val);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1462
1463
  	if (err)
  		return err;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1464

d58e47d78   Axel Lin   hwmon: (dme1737) ...
1465
1466
  	if (val > 255)
  		return -EINVAL;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1467
1468
1469
  	data->vrm = val;
  	return count;
  }
fd5ddb813   Julia Lawall   hwmon: (dme1737) ...
1470
1471
  static ssize_t cpu0_vid_show(struct device *dev,
  			     struct device_attribute *attr, char *buf)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1472
1473
1474
1475
1476
1477
  {
  	struct dme1737_data *data = dme1737_update_device(dev);
  
  	return sprintf(buf, "%d
  ", vid_from_reg(data->vid, data->vrm));
  }
fd5ddb813   Julia Lawall   hwmon: (dme1737) ...
1478
  static ssize_t name_show(struct device *dev, struct device_attribute *attr,
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
1479
1480
1481
  			 char *buf)
  {
  	struct dme1737_data *data = dev_get_drvdata(dev);
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
1482
1483
  	return sprintf(buf, "%s
  ", data->name);
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
1484
  }
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1485
1486
1487
  /* ---------------------------------------------------------------------
   * Sysfs device attribute defines and structs
   * --------------------------------------------------------------------- */
d4b94e1fa   Juerg Haefliger   hwmon: (dme1737) ...
1488
  /* Voltages 0-7 */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1489
1490
1491
  
  #define SENSOR_DEVICE_ATTR_IN(ix) \
  static SENSOR_DEVICE_ATTR_2(in##ix##_input, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1492
  	show_in, NULL, SYS_IN_INPUT, ix); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1493
  static SENSOR_DEVICE_ATTR_2(in##ix##_min, S_IRUGO | S_IWUSR, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1494
  	show_in, set_in, SYS_IN_MIN, ix); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1495
  static SENSOR_DEVICE_ATTR_2(in##ix##_max, S_IRUGO | S_IWUSR, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1496
  	show_in, set_in, SYS_IN_MAX, ix); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1497
  static SENSOR_DEVICE_ATTR_2(in##ix##_alarm, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1498
  	show_in, NULL, SYS_IN_ALARM, ix)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1499
1500
1501
1502
1503
1504
1505
1506
  
  SENSOR_DEVICE_ATTR_IN(0);
  SENSOR_DEVICE_ATTR_IN(1);
  SENSOR_DEVICE_ATTR_IN(2);
  SENSOR_DEVICE_ATTR_IN(3);
  SENSOR_DEVICE_ATTR_IN(4);
  SENSOR_DEVICE_ATTR_IN(5);
  SENSOR_DEVICE_ATTR_IN(6);
d4b94e1fa   Juerg Haefliger   hwmon: (dme1737) ...
1507
  SENSOR_DEVICE_ATTR_IN(7);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1508
1509
1510
1511
1512
  
  /* Temperatures 1-3 */
  
  #define SENSOR_DEVICE_ATTR_TEMP(ix) \
  static SENSOR_DEVICE_ATTR_2(temp##ix##_input, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1513
  	show_temp, NULL, SYS_TEMP_INPUT, ix-1); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1514
  static SENSOR_DEVICE_ATTR_2(temp##ix##_min, S_IRUGO | S_IWUSR, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1515
  	show_temp, set_temp, SYS_TEMP_MIN, ix-1); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1516
  static SENSOR_DEVICE_ATTR_2(temp##ix##_max, S_IRUGO | S_IWUSR, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1517
  	show_temp, set_temp, SYS_TEMP_MAX, ix-1); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1518
  static SENSOR_DEVICE_ATTR_2(temp##ix##_offset, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1519
  	show_temp, set_temp, SYS_TEMP_OFFSET, ix-1); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1520
  static SENSOR_DEVICE_ATTR_2(temp##ix##_alarm, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1521
  	show_temp, NULL, SYS_TEMP_ALARM, ix-1); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1522
  static SENSOR_DEVICE_ATTR_2(temp##ix##_fault, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1523
  	show_temp, NULL, SYS_TEMP_FAULT, ix-1)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1524
1525
1526
1527
1528
1529
1530
1531
1532
  
  SENSOR_DEVICE_ATTR_TEMP(1);
  SENSOR_DEVICE_ATTR_TEMP(2);
  SENSOR_DEVICE_ATTR_TEMP(3);
  
  /* Zones 1-3 */
  
  #define SENSOR_DEVICE_ATTR_ZONE(ix) \
  static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_channels_temp, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1533
  	show_zone, NULL, SYS_ZONE_AUTO_CHANNELS_TEMP, ix-1); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1534
  static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_point1_temp_hyst, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1535
  	show_zone, set_zone, SYS_ZONE_AUTO_POINT1_TEMP_HYST, ix-1); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1536
  static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_point1_temp, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1537
  	show_zone, set_zone, SYS_ZONE_AUTO_POINT1_TEMP, ix-1); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1538
  static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_point2_temp, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1539
  	show_zone, set_zone, SYS_ZONE_AUTO_POINT2_TEMP, ix-1); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1540
  static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_point3_temp, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1541
  	show_zone, set_zone, SYS_ZONE_AUTO_POINT3_TEMP, ix-1)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1542
1543
1544
1545
1546
1547
1548
1549
1550
  
  SENSOR_DEVICE_ATTR_ZONE(1);
  SENSOR_DEVICE_ATTR_ZONE(2);
  SENSOR_DEVICE_ATTR_ZONE(3);
  
  /* Fans 1-4 */
  
  #define SENSOR_DEVICE_ATTR_FAN_1TO4(ix) \
  static SENSOR_DEVICE_ATTR_2(fan##ix##_input, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1551
  	show_fan, NULL, SYS_FAN_INPUT, ix-1); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1552
  static SENSOR_DEVICE_ATTR_2(fan##ix##_min, S_IRUGO | S_IWUSR, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1553
  	show_fan, set_fan, SYS_FAN_MIN, ix-1); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1554
  static SENSOR_DEVICE_ATTR_2(fan##ix##_alarm, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1555
  	show_fan, NULL, SYS_FAN_ALARM, ix-1); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1556
  static SENSOR_DEVICE_ATTR_2(fan##ix##_type, S_IRUGO | S_IWUSR, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1557
  	show_fan, set_fan, SYS_FAN_TYPE, ix-1)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
  
  SENSOR_DEVICE_ATTR_FAN_1TO4(1);
  SENSOR_DEVICE_ATTR_FAN_1TO4(2);
  SENSOR_DEVICE_ATTR_FAN_1TO4(3);
  SENSOR_DEVICE_ATTR_FAN_1TO4(4);
  
  /* Fans 5-6 */
  
  #define SENSOR_DEVICE_ATTR_FAN_5TO6(ix) \
  static SENSOR_DEVICE_ATTR_2(fan##ix##_input, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1568
  	show_fan, NULL, SYS_FAN_INPUT, ix-1); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1569
  static SENSOR_DEVICE_ATTR_2(fan##ix##_min, S_IRUGO | S_IWUSR, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1570
  	show_fan, set_fan, SYS_FAN_MIN, ix-1); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1571
  static SENSOR_DEVICE_ATTR_2(fan##ix##_alarm, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1572
  	show_fan, NULL, SYS_FAN_ALARM, ix-1); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1573
  static SENSOR_DEVICE_ATTR_2(fan##ix##_max, S_IRUGO | S_IWUSR, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1574
  	show_fan, set_fan, SYS_FAN_MAX, ix-1)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1575
1576
1577
1578
1579
1580
1581
1582
  
  SENSOR_DEVICE_ATTR_FAN_5TO6(5);
  SENSOR_DEVICE_ATTR_FAN_5TO6(6);
  
  /* PWMs 1-3 */
  
  #define SENSOR_DEVICE_ATTR_PWM_1TO3(ix) \
  static SENSOR_DEVICE_ATTR_2(pwm##ix, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1583
  	show_pwm, set_pwm, SYS_PWM, ix-1); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1584
  static SENSOR_DEVICE_ATTR_2(pwm##ix##_freq, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1585
  	show_pwm, set_pwm, SYS_PWM_FREQ, ix-1); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1586
  static SENSOR_DEVICE_ATTR_2(pwm##ix##_enable, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1587
  	show_pwm, set_pwm, SYS_PWM_ENABLE, ix-1); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1588
  static SENSOR_DEVICE_ATTR_2(pwm##ix##_ramp_rate, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1589
  	show_pwm, set_pwm, SYS_PWM_RAMP_RATE, ix-1); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1590
  static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_channels_zone, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1591
  	show_pwm, set_pwm, SYS_PWM_AUTO_CHANNELS_ZONE, ix-1); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1592
  static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_pwm_min, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1593
  	show_pwm, set_pwm, SYS_PWM_AUTO_PWM_MIN, ix-1); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1594
  static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_point1_pwm, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1595
  	show_pwm, set_pwm, SYS_PWM_AUTO_POINT1_PWM, ix-1); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1596
  static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_point2_pwm, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1597
  	show_pwm, NULL, SYS_PWM_AUTO_POINT2_PWM, ix-1)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1598
1599
1600
1601
1602
1603
1604
1605
  
  SENSOR_DEVICE_ATTR_PWM_1TO3(1);
  SENSOR_DEVICE_ATTR_PWM_1TO3(2);
  SENSOR_DEVICE_ATTR_PWM_1TO3(3);
  
  /* PWMs 5-6 */
  
  #define SENSOR_DEVICE_ATTR_PWM_5TO6(ix) \
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1606
  static SENSOR_DEVICE_ATTR_2(pwm##ix, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1607
  	show_pwm, set_pwm, SYS_PWM, ix-1); \
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1608
  static SENSOR_DEVICE_ATTR_2(pwm##ix##_freq, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1609
  	show_pwm, set_pwm, SYS_PWM_FREQ, ix-1); \
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1610
  static SENSOR_DEVICE_ATTR_2(pwm##ix##_enable, S_IRUGO, \
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1611
  	show_pwm, NULL, SYS_PWM_ENABLE, ix-1)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1612
1613
1614
1615
1616
  
  SENSOR_DEVICE_ATTR_PWM_5TO6(5);
  SENSOR_DEVICE_ATTR_PWM_5TO6(6);
  
  /* Misc */
fd5ddb813   Julia Lawall   hwmon: (dme1737) ...
1617
1618
1619
  static DEVICE_ATTR_RW(vrm);
  static DEVICE_ATTR_RO(cpu0_vid);
  static DEVICE_ATTR_RO(name);   /* for ISA devices */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1620

c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1621
1622
  /*
   * This struct holds all the attributes that are always present and need to be
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1623
1624
   * created unconditionally. The attributes that need modification of their
   * permissions are created read-only and write permissions are added or removed
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1625
1626
   * on the fly when required
   */
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
1627
  static struct attribute *dme1737_attr[] = {
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1628
  	/* Voltages */
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
  	&sensor_dev_attr_in0_input.dev_attr.attr,
  	&sensor_dev_attr_in0_min.dev_attr.attr,
  	&sensor_dev_attr_in0_max.dev_attr.attr,
  	&sensor_dev_attr_in0_alarm.dev_attr.attr,
  	&sensor_dev_attr_in1_input.dev_attr.attr,
  	&sensor_dev_attr_in1_min.dev_attr.attr,
  	&sensor_dev_attr_in1_max.dev_attr.attr,
  	&sensor_dev_attr_in1_alarm.dev_attr.attr,
  	&sensor_dev_attr_in2_input.dev_attr.attr,
  	&sensor_dev_attr_in2_min.dev_attr.attr,
  	&sensor_dev_attr_in2_max.dev_attr.attr,
  	&sensor_dev_attr_in2_alarm.dev_attr.attr,
  	&sensor_dev_attr_in3_input.dev_attr.attr,
  	&sensor_dev_attr_in3_min.dev_attr.attr,
  	&sensor_dev_attr_in3_max.dev_attr.attr,
  	&sensor_dev_attr_in3_alarm.dev_attr.attr,
  	&sensor_dev_attr_in4_input.dev_attr.attr,
  	&sensor_dev_attr_in4_min.dev_attr.attr,
  	&sensor_dev_attr_in4_max.dev_attr.attr,
  	&sensor_dev_attr_in4_alarm.dev_attr.attr,
  	&sensor_dev_attr_in5_input.dev_attr.attr,
  	&sensor_dev_attr_in5_min.dev_attr.attr,
  	&sensor_dev_attr_in5_max.dev_attr.attr,
  	&sensor_dev_attr_in5_alarm.dev_attr.attr,
  	&sensor_dev_attr_in6_input.dev_attr.attr,
  	&sensor_dev_attr_in6_min.dev_attr.attr,
  	&sensor_dev_attr_in6_max.dev_attr.attr,
  	&sensor_dev_attr_in6_alarm.dev_attr.attr,
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1657
  	/* Temperatures */
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1658
1659
1660
1661
1662
  	&sensor_dev_attr_temp1_input.dev_attr.attr,
  	&sensor_dev_attr_temp1_min.dev_attr.attr,
  	&sensor_dev_attr_temp1_max.dev_attr.attr,
  	&sensor_dev_attr_temp1_alarm.dev_attr.attr,
  	&sensor_dev_attr_temp1_fault.dev_attr.attr,
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1663
1664
1665
1666
1667
  	&sensor_dev_attr_temp2_input.dev_attr.attr,
  	&sensor_dev_attr_temp2_min.dev_attr.attr,
  	&sensor_dev_attr_temp2_max.dev_attr.attr,
  	&sensor_dev_attr_temp2_alarm.dev_attr.attr,
  	&sensor_dev_attr_temp2_fault.dev_attr.attr,
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1668
1669
1670
1671
1672
  	&sensor_dev_attr_temp3_input.dev_attr.attr,
  	&sensor_dev_attr_temp3_min.dev_attr.attr,
  	&sensor_dev_attr_temp3_max.dev_attr.attr,
  	&sensor_dev_attr_temp3_alarm.dev_attr.attr,
  	&sensor_dev_attr_temp3_fault.dev_attr.attr,
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1673
  	/* Zones */
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1674
1675
1676
1677
  	&sensor_dev_attr_zone1_auto_point1_temp.dev_attr.attr,
  	&sensor_dev_attr_zone1_auto_point2_temp.dev_attr.attr,
  	&sensor_dev_attr_zone1_auto_point3_temp.dev_attr.attr,
  	&sensor_dev_attr_zone1_auto_channels_temp.dev_attr.attr,
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1678
1679
1680
1681
  	&sensor_dev_attr_zone2_auto_point1_temp.dev_attr.attr,
  	&sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr,
  	&sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr,
  	&sensor_dev_attr_zone2_auto_channels_temp.dev_attr.attr,
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
1682
1683
1684
1685
1686
1687
  	NULL
  };
  
  static const struct attribute_group dme1737_group = {
  	.attrs = dme1737_attr,
  };
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1688
1689
  /*
   * The following struct holds temp offset attributes, which are not available
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
1690
   * in all chips. The following chips support them:
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1691
1692
   * DME1737, SCH311x
   */
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
1693
  static struct attribute *dme1737_temp_offset_attr[] = {
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
1694
1695
1696
  	&sensor_dev_attr_temp1_offset.dev_attr.attr,
  	&sensor_dev_attr_temp2_offset.dev_attr.attr,
  	&sensor_dev_attr_temp3_offset.dev_attr.attr,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1697
1698
  	NULL
  };
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
1699
1700
  static const struct attribute_group dme1737_temp_offset_group = {
  	.attrs = dme1737_temp_offset_attr,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1701
  };
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1702
1703
  /*
   * The following struct holds VID related attributes, which are not available
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
1704
   * in all chips. The following chips support them:
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1705
1706
   * DME1737
   */
9d0914468   Jean Delvare   hwmon: (dme1737) ...
1707
1708
1709
1710
1711
1712
1713
1714
1715
  static struct attribute *dme1737_vid_attr[] = {
  	&dev_attr_vrm.attr,
  	&dev_attr_cpu0_vid.attr,
  	NULL
  };
  
  static const struct attribute_group dme1737_vid_group = {
  	.attrs = dme1737_vid_attr,
  };
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1716
1717
  /*
   * The following struct holds temp zone 3 related attributes, which are not
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
1718
   * available in all chips. The following chips support them:
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1719
1720
   * DME1737, SCH311x, SCH5027
   */
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
  static struct attribute *dme1737_zone3_attr[] = {
  	&sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr,
  	&sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr,
  	&sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr,
  	&sensor_dev_attr_zone3_auto_channels_temp.dev_attr.attr,
  	NULL
  };
  
  static const struct attribute_group dme1737_zone3_group = {
  	.attrs = dme1737_zone3_attr,
  };
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1732
1733
  /*
   * The following struct holds temp zone hysteresis related attributes, which
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
1734
   * are not available in all chips. The following chips support them:
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1735
1736
   * DME1737, SCH311x
   */
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
  static struct attribute *dme1737_zone_hyst_attr[] = {
  	&sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr,
  	&sensor_dev_attr_zone2_auto_point1_temp_hyst.dev_attr.attr,
  	&sensor_dev_attr_zone3_auto_point1_temp_hyst.dev_attr.attr,
  	NULL
  };
  
  static const struct attribute_group dme1737_zone_hyst_group = {
  	.attrs = dme1737_zone_hyst_attr,
  };
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1747
1748
  /*
   * The following struct holds voltage in7 related attributes, which
d4b94e1fa   Juerg Haefliger   hwmon: (dme1737) ...
1749
   * are not available in all chips. The following chips support them:
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1750
1751
   * SCH5127
   */
d4b94e1fa   Juerg Haefliger   hwmon: (dme1737) ...
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
  static struct attribute *dme1737_in7_attr[] = {
  	&sensor_dev_attr_in7_input.dev_attr.attr,
  	&sensor_dev_attr_in7_min.dev_attr.attr,
  	&sensor_dev_attr_in7_max.dev_attr.attr,
  	&sensor_dev_attr_in7_alarm.dev_attr.attr,
  	NULL
  };
  
  static const struct attribute_group dme1737_in7_group = {
  	.attrs = dme1737_in7_attr,
  };
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1763
1764
  /*
   * The following structs hold the PWM attributes, some of which are optional.
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1765
   * Their creation depends on the chip configuration which is determined during
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1766
1767
   * module load.
   */
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1768
  static struct attribute *dme1737_pwm1_attr[] = {
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1769
1770
1771
1772
1773
  	&sensor_dev_attr_pwm1.dev_attr.attr,
  	&sensor_dev_attr_pwm1_freq.dev_attr.attr,
  	&sensor_dev_attr_pwm1_enable.dev_attr.attr,
  	&sensor_dev_attr_pwm1_ramp_rate.dev_attr.attr,
  	&sensor_dev_attr_pwm1_auto_channels_zone.dev_attr.attr,
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1774
1775
  	&sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
  	&sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1776
1777
  	NULL
  };
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1778
  static struct attribute *dme1737_pwm2_attr[] = {
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1779
1780
1781
1782
1783
  	&sensor_dev_attr_pwm2.dev_attr.attr,
  	&sensor_dev_attr_pwm2_freq.dev_attr.attr,
  	&sensor_dev_attr_pwm2_enable.dev_attr.attr,
  	&sensor_dev_attr_pwm2_ramp_rate.dev_attr.attr,
  	&sensor_dev_attr_pwm2_auto_channels_zone.dev_attr.attr,
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1784
1785
  	&sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
  	&sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1786
1787
  	NULL
  };
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1788
  static struct attribute *dme1737_pwm3_attr[] = {
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1789
1790
1791
1792
1793
  	&sensor_dev_attr_pwm3.dev_attr.attr,
  	&sensor_dev_attr_pwm3_freq.dev_attr.attr,
  	&sensor_dev_attr_pwm3_enable.dev_attr.attr,
  	&sensor_dev_attr_pwm3_ramp_rate.dev_attr.attr,
  	&sensor_dev_attr_pwm3_auto_channels_zone.dev_attr.attr,
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1794
1795
  	&sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
  	&sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1796
1797
  	NULL
  };
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1798
  static struct attribute *dme1737_pwm5_attr[] = {
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1799
1800
1801
  	&sensor_dev_attr_pwm5.dev_attr.attr,
  	&sensor_dev_attr_pwm5_freq.dev_attr.attr,
  	&sensor_dev_attr_pwm5_enable.dev_attr.attr,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1802
1803
  	NULL
  };
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1804
  static struct attribute *dme1737_pwm6_attr[] = {
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1805
1806
1807
  	&sensor_dev_attr_pwm6.dev_attr.attr,
  	&sensor_dev_attr_pwm6_freq.dev_attr.attr,
  	&sensor_dev_attr_pwm6_enable.dev_attr.attr,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1808
1809
1810
1811
  	NULL
  };
  
  static const struct attribute_group dme1737_pwm_group[] = {
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1812
1813
1814
  	{ .attrs = dme1737_pwm1_attr },
  	{ .attrs = dme1737_pwm2_attr },
  	{ .attrs = dme1737_pwm3_attr },
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1815
  	{ .attrs = NULL },
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1816
1817
  	{ .attrs = dme1737_pwm5_attr },
  	{ .attrs = dme1737_pwm6_attr },
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1818
  };
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1819
1820
  /*
   * The following struct holds auto PWM min attributes, which are not available
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
1821
   * in all chips. Their creation depends on the chip type which is determined
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1822
1823
   * during module load.
   */
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
1824
  static struct attribute *dme1737_auto_pwm_min_attr[] = {
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
1825
1826
1827
1828
  	&sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr,
  	&sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr,
  	&sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr,
  };
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1829
1830
  /*
   * The following structs hold the fan attributes, some of which are optional.
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1831
   * Their creation depends on the chip configuration which is determined during
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1832
1833
   * module load.
   */
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1834
  static struct attribute *dme1737_fan1_attr[] = {
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1835
1836
1837
1838
  	&sensor_dev_attr_fan1_input.dev_attr.attr,
  	&sensor_dev_attr_fan1_min.dev_attr.attr,
  	&sensor_dev_attr_fan1_alarm.dev_attr.attr,
  	&sensor_dev_attr_fan1_type.dev_attr.attr,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1839
1840
  	NULL
  };
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1841
  static struct attribute *dme1737_fan2_attr[] = {
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1842
1843
1844
1845
  	&sensor_dev_attr_fan2_input.dev_attr.attr,
  	&sensor_dev_attr_fan2_min.dev_attr.attr,
  	&sensor_dev_attr_fan2_alarm.dev_attr.attr,
  	&sensor_dev_attr_fan2_type.dev_attr.attr,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1846
1847
  	NULL
  };
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1848
  static struct attribute *dme1737_fan3_attr[] = {
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1849
1850
1851
1852
  	&sensor_dev_attr_fan3_input.dev_attr.attr,
  	&sensor_dev_attr_fan3_min.dev_attr.attr,
  	&sensor_dev_attr_fan3_alarm.dev_attr.attr,
  	&sensor_dev_attr_fan3_type.dev_attr.attr,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1853
1854
  	NULL
  };
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1855
  static struct attribute *dme1737_fan4_attr[] = {
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1856
1857
1858
1859
  	&sensor_dev_attr_fan4_input.dev_attr.attr,
  	&sensor_dev_attr_fan4_min.dev_attr.attr,
  	&sensor_dev_attr_fan4_alarm.dev_attr.attr,
  	&sensor_dev_attr_fan4_type.dev_attr.attr,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1860
1861
  	NULL
  };
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1862
  static struct attribute *dme1737_fan5_attr[] = {
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1863
1864
1865
1866
  	&sensor_dev_attr_fan5_input.dev_attr.attr,
  	&sensor_dev_attr_fan5_min.dev_attr.attr,
  	&sensor_dev_attr_fan5_alarm.dev_attr.attr,
  	&sensor_dev_attr_fan5_max.dev_attr.attr,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1867
1868
  	NULL
  };
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1869
  static struct attribute *dme1737_fan6_attr[] = {
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1870
1871
1872
1873
  	&sensor_dev_attr_fan6_input.dev_attr.attr,
  	&sensor_dev_attr_fan6_min.dev_attr.attr,
  	&sensor_dev_attr_fan6_alarm.dev_attr.attr,
  	&sensor_dev_attr_fan6_max.dev_attr.attr,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1874
1875
1876
1877
  	NULL
  };
  
  static const struct attribute_group dme1737_fan_group[] = {
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1878
1879
1880
1881
1882
1883
  	{ .attrs = dme1737_fan1_attr },
  	{ .attrs = dme1737_fan2_attr },
  	{ .attrs = dme1737_fan3_attr },
  	{ .attrs = dme1737_fan4_attr },
  	{ .attrs = dme1737_fan5_attr },
  	{ .attrs = dme1737_fan6_attr },
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1884
  };
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1885
1886
1887
1888
  /*
   * The permissions of the following zone attributes are changed to read-
   * writeable if the chip is *not* locked. Otherwise they stay read-only.
   */
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
1889
  static struct attribute *dme1737_zone_chmod_attr[] = {
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1890
1891
1892
  	&sensor_dev_attr_zone1_auto_point1_temp.dev_attr.attr,
  	&sensor_dev_attr_zone1_auto_point2_temp.dev_attr.attr,
  	&sensor_dev_attr_zone1_auto_point3_temp.dev_attr.attr,
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1893
1894
1895
  	&sensor_dev_attr_zone2_auto_point1_temp.dev_attr.attr,
  	&sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr,
  	&sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr,
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
1896
1897
1898
1899
1900
1901
  	NULL
  };
  
  static const struct attribute_group dme1737_zone_chmod_group = {
  	.attrs = dme1737_zone_chmod_attr,
  };
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1902
1903
1904
1905
  /*
   * The permissions of the following zone 3 attributes are changed to read-
   * writeable if the chip is *not* locked. Otherwise they stay read-only.
   */
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
1906
  static struct attribute *dme1737_zone3_chmod_attr[] = {
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1907
1908
1909
  	&sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr,
  	&sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr,
  	&sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1910
1911
  	NULL
  };
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
1912
1913
  static const struct attribute_group dme1737_zone3_chmod_group = {
  	.attrs = dme1737_zone3_chmod_attr,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1914
  };
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1915
1916
  /*
   * The permissions of the following PWM attributes are changed to read-
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1917
   * writeable if the chip is *not* locked and the respective PWM is available.
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1918
1919
   * Otherwise they stay read-only.
   */
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1920
  static struct attribute *dme1737_pwm1_chmod_attr[] = {
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1921
1922
1923
1924
  	&sensor_dev_attr_pwm1_freq.dev_attr.attr,
  	&sensor_dev_attr_pwm1_enable.dev_attr.attr,
  	&sensor_dev_attr_pwm1_ramp_rate.dev_attr.attr,
  	&sensor_dev_attr_pwm1_auto_channels_zone.dev_attr.attr,
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1925
  	&sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1926
1927
  	NULL
  };
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1928
  static struct attribute *dme1737_pwm2_chmod_attr[] = {
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1929
1930
1931
1932
  	&sensor_dev_attr_pwm2_freq.dev_attr.attr,
  	&sensor_dev_attr_pwm2_enable.dev_attr.attr,
  	&sensor_dev_attr_pwm2_ramp_rate.dev_attr.attr,
  	&sensor_dev_attr_pwm2_auto_channels_zone.dev_attr.attr,
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1933
  	&sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1934
1935
  	NULL
  };
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1936
  static struct attribute *dme1737_pwm3_chmod_attr[] = {
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1937
1938
1939
1940
  	&sensor_dev_attr_pwm3_freq.dev_attr.attr,
  	&sensor_dev_attr_pwm3_enable.dev_attr.attr,
  	&sensor_dev_attr_pwm3_ramp_rate.dev_attr.attr,
  	&sensor_dev_attr_pwm3_auto_channels_zone.dev_attr.attr,
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1941
  	&sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1942
1943
  	NULL
  };
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1944
  static struct attribute *dme1737_pwm5_chmod_attr[] = {
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1945
1946
  	&sensor_dev_attr_pwm5.dev_attr.attr,
  	&sensor_dev_attr_pwm5_freq.dev_attr.attr,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1947
1948
  	NULL
  };
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1949
  static struct attribute *dme1737_pwm6_chmod_attr[] = {
9b257714a   Juerg Haefliger   hwmon: (dme1737) ...
1950
1951
  	&sensor_dev_attr_pwm6.dev_attr.attr,
  	&sensor_dev_attr_pwm6_freq.dev_attr.attr,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1952
1953
  	NULL
  };
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1954
1955
1956
1957
  static const struct attribute_group dme1737_pwm_chmod_group[] = {
  	{ .attrs = dme1737_pwm1_chmod_attr },
  	{ .attrs = dme1737_pwm2_chmod_attr },
  	{ .attrs = dme1737_pwm3_chmod_attr },
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1958
  	{ .attrs = NULL },
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1959
1960
  	{ .attrs = dme1737_pwm5_chmod_attr },
  	{ .attrs = dme1737_pwm6_chmod_attr },
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1961
  };
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
1962
1963
1964
1965
  /*
   * Pwm[1-3] are read-writeable if the associated pwm is in manual mode and the
   * chip is not locked. Otherwise they are read-only.
   */
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
1966
  static struct attribute *dme1737_pwm_chmod_attr[] = {
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1967
1968
1969
1970
1971
1972
1973
1974
  	&sensor_dev_attr_pwm1.dev_attr.attr,
  	&sensor_dev_attr_pwm2.dev_attr.attr,
  	&sensor_dev_attr_pwm3.dev_attr.attr,
  };
  
  /* ---------------------------------------------------------------------
   * Super-IO functions
   * --------------------------------------------------------------------- */
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
1975
1976
1977
1978
1979
1980
1981
1982
1983
  static inline void dme1737_sio_enter(int sio_cip)
  {
  	outb(0x55, sio_cip);
  }
  
  static inline void dme1737_sio_exit(int sio_cip)
  {
  	outb(0xaa, sio_cip);
  }
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
  static inline int dme1737_sio_inb(int sio_cip, int reg)
  {
  	outb(reg, sio_cip);
  	return inb(sio_cip + 1);
  }
  
  static inline void dme1737_sio_outb(int sio_cip, int reg, int val)
  {
  	outb(reg, sio_cip);
  	outb(val, sio_cip + 1);
  }
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1995
  /* ---------------------------------------------------------------------
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
1996
   * Device initialization
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1997
   * --------------------------------------------------------------------- */
67e2f3285   Juerg Haefliger   hwmon: (dme1737) ...
1998
  static int dme1737_i2c_get_features(int, struct dme1737_data*);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
1999

b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2000
  static void dme1737_chmod_file(struct device *dev,
48176a973   Al Viro   switch sysfs_chmo...
2001
  			       struct attribute *attr, umode_t mode)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2002
  {
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2003
2004
2005
  	if (sysfs_chmod_file(&dev->kobj, attr, mode)) {
  		dev_warn(dev, "Failed to change permissions of %s.
  ",
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2006
2007
2008
  			 attr->name);
  	}
  }
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2009
  static void dme1737_chmod_group(struct device *dev,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2010
  				const struct attribute_group *group,
48176a973   Al Viro   switch sysfs_chmo...
2011
  				umode_t mode)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2012
2013
  {
  	struct attribute **attr;
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2014
  	for (attr = group->attrs; *attr; attr++)
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2015
  		dme1737_chmod_file(dev, *attr, mode);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2016
  }
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2017
  static void dme1737_remove_files(struct device *dev)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2018
  {
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2019
2020
2021
2022
  	struct dme1737_data *data = dev_get_drvdata(dev);
  	int ix;
  
  	for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) {
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2023
  		if (data->has_features & HAS_FAN(ix)) {
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2024
2025
2026
2027
2028
2029
  			sysfs_remove_group(&dev->kobj,
  					   &dme1737_fan_group[ix]);
  		}
  	}
  
  	for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) {
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2030
  		if (data->has_features & HAS_PWM(ix)) {
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2031
2032
  			sysfs_remove_group(&dev->kobj,
  					   &dme1737_pwm_group[ix]);
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2033
  			if ((data->has_features & HAS_PWM_MIN) && ix < 3) {
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
2034
  				sysfs_remove_file(&dev->kobj,
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2035
  						dme1737_auto_pwm_min_attr[ix]);
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
2036
  			}
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2037
2038
  		}
  	}
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2039
  	if (data->has_features & HAS_TEMP_OFFSET)
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2040
  		sysfs_remove_group(&dev->kobj, &dme1737_temp_offset_group);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2041
  	if (data->has_features & HAS_VID)
9d0914468   Jean Delvare   hwmon: (dme1737) ...
2042
  		sysfs_remove_group(&dev->kobj, &dme1737_vid_group);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2043
  	if (data->has_features & HAS_ZONE3)
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2044
  		sysfs_remove_group(&dev->kobj, &dme1737_zone3_group);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2045
  	if (data->has_features & HAS_ZONE_HYST)
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2046
  		sysfs_remove_group(&dev->kobj, &dme1737_zone_hyst_group);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2047
  	if (data->has_features & HAS_IN7)
d4b94e1fa   Juerg Haefliger   hwmon: (dme1737) ...
2048
  		sysfs_remove_group(&dev->kobj, &dme1737_in7_group);
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2049
  	sysfs_remove_group(&dev->kobj, &dme1737_group);
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2050

c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2051
  	if (!data->client)
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2052
  		sysfs_remove_file(&dev->kobj, &dev_attr_name.attr);
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2053
2054
2055
2056
2057
2058
  }
  
  static int dme1737_create_files(struct device *dev)
  {
  	struct dme1737_data *data = dev_get_drvdata(dev);
  	int err, ix;
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2059
  	/* Create a name attribute for ISA devices */
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2060
2061
  	if (!data->client) {
  		err = sysfs_create_file(&dev->kobj, &dev_attr_name.attr);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2062
  		if (err)
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2063
  			goto exit;
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2064
  	}
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2065
  	/* Create standard sysfs attributes */
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2066
  	err = sysfs_create_group(&dev->kobj, &dme1737_group);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2067
  	if (err)
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2068
  		goto exit_remove;
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2069

ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2070
  	/* Create chip-dependent sysfs attributes */
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2071
2072
2073
  	if (data->has_features & HAS_TEMP_OFFSET) {
  		err = sysfs_create_group(&dev->kobj,
  					 &dme1737_temp_offset_group);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2074
  		if (err)
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2075
  			goto exit_remove;
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
2076
  	}
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2077
2078
  	if (data->has_features & HAS_VID) {
  		err = sysfs_create_group(&dev->kobj, &dme1737_vid_group);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2079
  		if (err)
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2080
  			goto exit_remove;
9d0914468   Jean Delvare   hwmon: (dme1737) ...
2081
  	}
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2082
2083
  	if (data->has_features & HAS_ZONE3) {
  		err = sysfs_create_group(&dev->kobj, &dme1737_zone3_group);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2084
  		if (err)
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2085
  			goto exit_remove;
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2086
  	}
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2087
2088
  	if (data->has_features & HAS_ZONE_HYST) {
  		err = sysfs_create_group(&dev->kobj, &dme1737_zone_hyst_group);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2089
  		if (err)
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2090
  			goto exit_remove;
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2091
  	}
d4b94e1fa   Juerg Haefliger   hwmon: (dme1737) ...
2092
2093
  	if (data->has_features & HAS_IN7) {
  		err = sysfs_create_group(&dev->kobj, &dme1737_in7_group);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2094
  		if (err)
d4b94e1fa   Juerg Haefliger   hwmon: (dme1737) ...
2095
  			goto exit_remove;
d4b94e1fa   Juerg Haefliger   hwmon: (dme1737) ...
2096
  	}
9d0914468   Jean Delvare   hwmon: (dme1737) ...
2097

b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2098
2099
  	/* Create fan sysfs attributes */
  	for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) {
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2100
  		if (data->has_features & HAS_FAN(ix)) {
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2101
2102
  			err = sysfs_create_group(&dev->kobj,
  						 &dme1737_fan_group[ix]);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2103
  			if (err)
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2104
  				goto exit_remove;
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2105
2106
2107
2108
2109
  		}
  	}
  
  	/* Create PWM sysfs attributes */
  	for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) {
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2110
  		if (data->has_features & HAS_PWM(ix)) {
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2111
2112
  			err = sysfs_create_group(&dev->kobj,
  						 &dme1737_pwm_group[ix]);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2113
  			if (err)
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2114
  				goto exit_remove;
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2115
2116
2117
  			if ((data->has_features & HAS_PWM_MIN) && (ix < 3)) {
  				err = sysfs_create_file(&dev->kobj,
  						dme1737_auto_pwm_min_attr[ix]);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2118
  				if (err)
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2119
  					goto exit_remove;
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
2120
  			}
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2121
2122
  		}
  	}
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2123
2124
2125
2126
  	/*
  	 * Inform if the device is locked. Otherwise change the permissions of
  	 * selected attributes from read-only to read-writeable.
  	 */
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2127
  	if (data->config & 0x02) {
b55f37572   Guenter Roeck   hwmon: Fix checkp...
2128
2129
2130
  		dev_info(dev,
  			 "Device is locked. Some attributes will be read-only.
  ");
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2131
  	} else {
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
2132
2133
  		/* Change permissions of zone sysfs attributes */
  		dme1737_chmod_group(dev, &dme1737_zone_chmod_group,
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2134
  				    S_IRUGO | S_IWUSR);
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
  		/* Change permissions of chip-dependent sysfs attributes */
  		if (data->has_features & HAS_TEMP_OFFSET) {
  			dme1737_chmod_group(dev, &dme1737_temp_offset_group,
  					    S_IRUGO | S_IWUSR);
  		}
  		if (data->has_features & HAS_ZONE3) {
  			dme1737_chmod_group(dev, &dme1737_zone3_chmod_group,
  					    S_IRUGO | S_IWUSR);
  		}
  		if (data->has_features & HAS_ZONE_HYST) {
  			dme1737_chmod_group(dev, &dme1737_zone_hyst_group,
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
2146
2147
  					    S_IRUGO | S_IWUSR);
  		}
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
2148
2149
  		/* Change permissions of PWM sysfs attributes */
  		for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_chmod_group); ix++) {
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2150
  			if (data->has_features & HAS_PWM(ix)) {
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2151
  				dme1737_chmod_group(dev,
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
2152
  						&dme1737_pwm_chmod_group[ix],
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2153
  						S_IRUGO | S_IWUSR);
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2154
2155
  				if ((data->has_features & HAS_PWM_MIN) &&
  				    ix < 3) {
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
2156
  					dme1737_chmod_file(dev,
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2157
  						dme1737_auto_pwm_min_attr[ix],
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
2158
2159
  						S_IRUGO | S_IWUSR);
  				}
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2160
2161
2162
2163
2164
  			}
  		}
  
  		/* Change permissions of pwm[1-3] if in manual mode */
  		for (ix = 0; ix < 3; ix++) {
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2165
  			if ((data->has_features & HAS_PWM(ix)) &&
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2166
2167
  			    (PWM_EN_FROM_REG(data->pwm_config[ix]) == 1)) {
  				dme1737_chmod_file(dev,
73ce48f6c   Juerg Haefliger   hwmon: (dme1737) ...
2168
  						dme1737_pwm_chmod_attr[ix],
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
  						S_IRUGO | S_IWUSR);
  			}
  		}
  	}
  
  	return 0;
  
  exit_remove:
  	dme1737_remove_files(dev);
  exit:
  	return err;
  }
  
  static int dme1737_init_device(struct device *dev)
  {
  	struct dme1737_data *data = dev_get_drvdata(dev);
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
2185
  	struct i2c_client *client = data->client;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2186
2187
  	int ix;
  	u8 reg;
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
2188
2189
  	/* Point to the right nominal voltages array */
  	data->in_nominal = IN_NOMINAL(data->type);
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
2190
  	data->config = dme1737_read(data, DME1737_REG_CONFIG);
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2191
2192
2193
  	/* Inform if part is not monitoring/started */
  	if (!(data->config & 0x01)) {
  		if (!force_start) {
b55f37572   Guenter Roeck   hwmon: Fix checkp...
2194
2195
2196
  			dev_err(dev,
  				"Device is not monitoring. Use the force_start load parameter to override.
  ");
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2197
2198
2199
2200
2201
  			return -EFAULT;
  		}
  
  		/* Force monitoring */
  		data->config |= 0x01;
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
2202
  		dme1737_write(data, DME1737_REG_CONFIG, data->config);
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2203
  	}
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2204
2205
  	/* Inform if part is not ready */
  	if (!(data->config & 0x04)) {
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2206
2207
  		dev_err(dev, "Device is not ready.
  ");
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2208
2209
  		return -EFAULT;
  	}
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2210
2211
2212
2213
  	/*
  	 * Determine which optional fan and pwm features are enabled (only
  	 * valid for I2C devices)
  	 */
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
2214
2215
  	if (client) {   /* I2C chip */
  		data->config2 = dme1737_read(data, DME1737_REG_CONFIG2);
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2216
  		/* Check if optional fan3 input is enabled */
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2217
  		if (data->config2 & 0x04)
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2218
  			data->has_features |= HAS_FAN(2);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2219

c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2220
2221
  		/*
  		 * Fan4 and pwm3 are only available if the client's I2C address
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2222
  		 * is the default 0x2e. Otherwise the I/Os associated with
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2223
2224
2225
  		 * these functions are used for addr enable/select.
  		 */
  		if (client->addr == 0x2e)
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2226
  			data->has_features |= HAS_FAN(3) | HAS_PWM(2);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2227

c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2228
2229
  		/*
  		 * Determine which of the optional fan[5-6] and pwm[5-6]
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2230
2231
  		 * features are enabled. For this, we need to query the runtime
  		 * registers through the Super-IO LPC interface. Try both
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2232
2233
  		 * config ports 0x2e and 0x4e.
  		 */
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2234
2235
  		if (dme1737_i2c_get_features(0x2e, data) &&
  		    dme1737_i2c_get_features(0x4e, data)) {
b55f37572   Guenter Roeck   hwmon: Fix checkp...
2236
2237
2238
  			dev_warn(dev,
  				 "Failed to query Super-IO for optional features.
  ");
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2239
  		}
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2240
  	}
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
  	/* Fan[1-2] and pwm[1-2] are present in all chips */
  	data->has_features |= HAS_FAN(0) | HAS_FAN(1) | HAS_PWM(0) | HAS_PWM(1);
  
  	/* Chip-dependent features */
  	switch (data->type) {
  	case dme1737:
  		data->has_features |= HAS_TEMP_OFFSET | HAS_VID | HAS_ZONE3 |
  			HAS_ZONE_HYST | HAS_PWM_MIN;
  		break;
  	case sch311x:
  		data->has_features |= HAS_TEMP_OFFSET | HAS_ZONE3 |
  			HAS_ZONE_HYST | HAS_PWM_MIN | HAS_FAN(2) | HAS_PWM(2);
  		break;
  	case sch5027:
  		data->has_features |= HAS_ZONE3;
  		break;
  	case sch5127:
d4b94e1fa   Juerg Haefliger   hwmon: (dme1737) ...
2258
  		data->has_features |= HAS_FAN(2) | HAS_PWM(2) | HAS_IN7;
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2259
2260
2261
2262
  		break;
  	default:
  		break;
  	}
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2263

b55f37572   Guenter Roeck   hwmon: Fix checkp...
2264
2265
2266
  	dev_info(dev,
  		 "Optional features: pwm3=%s, pwm5=%s, pwm6=%s, fan3=%s, fan4=%s, fan5=%s, fan6=%s.
  ",
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2267
2268
2269
2270
2271
2272
2273
  		 (data->has_features & HAS_PWM(2)) ? "yes" : "no",
  		 (data->has_features & HAS_PWM(4)) ? "yes" : "no",
  		 (data->has_features & HAS_PWM(5)) ? "yes" : "no",
  		 (data->has_features & HAS_FAN(2)) ? "yes" : "no",
  		 (data->has_features & HAS_FAN(3)) ? "yes" : "no",
  		 (data->has_features & HAS_FAN(4)) ? "yes" : "no",
  		 (data->has_features & HAS_FAN(5)) ? "yes" : "no");
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2274

dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
2275
  	reg = dme1737_read(data, DME1737_REG_TACH_PWM);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2276
  	/* Inform if fan-to-pwm mapping differs from the default */
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
2277
  	if (client && reg != 0xa4) {   /* I2C chip */
b55f37572   Guenter Roeck   hwmon: Fix checkp...
2278
2279
2280
  		dev_warn(dev,
  			 "Non-standard fan to pwm mapping: fan1->pwm%d, fan2->pwm%d, fan3->pwm%d, fan4->pwm%d. %s
  ",
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2281
  			 (reg & 0x03) + 1, ((reg >> 2) & 0x03) + 1,
b55f37572   Guenter Roeck   hwmon: Fix checkp...
2282
2283
  			 ((reg >> 4) & 0x03) + 1, ((reg >> 6) & 0x03) + 1,
  			 DO_REPORT);
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
2284
  	} else if (!client && reg != 0x24) {   /* ISA chip */
b55f37572   Guenter Roeck   hwmon: Fix checkp...
2285
2286
2287
  		dev_warn(dev,
  			 "Non-standard fan to pwm mapping: fan1->pwm%d, fan2->pwm%d, fan3->pwm%d. %s
  ",
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2288
  			 (reg & 0x03) + 1, ((reg >> 2) & 0x03) + 1,
b55f37572   Guenter Roeck   hwmon: Fix checkp...
2289
  			 ((reg >> 4) & 0x03) + 1, DO_REPORT);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2290
  	}
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2291
2292
  	/*
  	 * Switch pwm[1-3] to manual mode if they are currently disabled and
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2293
  	 * set the duty-cycles to 0% (which is identical to the PWMs being
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2294
2295
  	 * disabled).
  	 */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2296
2297
  	if (!(data->config & 0x02)) {
  		for (ix = 0; ix < 3; ix++) {
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
2298
  			data->pwm_config[ix] = dme1737_read(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2299
  						DME1737_REG_PWM_CONFIG(ix));
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2300
  			if ((data->has_features & HAS_PWM(ix)) &&
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2301
  			    (PWM_EN_FROM_REG(data->pwm_config[ix]) == -1)) {
b55f37572   Guenter Roeck   hwmon: Fix checkp...
2302
2303
2304
2305
  				dev_info(dev,
  					 "Switching pwm%d to manual mode.
  ",
  					 ix + 1);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2306
2307
  				data->pwm_config[ix] = PWM_EN_TO_REG(1,
  							data->pwm_config[ix]);
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
2308
2309
  				dme1737_write(data, DME1737_REG_PWM(ix), 0);
  				dme1737_write(data,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
  					      DME1737_REG_PWM_CONFIG(ix),
  					      data->pwm_config[ix]);
  			}
  		}
  	}
  
  	/* Initialize the default PWM auto channels zone (acz) assignments */
  	data->pwm_acz[0] = 1;	/* pwm1 -> zone1 */
  	data->pwm_acz[1] = 2;	/* pwm2 -> zone2 */
  	data->pwm_acz[2] = 4;	/* pwm3 -> zone3 */
  
  	/* Set VRM */
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2322
  	if (data->has_features & HAS_VID)
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
2323
  		data->vrm = vid_which_vrm();
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2324
2325
2326
  
  	return 0;
  }
67e2f3285   Juerg Haefliger   hwmon: (dme1737) ...
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
  /* ---------------------------------------------------------------------
   * I2C device detection and registration
   * --------------------------------------------------------------------- */
  
  static struct i2c_driver dme1737_i2c_driver;
  
  static int dme1737_i2c_get_features(int sio_cip, struct dme1737_data *data)
  {
  	int err = 0, reg;
  	u16 addr;
  
  	dme1737_sio_enter(sio_cip);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2339
2340
2341
2342
  	/*
  	 * Check device ID
  	 * We currently know about two kinds of DME1737 and SCH5027.
  	 */
345a22245   Juerg Haefliger   hwmon: (dme1737) ...
2343
  	reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20);
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2344
2345
  	if (!(reg == DME1737_ID_1 || reg == DME1737_ID_2 ||
  	      reg == SCH5027_ID)) {
67e2f3285   Juerg Haefliger   hwmon: (dme1737) ...
2346
2347
2348
2349
2350
2351
2352
2353
  		err = -ENODEV;
  		goto exit;
  	}
  
  	/* Select logical device A (runtime registers) */
  	dme1737_sio_outb(sio_cip, 0x07, 0x0a);
  
  	/* Get the base address of the runtime registers */
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2354
2355
2356
  	addr = (dme1737_sio_inb(sio_cip, 0x60) << 8) |
  		dme1737_sio_inb(sio_cip, 0x61);
  	if (!addr) {
67e2f3285   Juerg Haefliger   hwmon: (dme1737) ...
2357
2358
2359
  		err = -ENODEV;
  		goto exit;
  	}
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2360
2361
  	/*
  	 * Read the runtime registers to determine which optional features
67e2f3285   Juerg Haefliger   hwmon: (dme1737) ...
2362
  	 * are enabled and available. Bits [3:2] of registers 0x43-0x46 are set
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2363
2364
2365
  	 * to '10' if the respective feature is enabled.
  	 */
  	if ((inb(addr + 0x43) & 0x0c) == 0x08) /* fan6 */
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2366
  		data->has_features |= HAS_FAN(5);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2367
  	if ((inb(addr + 0x44) & 0x0c) == 0x08) /* pwm6 */
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2368
  		data->has_features |= HAS_PWM(5);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2369
  	if ((inb(addr + 0x45) & 0x0c) == 0x08) /* fan5 */
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2370
  		data->has_features |= HAS_FAN(4);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2371
  	if ((inb(addr + 0x46) & 0x0c) == 0x08) /* pwm5 */
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2372
  		data->has_features |= HAS_PWM(4);
67e2f3285   Juerg Haefliger   hwmon: (dme1737) ...
2373
2374
2375
2376
2377
2378
  
  exit:
  	dme1737_sio_exit(sio_cip);
  
  	return err;
  }
67a37308a   Jean Delvare   hwmon: (dme1737) ...
2379
  /* Return 0 if detection is successful, -ENODEV otherwise */
310ec7921   Jean Delvare   i2c: Drop the kin...
2380
  static int dme1737_i2c_detect(struct i2c_client *client,
67a37308a   Jean Delvare   hwmon: (dme1737) ...
2381
  			      struct i2c_board_info *info)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2382
  {
67a37308a   Jean Delvare   hwmon: (dme1737) ...
2383
2384
  	struct i2c_adapter *adapter = client->adapter;
  	struct device *dev = &adapter->dev;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2385
  	u8 company, verstep = 0;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2386
  	const char *name;
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2387
  	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
67a37308a   Jean Delvare   hwmon: (dme1737) ...
2388
  		return -ENODEV;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2389

52df6440a   Jean Delvare   hwmon: Clean up d...
2390
2391
  	company = i2c_smbus_read_byte_data(client, DME1737_REG_COMPANY);
  	verstep = i2c_smbus_read_byte_data(client, DME1737_REG_VERSTEP);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2392

52df6440a   Jean Delvare   hwmon: Clean up d...
2393
2394
  	if (company == DME1737_COMPANY_SMSC &&
  	    verstep == SCH5027_VERSTEP) {
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
2395
  		name = "sch5027";
52df6440a   Jean Delvare   hwmon: Clean up d...
2396
2397
  	} else if (company == DME1737_COMPANY_SMSC &&
  		   (verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP) {
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
2398
  		name = "dme1737";
52df6440a   Jean Delvare   hwmon: Clean up d...
2399
2400
  	} else {
  		return -ENODEV;
549edb833   Juerg Haefliger   hwmon: (dme1737) ...
2401
  	}
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2402

549edb833   Juerg Haefliger   hwmon: (dme1737) ...
2403
2404
  	dev_info(dev, "Found a %s chip at 0x%02x (rev 0x%02x).
  ",
52df6440a   Jean Delvare   hwmon: Clean up d...
2405
2406
  		 verstep == SCH5027_VERSTEP ? "SCH5027" : "DME1737",
  		 client->addr, verstep);
67a37308a   Jean Delvare   hwmon: (dme1737) ...
2407
2408
2409
2410
  	strlcpy(info->type, name, I2C_NAME_SIZE);
  
  	return 0;
  }
4e1b4d222   Stephen Kitt   hwmon: (dme1737) ...
2411
2412
2413
  static const struct i2c_device_id dme1737_id[];
  
  static int dme1737_i2c_probe(struct i2c_client *client)
67a37308a   Jean Delvare   hwmon: (dme1737) ...
2414
2415
2416
2417
  {
  	struct dme1737_data *data;
  	struct device *dev = &client->dev;
  	int err;
805fd8c5b   Guenter Roeck   hwmon: (dme1737) ...
2418
2419
2420
  	data = devm_kzalloc(dev, sizeof(struct dme1737_data), GFP_KERNEL);
  	if (!data)
  		return -ENOMEM;
67a37308a   Jean Delvare   hwmon: (dme1737) ...
2421
2422
  
  	i2c_set_clientdata(client, data);
4e1b4d222   Stephen Kitt   hwmon: (dme1737) ...
2423
  	data->type = i2c_match_id(dme1737_id, client)->driver_data;
67a37308a   Jean Delvare   hwmon: (dme1737) ...
2424
2425
2426
  	data->client = client;
  	data->name = client->name;
  	mutex_init(&data->update_lock);
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2427

9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2428
  	/* Initialize the DME1737 chip */
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2429
2430
  	err = dme1737_init_device(dev);
  	if (err) {
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2431
2432
  		dev_err(dev, "Failed to initialize device.
  ");
805fd8c5b   Guenter Roeck   hwmon: (dme1737) ...
2433
  		return err;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2434
  	}
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2435
  	/* Create sysfs files */
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2436
2437
  	err = dme1737_create_files(dev);
  	if (err) {
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2438
2439
  		dev_err(dev, "Failed to create sysfs files.
  ");
805fd8c5b   Guenter Roeck   hwmon: (dme1737) ...
2440
  		return err;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2441
2442
2443
  	}
  
  	/* Register device */
62ee3e10d   Mark M. Hoffman   hwmon: (dme1737) ...
2444
  	data->hwmon_dev = hwmon_device_register(dev);
1beeffe43   Tony Jones   hwmon: Convert fr...
2445
  	if (IS_ERR(data->hwmon_dev)) {
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2446
2447
  		dev_err(dev, "Failed to register device.
  ");
1beeffe43   Tony Jones   hwmon: Convert fr...
2448
  		err = PTR_ERR(data->hwmon_dev);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2449
2450
  		goto exit_remove;
  	}
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2451
2452
2453
  	return 0;
  
  exit_remove:
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2454
  	dme1737_remove_files(dev);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2455
2456
  	return err;
  }
67a37308a   Jean Delvare   hwmon: (dme1737) ...
2457
  static int dme1737_i2c_remove(struct i2c_client *client)
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2458
2459
  {
  	struct dme1737_data *data = i2c_get_clientdata(client);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2460

1beeffe43   Tony Jones   hwmon: Convert fr...
2461
  	hwmon_device_unregister(data->hwmon_dev);
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2462
  	dme1737_remove_files(&client->dev);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2463

9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2464
2465
  	return 0;
  }
67a37308a   Jean Delvare   hwmon: (dme1737) ...
2466
2467
2468
2469
2470
2471
  static const struct i2c_device_id dme1737_id[] = {
  	{ "dme1737", dme1737 },
  	{ "sch5027", sch5027 },
  	{ }
  };
  MODULE_DEVICE_TABLE(i2c, dme1737_id);
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2472
  static struct i2c_driver dme1737_i2c_driver = {
67a37308a   Jean Delvare   hwmon: (dme1737) ...
2473
  	.class = I2C_CLASS_HWMON,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2474
2475
2476
  	.driver = {
  		.name = "dme1737",
  	},
4e1b4d222   Stephen Kitt   hwmon: (dme1737) ...
2477
  	.probe_new = dme1737_i2c_probe,
67a37308a   Jean Delvare   hwmon: (dme1737) ...
2478
2479
2480
  	.remove = dme1737_i2c_remove,
  	.id_table = dme1737_id,
  	.detect = dme1737_i2c_detect,
c3813d6af   Jean Delvare   i2c: Get rid of s...
2481
  	.address_list = normal_i2c,
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2482
  };
67e2f3285   Juerg Haefliger   hwmon: (dme1737) ...
2483
  /* ---------------------------------------------------------------------
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2484
2485
2486
2487
2488
2489
2490
2491
2492
   * ISA device detection and registration
   * --------------------------------------------------------------------- */
  
  static int __init dme1737_isa_detect(int sio_cip, unsigned short *addr)
  {
  	int err = 0, reg;
  	unsigned short base_addr;
  
  	dme1737_sio_enter(sio_cip);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2493
2494
2495
2496
  	/*
  	 * Check device ID
  	 * We currently know about SCH3112, SCH3114, SCH3116, and SCH5127
  	 */
67b671bce   Jean Delvare   hwmon: Let the us...
2497
  	reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20);
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2498
2499
  	if (!(reg == SCH3112_ID || reg == SCH3114_ID || reg == SCH3116_ID ||
  	      reg == SCH5127_ID)) {
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2500
2501
2502
2503
2504
2505
2506
2507
  		err = -ENODEV;
  		goto exit;
  	}
  
  	/* Select logical device A (runtime registers) */
  	dme1737_sio_outb(sio_cip, 0x07, 0x0a);
  
  	/* Get the base address of the runtime registers */
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2508
2509
2510
  	base_addr = (dme1737_sio_inb(sio_cip, 0x60) << 8) |
  		     dme1737_sio_inb(sio_cip, 0x61);
  	if (!base_addr) {
9c6e13b41   Joe Perches   hwmon: (dme1737) ...
2511
2512
  		pr_err("Base address not set
  ");
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2513
2514
2515
  		err = -ENODEV;
  		goto exit;
  	}
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2516
2517
2518
2519
  	/*
  	 * Access to the hwmon registers is through an index/data register
  	 * pair located at offset 0x70/0x71.
  	 */
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
  	*addr = base_addr + 0x70;
  
  exit:
  	dme1737_sio_exit(sio_cip);
  	return err;
  }
  
  static int __init dme1737_isa_device_add(unsigned short addr)
  {
  	struct resource res = {
  		.start	= addr,
  		.end	= addr + DME1737_EXTENT - 1,
  		.name	= "dme1737",
  		.flags	= IORESOURCE_IO,
  	};
  	int err;
b9acb64a3   Jean Delvare   hwmon: Check for ...
2536
2537
2538
  	err = acpi_check_resource_conflict(&res);
  	if (err)
  		goto exit;
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2539
2540
  	pdev = platform_device_alloc("dme1737", addr);
  	if (!pdev) {
9c6e13b41   Joe Perches   hwmon: (dme1737) ...
2541
2542
  		pr_err("Failed to allocate device
  ");
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2543
2544
2545
  		err = -ENOMEM;
  		goto exit;
  	}
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2546
2547
  	err = platform_device_add_resources(pdev, &res, 1);
  	if (err) {
9c6e13b41   Joe Perches   hwmon: (dme1737) ...
2548
2549
  		pr_err("Failed to add device resource (err = %d)
  ", err);
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2550
2551
  		goto exit_device_put;
  	}
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2552
2553
  	err = platform_device_add(pdev);
  	if (err) {
9c6e13b41   Joe Perches   hwmon: (dme1737) ...
2554
2555
  		pr_err("Failed to add device (err = %d)
  ", err);
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
  		goto exit_device_put;
  	}
  
  	return 0;
  
  exit_device_put:
  	platform_device_put(pdev);
  	pdev = NULL;
  exit:
  	return err;
  }
6c931ae1c   Bill Pemberton   hwmon: remove use...
2567
  static int dme1737_isa_probe(struct platform_device *pdev)
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2568
2569
2570
  {
  	u8 company, device;
  	struct resource *res;
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2571
2572
2573
2574
2575
  	struct dme1737_data *data;
  	struct device *dev = &pdev->dev;
  	int err;
  
  	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
805fd8c5b   Guenter Roeck   hwmon: (dme1737) ...
2576
  	if (!devm_request_region(dev, res->start, DME1737_EXTENT, "dme1737")) {
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2577
2578
2579
2580
  		dev_err(dev, "Failed to request region 0x%04x-0x%04x.
  ",
  			(unsigned short)res->start,
  			(unsigned short)res->start + DME1737_EXTENT - 1);
805fd8c5b   Guenter Roeck   hwmon: (dme1737) ...
2581
  		return -EBUSY;
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2582
  	}
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2583

805fd8c5b   Guenter Roeck   hwmon: (dme1737) ...
2584
2585
2586
  	data = devm_kzalloc(dev, sizeof(struct dme1737_data), GFP_KERNEL);
  	if (!data)
  		return -ENOMEM;
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2587

dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
2588
  	data->addr = res->start;
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2589
  	platform_set_drvdata(pdev, data);
55d68d75a   Juerg Haefliger   hwmon: (dme1737) ...
2590
  	/* Skip chip detection if module is loaded with force_id parameter */
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
  	switch (force_id) {
  	case SCH3112_ID:
  	case SCH3114_ID:
  	case SCH3116_ID:
  		data->type = sch311x;
  		break;
  	case SCH5127_ID:
  		data->type = sch5127;
  		break;
  	default:
dbc2bc251   Jean Delvare   hwmon: (dme1737) ...
2601
2602
  		company = dme1737_read(data, DME1737_REG_COMPANY);
  		device = dme1737_read(data, DME1737_REG_DEVICE);
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2603

ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2604
2605
2606
2607
2608
2609
2610
  		if ((company == DME1737_COMPANY_SMSC) &&
  		    (device == SCH311X_DEVICE)) {
  			data->type = sch311x;
  		} else if ((company == DME1737_COMPANY_SMSC) &&
  			   (device == SCH5127_DEVICE)) {
  			data->type = sch5127;
  		} else {
805fd8c5b   Guenter Roeck   hwmon: (dme1737) ...
2611
  			return -ENODEV;
55d68d75a   Juerg Haefliger   hwmon: (dme1737) ...
2612
  		}
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2613
  	}
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2614
  	if (data->type == sch5127)
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2615
  		data->name = "sch5127";
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2616
  	else
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2617
  		data->name = "sch311x";
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2618
2619
  
  	/* Initialize the mutex */
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2620
  	mutex_init(&data->update_lock);
ea694431f   Juerg Haefliger   hwmon: (dme1737) ...
2621
2622
2623
  	dev_info(dev, "Found a %s chip at 0x%04x
  ",
  		 data->type == sch5127 ? "SCH5127" : "SCH311x", data->addr);
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2624
2625
  
  	/* Initialize the chip */
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2626
2627
  	err = dme1737_init_device(dev);
  	if (err) {
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2628
2629
  		dev_err(dev, "Failed to initialize device.
  ");
805fd8c5b   Guenter Roeck   hwmon: (dme1737) ...
2630
  		return err;
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2631
2632
2633
  	}
  
  	/* Create sysfs files */
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2634
2635
  	err = dme1737_create_files(dev);
  	if (err) {
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2636
2637
  		dev_err(dev, "Failed to create sysfs files.
  ");
805fd8c5b   Guenter Roeck   hwmon: (dme1737) ...
2638
  		return err;
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
  	}
  
  	/* Register device */
  	data->hwmon_dev = hwmon_device_register(dev);
  	if (IS_ERR(data->hwmon_dev)) {
  		dev_err(dev, "Failed to register device.
  ");
  		err = PTR_ERR(data->hwmon_dev);
  		goto exit_remove_files;
  	}
  
  	return 0;
  
  exit_remove_files:
  	dme1737_remove_files(dev);
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2654
2655
  	return err;
  }
281dfd0b6   Bill Pemberton   hwmon: remove use...
2656
  static int dme1737_isa_remove(struct platform_device *pdev)
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2657
2658
2659
2660
2661
  {
  	struct dme1737_data *data = platform_get_drvdata(pdev);
  
  	hwmon_device_unregister(data->hwmon_dev);
  	dme1737_remove_files(&pdev->dev);
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2662
2663
2664
2665
2666
2667
  
  	return 0;
  }
  
  static struct platform_driver dme1737_isa_driver = {
  	.driver = {
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2668
2669
2670
  		.name = "dme1737",
  	},
  	.probe = dme1737_isa_probe,
9e5e9b7a9   Bill Pemberton   hwmon: remove use...
2671
  	.remove = dme1737_isa_remove,
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2672
2673
2674
  };
  
  /* ---------------------------------------------------------------------
67e2f3285   Juerg Haefliger   hwmon: (dme1737) ...
2675
2676
   * Module initialization and cleanup
   * --------------------------------------------------------------------- */
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2677
2678
  static int __init dme1737_init(void)
  {
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2679
2680
  	int err;
  	unsigned short addr;
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2681
  	err = i2c_add_driver(&dme1737_i2c_driver);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2682
  	if (err)
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2683
  		goto exit;
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2684
2685
  
  	if (dme1737_isa_detect(0x2e, &addr) &&
92430b6fe   Juerg Haefliger   hwmon: (dme1737) ...
2686
2687
2688
2689
  	    dme1737_isa_detect(0x4e, &addr) &&
  	    (!probe_all_addr ||
  	     (dme1737_isa_detect(0x162e, &addr) &&
  	      dme1737_isa_detect(0x164e, &addr)))) {
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2690
2691
2692
  		/* Return 0 if we didn't find an ISA device */
  		return 0;
  	}
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2693
  	err = platform_driver_register(&dme1737_isa_driver);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2694
  	if (err)
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2695
  		goto exit_del_i2c_driver;
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2696
2697
  
  	/* Sets global pdev as a side effect */
06f3d9fb4   Juerg Haefliger   hwmon: (dme1737) ...
2698
  	err = dme1737_isa_device_add(addr);
c8de83624   Guenter Roeck   hwmon: (dme1737) ...
2699
  	if (err)
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2700
  		goto exit_del_isa_driver;
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2701
2702
2703
2704
2705
2706
2707
2708
2709
  
  	return 0;
  
  exit_del_isa_driver:
  	platform_driver_unregister(&dme1737_isa_driver);
  exit_del_i2c_driver:
  	i2c_del_driver(&dme1737_i2c_driver);
  exit:
  	return err;
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2710
2711
2712
2713
  }
  
  static void __exit dme1737_exit(void)
  {
e95c237d7   Juerg Haefliger   hwmon: (dme1737) ...
2714
2715
2716
2717
  	if (pdev) {
  		platform_device_unregister(pdev);
  		platform_driver_unregister(&dme1737_isa_driver);
  	}
b237eb25d   Juerg Haefliger   hwmon: (dme1737) ...
2718
  	i2c_del_driver(&dme1737_i2c_driver);
9431996f5   Juerg Haefliger   hwmon: New SMSC D...
2719
2720
2721
2722
2723
2724
2725
2726
  }
  
  MODULE_AUTHOR("Juerg Haefliger <juergh@gmail.com>");
  MODULE_DESCRIPTION("DME1737 sensors");
  MODULE_LICENSE("GPL");
  
  module_init(dme1737_init);
  module_exit(dme1737_exit);