Blame view

drivers/hwmon/w83795.c 62.1 KB
792d376b4   Wei Song   hwmon: New driver...
1
2
3
4
  /*
   *  w83795.c - Linux kernel driver for hardware monitoring
   *  Copyright (C) 2008 Nuvoton Technology Corp.
   *                Wei Song
e3760b432   Jean Delvare   hwmon: (w83795) A...
5
   *  Copyright (C) 2010 Jean Delvare <khali@linux-fr.org>
792d376b4   Wei Song   hwmon: New driver...
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
   *
   *  This program is free software; you can redistribute it and/or modify
   *  it under the terms of the GNU General Public License as published by
   *  the Free Software Foundation - version 2.
   *
   *  This program is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *  GNU General Public License for more details.
   *
   *  You should have received a copy of the GNU General Public License
   *  along with this program; if not, write to the Free Software
   *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
   *  02110-1301 USA.
   *
   *  Supports following chips:
   *
   *  Chip       #vin   #fanin #pwm #temp #dts wchipid  vendid  i2c  ISA
   *  w83795g     21     14     8     6     8    0x79   0x5ca3  yes   no
   *  w83795adg   18     14     2     6     8    0x79   0x5ca3  yes   no
   */
  
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/slab.h>
  #include <linux/i2c.h>
  #include <linux/hwmon.h>
  #include <linux/hwmon-sysfs.h>
  #include <linux/err.h>
  #include <linux/mutex.h>
  #include <linux/delay.h>
  
  /* Addresses to scan */
86ef4d2fd   Jean Delvare   hwmon: (w83795) A...
40
41
42
  static const unsigned short normal_i2c[] = {
  	0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END
  };
792d376b4   Wei Song   hwmon: New driver...
43

792d376b4   Wei Song   hwmon: New driver...
44

90ab5ee94   Rusty Russell   module_param: mak...
45
  static bool reset;
792d376b4   Wei Song   hwmon: New driver...
46
47
48
49
50
51
52
53
  module_param(reset, bool, 0);
  MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended");
  
  
  #define W83795_REG_BANKSEL		0x00
  #define W83795_REG_VENDORID		0xfd
  #define W83795_REG_CHIPID		0xfe
  #define W83795_REG_DEVICEID		0xfb
2be381de0   Jean Delvare   hwmon: (w83795) I...
54
  #define W83795_REG_DEVICEID_A		0xff
792d376b4   Wei Song   hwmon: New driver...
55
56
57
58
  
  #define W83795_REG_I2C_ADDR		0xfc
  #define W83795_REG_CONFIG		0x01
  #define W83795_REG_CONFIG_CONFIG48	0x04
80646b958   Jean Delvare   hwmon: (w83795) O...
59
  #define W83795_REG_CONFIG_START	0x01
792d376b4   Wei Song   hwmon: New driver...
60
61
62
63
64
65
66
67
68
  
  /* Multi-Function Pin Ctrl Registers */
  #define W83795_REG_VOLT_CTRL1		0x02
  #define W83795_REG_VOLT_CTRL2		0x03
  #define W83795_REG_TEMP_CTRL1		0x04
  #define W83795_REG_TEMP_CTRL2		0x05
  #define W83795_REG_FANIN_CTRL1		0x06
  #define W83795_REG_FANIN_CTRL2		0x07
  #define W83795_REG_VMIGB_CTRL		0x08
792d376b4   Wei Song   hwmon: New driver...
69
70
71
72
73
74
75
  #define TEMP_READ			0
  #define TEMP_CRIT			1
  #define TEMP_CRIT_HYST			2
  #define TEMP_WARN			3
  #define TEMP_WARN_HYST			4
  /* only crit and crit_hyst affect real-time alarm status
   * current crit crit_hyst warn warn_hyst */
86ef4d2fd   Jean Delvare   hwmon: (w83795) A...
76
  static const u16 W83795_REG_TEMP[][5] = {
792d376b4   Wei Song   hwmon: New driver...
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
  	{0x21, 0x96, 0x97, 0x98, 0x99},	/* TD1/TR1 */
  	{0x22, 0x9a, 0x9b, 0x9c, 0x9d},	/* TD2/TR2 */
  	{0x23, 0x9e, 0x9f, 0xa0, 0xa1},	/* TD3/TR3 */
  	{0x24, 0xa2, 0xa3, 0xa4, 0xa5},	/* TD4/TR4 */
  	{0x1f, 0xa6, 0xa7, 0xa8, 0xa9},	/* TR5 */
  	{0x20, 0xaa, 0xab, 0xac, 0xad},	/* TR6 */
  };
  
  #define IN_READ				0
  #define IN_MAX				1
  #define IN_LOW				2
  static const u16 W83795_REG_IN[][3] = {
  	/* Current, HL, LL */
  	{0x10, 0x70, 0x71},	/* VSEN1 */
  	{0x11, 0x72, 0x73},	/* VSEN2 */
  	{0x12, 0x74, 0x75},	/* VSEN3 */
  	{0x13, 0x76, 0x77},	/* VSEN4 */
  	{0x14, 0x78, 0x79},	/* VSEN5 */
  	{0x15, 0x7a, 0x7b},	/* VSEN6 */
  	{0x16, 0x7c, 0x7d},	/* VSEN7 */
  	{0x17, 0x7e, 0x7f},	/* VSEN8 */
  	{0x18, 0x80, 0x81},	/* VSEN9 */
  	{0x19, 0x82, 0x83},	/* VSEN10 */
  	{0x1A, 0x84, 0x85},	/* VSEN11 */
  	{0x1B, 0x86, 0x87},	/* VTT */
  	{0x1C, 0x88, 0x89},	/* 3VDD */
  	{0x1D, 0x8a, 0x8b},	/* 3VSB */
  	{0x1E, 0x8c, 0x8d},	/* VBAT */
  	{0x1F, 0xa6, 0xa7},	/* VSEN12 */
  	{0x20, 0xaa, 0xab},	/* VSEN13 */
  	{0x21, 0x96, 0x97},	/* VSEN14 */
  	{0x22, 0x9a, 0x9b},	/* VSEN15 */
  	{0x23, 0x9e, 0x9f},	/* VSEN16 */
  	{0x24, 0xa2, 0xa3},	/* VSEN17 */
  };
  #define W83795_REG_VRLSB		0x3C
792d376b4   Wei Song   hwmon: New driver...
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
  
  static const u8 W83795_REG_IN_HL_LSB[] = {
  	0x8e,	/* VSEN1-4 */
  	0x90,	/* VSEN5-8 */
  	0x92,	/* VSEN9-11 */
  	0x94,	/* VTT, 3VDD, 3VSB, 3VBAT */
  	0xa8,	/* VSEN12 */
  	0xac,	/* VSEN13 */
  	0x98,	/* VSEN14 */
  	0x9c,	/* VSEN15 */
  	0xa0,	/* VSEN16 */
  	0xa4,	/* VSEN17 */
  };
  
  #define IN_LSB_REG(index, type) \
  	(((type) == 1) ? W83795_REG_IN_HL_LSB[(index)] \
  	: (W83795_REG_IN_HL_LSB[(index)] + 1))
792d376b4   Wei Song   hwmon: New driver...
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
  #define IN_LSB_SHIFT			0
  #define IN_LSB_IDX			1
  static const u8 IN_LSB_SHIFT_IDX[][2] = {
  	/* High/Low LSB shift, LSB No. */
  	{0x00, 0x00},	/* VSEN1 */
  	{0x02, 0x00},	/* VSEN2 */
  	{0x04, 0x00},	/* VSEN3 */
  	{0x06, 0x00},	/* VSEN4 */
  	{0x00, 0x01},	/* VSEN5 */
  	{0x02, 0x01},	/* VSEN6 */
  	{0x04, 0x01},	/* VSEN7 */
  	{0x06, 0x01},	/* VSEN8 */
  	{0x00, 0x02},	/* VSEN9 */
  	{0x02, 0x02},	/* VSEN10 */
  	{0x04, 0x02},	/* VSEN11 */
  	{0x00, 0x03},	/* VTT */
  	{0x02, 0x03},	/* 3VDD */
  	{0x04, 0x03},	/* 3VSB	*/
  	{0x06, 0x03},	/* VBAT	*/
  	{0x06, 0x04},	/* VSEN12 */
  	{0x06, 0x05},	/* VSEN13 */
  	{0x06, 0x06},	/* VSEN14 */
  	{0x06, 0x07},	/* VSEN15 */
  	{0x06, 0x08},	/* VSEN16 */
  	{0x06, 0x09},	/* VSEN17 */
  };
792d376b4   Wei Song   hwmon: New driver...
156
157
158
159
  #define W83795_REG_FAN(index)		(0x2E + (index))
  #define W83795_REG_FAN_MIN_HL(index)	(0xB6 + (index))
  #define W83795_REG_FAN_MIN_LSB(index)	(0xC4 + (index) / 2)
  #define W83795_REG_FAN_MIN_LSB_SHIFT(index) \
7eb8d508b   Jean Delvare   hwmon: (w83795) F...
160
  	(((index) & 1) ? 4 : 0)
792d376b4   Wei Song   hwmon: New driver...
161
162
  
  #define W83795_REG_VID_CTRL		0x6A
cf6b9ea66   Jean Delvare   hwmon: (w83795) R...
163
164
  #define W83795_REG_ALARM_CTRL		0x40
  #define ALARM_CTRL_RTSACS		(1 << 7)
792d376b4   Wei Song   hwmon: New driver...
165
  #define W83795_REG_ALARM(index)		(0x41 + (index))
792d376b4   Wei Song   hwmon: New driver...
166
  #define W83795_REG_CLR_CHASSIS		0x4D
cf6b9ea66   Jean Delvare   hwmon: (w83795) R...
167
  #define W83795_REG_BEEP(index)		(0x50 + (index))
792d376b4   Wei Song   hwmon: New driver...
168

52d159eec   Jean Delvare   hwmon: (w83795) C...
169
170
  #define W83795_REG_OVT_CFG		0x58
  #define OVT_CFG_SEL			(1 << 7)
792d376b4   Wei Song   hwmon: New driver...
171

792d376b4   Wei Song   hwmon: New driver...
172
173
174
175
  #define W83795_REG_FCMS1		0x201
  #define W83795_REG_FCMS2		0x208
  #define W83795_REG_TFMR(index)		(0x202 + (index))
  #define W83795_REG_FOMC			0x20F
792d376b4   Wei Song   hwmon: New driver...
176
177
  
  #define W83795_REG_TSS(index)		(0x209 + (index))
edff2f8d8   Jean Delvare   hwmon: (w83795) L...
178
179
180
181
182
183
184
  #define TSS_MAP_RESERVED		0xff
  static const u8 tss_map[4][6] = {
  	{ 0,  1,  2,  3,  4,  5},
  	{ 6,  7,  8,  9,  0,  1},
  	{10, 11, 12, 13,  2,  3},
  	{ 4,  5,  4,  5, TSS_MAP_RESERVED, TSS_MAP_RESERVED},
  };
792d376b4   Wei Song   hwmon: New driver...
185
  #define PWM_OUTPUT			0
fd7f82b8a   Jean Delvare   hwmon: (w83795) M...
186
187
188
189
190
  #define PWM_FREQ			1
  #define PWM_START			2
  #define PWM_NONSTOP			3
  #define PWM_STOP_TIME			4
  #define W83795_REG_PWM(index, nr)	(0x210 + (nr) * 8 + (index))
792d376b4   Wei Song   hwmon: New driver...
191

792d376b4   Wei Song   hwmon: New driver...
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
  #define W83795_REG_FTSH(index)		(0x240 + (index) * 2)
  #define W83795_REG_FTSL(index)		(0x241 + (index) * 2)
  #define W83795_REG_TFTS			0x250
  
  #define TEMP_PWM_TTTI			0
  #define TEMP_PWM_CTFS			1
  #define TEMP_PWM_HCT			2
  #define TEMP_PWM_HOT			3
  #define W83795_REG_TTTI(index)		(0x260 + (index))
  #define W83795_REG_CTFS(index)		(0x268 + (index))
  #define W83795_REG_HT(index)		(0x270 + (index))
  
  #define SF4_TEMP			0
  #define SF4_PWM				1
  #define W83795_REG_SF4_TEMP(temp_num, index) \
  	(0x280 + 0x10 * (temp_num) + (index))
  #define W83795_REG_SF4_PWM(temp_num, index) \
  	(0x288 + 0x10 * (temp_num) + (index))
  
  #define W83795_REG_DTSC			0x301
  #define W83795_REG_DTSE			0x302
  #define W83795_REG_DTS(index)		(0x26 + (index))
54891a3c1   Jean Delvare   hwmon: (w83795) R...
214
  #define W83795_REG_PECI_TBASE(index)	(0x320 + (index))
792d376b4   Wei Song   hwmon: New driver...
215
216
217
218
219
220
221
222
223
224
225
226
227
228
  
  #define DTS_CRIT			0
  #define DTS_CRIT_HYST			1
  #define DTS_WARN			2
  #define DTS_WARN_HYST			3
  #define W83795_REG_DTS_EXT(index)	(0xB2 + (index))
  
  #define SETUP_PWM_DEFAULT		0
  #define SETUP_PWM_UPTIME		1
  #define SETUP_PWM_DOWNTIME		2
  #define W83795_REG_SETUP_PWM(index)    (0x20C + (index))
  
  static inline u16 in_from_reg(u8 index, u16 val)
  {
49c7347a4   Jean Delvare   hwmon: (w83795) D...
229
230
  	/* 3VDD, 3VSB and VBAT: 6 mV/bit; other inputs: 2 mV/bit */
  	if (index >= 12 && index <= 14)
792d376b4   Wei Song   hwmon: New driver...
231
232
233
234
235
236
237
  		return val * 6;
  	else
  		return val * 2;
  }
  
  static inline u16 in_to_reg(u8 index, u16 val)
  {
49c7347a4   Jean Delvare   hwmon: (w83795) D...
238
  	if (index >= 12 && index <= 14)
792d376b4   Wei Song   hwmon: New driver...
239
240
241
242
243
244
245
  		return val / 6;
  	else
  		return val / 2;
  }
  
  static inline unsigned long fan_from_reg(u16 val)
  {
6c82b2f3f   Jean Delvare   hwmon: (w83795) F...
246
  	if ((val == 0xfff) || (val == 0))
792d376b4   Wei Song   hwmon: New driver...
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
  		return 0;
  	return 1350000UL / val;
  }
  
  static inline u16 fan_to_reg(long rpm)
  {
  	if (rpm <= 0)
  		return 0x0fff;
  	return SENSORS_LIMIT((1350000 + (rpm >> 1)) / rpm, 1, 0xffe);
  }
  
  static inline unsigned long time_from_reg(u8 reg)
  {
  	return reg * 100;
  }
  
  static inline u8 time_to_reg(unsigned long val)
  {
  	return SENSORS_LIMIT((val + 50) / 100, 0, 0xff);
  }
  
  static inline long temp_from_reg(s8 reg)
  {
  	return reg * 1000;
  }
  
  static inline s8 temp_to_reg(long val, s8 min, s8 max)
  {
dd127f5cc   Jean Delvare   hwmon: (w83795) P...
275
  	return SENSORS_LIMIT(val / 1000, min, max);
792d376b4   Wei Song   hwmon: New driver...
276
  }
01879a855   Jean Delvare   hwmon: (w83795) F...
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
  static const u16 pwm_freq_cksel0[16] = {
  	1024, 512, 341, 256, 205, 171, 146, 128,
  	85, 64, 32, 16, 8, 4, 2, 1
  };
  
  static unsigned int pwm_freq_from_reg(u8 reg, u16 clkin)
  {
  	unsigned long base_clock;
  
  	if (reg & 0x80) {
  		base_clock = clkin * 1000 / ((clkin == 48000) ? 384 : 256);
  		return base_clock / ((reg & 0x7f) + 1);
  	} else
  		return pwm_freq_cksel0[reg & 0x0f];
  }
  
  static u8 pwm_freq_to_reg(unsigned long val, u16 clkin)
  {
  	unsigned long base_clock;
  	u8 reg0, reg1;
  	unsigned long best0, best1;
  
  	/* Best fit for cksel = 0 */
  	for (reg0 = 0; reg0 < ARRAY_SIZE(pwm_freq_cksel0) - 1; reg0++) {
  		if (val > (pwm_freq_cksel0[reg0] +
  			   pwm_freq_cksel0[reg0 + 1]) / 2)
  			break;
  	}
  	if (val < 375)	/* cksel = 1 can't beat this */
  		return reg0;
  	best0 = pwm_freq_cksel0[reg0];
  
  	/* Best fit for cksel = 1 */
  	base_clock = clkin * 1000 / ((clkin == 48000) ? 384 : 256);
  	reg1 = SENSORS_LIMIT(DIV_ROUND_CLOSEST(base_clock, val), 1, 128);
  	best1 = base_clock / reg1;
  	reg1 = 0x80 | (reg1 - 1);
  
  	/* Choose the closest one */
  	if (abs(val - best0) > abs(val - best1))
  		return reg1;
  	else
  		return reg0;
  }
792d376b4   Wei Song   hwmon: New driver...
321
322
323
324
325
326
327
328
329
330
331
332
  
  enum chip_types {w83795g, w83795adg};
  
  struct w83795_data {
  	struct device *hwmon_dev;
  	struct mutex update_lock;
  	unsigned long last_updated;	/* In jiffies */
  	enum chip_types chip_type;
  
  	u8 bank;
  
  	u32 has_in;		/* Enable monitor VIN or not */
0e256018b   Jean Delvare   hwmon: (w83795) A...
333
  	u8 has_dyn_in;		/* Only in2-0 can have this */
792d376b4   Wei Song   hwmon: New driver...
334
335
336
337
338
339
340
341
342
  	u16 in[21][3];		/* Register value, read/high/low */
  	u8 in_lsb[10][3];	/* LSB Register value, high/low */
  	u8 has_gain;		/* has gain: in17-20 * 8 */
  
  	u16 has_fan;		/* Enable fan14-1 or not */
  	u16 fan[14];		/* Register value combine */
  	u16 fan_min[14];	/* Register value combine */
  
  	u8 has_temp;		/* Enable monitor temp6-1 or not */
dd127f5cc   Jean Delvare   hwmon: (w83795) P...
343
  	s8 temp[6][5];		/* current, crit, crit_hyst, warn, warn_hyst */
792d376b4   Wei Song   hwmon: New driver...
344
  	u8 temp_read_vrlsb[6];
39deb6993   Jean Delvare   hwmon: (w83795) S...
345
  	u8 temp_mode;		/* Bit vector, 0 = TR, 1 = TD */
792d376b4   Wei Song   hwmon: New driver...
346
347
348
349
350
351
  	u8 temp_src[3];		/* Register value */
  
  	u8 enable_dts;		/* Enable PECI and SB-TSI,
  				 * bit 0: =1 enable, =0 disable,
  				 * bit 1: =1 AMD SB-TSI, =0 Intel PECI */
  	u8 has_dts;		/* Enable monitor DTS temp */
dd127f5cc   Jean Delvare   hwmon: (w83795) P...
352
  	s8 dts[8];		/* Register value */
792d376b4   Wei Song   hwmon: New driver...
353
  	u8 dts_read_vrlsb[8];	/* Register value */
dd127f5cc   Jean Delvare   hwmon: (w83795) P...
354
  	s8 dts_ext[4];		/* Register value */
792d376b4   Wei Song   hwmon: New driver...
355
356
357
358
  
  	u8 has_pwm;		/* 795g supports 8 pwm, 795adg only supports 2,
  				 * no config register, only affected by chip
  				 * type */
fd7f82b8a   Jean Delvare   hwmon: (w83795) M...
359
360
  	u8 pwm[8][5];		/* Register value, output, freq, start,
  				 *  non stop, stop time */
01879a855   Jean Delvare   hwmon: (w83795) F...
361
  	u16 clkin;		/* CLKIN frequency in kHz */
792d376b4   Wei Song   hwmon: New driver...
362
363
364
365
366
367
368
369
370
371
372
373
374
  	u8 pwm_fcms[2];		/* Register value */
  	u8 pwm_tfmr[6];		/* Register value */
  	u8 pwm_fomc;		/* Register value */
  
  	u16 target_speed[8];	/* Register value, target speed for speed
  				 * cruise */
  	u8 tol_speed;		/* tolerance of target speed */
  	u8 pwm_temp[6][4];	/* TTTI, CTFS, HCT, HOT */
  	u8 sf4_reg[6][2][7];	/* 6 temp, temp/dcpwm, 7 registers */
  
  	u8 setup_pwm[3];	/* Register value */
  
  	u8 alarms[6];		/* Register value */
52d159eec   Jean Delvare   hwmon: (w83795) C...
375
  	u8 enable_beep;
792d376b4   Wei Song   hwmon: New driver...
376
  	u8 beeps[6];		/* Register value */
792d376b4   Wei Song   hwmon: New driver...
377
378
  
  	char valid;
2ae61de90   Jean Delvare   hwmon: (w83795) D...
379
  	char valid_limits;
1bb3450ce   Jean Delvare   hwmon: (w83795) D...
380
  	char valid_pwm_config;
792d376b4   Wei Song   hwmon: New driver...
381
382
383
384
  };
  
  /*
   * Hardware access
b2469f422   Jean Delvare   hwmon: (w83795) R...
385
   * We assume that nobdody can change the bank outside the driver.
792d376b4   Wei Song   hwmon: New driver...
386
   */
b2469f422   Jean Delvare   hwmon: (w83795) R...
387
388
  /* Must be called with data->update_lock held, except during initialization */
  static int w83795_set_bank(struct i2c_client *client, u8 bank)
792d376b4   Wei Song   hwmon: New driver...
389
390
  {
  	struct w83795_data *data = i2c_get_clientdata(client);
b2469f422   Jean Delvare   hwmon: (w83795) R...
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
  	int err;
  
  	/* If the same bank is already set, nothing to do */
  	if ((data->bank & 0x07) == bank)
  		return 0;
  
  	/* Change to new bank, preserve all other bits */
  	bank |= data->bank & ~0x07;
  	err = i2c_smbus_write_byte_data(client, W83795_REG_BANKSEL, bank);
  	if (err < 0) {
  		dev_err(&client->dev,
  			"Failed to set bank to %d, err %d
  ",
  			(int)bank, err);
  		return err;
792d376b4   Wei Song   hwmon: New driver...
406
  	}
b2469f422   Jean Delvare   hwmon: (w83795) R...
407
408
409
  	data->bank = bank;
  
  	return 0;
792d376b4   Wei Song   hwmon: New driver...
410
411
412
  }
  
  /* Must be called with data->update_lock held, except during initialization */
b2469f422   Jean Delvare   hwmon: (w83795) R...
413
  static u8 w83795_read(struct i2c_client *client, u16 reg)
792d376b4   Wei Song   hwmon: New driver...
414
  {
b2469f422   Jean Delvare   hwmon: (w83795) R...
415
416
417
418
419
420
421
422
423
424
425
426
427
  	int err;
  
  	err = w83795_set_bank(client, reg >> 8);
  	if (err < 0)
  		return 0x00;	/* Arbitrary */
  
  	err = i2c_smbus_read_byte_data(client, reg & 0xff);
  	if (err < 0) {
  		dev_err(&client->dev,
  			"Failed to read from register 0x%03x, err %d
  ",
  			(int)reg, err);
  		return 0x00;	/* Arbitrary */
792d376b4   Wei Song   hwmon: New driver...
428
  	}
b2469f422   Jean Delvare   hwmon: (w83795) R...
429
430
  	return err;
  }
792d376b4   Wei Song   hwmon: New driver...
431

b2469f422   Jean Delvare   hwmon: (w83795) R...
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
  /* Must be called with data->update_lock held, except during initialization */
  static int w83795_write(struct i2c_client *client, u16 reg, u8 value)
  {
  	int err;
  
  	err = w83795_set_bank(client, reg >> 8);
  	if (err < 0)
  		return err;
  
  	err = i2c_smbus_write_byte_data(client, reg & 0xff, value);
  	if (err < 0)
  		dev_err(&client->dev,
  			"Failed to write to register 0x%03x, err %d
  ",
  			(int)reg, err);
  	return err;
792d376b4   Wei Song   hwmon: New driver...
448
  }
0d7237bfd   Jean Delvare   hwmon: (w83795) M...
449
450
451
452
  static void w83795_update_limits(struct i2c_client *client)
  {
  	struct w83795_data *data = i2c_get_clientdata(client);
  	int i, limit;
014bcd28a   Jean Delvare   hwmon: (w83795) S...
453
  	u8 lsb;
0d7237bfd   Jean Delvare   hwmon: (w83795) M...
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
  
  	/* Read the voltage limits */
  	for (i = 0; i < ARRAY_SIZE(data->in); i++) {
  		if (!(data->has_in & (1 << i)))
  			continue;
  		data->in[i][IN_MAX] =
  			w83795_read(client, W83795_REG_IN[i][IN_MAX]);
  		data->in[i][IN_LOW] =
  			w83795_read(client, W83795_REG_IN[i][IN_LOW]);
  	}
  	for (i = 0; i < ARRAY_SIZE(data->in_lsb); i++) {
  		if ((i == 2 && data->chip_type == w83795adg) ||
  		    (i >= 4 && !(data->has_in & (1 << (i + 11)))))
  			continue;
  		data->in_lsb[i][IN_MAX] =
  			w83795_read(client, IN_LSB_REG(i, IN_MAX));
  		data->in_lsb[i][IN_LOW] =
  			w83795_read(client, IN_LSB_REG(i, IN_LOW));
  	}
  
  	/* Read the fan limits */
014bcd28a   Jean Delvare   hwmon: (w83795) S...
475
  	lsb = 0; /* Silent false gcc warning */
0d7237bfd   Jean Delvare   hwmon: (w83795) M...
476
  	for (i = 0; i < ARRAY_SIZE(data->fan); i++) {
0d7237bfd   Jean Delvare   hwmon: (w83795) M...
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
  		/* Each register contains LSB for 2 fans, but we want to
  		 * read it only once to save time */
  		if ((i & 1) == 0 && (data->has_fan & (3 << i)))
  			lsb = w83795_read(client, W83795_REG_FAN_MIN_LSB(i));
  
  		if (!(data->has_fan & (1 << i)))
  			continue;
  		data->fan_min[i] =
  			w83795_read(client, W83795_REG_FAN_MIN_HL(i)) << 4;
  		data->fan_min[i] |=
  			(lsb >> W83795_REG_FAN_MIN_LSB_SHIFT(i)) & 0x0F;
  	}
  
  	/* Read the temperature limits */
  	for (i = 0; i < ARRAY_SIZE(data->temp); i++) {
  		if (!(data->has_temp & (1 << i)))
  			continue;
  		for (limit = TEMP_CRIT; limit <= TEMP_WARN_HYST; limit++)
  			data->temp[i][limit] =
  				w83795_read(client, W83795_REG_TEMP[i][limit]);
  	}
  
  	/* Read the DTS limits */
eb02755a5   Jean Delvare   hwmon: (w83795) M...
500
  	if (data->enable_dts) {
0d7237bfd   Jean Delvare   hwmon: (w83795) M...
501
502
503
504
505
506
  		for (limit = DTS_CRIT; limit <= DTS_WARN_HYST; limit++)
  			data->dts_ext[limit] =
  				w83795_read(client, W83795_REG_DTS_EXT(limit));
  	}
  
  	/* Read beep settings */
52d159eec   Jean Delvare   hwmon: (w83795) C...
507
508
509
510
511
  	if (data->enable_beep) {
  		for (i = 0; i < ARRAY_SIZE(data->beeps); i++)
  			data->beeps[i] =
  				w83795_read(client, W83795_REG_BEEP(i));
  	}
2ae61de90   Jean Delvare   hwmon: (w83795) D...
512
513
  
  	data->valid_limits = 1;
0d7237bfd   Jean Delvare   hwmon: (w83795) M...
514
  }
1bb3450ce   Jean Delvare   hwmon: (w83795) D...
515
  static struct w83795_data *w83795_update_pwm_config(struct device *dev)
0d7237bfd   Jean Delvare   hwmon: (w83795) M...
516
  {
1bb3450ce   Jean Delvare   hwmon: (w83795) D...
517
  	struct i2c_client *client = to_i2c_client(dev);
0d7237bfd   Jean Delvare   hwmon: (w83795) M...
518
519
  	struct w83795_data *data = i2c_get_clientdata(client);
  	int i, tmp;
1bb3450ce   Jean Delvare   hwmon: (w83795) D...
520
521
522
523
  	mutex_lock(&data->update_lock);
  
  	if (data->valid_pwm_config)
  		goto END;
0d7237bfd   Jean Delvare   hwmon: (w83795) M...
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
  	/* Read temperature source selection */
  	for (i = 0; i < ARRAY_SIZE(data->temp_src); i++)
  		data->temp_src[i] = w83795_read(client, W83795_REG_TSS(i));
  
  	/* Read automatic fan speed control settings */
  	data->pwm_fcms[0] = w83795_read(client, W83795_REG_FCMS1);
  	data->pwm_fcms[1] = w83795_read(client, W83795_REG_FCMS2);
  	for (i = 0; i < ARRAY_SIZE(data->pwm_tfmr); i++)
  		data->pwm_tfmr[i] = w83795_read(client, W83795_REG_TFMR(i));
  	data->pwm_fomc = w83795_read(client, W83795_REG_FOMC);
  	for (i = 0; i < data->has_pwm; i++) {
  		for (tmp = PWM_FREQ; tmp <= PWM_STOP_TIME; tmp++)
  			data->pwm[i][tmp] =
  				w83795_read(client, W83795_REG_PWM(i, tmp));
  	}
  	for (i = 0; i < ARRAY_SIZE(data->target_speed); i++) {
  		data->target_speed[i] =
  			w83795_read(client, W83795_REG_FTSH(i)) << 4;
  		data->target_speed[i] |=
  			w83795_read(client, W83795_REG_FTSL(i)) >> 4;
  	}
  	data->tol_speed = w83795_read(client, W83795_REG_TFTS) & 0x3f;
  
  	for (i = 0; i < ARRAY_SIZE(data->pwm_temp); i++) {
  		data->pwm_temp[i][TEMP_PWM_TTTI] =
  			w83795_read(client, W83795_REG_TTTI(i)) & 0x7f;
  		data->pwm_temp[i][TEMP_PWM_CTFS] =
  			w83795_read(client, W83795_REG_CTFS(i));
  		tmp = w83795_read(client, W83795_REG_HT(i));
eb02755a5   Jean Delvare   hwmon: (w83795) M...
553
  		data->pwm_temp[i][TEMP_PWM_HCT] = tmp >> 4;
0d7237bfd   Jean Delvare   hwmon: (w83795) M...
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
  		data->pwm_temp[i][TEMP_PWM_HOT] = tmp & 0x0f;
  	}
  
  	/* Read SmartFanIV trip points */
  	for (i = 0; i < ARRAY_SIZE(data->sf4_reg); i++) {
  		for (tmp = 0; tmp < 7; tmp++) {
  			data->sf4_reg[i][SF4_TEMP][tmp] =
  				w83795_read(client,
  					    W83795_REG_SF4_TEMP(i, tmp));
  			data->sf4_reg[i][SF4_PWM][tmp] =
  				w83795_read(client, W83795_REG_SF4_PWM(i, tmp));
  		}
  	}
  
  	/* Read setup PWM */
  	for (i = 0; i < ARRAY_SIZE(data->setup_pwm); i++)
  		data->setup_pwm[i] =
  			w83795_read(client, W83795_REG_SETUP_PWM(i));
1bb3450ce   Jean Delvare   hwmon: (w83795) D...
572
573
574
575
576
577
  
  	data->valid_pwm_config = 1;
  
  END:
  	mutex_unlock(&data->update_lock);
  	return data;
0d7237bfd   Jean Delvare   hwmon: (w83795) M...
578
  }
792d376b4   Wei Song   hwmon: New driver...
579
580
581
582
583
  static struct w83795_data *w83795_update_device(struct device *dev)
  {
  	struct i2c_client *client = to_i2c_client(dev);
  	struct w83795_data *data = i2c_get_clientdata(client);
  	u16 tmp;
cf6b9ea66   Jean Delvare   hwmon: (w83795) R...
584
  	u8 intrusion;
792d376b4   Wei Song   hwmon: New driver...
585
586
587
  	int i;
  
  	mutex_lock(&data->update_lock);
2ae61de90   Jean Delvare   hwmon: (w83795) D...
588
589
  	if (!data->valid_limits)
  		w83795_update_limits(client);
792d376b4   Wei Song   hwmon: New driver...
590
591
592
593
594
595
596
597
598
  	if (!(time_after(jiffies, data->last_updated + HZ * 2)
  	      || !data->valid))
  		goto END;
  
  	/* Update the voltages value */
  	for (i = 0; i < ARRAY_SIZE(data->in); i++) {
  		if (!(data->has_in & (1 << i)))
  			continue;
  		tmp = w83795_read(client, W83795_REG_IN[i][IN_READ]) << 2;
a654b9d4e   Jean Delvare   hwmon: (w83795) G...
599
  		tmp |= w83795_read(client, W83795_REG_VRLSB) >> 6;
792d376b4   Wei Song   hwmon: New driver...
600
601
  		data->in[i][IN_READ] = tmp;
  	}
0e256018b   Jean Delvare   hwmon: (w83795) A...
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
  	/* in0-2 can have dynamic limits (W83795G only) */
  	if (data->has_dyn_in) {
  		u8 lsb_max = w83795_read(client, IN_LSB_REG(0, IN_MAX));
  		u8 lsb_low = w83795_read(client, IN_LSB_REG(0, IN_LOW));
  
  		for (i = 0; i < 3; i++) {
  			if (!(data->has_dyn_in & (1 << i)))
  				continue;
  			data->in[i][IN_MAX] =
  				w83795_read(client, W83795_REG_IN[i][IN_MAX]);
  			data->in[i][IN_LOW] =
  				w83795_read(client, W83795_REG_IN[i][IN_LOW]);
  			data->in_lsb[i][IN_MAX] = (lsb_max >> (2 * i)) & 0x03;
  			data->in_lsb[i][IN_LOW] = (lsb_low >> (2 * i)) & 0x03;
  		}
  	}
792d376b4   Wei Song   hwmon: New driver...
618
619
620
621
622
  	/* Update fan */
  	for (i = 0; i < ARRAY_SIZE(data->fan); i++) {
  		if (!(data->has_fan & (1 << i)))
  			continue;
  		data->fan[i] = w83795_read(client, W83795_REG_FAN(i)) << 4;
eb02755a5   Jean Delvare   hwmon: (w83795) M...
623
  		data->fan[i] |= w83795_read(client, W83795_REG_VRLSB) >> 4;
792d376b4   Wei Song   hwmon: New driver...
624
625
626
627
  	}
  
  	/* Update temperature */
  	for (i = 0; i < ARRAY_SIZE(data->temp); i++) {
792d376b4   Wei Song   hwmon: New driver...
628
629
630
631
632
633
634
  		data->temp[i][TEMP_READ] =
  			w83795_read(client, W83795_REG_TEMP[i][TEMP_READ]);
  		data->temp_read_vrlsb[i] =
  			w83795_read(client, W83795_REG_VRLSB);
  	}
  
  	/* Update dts temperature */
eb02755a5   Jean Delvare   hwmon: (w83795) M...
635
  	if (data->enable_dts) {
792d376b4   Wei Song   hwmon: New driver...
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
  		for (i = 0; i < ARRAY_SIZE(data->dts); i++) {
  			if (!(data->has_dts & (1 << i)))
  				continue;
  			data->dts[i] =
  				w83795_read(client, W83795_REG_DTS(i));
  			data->dts_read_vrlsb[i] =
  				w83795_read(client, W83795_REG_VRLSB);
  		}
  	}
  
  	/* Update pwm output */
  	for (i = 0; i < data->has_pwm; i++) {
  		data->pwm[i][PWM_OUTPUT] =
  		    w83795_read(client, W83795_REG_PWM(i, PWM_OUTPUT));
  	}
cf6b9ea66   Jean Delvare   hwmon: (w83795) R...
651
652
653
654
655
656
657
658
659
660
661
  	/* Update intrusion and alarms
  	 * It is important to read intrusion first, because reading from
  	 * register SMI STS6 clears the interrupt status temporarily. */
  	tmp = w83795_read(client, W83795_REG_ALARM_CTRL);
  	/* Switch to interrupt status for intrusion if needed */
  	if (tmp & ALARM_CTRL_RTSACS)
  		w83795_write(client, W83795_REG_ALARM_CTRL,
  			     tmp & ~ALARM_CTRL_RTSACS);
  	intrusion = w83795_read(client, W83795_REG_ALARM(5)) & (1 << 6);
  	/* Switch to real-time alarms */
  	w83795_write(client, W83795_REG_ALARM_CTRL, tmp | ALARM_CTRL_RTSACS);
cd316df58   Jean Delvare   hwmon: (w83795) D...
662
  	for (i = 0; i < ARRAY_SIZE(data->alarms); i++)
792d376b4   Wei Song   hwmon: New driver...
663
  		data->alarms[i] = w83795_read(client, W83795_REG_ALARM(i));
cf6b9ea66   Jean Delvare   hwmon: (w83795) R...
664
665
666
667
668
  	data->alarms[5] |= intrusion;
  	/* Restore original configuration if needed */
  	if (!(tmp & ALARM_CTRL_RTSACS))
  		w83795_write(client, W83795_REG_ALARM_CTRL,
  			     tmp & ~ALARM_CTRL_RTSACS);
792d376b4   Wei Song   hwmon: New driver...
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
  
  	data->last_updated = jiffies;
  	data->valid = 1;
  
  END:
  	mutex_unlock(&data->update_lock);
  	return data;
  }
  
  /*
   * Sysfs attributes
   */
  
  #define ALARM_STATUS      0
  #define BEEP_ENABLE       1
  static ssize_t
  show_alarm_beep(struct device *dev, struct device_attribute *attr, char *buf)
  {
  	struct w83795_data *data = w83795_update_device(dev);
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int nr = sensor_attr->nr;
  	int index = sensor_attr->index >> 3;
  	int bit = sensor_attr->index & 0x07;
  	u8 val;
eb02755a5   Jean Delvare   hwmon: (w83795) M...
694
695
696
697
  	if (nr == ALARM_STATUS)
  		val = (data->alarms[index] >> bit) & 1;
  	else		/* BEEP_ENABLE */
  		val = (data->beeps[index] >> bit) & 1;
792d376b4   Wei Song   hwmon: New driver...
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
  
  	return sprintf(buf, "%u
  ", val);
  }
  
  static ssize_t
  store_beep(struct device *dev, struct device_attribute *attr,
  	   const char *buf, size_t count)
  {
  	struct i2c_client *client = to_i2c_client(dev);
  	struct w83795_data *data = i2c_get_clientdata(client);
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int index = sensor_attr->index >> 3;
  	int shift = sensor_attr->index & 0x07;
  	u8 beep_bit = 1 << shift;
  	unsigned long val;
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
715
  	if (kstrtoul(buf, 10, &val) < 0)
792d376b4   Wei Song   hwmon: New driver...
716
717
718
719
720
721
722
723
724
725
726
727
728
  		return -EINVAL;
  	if (val != 0 && val != 1)
  		return -EINVAL;
  
  	mutex_lock(&data->update_lock);
  	data->beeps[index] = w83795_read(client, W83795_REG_BEEP(index));
  	data->beeps[index] &= ~beep_bit;
  	data->beeps[index] |= val << shift;
  	w83795_write(client, W83795_REG_BEEP(index), data->beeps[index]);
  	mutex_unlock(&data->update_lock);
  
  	return count;
  }
243771010   Jean Delvare   hwmon: (w83795) U...
729
  /* Write 0 to clear chassis alarm */
792d376b4   Wei Song   hwmon: New driver...
730
731
732
733
734
735
736
  static ssize_t
  store_chassis_clear(struct device *dev,
  		    struct device_attribute *attr, const char *buf,
  		    size_t count)
  {
  	struct i2c_client *client = to_i2c_client(dev);
  	struct w83795_data *data = i2c_get_clientdata(client);
243771010   Jean Delvare   hwmon: (w83795) U...
737
  	unsigned long val;
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
738
  	if (kstrtoul(buf, 10, &val) < 0 || val != 0)
243771010   Jean Delvare   hwmon: (w83795) U...
739
  		return -EINVAL;
792d376b4   Wei Song   hwmon: New driver...
740
741
742
743
744
  
  	mutex_lock(&data->update_lock);
  	val = w83795_read(client, W83795_REG_CLR_CHASSIS);
  	val |= 0x80;
  	w83795_write(client, W83795_REG_CLR_CHASSIS, val);
793c51d5f   Jean Delvare   hwmon: (w83795) C...
745
746
747
748
  
  	/* Clear status and force cache refresh */
  	w83795_read(client, W83795_REG_ALARM(5));
  	data->valid = 0;
792d376b4   Wei Song   hwmon: New driver...
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
  	mutex_unlock(&data->update_lock);
  	return count;
  }
  
  #define FAN_INPUT     0
  #define FAN_MIN       1
  static ssize_t
  show_fan(struct device *dev, struct device_attribute *attr, char *buf)
  {
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int nr = sensor_attr->nr;
  	int index = sensor_attr->index;
  	struct w83795_data *data = w83795_update_device(dev);
  	u16 val;
eb02755a5   Jean Delvare   hwmon: (w83795) M...
764
  	if (nr == FAN_INPUT)
792d376b4   Wei Song   hwmon: New driver...
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
  		val = data->fan[index] & 0x0fff;
  	else
  		val = data->fan_min[index] & 0x0fff;
  
  	return sprintf(buf, "%lu
  ", fan_from_reg(val));
  }
  
  static ssize_t
  store_fan_min(struct device *dev, struct device_attribute *attr,
  	      const char *buf, size_t count)
  {
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int index = sensor_attr->index;
  	struct i2c_client *client = to_i2c_client(dev);
  	struct w83795_data *data = i2c_get_clientdata(client);
  	unsigned long val;
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
783
  	if (kstrtoul(buf, 10, &val))
792d376b4   Wei Song   hwmon: New driver...
784
785
786
787
788
789
790
  		return -EINVAL;
  	val = fan_to_reg(val);
  
  	mutex_lock(&data->update_lock);
  	data->fan_min[index] = val;
  	w83795_write(client, W83795_REG_FAN_MIN_HL(index), (val >> 4) & 0xff);
  	val &= 0x0f;
7eb8d508b   Jean Delvare   hwmon: (w83795) F...
791
  	if (index & 1) {
792d376b4   Wei Song   hwmon: New driver...
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
  		val <<= 4;
  		val |= w83795_read(client, W83795_REG_FAN_MIN_LSB(index))
  		       & 0x0f;
  	} else {
  		val |= w83795_read(client, W83795_REG_FAN_MIN_LSB(index))
  		       & 0xf0;
  	}
  	w83795_write(client, W83795_REG_FAN_MIN_LSB(index), val & 0xff);
  	mutex_unlock(&data->update_lock);
  
  	return count;
  }
  
  static ssize_t
  show_pwm(struct device *dev, struct device_attribute *attr, char *buf)
  {
1bb3450ce   Jean Delvare   hwmon: (w83795) D...
808
  	struct w83795_data *data;
792d376b4   Wei Song   hwmon: New driver...
809
810
811
812
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int nr = sensor_attr->nr;
  	int index = sensor_attr->index;
01879a855   Jean Delvare   hwmon: (w83795) F...
813
  	unsigned int val;
792d376b4   Wei Song   hwmon: New driver...
814

1bb3450ce   Jean Delvare   hwmon: (w83795) D...
815
816
  	data = nr == PWM_OUTPUT ? w83795_update_device(dev)
  				: w83795_update_pwm_config(dev);
792d376b4   Wei Song   hwmon: New driver...
817
818
819
820
  	switch (nr) {
  	case PWM_STOP_TIME:
  		val = time_from_reg(data->pwm[index][nr]);
  		break;
01879a855   Jean Delvare   hwmon: (w83795) F...
821
822
  	case PWM_FREQ:
  		val = pwm_freq_from_reg(data->pwm[index][nr], data->clkin);
792d376b4   Wei Song   hwmon: New driver...
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
  		break;
  	default:
  		val = data->pwm[index][nr];
  		break;
  	}
  
  	return sprintf(buf, "%u
  ", val);
  }
  
  static ssize_t
  store_pwm(struct device *dev, struct device_attribute *attr,
  	  const char *buf, size_t count)
  {
  	struct i2c_client *client = to_i2c_client(dev);
  	struct w83795_data *data = i2c_get_clientdata(client);
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int nr = sensor_attr->nr;
  	int index = sensor_attr->index;
  	unsigned long val;
792d376b4   Wei Song   hwmon: New driver...
844

179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
845
  	if (kstrtoul(buf, 10, &val) < 0)
792d376b4   Wei Song   hwmon: New driver...
846
847
848
849
850
851
852
  		return -EINVAL;
  
  	mutex_lock(&data->update_lock);
  	switch (nr) {
  	case PWM_STOP_TIME:
  		val = time_to_reg(val);
  		break;
01879a855   Jean Delvare   hwmon: (w83795) F...
853
854
  	case PWM_FREQ:
  		val = pwm_freq_to_reg(val, data->clkin);
792d376b4   Wei Song   hwmon: New driver...
855
856
857
858
859
860
  		break;
  	default:
  		val = SENSORS_LIMIT(val, 0, 0xff);
  		break;
  	}
  	w83795_write(client, W83795_REG_PWM(index, nr), val);
01879a855   Jean Delvare   hwmon: (w83795) F...
861
  	data->pwm[index][nr] = val;
792d376b4   Wei Song   hwmon: New driver...
862
863
  	mutex_unlock(&data->update_lock);
  	return count;
792d376b4   Wei Song   hwmon: New driver...
864
865
866
867
868
869
870
  }
  
  static ssize_t
  show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf)
  {
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
1bb3450ce   Jean Delvare   hwmon: (w83795) D...
871
  	struct w83795_data *data = w83795_update_pwm_config(dev);
792d376b4   Wei Song   hwmon: New driver...
872
873
  	int index = sensor_attr->index;
  	u8 tmp;
ae51cd9bc   Jean Delvare   hwmon: (w83795) F...
874
875
  	/* Speed cruise mode */
  	if (data->pwm_fcms[0] & (1 << index)) {
792d376b4   Wei Song   hwmon: New driver...
876
877
878
  		tmp = 2;
  		goto out;
  	}
ae51cd9bc   Jean Delvare   hwmon: (w83795) F...
879
  	/* Thermal cruise or SmartFan IV mode */
792d376b4   Wei Song   hwmon: New driver...
880
881
882
883
884
885
  	for (tmp = 0; tmp < 6; tmp++) {
  		if (data->pwm_tfmr[tmp] & (1 << index)) {
  			tmp = 3;
  			goto out;
  		}
  	}
ae51cd9bc   Jean Delvare   hwmon: (w83795) F...
886
887
  	/* Manual mode */
  	tmp = 1;
792d376b4   Wei Song   hwmon: New driver...
888
889
890
891
892
893
894
895
896
897
898
  
  out:
  	return sprintf(buf, "%u
  ", tmp);
  }
  
  static ssize_t
  store_pwm_enable(struct device *dev, struct device_attribute *attr,
  	  const char *buf, size_t count)
  {
  	struct i2c_client *client = to_i2c_client(dev);
1bb3450ce   Jean Delvare   hwmon: (w83795) D...
899
  	struct w83795_data *data = w83795_update_pwm_config(dev);
792d376b4   Wei Song   hwmon: New driver...
900
901
902
903
904
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int index = sensor_attr->index;
  	unsigned long val;
  	int i;
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
905
  	if (kstrtoul(buf, 10, &val) < 0)
792d376b4   Wei Song   hwmon: New driver...
906
  		return -EINVAL;
ae51cd9bc   Jean Delvare   hwmon: (w83795) F...
907
  	if (val < 1 || val > 2)
792d376b4   Wei Song   hwmon: New driver...
908
909
910
911
  		return -EINVAL;
  
  	mutex_lock(&data->update_lock);
  	switch (val) {
792d376b4   Wei Song   hwmon: New driver...
912
  	case 1:
ae51cd9bc   Jean Delvare   hwmon: (w83795) F...
913
  		/* Clear speed cruise mode bits */
792d376b4   Wei Song   hwmon: New driver...
914
915
  		data->pwm_fcms[0] &= ~(1 << index);
  		w83795_write(client, W83795_REG_FCMS1, data->pwm_fcms[0]);
ae51cd9bc   Jean Delvare   hwmon: (w83795) F...
916
  		/* Clear thermal cruise mode bits */
792d376b4   Wei Song   hwmon: New driver...
917
918
919
920
921
  		for (i = 0; i < 6; i++) {
  			data->pwm_tfmr[i] &= ~(1 << index);
  			w83795_write(client, W83795_REG_TFMR(i),
  				data->pwm_tfmr[i]);
  		}
792d376b4   Wei Song   hwmon: New driver...
922
923
924
925
926
927
928
929
  		break;
  	case 2:
  		data->pwm_fcms[0] |= (1 << index);
  		w83795_write(client, W83795_REG_FCMS1, data->pwm_fcms[0]);
  		break;
  	}
  	mutex_unlock(&data->update_lock);
  	return count;
792d376b4   Wei Song   hwmon: New driver...
930
931
932
  }
  
  static ssize_t
d5ab845a1   Jean Delvare   hwmon: (w83795) E...
933
934
935
936
937
938
939
940
941
942
943
944
945
946
  show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf)
  {
  	struct w83795_data *data = w83795_update_pwm_config(dev);
  	int index = to_sensor_dev_attr_2(attr)->index;
  	unsigned int mode;
  
  	if (data->pwm_fomc & (1 << index))
  		mode = 0;	/* DC */
  	else
  		mode = 1;	/* PWM */
  
  	return sprintf(buf, "%u
  ", mode);
  }
edff2f8d8   Jean Delvare   hwmon: (w83795) L...
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
  /*
   * Check whether a given temperature source can ever be useful.
   * Returns the number of selectable temperature channels which are
   * enabled.
   */
  static int w83795_tss_useful(const struct w83795_data *data, int tsrc)
  {
  	int useful = 0, i;
  
  	for (i = 0; i < 4; i++) {
  		if (tss_map[i][tsrc] == TSS_MAP_RESERVED)
  			continue;
  		if (tss_map[i][tsrc] < 6)	/* Analog */
  			useful += (data->has_temp >> tss_map[i][tsrc]) & 1;
  		else				/* Digital */
  			useful += (data->has_dts >> (tss_map[i][tsrc] - 6)) & 1;
  	}
  
  	return useful;
  }
d5ab845a1   Jean Delvare   hwmon: (w83795) E...
967
  static ssize_t
792d376b4   Wei Song   hwmon: New driver...
968
969
970
971
  show_temp_src(struct device *dev, struct device_attribute *attr, char *buf)
  {
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
1bb3450ce   Jean Delvare   hwmon: (w83795) D...
972
  	struct w83795_data *data = w83795_update_pwm_config(dev);
792d376b4   Wei Song   hwmon: New driver...
973
  	int index = sensor_attr->index;
2a2d27da0   Jean Delvare   hwmon: (w83795) P...
974
  	u8 tmp = data->temp_src[index / 2];
792d376b4   Wei Song   hwmon: New driver...
975

7eb8d508b   Jean Delvare   hwmon: (w83795) F...
976
  	if (index & 1)
2a2d27da0   Jean Delvare   hwmon: (w83795) P...
977
  		tmp >>= 4;	/* Pick high nibble */
792d376b4   Wei Song   hwmon: New driver...
978
  	else
2a2d27da0   Jean Delvare   hwmon: (w83795) P...
979
  		tmp &= 0x0f;	/* Pick low nibble */
792d376b4   Wei Song   hwmon: New driver...
980

2a2d27da0   Jean Delvare   hwmon: (w83795) P...
981
982
983
984
985
986
  	/* Look-up the actual temperature channel number */
  	if (tmp >= 4 || tss_map[tmp][index] == TSS_MAP_RESERVED)
  		return -EINVAL;		/* Shouldn't happen */
  
  	return sprintf(buf, "%u
  ", (unsigned int)tss_map[tmp][index] + 1);
792d376b4   Wei Song   hwmon: New driver...
987
988
989
990
991
992
993
  }
  
  static ssize_t
  store_temp_src(struct device *dev, struct device_attribute *attr,
  	  const char *buf, size_t count)
  {
  	struct i2c_client *client = to_i2c_client(dev);
1bb3450ce   Jean Delvare   hwmon: (w83795) D...
994
  	struct w83795_data *data = w83795_update_pwm_config(dev);
792d376b4   Wei Song   hwmon: New driver...
995
996
997
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int index = sensor_attr->index;
2a2d27da0   Jean Delvare   hwmon: (w83795) P...
998
999
  	int tmp;
  	unsigned long channel;
792d376b4   Wei Song   hwmon: New driver...
1000
  	u8 val = index / 2;
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
1001
  	if (kstrtoul(buf, 10, &channel) < 0 ||
2a2d27da0   Jean Delvare   hwmon: (w83795) P...
1002
1003
1004
1005
1006
1007
1008
1009
1010
  	    channel < 1 || channel > 14)
  		return -EINVAL;
  
  	/* Check if request can be fulfilled */
  	for (tmp = 0; tmp < 4; tmp++) {
  		if (tss_map[tmp][index] == channel - 1)
  			break;
  	}
  	if (tmp == 4)	/* No match */
792d376b4   Wei Song   hwmon: New driver...
1011
  		return -EINVAL;
792d376b4   Wei Song   hwmon: New driver...
1012
1013
  
  	mutex_lock(&data->update_lock);
7eb8d508b   Jean Delvare   hwmon: (w83795) F...
1014
  	if (index & 1) {
792d376b4   Wei Song   hwmon: New driver...
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
  		tmp <<= 4;
  		data->temp_src[val] &= 0x0f;
  	} else {
  		data->temp_src[val] &= 0xf0;
  	}
  	data->temp_src[val] |= tmp;
  	w83795_write(client, W83795_REG_TSS(val), data->temp_src[val]);
  	mutex_unlock(&data->update_lock);
  
  	return count;
  }
  
  #define TEMP_PWM_ENABLE   0
  #define TEMP_PWM_FAN_MAP  1
  static ssize_t
  show_temp_pwm_enable(struct device *dev, struct device_attribute *attr,
  		     char *buf)
  {
1bb3450ce   Jean Delvare   hwmon: (w83795) D...
1033
  	struct w83795_data *data = w83795_update_pwm_config(dev);
792d376b4   Wei Song   hwmon: New driver...
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int nr = sensor_attr->nr;
  	int index = sensor_attr->index;
  	u8 tmp = 0xff;
  
  	switch (nr) {
  	case TEMP_PWM_ENABLE:
  		tmp = (data->pwm_fcms[1] >> index) & 1;
  		if (tmp)
  			tmp = 4;
  		else
  			tmp = 3;
  		break;
  	case TEMP_PWM_FAN_MAP:
  		tmp = data->pwm_tfmr[index];
  		break;
  	}
  
  	return sprintf(buf, "%u
  ", tmp);
  }
  
  static ssize_t
  store_temp_pwm_enable(struct device *dev, struct device_attribute *attr,
  	  const char *buf, size_t count)
  {
  	struct i2c_client *client = to_i2c_client(dev);
1bb3450ce   Jean Delvare   hwmon: (w83795) D...
1062
  	struct w83795_data *data = w83795_update_pwm_config(dev);
792d376b4   Wei Song   hwmon: New driver...
1063
1064
1065
1066
1067
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int nr = sensor_attr->nr;
  	int index = sensor_attr->index;
  	unsigned long tmp;
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
1068
  	if (kstrtoul(buf, 10, &tmp) < 0)
792d376b4   Wei Song   hwmon: New driver...
1069
1070
1071
1072
  		return -EINVAL;
  
  	switch (nr) {
  	case TEMP_PWM_ENABLE:
eb02755a5   Jean Delvare   hwmon: (w83795) M...
1073
  		if (tmp != 3 && tmp != 4)
792d376b4   Wei Song   hwmon: New driver...
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
  			return -EINVAL;
  		tmp -= 3;
  		mutex_lock(&data->update_lock);
  		data->pwm_fcms[1] &= ~(1 << index);
  		data->pwm_fcms[1] |= tmp << index;
  		w83795_write(client, W83795_REG_FCMS2, data->pwm_fcms[1]);
  		mutex_unlock(&data->update_lock);
  		break;
  	case TEMP_PWM_FAN_MAP:
  		mutex_lock(&data->update_lock);
  		tmp = SENSORS_LIMIT(tmp, 0, 0xff);
  		w83795_write(client, W83795_REG_TFMR(index), tmp);
  		data->pwm_tfmr[index] = tmp;
  		mutex_unlock(&data->update_lock);
  		break;
  	}
  	return count;
  }
  
  #define FANIN_TARGET   0
  #define FANIN_TOL      1
  static ssize_t
  show_fanin(struct device *dev, struct device_attribute *attr, char *buf)
  {
1bb3450ce   Jean Delvare   hwmon: (w83795) D...
1098
  	struct w83795_data *data = w83795_update_pwm_config(dev);
792d376b4   Wei Song   hwmon: New driver...
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int nr = sensor_attr->nr;
  	int index = sensor_attr->index;
  	u16 tmp = 0;
  
  	switch (nr) {
  	case FANIN_TARGET:
  		tmp = fan_from_reg(data->target_speed[index]);
  		break;
  	case FANIN_TOL:
  		tmp = data->tol_speed;
  		break;
  	}
  
  	return sprintf(buf, "%u
  ", tmp);
  }
  
  static ssize_t
  store_fanin(struct device *dev, struct device_attribute *attr,
  	  const char *buf, size_t count)
  {
  	struct i2c_client *client = to_i2c_client(dev);
  	struct w83795_data *data = i2c_get_clientdata(client);
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int nr = sensor_attr->nr;
  	int index = sensor_attr->index;
  	unsigned long val;
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
1129
  	if (kstrtoul(buf, 10, &val) < 0)
792d376b4   Wei Song   hwmon: New driver...
1130
1131
1132
1133
1134
1135
  		return -EINVAL;
  
  	mutex_lock(&data->update_lock);
  	switch (nr) {
  	case FANIN_TARGET:
  		val = fan_to_reg(SENSORS_LIMIT(val, 0, 0xfff));
eb02755a5   Jean Delvare   hwmon: (w83795) M...
1136
  		w83795_write(client, W83795_REG_FTSH(index), val >> 4);
792d376b4   Wei Song   hwmon: New driver...
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
  		w83795_write(client, W83795_REG_FTSL(index), (val << 4) & 0xf0);
  		data->target_speed[index] = val;
  		break;
  	case FANIN_TOL:
  		val = SENSORS_LIMIT(val, 0, 0x3f);
  		w83795_write(client, W83795_REG_TFTS, val);
  		data->tol_speed = val;
  		break;
  	}
  	mutex_unlock(&data->update_lock);
  
  	return count;
  }
  
  
  static ssize_t
  show_temp_pwm(struct device *dev, struct device_attribute *attr, char *buf)
  {
1bb3450ce   Jean Delvare   hwmon: (w83795) D...
1155
  	struct w83795_data *data = w83795_update_pwm_config(dev);
792d376b4   Wei Song   hwmon: New driver...
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int nr = sensor_attr->nr;
  	int index = sensor_attr->index;
  	long tmp = temp_from_reg(data->pwm_temp[index][nr]);
  
  	return sprintf(buf, "%ld
  ", tmp);
  }
  
  static ssize_t
  store_temp_pwm(struct device *dev, struct device_attribute *attr,
  	  const char *buf, size_t count)
  {
  	struct i2c_client *client = to_i2c_client(dev);
  	struct w83795_data *data = i2c_get_clientdata(client);
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int nr = sensor_attr->nr;
  	int index = sensor_attr->index;
  	unsigned long val;
  	u8 tmp;
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
1178
  	if (kstrtoul(buf, 10, &val) < 0)
792d376b4   Wei Song   hwmon: New driver...
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
  		return -EINVAL;
  	val /= 1000;
  
  	mutex_lock(&data->update_lock);
  	switch (nr) {
  	case TEMP_PWM_TTTI:
  		val = SENSORS_LIMIT(val, 0, 0x7f);
  		w83795_write(client, W83795_REG_TTTI(index), val);
  		break;
  	case TEMP_PWM_CTFS:
  		val = SENSORS_LIMIT(val, 0, 0x7f);
  		w83795_write(client, W83795_REG_CTFS(index), val);
  		break;
  	case TEMP_PWM_HCT:
  		val = SENSORS_LIMIT(val, 0, 0x0f);
  		tmp = w83795_read(client, W83795_REG_HT(index));
  		tmp &= 0x0f;
  		tmp |= (val << 4) & 0xf0;
  		w83795_write(client, W83795_REG_HT(index), tmp);
  		break;
  	case TEMP_PWM_HOT:
  		val = SENSORS_LIMIT(val, 0, 0x0f);
  		tmp = w83795_read(client, W83795_REG_HT(index));
  		tmp &= 0xf0;
  		tmp |= val & 0x0f;
  		w83795_write(client, W83795_REG_HT(index), tmp);
  		break;
  	}
  	data->pwm_temp[index][nr] = val;
  	mutex_unlock(&data->update_lock);
  
  	return count;
  }
  
  static ssize_t
  show_sf4_pwm(struct device *dev, struct device_attribute *attr, char *buf)
  {
1bb3450ce   Jean Delvare   hwmon: (w83795) D...
1216
  	struct w83795_data *data = w83795_update_pwm_config(dev);
792d376b4   Wei Song   hwmon: New driver...
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int nr = sensor_attr->nr;
  	int index = sensor_attr->index;
  
  	return sprintf(buf, "%u
  ", data->sf4_reg[index][SF4_PWM][nr]);
  }
  
  static ssize_t
  store_sf4_pwm(struct device *dev, struct device_attribute *attr,
  	  const char *buf, size_t count)
  {
  	struct i2c_client *client = to_i2c_client(dev);
  	struct w83795_data *data = i2c_get_clientdata(client);
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int nr = sensor_attr->nr;
  	int index = sensor_attr->index;
  	unsigned long val;
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
1237
  	if (kstrtoul(buf, 10, &val) < 0)
792d376b4   Wei Song   hwmon: New driver...
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
  		return -EINVAL;
  
  	mutex_lock(&data->update_lock);
  	w83795_write(client, W83795_REG_SF4_PWM(index, nr), val);
  	data->sf4_reg[index][SF4_PWM][nr] = val;
  	mutex_unlock(&data->update_lock);
  
  	return count;
  }
  
  static ssize_t
  show_sf4_temp(struct device *dev, struct device_attribute *attr, char *buf)
  {
1bb3450ce   Jean Delvare   hwmon: (w83795) D...
1251
  	struct w83795_data *data = w83795_update_pwm_config(dev);
792d376b4   Wei Song   hwmon: New driver...
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int nr = sensor_attr->nr;
  	int index = sensor_attr->index;
  
  	return sprintf(buf, "%u
  ",
  		(data->sf4_reg[index][SF4_TEMP][nr]) * 1000);
  }
  
  static ssize_t
  store_sf4_temp(struct device *dev, struct device_attribute *attr,
  	  const char *buf, size_t count)
  {
  	struct i2c_client *client = to_i2c_client(dev);
  	struct w83795_data *data = i2c_get_clientdata(client);
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int nr = sensor_attr->nr;
  	int index = sensor_attr->index;
  	unsigned long val;
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
1273
  	if (kstrtoul(buf, 10, &val) < 0)
792d376b4   Wei Song   hwmon: New driver...
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
  		return -EINVAL;
  	val /= 1000;
  
  	mutex_lock(&data->update_lock);
  	w83795_write(client, W83795_REG_SF4_TEMP(index, nr), val);
  	data->sf4_reg[index][SF4_TEMP][nr] = val;
  	mutex_unlock(&data->update_lock);
  
  	return count;
  }
  
  
  static ssize_t
  show_temp(struct device *dev, struct device_attribute *attr, char *buf)
  {
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int nr = sensor_attr->nr;
  	int index = sensor_attr->index;
  	struct w83795_data *data = w83795_update_device(dev);
dd127f5cc   Jean Delvare   hwmon: (w83795) P...
1294
  	long temp = temp_from_reg(data->temp[index][nr]);
792d376b4   Wei Song   hwmon: New driver...
1295

eb02755a5   Jean Delvare   hwmon: (w83795) M...
1296
  	if (nr == TEMP_READ)
a654b9d4e   Jean Delvare   hwmon: (w83795) G...
1297
  		temp += (data->temp_read_vrlsb[index] >> 6) * 250;
792d376b4   Wei Song   hwmon: New driver...
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
  	return sprintf(buf, "%ld
  ", temp);
  }
  
  static ssize_t
  store_temp(struct device *dev, struct device_attribute *attr,
  	   const char *buf, size_t count)
  {
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int nr = sensor_attr->nr;
  	int index = sensor_attr->index;
  	struct i2c_client *client = to_i2c_client(dev);
  	struct w83795_data *data = i2c_get_clientdata(client);
  	long tmp;
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
1313
  	if (kstrtol(buf, 10, &tmp) < 0)
792d376b4   Wei Song   hwmon: New driver...
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
  		return -EINVAL;
  
  	mutex_lock(&data->update_lock);
  	data->temp[index][nr] = temp_to_reg(tmp, -128, 127);
  	w83795_write(client, W83795_REG_TEMP[index][nr], data->temp[index][nr]);
  	mutex_unlock(&data->update_lock);
  	return count;
  }
  
  
  static ssize_t
  show_dts_mode(struct device *dev, struct device_attribute *attr, char *buf)
  {
21fc97755   Jean Delvare   hwmon: (w83795) U...
1327
  	struct w83795_data *data = dev_get_drvdata(dev);
39deb6993   Jean Delvare   hwmon: (w83795) S...
1328
  	int tmp;
792d376b4   Wei Song   hwmon: New driver...
1329

39deb6993   Jean Delvare   hwmon: (w83795) S...
1330
1331
1332
1333
  	if (data->enable_dts & 2)
  		tmp = 5;
  	else
  		tmp = 6;
792d376b4   Wei Song   hwmon: New driver...
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
  
  	return sprintf(buf, "%d
  ", tmp);
  }
  
  static ssize_t
  show_dts(struct device *dev, struct device_attribute *attr, char *buf)
  {
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int index = sensor_attr->index;
  	struct w83795_data *data = w83795_update_device(dev);
dd127f5cc   Jean Delvare   hwmon: (w83795) P...
1346
  	long temp = temp_from_reg(data->dts[index]);
792d376b4   Wei Song   hwmon: New driver...
1347

a654b9d4e   Jean Delvare   hwmon: (w83795) G...
1348
  	temp += (data->dts_read_vrlsb[index] >> 6) * 250;
792d376b4   Wei Song   hwmon: New driver...
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
  	return sprintf(buf, "%ld
  ", temp);
  }
  
  static ssize_t
  show_dts_ext(struct device *dev, struct device_attribute *attr, char *buf)
  {
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int nr = sensor_attr->nr;
21fc97755   Jean Delvare   hwmon: (w83795) U...
1359
  	struct w83795_data *data = dev_get_drvdata(dev);
dd127f5cc   Jean Delvare   hwmon: (w83795) P...
1360
  	long temp = temp_from_reg(data->dts_ext[nr]);
792d376b4   Wei Song   hwmon: New driver...
1361

792d376b4   Wei Song   hwmon: New driver...
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
  	return sprintf(buf, "%ld
  ", temp);
  }
  
  static ssize_t
  store_dts_ext(struct device *dev, struct device_attribute *attr,
  	   const char *buf, size_t count)
  {
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int nr = sensor_attr->nr;
  	struct i2c_client *client = to_i2c_client(dev);
  	struct w83795_data *data = i2c_get_clientdata(client);
  	long tmp;
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
1376
  	if (kstrtol(buf, 10, &tmp) < 0)
792d376b4   Wei Song   hwmon: New driver...
1377
1378
1379
1380
1381
1382
1383
1384
  		return -EINVAL;
  
  	mutex_lock(&data->update_lock);
  	data->dts_ext[nr] = temp_to_reg(tmp, -128, 127);
  	w83795_write(client, W83795_REG_DTS_EXT(nr), data->dts_ext[nr]);
  	mutex_unlock(&data->update_lock);
  	return count;
  }
792d376b4   Wei Song   hwmon: New driver...
1385
1386
1387
  static ssize_t
  show_temp_mode(struct device *dev, struct device_attribute *attr, char *buf)
  {
21fc97755   Jean Delvare   hwmon: (w83795) U...
1388
  	struct w83795_data *data = dev_get_drvdata(dev);
792d376b4   Wei Song   hwmon: New driver...
1389
1390
1391
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int index = sensor_attr->index;
39deb6993   Jean Delvare   hwmon: (w83795) S...
1392
  	int tmp;
792d376b4   Wei Song   hwmon: New driver...
1393

39deb6993   Jean Delvare   hwmon: (w83795) S...
1394
1395
1396
1397
  	if (data->temp_mode & (1 << index))
  		tmp = 3;	/* Thermal diode */
  	else
  		tmp = 4;	/* Thermistor */
792d376b4   Wei Song   hwmon: New driver...
1398
1399
1400
1401
  
  	return sprintf(buf, "%d
  ", tmp);
  }
39deb6993   Jean Delvare   hwmon: (w83795) S...
1402
  /* Only for temp1-4 (temp5-6 can only be thermistor) */
792d376b4   Wei Song   hwmon: New driver...
1403
1404
1405
1406
1407
1408
1409
1410
1411
  static ssize_t
  store_temp_mode(struct device *dev, struct device_attribute *attr,
  		const char *buf, size_t count)
  {
  	struct i2c_client *client = to_i2c_client(dev);
  	struct w83795_data *data = i2c_get_clientdata(client);
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int index = sensor_attr->index;
39deb6993   Jean Delvare   hwmon: (w83795) S...
1412
  	int reg_shift;
792d376b4   Wei Song   hwmon: New driver...
1413
1414
  	unsigned long val;
  	u8 tmp;
792d376b4   Wei Song   hwmon: New driver...
1415

179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
1416
  	if (kstrtoul(buf, 10, &val) < 0)
792d376b4   Wei Song   hwmon: New driver...
1417
1418
1419
  		return -EINVAL;
  	if ((val != 4) && (val != 3))
  		return -EINVAL;
792d376b4   Wei Song   hwmon: New driver...
1420
1421
1422
  
  	mutex_lock(&data->update_lock);
  	if (val == 3) {
39deb6993   Jean Delvare   hwmon: (w83795) S...
1423
1424
  		/* Thermal diode */
  		val = 0x01;
792d376b4   Wei Song   hwmon: New driver...
1425
1426
  		data->temp_mode |= 1 << index;
  	} else if (val == 4) {
39deb6993   Jean Delvare   hwmon: (w83795) S...
1427
1428
1429
  		/* Thermistor */
  		val = 0x03;
  		data->temp_mode &= ~(1 << index);
792d376b4   Wei Song   hwmon: New driver...
1430
  	}
39deb6993   Jean Delvare   hwmon: (w83795) S...
1431
1432
1433
1434
1435
  	reg_shift = 2 * index;
  	tmp = w83795_read(client, W83795_REG_TEMP_CTRL2);
  	tmp &= ~(0x03 << reg_shift);
  	tmp |= val << reg_shift;
  	w83795_write(client, W83795_REG_TEMP_CTRL2, tmp);
792d376b4   Wei Song   hwmon: New driver...
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
  
  	mutex_unlock(&data->update_lock);
  	return count;
  }
  
  
  /* show/store VIN */
  static ssize_t
  show_in(struct device *dev, struct device_attribute *attr, char *buf)
  {
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int nr = sensor_attr->nr;
  	int index = sensor_attr->index;
  	struct w83795_data *data = w83795_update_device(dev);
  	u16 val = data->in[index][nr];
  	u8 lsb_idx;
  
  	switch (nr) {
  	case IN_READ:
  		/* calculate this value again by sensors as sensors3.conf */
  		if ((index >= 17) &&
6f9dfd85f   Jean Delvare   hwmon: (w83795) F...
1458
  		    !((data->has_gain >> (index - 17)) & 1))
792d376b4   Wei Song   hwmon: New driver...
1459
1460
1461
1462
1463
1464
1465
  			val *= 8;
  		break;
  	case IN_MAX:
  	case IN_LOW:
  		lsb_idx = IN_LSB_SHIFT_IDX[index][IN_LSB_IDX];
  		val <<= 2;
  		val |= (data->in_lsb[lsb_idx][nr] >>
5d2cd958f   Jean Delvare   hwmon: (w83795) F...
1466
  			IN_LSB_SHIFT_IDX[index][IN_LSB_SHIFT]) & 0x03;
792d376b4   Wei Song   hwmon: New driver...
1467
  		if ((index >= 17) &&
6f9dfd85f   Jean Delvare   hwmon: (w83795) F...
1468
  		    !((data->has_gain >> (index - 17)) & 1))
792d376b4   Wei Song   hwmon: New driver...
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
  			val *= 8;
  		break;
  	}
  	val = in_from_reg(index, val);
  
  	return sprintf(buf, "%d
  ", val);
  }
  
  static ssize_t
  store_in(struct device *dev, struct device_attribute *attr,
  	 const char *buf, size_t count)
  {
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int nr = sensor_attr->nr;
  	int index = sensor_attr->index;
  	struct i2c_client *client = to_i2c_client(dev);
  	struct w83795_data *data = i2c_get_clientdata(client);
  	unsigned long val;
  	u8 tmp;
  	u8 lsb_idx;
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
1491
  	if (kstrtoul(buf, 10, &val) < 0)
792d376b4   Wei Song   hwmon: New driver...
1492
1493
1494
1495
  		return -EINVAL;
  	val = in_to_reg(index, val);
  
  	if ((index >= 17) &&
6f9dfd85f   Jean Delvare   hwmon: (w83795) F...
1496
  	    !((data->has_gain >> (index - 17)) & 1))
792d376b4   Wei Song   hwmon: New driver...
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
  		val /= 8;
  	val = SENSORS_LIMIT(val, 0, 0x3FF);
  	mutex_lock(&data->update_lock);
  
  	lsb_idx = IN_LSB_SHIFT_IDX[index][IN_LSB_IDX];
  	tmp = w83795_read(client, IN_LSB_REG(lsb_idx, nr));
  	tmp &= ~(0x03 << IN_LSB_SHIFT_IDX[index][IN_LSB_SHIFT]);
  	tmp |= (val & 0x03) << IN_LSB_SHIFT_IDX[index][IN_LSB_SHIFT];
  	w83795_write(client, IN_LSB_REG(lsb_idx, nr), tmp);
  	data->in_lsb[lsb_idx][nr] = tmp;
  
  	tmp = (val >> 2) & 0xff;
  	w83795_write(client, W83795_REG_IN[index][nr], tmp);
  	data->in[index][nr] = tmp;
  
  	mutex_unlock(&data->update_lock);
  	return count;
  }
00030af23   Jean Delvare   hwmon: (w83795) E...
1515
  #ifdef CONFIG_SENSORS_W83795_FANCTRL
792d376b4   Wei Song   hwmon: New driver...
1516
1517
1518
1519
1520
1521
  static ssize_t
  show_sf_setup(struct device *dev, struct device_attribute *attr, char *buf)
  {
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int nr = sensor_attr->nr;
1bb3450ce   Jean Delvare   hwmon: (w83795) D...
1522
  	struct w83795_data *data = w83795_update_pwm_config(dev);
792d376b4   Wei Song   hwmon: New driver...
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
  	u16 val = data->setup_pwm[nr];
  
  	switch (nr) {
  	case SETUP_PWM_UPTIME:
  	case SETUP_PWM_DOWNTIME:
  		val = time_from_reg(val);
  		break;
  	}
  
  	return sprintf(buf, "%d
  ", val);
  }
  
  static ssize_t
  store_sf_setup(struct device *dev, struct device_attribute *attr,
  	 const char *buf, size_t count)
  {
  	struct sensor_device_attribute_2 *sensor_attr =
  	    to_sensor_dev_attr_2(attr);
  	int nr = sensor_attr->nr;
  	struct i2c_client *client = to_i2c_client(dev);
  	struct w83795_data *data = i2c_get_clientdata(client);
  	unsigned long val;
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
1546
  	if (kstrtoul(buf, 10, &val) < 0)
792d376b4   Wei Song   hwmon: New driver...
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
  		return -EINVAL;
  
  	switch (nr) {
  	case SETUP_PWM_DEFAULT:
  		val = SENSORS_LIMIT(val, 0, 0xff);
  		break;
  	case SETUP_PWM_UPTIME:
  	case SETUP_PWM_DOWNTIME:
  		val = time_to_reg(val);
  		if (val == 0)
  			return -EINVAL;
  		break;
  	}
  
  	mutex_lock(&data->update_lock);
  	data->setup_pwm[nr] = val;
  	w83795_write(client, W83795_REG_SETUP_PWM(nr), val);
  	mutex_unlock(&data->update_lock);
  	return count;
  }
00030af23   Jean Delvare   hwmon: (w83795) E...
1567
  #endif
792d376b4   Wei Song   hwmon: New driver...
1568
1569
1570
  
  
  #define NOT_USED			-1
52d159eec   Jean Delvare   hwmon: (w83795) C...
1571
  /* Don't change the attribute order, _max, _min and _beep are accessed by index
0e256018b   Jean Delvare   hwmon: (w83795) A...
1572
   * somewhere else in the code */
87df0dad3   Jean Delvare   hwmon: (w83795) U...
1573
  #define SENSOR_ATTR_IN(index) {						\
792d376b4   Wei Song   hwmon: New driver...
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
  	SENSOR_ATTR_2(in##index##_input, S_IRUGO, show_in, NULL,	\
  		IN_READ, index), \
  	SENSOR_ATTR_2(in##index##_max, S_IRUGO | S_IWUSR, show_in,	\
  		store_in, IN_MAX, index),				\
  	SENSOR_ATTR_2(in##index##_min, S_IRUGO | S_IWUSR, show_in,	\
  		store_in, IN_LOW, index),				\
  	SENSOR_ATTR_2(in##index##_alarm, S_IRUGO, show_alarm_beep,	\
  		NULL, ALARM_STATUS, index + ((index > 14) ? 1 : 0)), \
  	SENSOR_ATTR_2(in##index##_beep, S_IWUSR | S_IRUGO,		\
  		show_alarm_beep, store_beep, BEEP_ENABLE,		\
87df0dad3   Jean Delvare   hwmon: (w83795) U...
1584
  		index + ((index > 14) ? 1 : 0)) }
792d376b4   Wei Song   hwmon: New driver...
1585

52d159eec   Jean Delvare   hwmon: (w83795) C...
1586
1587
  /* Don't change the attribute order, _beep is accessed by index
   * somewhere else in the code */
87df0dad3   Jean Delvare   hwmon: (w83795) U...
1588
  #define SENSOR_ATTR_FAN(index) {					\
792d376b4   Wei Song   hwmon: New driver...
1589
1590
1591
1592
1593
1594
1595
  	SENSOR_ATTR_2(fan##index##_input, S_IRUGO, show_fan,		\
  		NULL, FAN_INPUT, index - 1), \
  	SENSOR_ATTR_2(fan##index##_min, S_IWUSR | S_IRUGO,		\
  		show_fan, store_fan_min, FAN_MIN, index - 1),	\
  	SENSOR_ATTR_2(fan##index##_alarm, S_IRUGO, show_alarm_beep,	\
  		NULL, ALARM_STATUS, index + 31),			\
  	SENSOR_ATTR_2(fan##index##_beep, S_IWUSR | S_IRUGO,		\
87df0dad3   Jean Delvare   hwmon: (w83795) U...
1596
  		show_alarm_beep, store_beep, BEEP_ENABLE, index + 31) }
792d376b4   Wei Song   hwmon: New driver...
1597

b5f6a90a0   Jean Delvare   hwmon: (w83795) M...
1598
  #define SENSOR_ATTR_PWM(index) {					\
792d376b4   Wei Song   hwmon: New driver...
1599
1600
1601
1602
1603
1604
1605
1606
  	SENSOR_ATTR_2(pwm##index, S_IWUSR | S_IRUGO, show_pwm,		\
  		store_pwm, PWM_OUTPUT, index - 1),			\
  	SENSOR_ATTR_2(pwm##index##_nonstop, S_IWUSR | S_IRUGO,		\
  		show_pwm, store_pwm, PWM_NONSTOP, index - 1),		\
  	SENSOR_ATTR_2(pwm##index##_start, S_IWUSR | S_IRUGO,		\
  		show_pwm, store_pwm, PWM_START, index - 1),		\
  	SENSOR_ATTR_2(pwm##index##_stop_time, S_IWUSR | S_IRUGO,	\
  		show_pwm, store_pwm, PWM_STOP_TIME, index - 1),	 \
01879a855   Jean Delvare   hwmon: (w83795) F...
1607
1608
  	SENSOR_ATTR_2(pwm##index##_freq, S_IWUSR | S_IRUGO,	\
  		show_pwm, store_pwm, PWM_FREQ, index - 1),	 \
792d376b4   Wei Song   hwmon: New driver...
1609
  	SENSOR_ATTR_2(pwm##index##_enable, S_IWUSR | S_IRUGO,		\
b2cc528e5   Jean Delvare   hwmon: (w83795) O...
1610
  		show_pwm_enable, store_pwm_enable, NOT_USED, index - 1), \
d5ab845a1   Jean Delvare   hwmon: (w83795) E...
1611
1612
  	SENSOR_ATTR_2(pwm##index##_mode, S_IRUGO,			\
  		show_pwm_mode, NULL, NOT_USED, index - 1),		\
b2cc528e5   Jean Delvare   hwmon: (w83795) O...
1613
1614
  	SENSOR_ATTR_2(fan##index##_target, S_IWUSR | S_IRUGO, \
  		show_fanin, store_fanin, FANIN_TARGET, index - 1) }
792d376b4   Wei Song   hwmon: New driver...
1615

52d159eec   Jean Delvare   hwmon: (w83795) C...
1616
1617
  /* Don't change the attribute order, _beep is accessed by index
   * somewhere else in the code */
87df0dad3   Jean Delvare   hwmon: (w83795) U...
1618
  #define SENSOR_ATTR_DTS(index) {					\
792d376b4   Wei Song   hwmon: New driver...
1619
1620
1621
1622
  	SENSOR_ATTR_2(temp##index##_type, S_IRUGO ,		\
  		show_dts_mode, NULL, NOT_USED, index - 7),	\
  	SENSOR_ATTR_2(temp##index##_input, S_IRUGO, show_dts,		\
  		NULL, NOT_USED, index - 7),				\
a0ce402fb   Jean Delvare   hwmon: (w83795) R...
1623
  	SENSOR_ATTR_2(temp##index##_crit, S_IRUGO | S_IWUSR, show_dts_ext, \
792d376b4   Wei Song   hwmon: New driver...
1624
  		store_dts_ext, DTS_CRIT, NOT_USED),			\
a0ce402fb   Jean Delvare   hwmon: (w83795) R...
1625
  	SENSOR_ATTR_2(temp##index##_crit_hyst, S_IRUGO | S_IWUSR,	\
792d376b4   Wei Song   hwmon: New driver...
1626
  		show_dts_ext, store_dts_ext, DTS_CRIT_HYST, NOT_USED),	\
a0ce402fb   Jean Delvare   hwmon: (w83795) R...
1627
  	SENSOR_ATTR_2(temp##index##_max, S_IRUGO | S_IWUSR, show_dts_ext, \
792d376b4   Wei Song   hwmon: New driver...
1628
  		store_dts_ext, DTS_WARN, NOT_USED),			\
a0ce402fb   Jean Delvare   hwmon: (w83795) R...
1629
  	SENSOR_ATTR_2(temp##index##_max_hyst, S_IRUGO | S_IWUSR,	\
792d376b4   Wei Song   hwmon: New driver...
1630
1631
1632
1633
  		show_dts_ext, store_dts_ext, DTS_WARN_HYST, NOT_USED),	\
  	SENSOR_ATTR_2(temp##index##_alarm, S_IRUGO,			\
  		show_alarm_beep, NULL, ALARM_STATUS, index + 17),	\
  	SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO,		\
87df0dad3   Jean Delvare   hwmon: (w83795) U...
1634
  		show_alarm_beep, store_beep, BEEP_ENABLE, index + 17) }
792d376b4   Wei Song   hwmon: New driver...
1635

52d159eec   Jean Delvare   hwmon: (w83795) C...
1636
1637
  /* Don't change the attribute order, _beep is accessed by index
   * somewhere else in the code */
87df0dad3   Jean Delvare   hwmon: (w83795) U...
1638
  #define SENSOR_ATTR_TEMP(index) {					\
39deb6993   Jean Delvare   hwmon: (w83795) S...
1639
  	SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 4 ? S_IWUSR : 0), \
792d376b4   Wei Song   hwmon: New driver...
1640
1641
1642
  		show_temp_mode, store_temp_mode, NOT_USED, index - 1),	\
  	SENSOR_ATTR_2(temp##index##_input, S_IRUGO, show_temp,		\
  		NULL, TEMP_READ, index - 1),				\
a0ce402fb   Jean Delvare   hwmon: (w83795) R...
1643
  	SENSOR_ATTR_2(temp##index##_crit, S_IRUGO | S_IWUSR, show_temp,	\
792d376b4   Wei Song   hwmon: New driver...
1644
  		store_temp, TEMP_CRIT, index - 1),			\
a0ce402fb   Jean Delvare   hwmon: (w83795) R...
1645
  	SENSOR_ATTR_2(temp##index##_crit_hyst, S_IRUGO | S_IWUSR,	\
792d376b4   Wei Song   hwmon: New driver...
1646
  		show_temp, store_temp, TEMP_CRIT_HYST, index - 1),	\
a0ce402fb   Jean Delvare   hwmon: (w83795) R...
1647
  	SENSOR_ATTR_2(temp##index##_max, S_IRUGO | S_IWUSR, show_temp,	\
792d376b4   Wei Song   hwmon: New driver...
1648
  		store_temp, TEMP_WARN, index - 1),			\
a0ce402fb   Jean Delvare   hwmon: (w83795) R...
1649
  	SENSOR_ATTR_2(temp##index##_max_hyst, S_IRUGO | S_IWUSR,	\
792d376b4   Wei Song   hwmon: New driver...
1650
1651
1652
1653
1654
1655
1656
  		show_temp, store_temp, TEMP_WARN_HYST, index - 1),	\
  	SENSOR_ATTR_2(temp##index##_alarm, S_IRUGO,			\
  		show_alarm_beep, NULL, ALARM_STATUS,			\
  		index + (index > 4 ? 11 : 17)),				\
  	SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO,		\
  		show_alarm_beep, store_beep, BEEP_ENABLE,		\
  		index + (index > 4 ? 11 : 17)),				\
792d376b4   Wei Song   hwmon: New driver...
1657
1658
1659
1660
1661
1662
1663
1664
  	SENSOR_ATTR_2(temp##index##_pwm_enable, S_IWUSR | S_IRUGO,	\
  		show_temp_pwm_enable, store_temp_pwm_enable,		\
  		TEMP_PWM_ENABLE, index - 1),				\
  	SENSOR_ATTR_2(temp##index##_auto_channels_pwm, S_IWUSR | S_IRUGO, \
  		show_temp_pwm_enable, store_temp_pwm_enable,		\
  		TEMP_PWM_FAN_MAP, index - 1),				\
  	SENSOR_ATTR_2(thermal_cruise##index, S_IWUSR | S_IRUGO,		\
  		show_temp_pwm, store_temp_pwm, TEMP_PWM_TTTI, index - 1), \
a0ce402fb   Jean Delvare   hwmon: (w83795) R...
1665
  	SENSOR_ATTR_2(temp##index##_warn, S_IWUSR | S_IRUGO,		\
792d376b4   Wei Song   hwmon: New driver...
1666
  		show_temp_pwm, store_temp_pwm, TEMP_PWM_CTFS, index - 1), \
a0ce402fb   Jean Delvare   hwmon: (w83795) R...
1667
  	SENSOR_ATTR_2(temp##index##_warn_hyst, S_IWUSR | S_IRUGO,	\
792d376b4   Wei Song   hwmon: New driver...
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
  		show_temp_pwm, store_temp_pwm, TEMP_PWM_HCT, index - 1), \
  	SENSOR_ATTR_2(temp##index##_operation_hyst, S_IWUSR | S_IRUGO,	\
  		show_temp_pwm, store_temp_pwm, TEMP_PWM_HOT, index - 1), \
  	SENSOR_ATTR_2(temp##index##_auto_point1_pwm, S_IRUGO | S_IWUSR, \
  		show_sf4_pwm, store_sf4_pwm, 0, index - 1),		\
  	SENSOR_ATTR_2(temp##index##_auto_point2_pwm, S_IRUGO | S_IWUSR, \
  		show_sf4_pwm, store_sf4_pwm, 1, index - 1),		\
  	SENSOR_ATTR_2(temp##index##_auto_point3_pwm, S_IRUGO | S_IWUSR, \
  		show_sf4_pwm, store_sf4_pwm, 2, index - 1),		\
  	SENSOR_ATTR_2(temp##index##_auto_point4_pwm, S_IRUGO | S_IWUSR, \
  		show_sf4_pwm, store_sf4_pwm, 3, index - 1),		\
  	SENSOR_ATTR_2(temp##index##_auto_point5_pwm, S_IRUGO | S_IWUSR, \
  		show_sf4_pwm, store_sf4_pwm, 4, index - 1),		\
  	SENSOR_ATTR_2(temp##index##_auto_point6_pwm, S_IRUGO | S_IWUSR, \
  		show_sf4_pwm, store_sf4_pwm, 5, index - 1),		\
  	SENSOR_ATTR_2(temp##index##_auto_point7_pwm, S_IRUGO | S_IWUSR, \
  		show_sf4_pwm, store_sf4_pwm, 6, index - 1),		\
  	SENSOR_ATTR_2(temp##index##_auto_point1_temp, S_IRUGO | S_IWUSR,\
  		show_sf4_temp, store_sf4_temp, 0, index - 1),		\
  	SENSOR_ATTR_2(temp##index##_auto_point2_temp, S_IRUGO | S_IWUSR,\
  		show_sf4_temp, store_sf4_temp, 1, index - 1),		\
  	SENSOR_ATTR_2(temp##index##_auto_point3_temp, S_IRUGO | S_IWUSR,\
  		show_sf4_temp, store_sf4_temp, 2, index - 1),		\
  	SENSOR_ATTR_2(temp##index##_auto_point4_temp, S_IRUGO | S_IWUSR,\
  		show_sf4_temp, store_sf4_temp, 3, index - 1),		\
  	SENSOR_ATTR_2(temp##index##_auto_point5_temp, S_IRUGO | S_IWUSR,\
  		show_sf4_temp, store_sf4_temp, 4, index - 1),		\
  	SENSOR_ATTR_2(temp##index##_auto_point6_temp, S_IRUGO | S_IWUSR,\
  		show_sf4_temp, store_sf4_temp, 5, index - 1),		\
  	SENSOR_ATTR_2(temp##index##_auto_point7_temp, S_IRUGO | S_IWUSR,\
87df0dad3   Jean Delvare   hwmon: (w83795) U...
1698
  		show_sf4_temp, store_sf4_temp, 6, index - 1) }
792d376b4   Wei Song   hwmon: New driver...
1699

87df0dad3   Jean Delvare   hwmon: (w83795) U...
1700
  static struct sensor_device_attribute_2 w83795_in[][5] = {
792d376b4   Wei Song   hwmon: New driver...
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
  	SENSOR_ATTR_IN(0),
  	SENSOR_ATTR_IN(1),
  	SENSOR_ATTR_IN(2),
  	SENSOR_ATTR_IN(3),
  	SENSOR_ATTR_IN(4),
  	SENSOR_ATTR_IN(5),
  	SENSOR_ATTR_IN(6),
  	SENSOR_ATTR_IN(7),
  	SENSOR_ATTR_IN(8),
  	SENSOR_ATTR_IN(9),
  	SENSOR_ATTR_IN(10),
  	SENSOR_ATTR_IN(11),
  	SENSOR_ATTR_IN(12),
  	SENSOR_ATTR_IN(13),
  	SENSOR_ATTR_IN(14),
  	SENSOR_ATTR_IN(15),
  	SENSOR_ATTR_IN(16),
  	SENSOR_ATTR_IN(17),
  	SENSOR_ATTR_IN(18),
  	SENSOR_ATTR_IN(19),
  	SENSOR_ATTR_IN(20),
  };
86ef4d2fd   Jean Delvare   hwmon: (w83795) A...
1723
  static const struct sensor_device_attribute_2 w83795_fan[][4] = {
792d376b4   Wei Song   hwmon: New driver...
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
  	SENSOR_ATTR_FAN(1),
  	SENSOR_ATTR_FAN(2),
  	SENSOR_ATTR_FAN(3),
  	SENSOR_ATTR_FAN(4),
  	SENSOR_ATTR_FAN(5),
  	SENSOR_ATTR_FAN(6),
  	SENSOR_ATTR_FAN(7),
  	SENSOR_ATTR_FAN(8),
  	SENSOR_ATTR_FAN(9),
  	SENSOR_ATTR_FAN(10),
  	SENSOR_ATTR_FAN(11),
  	SENSOR_ATTR_FAN(12),
  	SENSOR_ATTR_FAN(13),
  	SENSOR_ATTR_FAN(14),
  };
edff2f8d8   Jean Delvare   hwmon: (w83795) L...
1739
  static const struct sensor_device_attribute_2 w83795_temp[][28] = {
792d376b4   Wei Song   hwmon: New driver...
1740
1741
1742
1743
1744
1745
1746
  	SENSOR_ATTR_TEMP(1),
  	SENSOR_ATTR_TEMP(2),
  	SENSOR_ATTR_TEMP(3),
  	SENSOR_ATTR_TEMP(4),
  	SENSOR_ATTR_TEMP(5),
  	SENSOR_ATTR_TEMP(6),
  };
86ef4d2fd   Jean Delvare   hwmon: (w83795) A...
1747
  static const struct sensor_device_attribute_2 w83795_dts[][8] = {
792d376b4   Wei Song   hwmon: New driver...
1748
1749
1750
1751
1752
1753
1754
1755
1756
  	SENSOR_ATTR_DTS(7),
  	SENSOR_ATTR_DTS(8),
  	SENSOR_ATTR_DTS(9),
  	SENSOR_ATTR_DTS(10),
  	SENSOR_ATTR_DTS(11),
  	SENSOR_ATTR_DTS(12),
  	SENSOR_ATTR_DTS(13),
  	SENSOR_ATTR_DTS(14),
  };
d5ab845a1   Jean Delvare   hwmon: (w83795) E...
1757
  static const struct sensor_device_attribute_2 w83795_pwm[][8] = {
b5f6a90a0   Jean Delvare   hwmon: (w83795) M...
1758
1759
  	SENSOR_ATTR_PWM(1),
  	SENSOR_ATTR_PWM(2),
792d376b4   Wei Song   hwmon: New driver...
1760
1761
1762
1763
1764
1765
1766
  	SENSOR_ATTR_PWM(3),
  	SENSOR_ATTR_PWM(4),
  	SENSOR_ATTR_PWM(5),
  	SENSOR_ATTR_PWM(6),
  	SENSOR_ATTR_PWM(7),
  	SENSOR_ATTR_PWM(8),
  };
edff2f8d8   Jean Delvare   hwmon: (w83795) L...
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
  static const struct sensor_device_attribute_2 w83795_tss[6] = {
  	SENSOR_ATTR_2(temp1_source_sel, S_IWUSR | S_IRUGO,
  		      show_temp_src, store_temp_src, NOT_USED, 0),
  	SENSOR_ATTR_2(temp2_source_sel, S_IWUSR | S_IRUGO,
  		      show_temp_src, store_temp_src, NOT_USED, 1),
  	SENSOR_ATTR_2(temp3_source_sel, S_IWUSR | S_IRUGO,
  		      show_temp_src, store_temp_src, NOT_USED, 2),
  	SENSOR_ATTR_2(temp4_source_sel, S_IWUSR | S_IRUGO,
  		      show_temp_src, store_temp_src, NOT_USED, 3),
  	SENSOR_ATTR_2(temp5_source_sel, S_IWUSR | S_IRUGO,
  		      show_temp_src, store_temp_src, NOT_USED, 4),
  	SENSOR_ATTR_2(temp6_source_sel, S_IWUSR | S_IRUGO,
  		      show_temp_src, store_temp_src, NOT_USED, 5),
  };
86ef4d2fd   Jean Delvare   hwmon: (w83795) A...
1781
  static const struct sensor_device_attribute_2 sda_single_files[] = {
243771010   Jean Delvare   hwmon: (w83795) U...
1782
  	SENSOR_ATTR_2(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm_beep,
792d376b4   Wei Song   hwmon: New driver...
1783
  		      store_chassis_clear, ALARM_STATUS, 46),
00030af23   Jean Delvare   hwmon: (w83795) E...
1784
  #ifdef CONFIG_SENSORS_W83795_FANCTRL
792d376b4   Wei Song   hwmon: New driver...
1785
1786
1787
1788
1789
1790
1791
1792
  	SENSOR_ATTR_2(speed_cruise_tolerance, S_IWUSR | S_IRUGO, show_fanin,
  		store_fanin, FANIN_TOL, NOT_USED),
  	SENSOR_ATTR_2(pwm_default, S_IWUSR | S_IRUGO, show_sf_setup,
  		      store_sf_setup, SETUP_PWM_DEFAULT, NOT_USED),
  	SENSOR_ATTR_2(pwm_uptime, S_IWUSR | S_IRUGO, show_sf_setup,
  		      store_sf_setup, SETUP_PWM_UPTIME, NOT_USED),
  	SENSOR_ATTR_2(pwm_downtime, S_IWUSR | S_IRUGO, show_sf_setup,
  		      store_sf_setup, SETUP_PWM_DOWNTIME, NOT_USED),
00030af23   Jean Delvare   hwmon: (w83795) E...
1793
  #endif
792d376b4   Wei Song   hwmon: New driver...
1794
  };
52d159eec   Jean Delvare   hwmon: (w83795) C...
1795
1796
1797
1798
1799
1800
  static const struct sensor_device_attribute_2 sda_beep_files[] = {
  	SENSOR_ATTR_2(intrusion0_beep, S_IWUSR | S_IRUGO, show_alarm_beep,
  		      store_beep, BEEP_ENABLE, 46),
  	SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_alarm_beep,
  		      store_beep, BEEP_ENABLE, 47),
  };
792d376b4   Wei Song   hwmon: New driver...
1801
1802
1803
1804
1805
1806
  /*
   * Driver interface
   */
  
  static void w83795_init_client(struct i2c_client *client)
  {
01879a855   Jean Delvare   hwmon: (w83795) F...
1807
1808
1809
1810
  	struct w83795_data *data = i2c_get_clientdata(client);
  	static const u16 clkin[4] = {	/* in kHz */
  		14318, 24000, 33333, 48000
  	};
80646b958   Jean Delvare   hwmon: (w83795) O...
1811
  	u8 config;
792d376b4   Wei Song   hwmon: New driver...
1812
1813
  	if (reset)
  		w83795_write(client, W83795_REG_CONFIG, 0x80);
80646b958   Jean Delvare   hwmon: (w83795) O...
1814
1815
1816
1817
1818
1819
1820
1821
  	/* Start monitoring if needed */
  	config = w83795_read(client, W83795_REG_CONFIG);
  	if (!(config & W83795_REG_CONFIG_START)) {
  		dev_info(&client->dev, "Enabling monitoring operations
  ");
  		w83795_write(client, W83795_REG_CONFIG,
  			     config | W83795_REG_CONFIG_START);
  	}
01879a855   Jean Delvare   hwmon: (w83795) F...
1822
1823
1824
1825
  
  	data->clkin = clkin[(config >> 3) & 0x3];
  	dev_dbg(&client->dev, "clkin = %u kHz
  ", data->clkin);
792d376b4   Wei Song   hwmon: New driver...
1826
  }
2be381de0   Jean Delvare   hwmon: (w83795) I...
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
  static int w83795_get_device_id(struct i2c_client *client)
  {
  	int device_id;
  
  	device_id = i2c_smbus_read_byte_data(client, W83795_REG_DEVICEID);
  
  	/* Special case for rev. A chips; can't be checked first because later
  	   revisions emulate this for compatibility */
  	if (device_id < 0 || (device_id & 0xf0) != 0x50) {
  		int alt_id;
  
  		alt_id = i2c_smbus_read_byte_data(client,
  						  W83795_REG_DEVICEID_A);
  		if (alt_id == 0x50)
  			device_id = alt_id;
  	}
  
  	return device_id;
  }
792d376b4   Wei Song   hwmon: New driver...
1846
1847
1848
1849
  /* Return 0 if detection is successful, -ENODEV otherwise */
  static int w83795_detect(struct i2c_client *client,
  			 struct i2c_board_info *info)
  {
2be381de0   Jean Delvare   hwmon: (w83795) I...
1850
  	int bank, vendor_id, device_id, expected, i2c_addr, config;
792d376b4   Wei Song   hwmon: New driver...
1851
1852
  	struct i2c_adapter *adapter = client->adapter;
  	unsigned short address = client->addr;
093d1a479   Jean Delvare   hwmon: (w83795) D...
1853
  	const char *chip_name;
792d376b4   Wei Song   hwmon: New driver...
1854
1855
1856
1857
  
  	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
  		return -ENODEV;
  	bank = i2c_smbus_read_byte_data(client, W83795_REG_BANKSEL);
2be381de0   Jean Delvare   hwmon: (w83795) I...
1858
1859
1860
1861
1862
1863
1864
  	if (bank < 0 || (bank & 0x7c)) {
  		dev_dbg(&adapter->dev,
  			"w83795: Detection failed at addr 0x%02hx, check %s
  ",
  			address, "bank");
  		return -ENODEV;
  	}
792d376b4   Wei Song   hwmon: New driver...
1865

792d376b4   Wei Song   hwmon: New driver...
1866
  	/* Check Nuvoton vendor ID */
2be381de0   Jean Delvare   hwmon: (w83795) I...
1867
1868
1869
1870
1871
1872
1873
  	vendor_id = i2c_smbus_read_byte_data(client, W83795_REG_VENDORID);
  	expected = bank & 0x80 ? 0x5c : 0xa3;
  	if (vendor_id != expected) {
  		dev_dbg(&adapter->dev,
  			"w83795: Detection failed at addr 0x%02hx, check %s
  ",
  			address, "vendor id");
792d376b4   Wei Song   hwmon: New driver...
1874
1875
  		return -ENODEV;
  	}
2be381de0   Jean Delvare   hwmon: (w83795) I...
1876
1877
1878
1879
1880
1881
1882
1883
1884
  	/* Check device ID */
  	device_id = w83795_get_device_id(client) |
  		    (i2c_smbus_read_byte_data(client, W83795_REG_CHIPID) << 8);
  	if ((device_id >> 4) != 0x795) {
  		dev_dbg(&adapter->dev,
  			"w83795: Detection failed at addr 0x%02hx, check %s
  ",
  			address, "device id
  ");
792d376b4   Wei Song   hwmon: New driver...
1885
1886
  		return -ENODEV;
  	}
2be381de0   Jean Delvare   hwmon: (w83795) I...
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
  	/* If Nuvoton chip, address of chip and W83795_REG_I2C_ADDR
  	   should match */
  	if ((bank & 0x07) == 0) {
  		i2c_addr = i2c_smbus_read_byte_data(client,
  						    W83795_REG_I2C_ADDR);
  		if ((i2c_addr & 0x7f) != address) {
  			dev_dbg(&adapter->dev,
  				"w83795: Detection failed at addr 0x%02hx, "
  				"check %s
  ", address, "i2c addr");
  			return -ENODEV;
  		}
792d376b4   Wei Song   hwmon: New driver...
1899
  	}
093d1a479   Jean Delvare   hwmon: (w83795) D...
1900
1901
1902
1903
1904
1905
1906
  	/* Check 795 chip type: 795G or 795ADG
  	   Usually we don't write to chips during detection, but here we don't
  	   quite have the choice; hopefully it's OK, we are about to return
  	   success anyway */
  	if ((bank & 0x07) != 0)
  		i2c_smbus_write_byte_data(client, W83795_REG_BANKSEL,
  					  bank & ~0x07);
2be381de0   Jean Delvare   hwmon: (w83795) I...
1907
1908
  	config = i2c_smbus_read_byte_data(client, W83795_REG_CONFIG);
  	if (config & W83795_REG_CONFIG_CONFIG48)
093d1a479   Jean Delvare   hwmon: (w83795) D...
1909
  		chip_name = "w83795adg";
2be381de0   Jean Delvare   hwmon: (w83795) I...
1910
  	else
093d1a479   Jean Delvare   hwmon: (w83795) D...
1911
  		chip_name = "w83795g";
792d376b4   Wei Song   hwmon: New driver...
1912

093d1a479   Jean Delvare   hwmon: (w83795) D...
1913
  	strlcpy(info->type, chip_name, I2C_NAME_SIZE);
2be381de0   Jean Delvare   hwmon: (w83795) I...
1914
1915
1916
  	dev_info(&adapter->dev, "Found %s rev. %c at 0x%02hx
  ", chip_name,
  		 'A' + (device_id & 0xf), address);
792d376b4   Wei Song   hwmon: New driver...
1917
1918
1919
  
  	return 0;
  }
6f3dcde9c   Jean Delvare   hwmon: (w83795) M...
1920
1921
  static int w83795_handle_files(struct device *dev, int (*fn)(struct device *,
  			       const struct device_attribute *))
892514a63   Jean Delvare   hwmon: (w83795) M...
1922
1923
  {
  	struct w83795_data *data = dev_get_drvdata(dev);
87df0dad3   Jean Delvare   hwmon: (w83795) U...
1924
  	int err, i, j;
892514a63   Jean Delvare   hwmon: (w83795) M...
1925
1926
  
  	for (i = 0; i < ARRAY_SIZE(w83795_in); i++) {
87df0dad3   Jean Delvare   hwmon: (w83795) U...
1927
  		if (!(data->has_in & (1 << i)))
892514a63   Jean Delvare   hwmon: (w83795) M...
1928
  			continue;
87df0dad3   Jean Delvare   hwmon: (w83795) U...
1929
  		for (j = 0; j < ARRAY_SIZE(w83795_in[0]); j++) {
52d159eec   Jean Delvare   hwmon: (w83795) C...
1930
1931
  			if (j == 4 && !data->enable_beep)
  				continue;
87df0dad3   Jean Delvare   hwmon: (w83795) U...
1932
1933
1934
1935
  			err = fn(dev, &w83795_in[i][j].dev_attr);
  			if (err)
  				return err;
  		}
892514a63   Jean Delvare   hwmon: (w83795) M...
1936
1937
1938
  	}
  
  	for (i = 0; i < ARRAY_SIZE(w83795_fan); i++) {
87df0dad3   Jean Delvare   hwmon: (w83795) U...
1939
  		if (!(data->has_fan & (1 << i)))
892514a63   Jean Delvare   hwmon: (w83795) M...
1940
  			continue;
87df0dad3   Jean Delvare   hwmon: (w83795) U...
1941
  		for (j = 0; j < ARRAY_SIZE(w83795_fan[0]); j++) {
52d159eec   Jean Delvare   hwmon: (w83795) C...
1942
1943
  			if (j == 3 && !data->enable_beep)
  				continue;
87df0dad3   Jean Delvare   hwmon: (w83795) U...
1944
1945
1946
1947
  			err = fn(dev, &w83795_fan[i][j].dev_attr);
  			if (err)
  				return err;
  		}
892514a63   Jean Delvare   hwmon: (w83795) M...
1948
  	}
edff2f8d8   Jean Delvare   hwmon: (w83795) L...
1949
1950
1951
1952
1953
1954
1955
1956
  	for (i = 0; i < ARRAY_SIZE(w83795_tss); i++) {
  		j = w83795_tss_useful(data, i);
  		if (!j)
  			continue;
  		err = fn(dev, &w83795_tss[i].dev_attr);
  		if (err)
  			return err;
  	}
892514a63   Jean Delvare   hwmon: (w83795) M...
1957
  	for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) {
6f3dcde9c   Jean Delvare   hwmon: (w83795) M...
1958
  		err = fn(dev, &sda_single_files[i].dev_attr);
892514a63   Jean Delvare   hwmon: (w83795) M...
1959
1960
1961
  		if (err)
  			return err;
  	}
52d159eec   Jean Delvare   hwmon: (w83795) C...
1962
1963
1964
1965
1966
1967
1968
  	if (data->enable_beep) {
  		for (i = 0; i < ARRAY_SIZE(sda_beep_files); i++) {
  			err = fn(dev, &sda_beep_files[i].dev_attr);
  			if (err)
  				return err;
  		}
  	}
00030af23   Jean Delvare   hwmon: (w83795) E...
1969
  #ifdef CONFIG_SENSORS_W83795_FANCTRL
b5f6a90a0   Jean Delvare   hwmon: (w83795) M...
1970
1971
1972
  	for (i = 0; i < data->has_pwm; i++) {
  		for (j = 0; j < ARRAY_SIZE(w83795_pwm[0]); j++) {
  			err = fn(dev, &w83795_pwm[i][j].dev_attr);
892514a63   Jean Delvare   hwmon: (w83795) M...
1973
1974
1975
1976
  			if (err)
  				return err;
  		}
  	}
00030af23   Jean Delvare   hwmon: (w83795) E...
1977
  #endif
892514a63   Jean Delvare   hwmon: (w83795) M...
1978
1979
  
  	for (i = 0; i < ARRAY_SIZE(w83795_temp); i++) {
87df0dad3   Jean Delvare   hwmon: (w83795) U...
1980
  		if (!(data->has_temp & (1 << i)))
892514a63   Jean Delvare   hwmon: (w83795) M...
1981
  			continue;
00030af23   Jean Delvare   hwmon: (w83795) E...
1982
  #ifdef CONFIG_SENSORS_W83795_FANCTRL
87df0dad3   Jean Delvare   hwmon: (w83795) U...
1983
  		for (j = 0; j < ARRAY_SIZE(w83795_temp[0]); j++) {
00030af23   Jean Delvare   hwmon: (w83795) E...
1984
1985
1986
  #else
  		for (j = 0; j < 8; j++) {
  #endif
52d159eec   Jean Delvare   hwmon: (w83795) C...
1987
1988
  			if (j == 7 && !data->enable_beep)
  				continue;
87df0dad3   Jean Delvare   hwmon: (w83795) U...
1989
1990
1991
1992
  			err = fn(dev, &w83795_temp[i][j].dev_attr);
  			if (err)
  				return err;
  		}
892514a63   Jean Delvare   hwmon: (w83795) M...
1993
  	}
eb02755a5   Jean Delvare   hwmon: (w83795) M...
1994
  	if (data->enable_dts) {
892514a63   Jean Delvare   hwmon: (w83795) M...
1995
  		for (i = 0; i < ARRAY_SIZE(w83795_dts); i++) {
87df0dad3   Jean Delvare   hwmon: (w83795) U...
1996
  			if (!(data->has_dts & (1 << i)))
892514a63   Jean Delvare   hwmon: (w83795) M...
1997
  				continue;
87df0dad3   Jean Delvare   hwmon: (w83795) U...
1998
  			for (j = 0; j < ARRAY_SIZE(w83795_dts[0]); j++) {
52d159eec   Jean Delvare   hwmon: (w83795) C...
1999
2000
  				if (j == 7 && !data->enable_beep)
  					continue;
87df0dad3   Jean Delvare   hwmon: (w83795) U...
2001
2002
2003
2004
  				err = fn(dev, &w83795_dts[i][j].dev_attr);
  				if (err)
  					return err;
  			}
892514a63   Jean Delvare   hwmon: (w83795) M...
2005
2006
  		}
  	}
892514a63   Jean Delvare   hwmon: (w83795) M...
2007
2008
  	return 0;
  }
6f3dcde9c   Jean Delvare   hwmon: (w83795) M...
2009
2010
2011
  /* We need a wrapper that fits in w83795_handle_files */
  static int device_remove_file_wrapper(struct device *dev,
  				      const struct device_attribute *attr)
2fa09878b   Jean Delvare   hwmon: (w83795) M...
2012
  {
6f3dcde9c   Jean Delvare   hwmon: (w83795) M...
2013
2014
  	device_remove_file(dev, attr);
  	return 0;
2fa09878b   Jean Delvare   hwmon: (w83795) M...
2015
  }
0e256018b   Jean Delvare   hwmon: (w83795) A...
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
  static void w83795_check_dynamic_in_limits(struct i2c_client *client)
  {
  	struct w83795_data *data = i2c_get_clientdata(client);
  	u8 vid_ctl;
  	int i, err_max, err_min;
  
  	vid_ctl = w83795_read(client, W83795_REG_VID_CTRL);
  
  	/* Return immediately if VRM isn't configured */
  	if ((vid_ctl & 0x07) == 0x00 || (vid_ctl & 0x07) == 0x07)
  		return;
  
  	data->has_dyn_in = (vid_ctl >> 3) & 0x07;
  	for (i = 0; i < 2; i++) {
  		if (!(data->has_dyn_in & (1 << i)))
  			continue;
  
  		/* Voltage limits in dynamic mode, switch to read-only */
  		err_max = sysfs_chmod_file(&client->dev.kobj,
  					   &w83795_in[i][2].dev_attr.attr,
  					   S_IRUGO);
  		err_min = sysfs_chmod_file(&client->dev.kobj,
  					   &w83795_in[i][3].dev_attr.attr,
  					   S_IRUGO);
  		if (err_max || err_min)
  			dev_warn(&client->dev, "Failed to set in%d limits "
  				 "read-only (%d, %d)
  ", i, err_max, err_min);
  		else
  			dev_info(&client->dev, "in%d limits set dynamically "
  				 "from VID
  ", i);
  	}
  }
71caf46fb   Jean Delvare   hwmon: (w83795) C...
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
  /* Check pins that can be used for either temperature or voltage monitoring */
  static void w83795_apply_temp_config(struct w83795_data *data, u8 config,
  				     int temp_chan, int in_chan)
  {
  	/* config is a 2-bit value */
  	switch (config) {
  	case 0x2: /* Voltage monitoring */
  		data->has_in |= 1 << in_chan;
  		break;
  	case 0x1: /* Thermal diode */
  		if (temp_chan >= 4)
  			break;
  		data->temp_mode |= 1 << temp_chan;
  		/* fall through */
  	case 0x3: /* Thermistor */
  		data->has_temp |= 1 << temp_chan;
  		break;
  	}
  }
792d376b4   Wei Song   hwmon: New driver...
2069
2070
2071
2072
2073
2074
2075
  static int w83795_probe(struct i2c_client *client,
  			const struct i2c_device_id *id)
  {
  	int i;
  	u8 tmp;
  	struct device *dev = &client->dev;
  	struct w83795_data *data;
71caf46fb   Jean Delvare   hwmon: (w83795) C...
2076
  	int err;
792d376b4   Wei Song   hwmon: New driver...
2077
2078
2079
2080
2081
2082
2083
2084
  
  	data = kzalloc(sizeof(struct w83795_data), GFP_KERNEL);
  	if (!data) {
  		err = -ENOMEM;
  		goto exit;
  	}
  
  	i2c_set_clientdata(client, data);
093d1a479   Jean Delvare   hwmon: (w83795) D...
2085
  	data->chip_type = id->driver_data;
792d376b4   Wei Song   hwmon: New driver...
2086
2087
2088
2089
2090
  	data->bank = i2c_smbus_read_byte_data(client, W83795_REG_BANKSEL);
  	mutex_init(&data->update_lock);
  
  	/* Initialize the chip */
  	w83795_init_client(client);
71caf46fb   Jean Delvare   hwmon: (w83795) C...
2091
2092
2093
2094
2095
  	/* Check which voltages and fans are present */
  	data->has_in = w83795_read(client, W83795_REG_VOLT_CTRL1)
  		     | (w83795_read(client, W83795_REG_VOLT_CTRL2) << 8);
  	data->has_fan = w83795_read(client, W83795_REG_FANIN_CTRL1)
  		      | (w83795_read(client, W83795_REG_FANIN_CTRL2) << 8);
792d376b4   Wei Song   hwmon: New driver...
2096

71caf46fb   Jean Delvare   hwmon: (w83795) C...
2097
  	/* Check which analog temperatures and extra voltages are present */
792d376b4   Wei Song   hwmon: New driver...
2098
2099
2100
  	tmp = w83795_read(client, W83795_REG_TEMP_CTRL1);
  	if (tmp & 0x20)
  		data->enable_dts = 1;
71caf46fb   Jean Delvare   hwmon: (w83795) C...
2101
2102
  	w83795_apply_temp_config(data, (tmp >> 2) & 0x3, 5, 16);
  	w83795_apply_temp_config(data, tmp & 0x3, 4, 15);
792d376b4   Wei Song   hwmon: New driver...
2103
  	tmp = w83795_read(client, W83795_REG_TEMP_CTRL2);
71caf46fb   Jean Delvare   hwmon: (w83795) C...
2104
2105
2106
2107
  	w83795_apply_temp_config(data, tmp >> 6, 3, 20);
  	w83795_apply_temp_config(data, (tmp >> 4) & 0x3, 2, 19);
  	w83795_apply_temp_config(data, (tmp >> 2) & 0x3, 1, 18);
  	w83795_apply_temp_config(data, tmp & 0x3, 0, 17);
792d376b4   Wei Song   hwmon: New driver...
2108
2109
  
  	/* Check DTS enable status */
71caf46fb   Jean Delvare   hwmon: (w83795) C...
2110
  	if (data->enable_dts) {
792d376b4   Wei Song   hwmon: New driver...
2111
2112
2113
2114
  		if (1 & w83795_read(client, W83795_REG_DTSC))
  			data->enable_dts |= 2;
  		data->has_dts = w83795_read(client, W83795_REG_DTSE);
  	}
54891a3c1   Jean Delvare   hwmon: (w83795) R...
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
  	/* Report PECI Tbase values */
  	if (data->enable_dts == 1) {
  		for (i = 0; i < 8; i++) {
  			if (!(data->has_dts & (1 << i)))
  				continue;
  			tmp = w83795_read(client, W83795_REG_PECI_TBASE(i));
  			dev_info(&client->dev,
  				 "PECI agent %d Tbase temperature: %u
  ",
  				 i + 1, (unsigned int)tmp & 0x7f);
  		}
  	}
792d376b4   Wei Song   hwmon: New driver...
2127
  	data->has_gain = w83795_read(client, W83795_REG_VMIGB_CTRL) & 0x0f;
792d376b4   Wei Song   hwmon: New driver...
2128
2129
2130
2131
2132
2133
  
  	/* pwm and smart fan */
  	if (data->chip_type == w83795g)
  		data->has_pwm = 8;
  	else
  		data->has_pwm = 2;
792d376b4   Wei Song   hwmon: New driver...
2134

52d159eec   Jean Delvare   hwmon: (w83795) C...
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
  	/* Check if BEEP pin is available */
  	if (data->chip_type == w83795g) {
  		/* The W83795G has a dedicated BEEP pin */
  		data->enable_beep = 1;
  	} else {
  		/* The W83795ADG has a shared pin for OVT# and BEEP, so you
  		 * can't have both */
  		tmp = w83795_read(client, W83795_REG_OVT_CFG);
  		if ((tmp & OVT_CFG_SEL) == 0)
  			data->enable_beep = 1;
  	}
6f3dcde9c   Jean Delvare   hwmon: (w83795) M...
2146
  	err = w83795_handle_files(dev, device_create_file);
892514a63   Jean Delvare   hwmon: (w83795) M...
2147
2148
  	if (err)
  		goto exit_remove;
792d376b4   Wei Song   hwmon: New driver...
2149

0e256018b   Jean Delvare   hwmon: (w83795) A...
2150
2151
  	if (data->chip_type == w83795g)
  		w83795_check_dynamic_in_limits(client);
792d376b4   Wei Song   hwmon: New driver...
2152
2153
2154
2155
2156
2157
2158
  	data->hwmon_dev = hwmon_device_register(dev);
  	if (IS_ERR(data->hwmon_dev)) {
  		err = PTR_ERR(data->hwmon_dev);
  		goto exit_remove;
  	}
  
  	return 0;
792d376b4   Wei Song   hwmon: New driver...
2159
  exit_remove:
6f3dcde9c   Jean Delvare   hwmon: (w83795) M...
2160
  	w83795_handle_files(dev, device_remove_file_wrapper);
792d376b4   Wei Song   hwmon: New driver...
2161
2162
2163
2164
2165
2166
2167
2168
  	kfree(data);
  exit:
  	return err;
  }
  
  static int w83795_remove(struct i2c_client *client)
  {
  	struct w83795_data *data = i2c_get_clientdata(client);
792d376b4   Wei Song   hwmon: New driver...
2169
2170
  
  	hwmon_device_unregister(data->hwmon_dev);
6f3dcde9c   Jean Delvare   hwmon: (w83795) M...
2171
  	w83795_handle_files(&client->dev, device_remove_file_wrapper);
792d376b4   Wei Song   hwmon: New driver...
2172
2173
2174
2175
2176
2177
2178
  	kfree(data);
  
  	return 0;
  }
  
  
  static const struct i2c_device_id w83795_id[] = {
093d1a479   Jean Delvare   hwmon: (w83795) D...
2179
2180
  	{ "w83795g", w83795g },
  	{ "w83795adg", w83795adg },
792d376b4   Wei Song   hwmon: New driver...
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
  	{ }
  };
  MODULE_DEVICE_TABLE(i2c, w83795_id);
  
  static struct i2c_driver w83795_driver = {
  	.driver = {
  		   .name = "w83795",
  	},
  	.probe		= w83795_probe,
  	.remove		= w83795_remove,
  	.id_table	= w83795_id,
  
  	.class		= I2C_CLASS_HWMON,
  	.detect		= w83795_detect,
  	.address_list	= normal_i2c,
  };
  
  static int __init sensors_w83795_init(void)
  {
  	return i2c_add_driver(&w83795_driver);
  }
  
  static void __exit sensors_w83795_exit(void)
  {
  	i2c_del_driver(&w83795_driver);
  }
e3760b432   Jean Delvare   hwmon: (w83795) A...
2207
  MODULE_AUTHOR("Wei Song, Jean Delvare <khali@linux-fr.org>");
315bacfdb   Jean Delvare   hwmon: (w83795) M...
2208
  MODULE_DESCRIPTION("W83795G/ADG hardware monitoring driver");
792d376b4   Wei Song   hwmon: New driver...
2209
2210
2211
2212
  MODULE_LICENSE("GPL");
  
  module_init(sensors_w83795_init);
  module_exit(sensors_w83795_exit);