Blame view

drivers/hwmon/f75375s.c 24.7 KB
84f1e4429   Riku Voipio   hwmon: Add f75375...
1
  /*
f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
2
3
   * f75375s.c - driver for the Fintek F75375/SP, F75373 and
   *             F75387SG/RG hardware monitoring features
b26e0ed49   Riku Voipio   trivial: Update m...
4
   * Copyright (C) 2006-2007  Riku Voipio
84f1e4429   Riku Voipio   hwmon: Add f75375...
5
6
7
8
   *
   * Datasheets available at:
   *
   * f75375:
4fd826ef9   Guenter Roeck   hwmon: (f75375s) ...
9
   * http://www.fintek.com.tw/files/productfiles/F75375_V026P.pdf
84f1e4429   Riku Voipio   hwmon: Add f75375...
10
11
   *
   * f75373:
631dd1a88   Justin P. Mattock   Update broken web...
12
   * http://www.fintek.com.tw/files/productfiles/F75373_V025P.pdf
84f1e4429   Riku Voipio   hwmon: Add f75375...
13
   *
f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
14
15
16
   * f75387:
   * http://www.fintek.com.tw/files/productfiles/F75387_V027P.pdf
   *
84f1e4429   Riku Voipio   hwmon: Add f75375...
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; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   *
   */
  
  #include <linux/module.h>
  #include <linux/jiffies.h>
  #include <linux/hwmon.h>
  #include <linux/hwmon-sysfs.h>
  #include <linux/i2c.h>
  #include <linux/err.h>
  #include <linux/mutex.h>
ff312d07c   Riku Voipio   hwmon: (f75375s) ...
40
  #include <linux/f75375s.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
41
  #include <linux/slab.h>
84f1e4429   Riku Voipio   hwmon: Add f75375...
42
43
  
  /* Addresses to scan */
25e9c86d5   Mark M. Hoffman   hwmon: normal_i2c...
44
  static const unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END };
84f1e4429   Riku Voipio   hwmon: Add f75375...
45

f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
46
  enum chips { f75373, f75375, f75387 };
84f1e4429   Riku Voipio   hwmon: Add f75375...
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
  
  /* Fintek F75375 registers  */
  #define F75375_REG_CONFIG0		0x0
  #define F75375_REG_CONFIG1		0x1
  #define F75375_REG_CONFIG2		0x2
  #define F75375_REG_CONFIG3		0x3
  #define F75375_REG_ADDR			0x4
  #define F75375_REG_INTR			0x31
  #define F75375_CHIP_ID			0x5A
  #define F75375_REG_VERSION		0x5C
  #define F75375_REG_VENDOR		0x5D
  #define F75375_REG_FAN_TIMER		0x60
  
  #define F75375_REG_VOLT(nr)		(0x10 + (nr))
  #define F75375_REG_VOLT_HIGH(nr)	(0x20 + (nr) * 2)
  #define F75375_REG_VOLT_LOW(nr)		(0x21 + (nr) * 2)
  
  #define F75375_REG_TEMP(nr)		(0x14 + (nr))
f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
65
  #define F75387_REG_TEMP11_LSB(nr)	(0x1a + (nr))
84f1e4429   Riku Voipio   hwmon: Add f75375...
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
  #define F75375_REG_TEMP_HIGH(nr)	(0x28 + (nr) * 2)
  #define F75375_REG_TEMP_HYST(nr)	(0x29 + (nr) * 2)
  
  #define F75375_REG_FAN(nr)		(0x16 + (nr) * 2)
  #define F75375_REG_FAN_MIN(nr)		(0x2C + (nr) * 2)
  #define F75375_REG_FAN_FULL(nr)		(0x70 + (nr) * 0x10)
  #define F75375_REG_FAN_PWM_DUTY(nr)	(0x76 + (nr) * 0x10)
  #define F75375_REG_FAN_PWM_CLOCK(nr)	(0x7D + (nr) * 0x10)
  
  #define F75375_REG_FAN_EXP(nr)		(0x74 + (nr) * 0x10)
  #define F75375_REG_FAN_B_TEMP(nr, step)	((0xA0 + (nr) * 0x10) + (step))
  #define F75375_REG_FAN_B_SPEED(nr, step) \
  	((0xA5 + (nr) * 0x10) + (step) * 2)
  
  #define F75375_REG_PWM1_RAISE_DUTY	0x69
  #define F75375_REG_PWM2_RAISE_DUTY	0x6A
  #define F75375_REG_PWM1_DROP_DUTY	0x6B
  #define F75375_REG_PWM2_DROP_DUTY	0x6C
f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
84
85
  #define F75375_FAN_CTRL_LINEAR(nr)	(4 + nr)
  #define F75387_FAN_CTRL_LINEAR(nr)	(1 + ((nr) * 4))
96f364089   Guillem Jover   hwmon: (f75375s) ...
86
  #define FAN_CTRL_MODE(nr)		(4 + ((nr) * 2))
f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
87
88
  #define F75387_FAN_DUTY_MODE(nr)	(2 + ((nr) * 4))
  #define F75387_FAN_MANU_MODE(nr)	((nr) * 4)
84f1e4429   Riku Voipio   hwmon: Add f75375...
89
90
91
92
93
94
95
  
  /*
   * Data structures and manipulation thereof
   */
  
  struct f75375_data {
  	unsigned short addr;
1beeffe43   Tony Jones   hwmon: Convert fr...
96
  	struct device *hwmon_dev;
84f1e4429   Riku Voipio   hwmon: Add f75375...
97
98
99
100
101
102
103
104
105
106
107
108
109
110
  
  	const char *name;
  	int kind;
  	struct mutex update_lock; /* protect register access */
  	char valid;
  	unsigned long last_updated;	/* In jiffies */
  	unsigned long last_limits;	/* In jiffies */
  
  	/* Register values */
  	u8 in[4];
  	u8 in_max[4];
  	u8 in_min[4];
  	u16 fan[2];
  	u16 fan_min[2];
740f6be3c   Guenter Roeck   hwmon: (f75375s) ...
111
112
  	u16 fan_max[2];
  	u16 fan_target[2];
84f1e4429   Riku Voipio   hwmon: Add f75375...
113
114
115
116
  	u8 fan_timer;
  	u8 pwm[2];
  	u8 pwm_mode[2];
  	u8 pwm_enable[2];
f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
117
118
119
120
121
122
  	/*
  	 * f75387: For remote temperature reading, it uses signed 11-bit
  	 * values with LSB = 0.125 degree Celsius, left-justified in 16-bit
  	 * registers. For original 8-bit temp readings, the LSB just is 0.
  	 */
  	s16 temp11[2];
84f1e4429   Riku Voipio   hwmon: Add f75375...
123
124
125
  	s8 temp_high[2];
  	s8 temp_max_hyst[2];
  };
310ec7921   Jean Delvare   i2c: Drop the kin...
126
  static int f75375_detect(struct i2c_client *client,
935ada8c4   Jean Delvare   hwmon: (f75375s) ...
127
  			 struct i2c_board_info *info);
d2653e927   Jean Delvare   i2c: Add support ...
128
129
  static int f75375_probe(struct i2c_client *client,
  			const struct i2c_device_id *id);
620c142db   Riku Voipio   hwmon: (f75375s) ...
130
  static int f75375_remove(struct i2c_client *client);
84f1e4429   Riku Voipio   hwmon: Add f75375...
131

3760f7367   Jean Delvare   i2c: Convert most...
132
133
134
  static const struct i2c_device_id f75375_id[] = {
  	{ "f75373", f75373 },
  	{ "f75375", f75375 },
f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
135
  	{ "f75387", f75387 },
3760f7367   Jean Delvare   i2c: Convert most...
136
137
138
  	{ }
  };
  MODULE_DEVICE_TABLE(i2c, f75375_id);
620c142db   Riku Voipio   hwmon: (f75375s) ...
139
  static struct i2c_driver f75375_driver = {
935ada8c4   Jean Delvare   hwmon: (f75375s) ...
140
  	.class = I2C_CLASS_HWMON,
620c142db   Riku Voipio   hwmon: (f75375s) ...
141
142
143
144
145
  	.driver = {
  		.name = "f75375",
  	},
  	.probe = f75375_probe,
  	.remove = f75375_remove,
3760f7367   Jean Delvare   i2c: Convert most...
146
  	.id_table = f75375_id,
935ada8c4   Jean Delvare   hwmon: (f75375s) ...
147
  	.detect = f75375_detect,
c3813d6af   Jean Delvare   i2c: Get rid of s...
148
  	.address_list = normal_i2c,
620c142db   Riku Voipio   hwmon: (f75375s) ...
149
  };
84f1e4429   Riku Voipio   hwmon: Add f75375...
150
151
152
153
154
155
156
157
  static inline int f75375_read8(struct i2c_client *client, u8 reg)
  {
  	return i2c_smbus_read_byte_data(client, reg);
  }
  
  /* in most cases, should be called while holding update_lock */
  static inline u16 f75375_read16(struct i2c_client *client, u8 reg)
  {
4fd826ef9   Guenter Roeck   hwmon: (f75375s) ...
158
159
  	return (i2c_smbus_read_byte_data(client, reg) << 8)
  		| i2c_smbus_read_byte_data(client, reg + 1);
84f1e4429   Riku Voipio   hwmon: Add f75375...
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
  }
  
  static inline void f75375_write8(struct i2c_client *client, u8 reg,
  		u8 value)
  {
  	i2c_smbus_write_byte_data(client, reg, value);
  }
  
  static inline void f75375_write16(struct i2c_client *client, u8 reg,
  		u16 value)
  {
  	int err = i2c_smbus_write_byte_data(client, reg, (value << 8));
  	if (err)
  		return;
  	i2c_smbus_write_byte_data(client, reg + 1, (value & 0xFF));
  }
  
  static struct f75375_data *f75375_update_device(struct device *dev)
  {
  	struct i2c_client *client = to_i2c_client(dev);
  	struct f75375_data *data = i2c_get_clientdata(client);
  	int nr;
  
  	mutex_lock(&data->update_lock);
  
  	/* Limit registers cache is refreshed after 60 seconds */
  	if (time_after(jiffies, data->last_limits + 60 * HZ)
  		|| !data->valid) {
  		for (nr = 0; nr < 2; nr++) {
  			data->temp_high[nr] =
  				f75375_read8(client, F75375_REG_TEMP_HIGH(nr));
  			data->temp_max_hyst[nr] =
  				f75375_read8(client, F75375_REG_TEMP_HYST(nr));
740f6be3c   Guenter Roeck   hwmon: (f75375s) ...
193
  			data->fan_max[nr] =
84f1e4429   Riku Voipio   hwmon: Add f75375...
194
195
196
  				f75375_read16(client, F75375_REG_FAN_FULL(nr));
  			data->fan_min[nr] =
  				f75375_read16(client, F75375_REG_FAN_MIN(nr));
740f6be3c   Guenter Roeck   hwmon: (f75375s) ...
197
  			data->fan_target[nr] =
84f1e4429   Riku Voipio   hwmon: Add f75375...
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
  				f75375_read16(client, F75375_REG_FAN_EXP(nr));
  			data->pwm[nr] =	f75375_read8(client,
  				F75375_REG_FAN_PWM_DUTY(nr));
  
  		}
  		for (nr = 0; nr < 4; nr++) {
  			data->in_max[nr] =
  				f75375_read8(client, F75375_REG_VOLT_HIGH(nr));
  			data->in_min[nr] =
  				f75375_read8(client, F75375_REG_VOLT_LOW(nr));
  		}
  		data->fan_timer = f75375_read8(client, F75375_REG_FAN_TIMER);
  		data->last_limits = jiffies;
  	}
  
  	/* Measurement registers cache is refreshed after 2 second */
  	if (time_after(jiffies, data->last_updated + 2 * HZ)
  		|| !data->valid) {
  		for (nr = 0; nr < 2; nr++) {
f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
217
218
219
220
221
222
223
224
  			/* assign MSB, therefore shift it by 8 bits */
  			data->temp11[nr] =
  				f75375_read8(client, F75375_REG_TEMP(nr)) << 8;
  			if (data->kind == f75387)
  				/* merge F75387's temperature LSB (11-bit) */
  				data->temp11[nr] |=
  					f75375_read8(client,
  						     F75387_REG_TEMP11_LSB(nr));
84f1e4429   Riku Voipio   hwmon: Add f75375...
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
  			data->fan[nr] =
  				f75375_read16(client, F75375_REG_FAN(nr));
  		}
  		for (nr = 0; nr < 4; nr++)
  			data->in[nr] =
  				f75375_read8(client, F75375_REG_VOLT(nr));
  
  		data->last_updated = jiffies;
  		data->valid = 1;
  	}
  
  	mutex_unlock(&data->update_lock);
  	return data;
  }
  
  static inline u16 rpm_from_reg(u16 reg)
  {
  	if (reg == 0 || reg == 0xffff)
  		return 0;
4fd826ef9   Guenter Roeck   hwmon: (f75375s) ...
244
  	return 1500000 / reg;
84f1e4429   Riku Voipio   hwmon: Add f75375...
245
246
247
248
249
250
  }
  
  static inline u16 rpm_to_reg(int rpm)
  {
  	if (rpm < 367 || rpm > 0xffff)
  		return 0xffff;
4fd826ef9   Guenter Roeck   hwmon: (f75375s) ...
251
  	return 1500000 / rpm;
84f1e4429   Riku Voipio   hwmon: Add f75375...
252
253
254
255
256
257
258
259
  }
  
  static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
  		const char *buf, size_t count)
  {
  	int nr = to_sensor_dev_attr(attr)->index;
  	struct i2c_client *client = to_i2c_client(dev);
  	struct f75375_data *data = i2c_get_clientdata(client);
4fd826ef9   Guenter Roeck   hwmon: (f75375s) ...
260
261
262
263
264
265
  	unsigned long val;
  	int err;
  
  	err = kstrtoul(buf, 10, &val);
  	if (err < 0)
  		return err;
84f1e4429   Riku Voipio   hwmon: Add f75375...
266
267
268
269
270
271
272
  
  	mutex_lock(&data->update_lock);
  	data->fan_min[nr] = rpm_to_reg(val);
  	f75375_write16(client, F75375_REG_FAN_MIN(nr), data->fan_min[nr]);
  	mutex_unlock(&data->update_lock);
  	return count;
  }
740f6be3c   Guenter Roeck   hwmon: (f75375s) ...
273
  static ssize_t set_fan_target(struct device *dev, struct device_attribute *attr,
84f1e4429   Riku Voipio   hwmon: Add f75375...
274
275
276
277
278
  		const char *buf, size_t count)
  {
  	int nr = to_sensor_dev_attr(attr)->index;
  	struct i2c_client *client = to_i2c_client(dev);
  	struct f75375_data *data = i2c_get_clientdata(client);
4fd826ef9   Guenter Roeck   hwmon: (f75375s) ...
279
280
281
282
283
284
  	unsigned long val;
  	int err;
  
  	err = kstrtoul(buf, 10, &val);
  	if (err < 0)
  		return err;
84f1e4429   Riku Voipio   hwmon: Add f75375...
285
286
  
  	mutex_lock(&data->update_lock);
740f6be3c   Guenter Roeck   hwmon: (f75375s) ...
287
288
  	data->fan_target[nr] = rpm_to_reg(val);
  	f75375_write16(client, F75375_REG_FAN_EXP(nr), data->fan_target[nr]);
84f1e4429   Riku Voipio   hwmon: Add f75375...
289
290
291
292
293
294
295
296
297
298
  	mutex_unlock(&data->update_lock);
  	return count;
  }
  
  static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
  		const char *buf, size_t count)
  {
  	int nr = to_sensor_dev_attr(attr)->index;
  	struct i2c_client *client = to_i2c_client(dev);
  	struct f75375_data *data = i2c_get_clientdata(client);
4fd826ef9   Guenter Roeck   hwmon: (f75375s) ...
299
300
301
302
303
304
  	unsigned long val;
  	int err;
  
  	err = kstrtoul(buf, 10, &val);
  	if (err < 0)
  		return err;
84f1e4429   Riku Voipio   hwmon: Add f75375...
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
  
  	mutex_lock(&data->update_lock);
  	data->pwm[nr] = SENSORS_LIMIT(val, 0, 255);
  	f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), data->pwm[nr]);
  	mutex_unlock(&data->update_lock);
  	return count;
  }
  
  static ssize_t show_pwm_enable(struct device *dev, struct device_attribute
  		*attr, char *buf)
  {
  	int nr = to_sensor_dev_attr(attr)->index;
  	struct f75375_data *data = f75375_update_device(dev);
  	return sprintf(buf, "%d
  ", data->pwm_enable[nr]);
  }
ff312d07c   Riku Voipio   hwmon: (f75375s) ...
321
  static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val)
84f1e4429   Riku Voipio   hwmon: Add f75375...
322
  {
84f1e4429   Riku Voipio   hwmon: Add f75375...
323
  	struct f75375_data *data = i2c_get_clientdata(client);
84f1e4429   Riku Voipio   hwmon: Add f75375...
324
  	u8 fanmode;
3310600aa   Guenter Roeck   hwmon: (f75375s) ...
325
  	if (val < 0 || val > 3)
84f1e4429   Riku Voipio   hwmon: Add f75375...
326
  		return -EINVAL;
84f1e4429   Riku Voipio   hwmon: Add f75375...
327
  	fanmode = f75375_read8(client, F75375_REG_FAN_TIMER);
f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
  	if (data->kind == f75387) {
  		/* clear each fanX_mode bit before setting them properly */
  		fanmode &= ~(1 << F75387_FAN_DUTY_MODE(nr));
  		fanmode &= ~(1 << F75387_FAN_MANU_MODE(nr));
  		switch (val) {
  		case 0: /* full speed */
  			fanmode |= (1 << F75387_FAN_MANU_MODE(nr));
  			fanmode |= (1 << F75387_FAN_DUTY_MODE(nr));
  			data->pwm[nr] = 255;
  			f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr),
  					data->pwm[nr]);
  			break;
  		case 1: /* PWM */
  			fanmode  |= (1 << F75387_FAN_MANU_MODE(nr));
  			fanmode  |= (1 << F75387_FAN_DUTY_MODE(nr));
  			break;
  		case 2: /* AUTOMATIC*/
  			fanmode  |=  (1 << F75387_FAN_DUTY_MODE(nr));
  			break;
  		case 3: /* fan speed */
  			fanmode |= (1 << F75387_FAN_MANU_MODE(nr));
  			break;
  		}
  	} else {
  		/* clear each fanX_mode bit before setting them properly */
  		fanmode &= ~(3 << FAN_CTRL_MODE(nr));
  		switch (val) {
  		case 0: /* full speed */
  			fanmode  |= (3 << FAN_CTRL_MODE(nr));
  			data->pwm[nr] = 255;
  			f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr),
  					data->pwm[nr]);
  			break;
  		case 1: /* PWM */
  			fanmode  |= (3 << FAN_CTRL_MODE(nr));
  			break;
  		case 2: /* AUTOMATIC*/
  			fanmode  |= (2 << FAN_CTRL_MODE(nr));
  			break;
  		case 3: /* fan speed */
  			break;
  		}
84f1e4429   Riku Voipio   hwmon: Add f75375...
370
  	}
f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
371

84f1e4429   Riku Voipio   hwmon: Add f75375...
372
373
  	f75375_write8(client, F75375_REG_FAN_TIMER, fanmode);
  	data->pwm_enable[nr] = val;
ff312d07c   Riku Voipio   hwmon: (f75375s) ...
374
375
376
377
378
379
380
381
382
  	return 0;
  }
  
  static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
  		const char *buf, size_t count)
  {
  	int nr = to_sensor_dev_attr(attr)->index;
  	struct i2c_client *client = to_i2c_client(dev);
  	struct f75375_data *data = i2c_get_clientdata(client);
4fd826ef9   Guenter Roeck   hwmon: (f75375s) ...
383
384
385
386
387
388
  	unsigned long val;
  	int err;
  
  	err = kstrtoul(buf, 10, &val);
  	if (err < 0)
  		return err;
ff312d07c   Riku Voipio   hwmon: (f75375s) ...
389
390
391
  
  	mutex_lock(&data->update_lock);
  	err = set_pwm_enable_direct(client, nr, val);
84f1e4429   Riku Voipio   hwmon: Add f75375...
392
  	mutex_unlock(&data->update_lock);
ff312d07c   Riku Voipio   hwmon: (f75375s) ...
393
  	return err ? err : count;
84f1e4429   Riku Voipio   hwmon: Add f75375...
394
395
396
397
398
399
400
401
  }
  
  static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *attr,
  		const char *buf, size_t count)
  {
  	int nr = to_sensor_dev_attr(attr)->index;
  	struct i2c_client *client = to_i2c_client(dev);
  	struct f75375_data *data = i2c_get_clientdata(client);
4fd826ef9   Guenter Roeck   hwmon: (f75375s) ...
402
403
404
  	unsigned long val;
  	int err;
  	u8 conf;
f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
405
  	char reg, ctrl;
4fd826ef9   Guenter Roeck   hwmon: (f75375s) ...
406
407
408
409
  
  	err = kstrtoul(buf, 10, &val);
  	if (err < 0)
  		return err;
84f1e4429   Riku Voipio   hwmon: Add f75375...
410

76e83bef1   Riku Voipio   hwmon: (f75375s) ...
411
  	if (!(val == 0 || val == 1))
84f1e4429   Riku Voipio   hwmon: Add f75375...
412
  		return -EINVAL;
5cd3222a9   Guenter Roeck   hwmon: (f75375s) ...
413
414
415
  	/* F75373 does not support DC (linear voltage) fan control mode */
  	if (data->kind == f75373 && val == 0)
  		return -EINVAL;
f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
416
417
418
419
420
421
422
423
  	/* take care for different registers */
  	if (data->kind == f75387) {
  		reg = F75375_REG_FAN_TIMER;
  		ctrl = F75387_FAN_CTRL_LINEAR(nr);
  	} else {
  		reg = F75375_REG_CONFIG1;
  		ctrl = F75375_FAN_CTRL_LINEAR(nr);
  	}
84f1e4429   Riku Voipio   hwmon: Add f75375...
424
  	mutex_lock(&data->update_lock);
f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
425
426
  	conf = f75375_read8(client, reg);
  	conf &= ~(1 << ctrl);
84f1e4429   Riku Voipio   hwmon: Add f75375...
427
428
  
  	if (val == 0)
f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
429
  		conf |= (1 << ctrl);
84f1e4429   Riku Voipio   hwmon: Add f75375...
430

f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
431
  	f75375_write8(client, reg, conf);
84f1e4429   Riku Voipio   hwmon: Add f75375...
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
  	data->pwm_mode[nr] = val;
  	mutex_unlock(&data->update_lock);
  	return count;
  }
  
  static ssize_t show_pwm(struct device *dev, struct device_attribute
  		*attr, char *buf)
  {
  	int nr = to_sensor_dev_attr(attr)->index;
  	struct f75375_data *data = f75375_update_device(dev);
  	return sprintf(buf, "%d
  ", data->pwm[nr]);
  }
  
  static ssize_t show_pwm_mode(struct device *dev, struct device_attribute
  		*attr, char *buf)
  {
  	int nr = to_sensor_dev_attr(attr)->index;
  	struct f75375_data *data = f75375_update_device(dev);
  	return sprintf(buf, "%d
  ", data->pwm_mode[nr]);
  }
  
  #define VOLT_FROM_REG(val) ((val) * 8)
  #define VOLT_TO_REG(val) ((val) / 8)
  
  static ssize_t show_in(struct device *dev, struct device_attribute *attr,
  		char *buf)
  {
  	int nr = to_sensor_dev_attr(attr)->index;
  	struct f75375_data *data = f75375_update_device(dev);
  	return sprintf(buf, "%d
  ", VOLT_FROM_REG(data->in[nr]));
  }
  
  static ssize_t show_in_max(struct device *dev, struct device_attribute *attr,
  		char *buf)
  {
  	int nr = to_sensor_dev_attr(attr)->index;
  	struct f75375_data *data = f75375_update_device(dev);
  	return sprintf(buf, "%d
  ", VOLT_FROM_REG(data->in_max[nr]));
  }
  
  static ssize_t show_in_min(struct device *dev, struct device_attribute *attr,
  		char *buf)
  {
  	int nr = to_sensor_dev_attr(attr)->index;
  	struct f75375_data *data = f75375_update_device(dev);
  	return sprintf(buf, "%d
  ", VOLT_FROM_REG(data->in_min[nr]));
  }
  
  static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
  		const char *buf, size_t count)
  {
  	int nr = to_sensor_dev_attr(attr)->index;
  	struct i2c_client *client = to_i2c_client(dev);
  	struct f75375_data *data = i2c_get_clientdata(client);
4fd826ef9   Guenter Roeck   hwmon: (f75375s) ...
491
492
493
494
495
496
  	unsigned long val;
  	int err;
  
  	err = kstrtoul(buf, 10, &val);
  	if (err < 0)
  		return err;
84f1e4429   Riku Voipio   hwmon: Add f75375...
497
498
499
500
501
502
503
504
505
506
507
508
509
510
  	val = SENSORS_LIMIT(VOLT_TO_REG(val), 0, 0xff);
  	mutex_lock(&data->update_lock);
  	data->in_max[nr] = val;
  	f75375_write8(client, F75375_REG_VOLT_HIGH(nr), data->in_max[nr]);
  	mutex_unlock(&data->update_lock);
  	return count;
  }
  
  static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
  		const char *buf, size_t count)
  {
  	int nr = to_sensor_dev_attr(attr)->index;
  	struct i2c_client *client = to_i2c_client(dev);
  	struct f75375_data *data = i2c_get_clientdata(client);
4fd826ef9   Guenter Roeck   hwmon: (f75375s) ...
511
512
513
514
515
516
  	unsigned long val;
  	int err;
  
  	err = kstrtoul(buf, 10, &val);
  	if (err < 0)
  		return err;
84f1e4429   Riku Voipio   hwmon: Add f75375...
517
518
519
520
521
522
523
524
525
  	val = SENSORS_LIMIT(VOLT_TO_REG(val), 0, 0xff);
  	mutex_lock(&data->update_lock);
  	data->in_min[nr] = val;
  	f75375_write8(client, F75375_REG_VOLT_LOW(nr), data->in_min[nr]);
  	mutex_unlock(&data->update_lock);
  	return count;
  }
  #define TEMP_FROM_REG(val) ((val) * 1000)
  #define TEMP_TO_REG(val) ((val) / 1000)
f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
526
  #define TEMP11_FROM_REG(reg)	((reg) / 32 * 125)
84f1e4429   Riku Voipio   hwmon: Add f75375...
527

f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
528
  static ssize_t show_temp11(struct device *dev, struct device_attribute *attr,
84f1e4429   Riku Voipio   hwmon: Add f75375...
529
530
531
532
  		char *buf)
  {
  	int nr = to_sensor_dev_attr(attr)->index;
  	struct f75375_data *data = f75375_update_device(dev);
f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
533
534
  	return sprintf(buf, "%d
  ", TEMP11_FROM_REG(data->temp11[nr]));
84f1e4429   Riku Voipio   hwmon: Add f75375...
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
  }
  
  static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr,
  		char *buf)
  {
  	int nr = to_sensor_dev_attr(attr)->index;
  	struct f75375_data *data = f75375_update_device(dev);
  	return sprintf(buf, "%d
  ", TEMP_FROM_REG(data->temp_high[nr]));
  }
  
  static ssize_t show_temp_max_hyst(struct device *dev,
  		struct device_attribute *attr, char *buf)
  {
  	int nr = to_sensor_dev_attr(attr)->index;
  	struct f75375_data *data = f75375_update_device(dev);
  	return sprintf(buf, "%d
  ", TEMP_FROM_REG(data->temp_max_hyst[nr]));
  }
  
  static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
  		const char *buf, size_t count)
  {
  	int nr = to_sensor_dev_attr(attr)->index;
  	struct i2c_client *client = to_i2c_client(dev);
  	struct f75375_data *data = i2c_get_clientdata(client);
4fd826ef9   Guenter Roeck   hwmon: (f75375s) ...
561
562
563
564
565
566
  	unsigned long val;
  	int err;
  
  	err = kstrtoul(buf, 10, &val);
  	if (err < 0)
  		return err;
84f1e4429   Riku Voipio   hwmon: Add f75375...
567
568
569
570
571
572
573
574
575
576
577
578
579
580
  	val = SENSORS_LIMIT(TEMP_TO_REG(val), 0, 127);
  	mutex_lock(&data->update_lock);
  	data->temp_high[nr] = val;
  	f75375_write8(client, F75375_REG_TEMP_HIGH(nr), data->temp_high[nr]);
  	mutex_unlock(&data->update_lock);
  	return count;
  }
  
  static ssize_t set_temp_max_hyst(struct device *dev,
  	struct device_attribute *attr, const char *buf, size_t count)
  {
  	int nr = to_sensor_dev_attr(attr)->index;
  	struct i2c_client *client = to_i2c_client(dev);
  	struct f75375_data *data = i2c_get_clientdata(client);
4fd826ef9   Guenter Roeck   hwmon: (f75375s) ...
581
582
583
584
585
586
  	unsigned long val;
  	int err;
  
  	err = kstrtoul(buf, 10, &val);
  	if (err < 0)
  		return err;
84f1e4429   Riku Voipio   hwmon: Add f75375...
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
  	val = SENSORS_LIMIT(TEMP_TO_REG(val), 0, 127);
  	mutex_lock(&data->update_lock);
  	data->temp_max_hyst[nr] = val;
  	f75375_write8(client, F75375_REG_TEMP_HYST(nr),
  		data->temp_max_hyst[nr]);
  	mutex_unlock(&data->update_lock);
  	return count;
  }
  
  #define show_fan(thing) \
  static ssize_t show_##thing(struct device *dev, struct device_attribute *attr, \
  			char *buf)\
  {\
  	int nr = to_sensor_dev_attr(attr)->index;\
  	struct f75375_data *data = f75375_update_device(dev); \
  	return sprintf(buf, "%d
  ", rpm_from_reg(data->thing[nr])); \
  }
  
  show_fan(fan);
  show_fan(fan_min);
740f6be3c   Guenter Roeck   hwmon: (f75375s) ...
608
609
  show_fan(fan_max);
  show_fan(fan_target);
84f1e4429   Riku Voipio   hwmon: Add f75375...
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
  
  static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_in, NULL, 0);
  static SENSOR_DEVICE_ATTR(in0_max, S_IRUGO|S_IWUSR,
  	show_in_max, set_in_max, 0);
  static SENSOR_DEVICE_ATTR(in0_min, S_IRUGO|S_IWUSR,
  	show_in_min, set_in_min, 0);
  static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in, NULL, 1);
  static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO|S_IWUSR,
  	show_in_max, set_in_max, 1);
  static SENSOR_DEVICE_ATTR(in1_min, S_IRUGO|S_IWUSR,
  	show_in_min, set_in_min, 1);
  static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_in, NULL, 2);
  static SENSOR_DEVICE_ATTR(in2_max, S_IRUGO|S_IWUSR,
  	show_in_max, set_in_max, 2);
  static SENSOR_DEVICE_ATTR(in2_min, S_IRUGO|S_IWUSR,
  	show_in_min, set_in_min, 2);
  static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_in, NULL, 3);
  static SENSOR_DEVICE_ATTR(in3_max, S_IRUGO|S_IWUSR,
  	show_in_max, set_in_max, 3);
  static SENSOR_DEVICE_ATTR(in3_min, S_IRUGO|S_IWUSR,
  	show_in_min, set_in_min, 3);
f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
631
  static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp11, NULL, 0);
84f1e4429   Riku Voipio   hwmon: Add f75375...
632
633
634
635
  static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO|S_IWUSR,
  	show_temp_max_hyst, set_temp_max_hyst, 0);
  static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO|S_IWUSR,
  	show_temp_max, set_temp_max, 0);
f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
636
  static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 1);
84f1e4429   Riku Voipio   hwmon: Add f75375...
637
638
639
640
641
  static SENSOR_DEVICE_ATTR(temp2_max_hyst, S_IRUGO|S_IWUSR,
  	show_temp_max_hyst, set_temp_max_hyst, 1);
  static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO|S_IWUSR,
  	show_temp_max, set_temp_max, 1);
  static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
740f6be3c   Guenter Roeck   hwmon: (f75375s) ...
642
  static SENSOR_DEVICE_ATTR(fan1_max, S_IRUGO, show_fan_max, NULL, 0);
84f1e4429   Riku Voipio   hwmon: Add f75375...
643
644
  static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO|S_IWUSR,
  	show_fan_min, set_fan_min, 0);
740f6be3c   Guenter Roeck   hwmon: (f75375s) ...
645
646
  static SENSOR_DEVICE_ATTR(fan1_target, S_IRUGO|S_IWUSR,
  	show_fan_target, set_fan_target, 0);
84f1e4429   Riku Voipio   hwmon: Add f75375...
647
  static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1);
740f6be3c   Guenter Roeck   hwmon: (f75375s) ...
648
  static SENSOR_DEVICE_ATTR(fan2_max, S_IRUGO, show_fan_max, NULL, 1);
84f1e4429   Riku Voipio   hwmon: Add f75375...
649
650
  static SENSOR_DEVICE_ATTR(fan2_min, S_IRUGO|S_IWUSR,
  	show_fan_min, set_fan_min, 1);
740f6be3c   Guenter Roeck   hwmon: (f75375s) ...
651
652
  static SENSOR_DEVICE_ATTR(fan2_target, S_IRUGO|S_IWUSR,
  	show_fan_target, set_fan_target, 1);
84f1e4429   Riku Voipio   hwmon: Add f75375...
653
654
655
656
  static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO|S_IWUSR,
  	show_pwm, set_pwm, 0);
  static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO|S_IWUSR,
  	show_pwm_enable, set_pwm_enable, 0);
76e83bef1   Riku Voipio   hwmon: (f75375s) ...
657
  static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO,
84f1e4429   Riku Voipio   hwmon: Add f75375...
658
659
660
661
662
  	show_pwm_mode, set_pwm_mode, 0);
  static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR,
  	show_pwm, set_pwm, 1);
  static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO|S_IWUSR,
  	show_pwm_enable, set_pwm_enable, 1);
76e83bef1   Riku Voipio   hwmon: (f75375s) ...
663
  static SENSOR_DEVICE_ATTR(pwm2_mode, S_IRUGO,
84f1e4429   Riku Voipio   hwmon: Add f75375...
664
665
666
667
668
669
670
671
672
673
  	show_pwm_mode, set_pwm_mode, 1);
  
  static struct attribute *f75375_attributes[] = {
  	&sensor_dev_attr_temp1_input.dev_attr.attr,
  	&sensor_dev_attr_temp1_max.dev_attr.attr,
  	&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
  	&sensor_dev_attr_temp2_input.dev_attr.attr,
  	&sensor_dev_attr_temp2_max.dev_attr.attr,
  	&sensor_dev_attr_temp2_max_hyst.dev_attr.attr,
  	&sensor_dev_attr_fan1_input.dev_attr.attr,
740f6be3c   Guenter Roeck   hwmon: (f75375s) ...
674
  	&sensor_dev_attr_fan1_max.dev_attr.attr,
84f1e4429   Riku Voipio   hwmon: Add f75375...
675
  	&sensor_dev_attr_fan1_min.dev_attr.attr,
740f6be3c   Guenter Roeck   hwmon: (f75375s) ...
676
  	&sensor_dev_attr_fan1_target.dev_attr.attr,
84f1e4429   Riku Voipio   hwmon: Add f75375...
677
  	&sensor_dev_attr_fan2_input.dev_attr.attr,
740f6be3c   Guenter Roeck   hwmon: (f75375s) ...
678
  	&sensor_dev_attr_fan2_max.dev_attr.attr,
84f1e4429   Riku Voipio   hwmon: Add f75375...
679
  	&sensor_dev_attr_fan2_min.dev_attr.attr,
740f6be3c   Guenter Roeck   hwmon: (f75375s) ...
680
  	&sensor_dev_attr_fan2_target.dev_attr.attr,
84f1e4429   Riku Voipio   hwmon: Add f75375...
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
  	&sensor_dev_attr_pwm1.dev_attr.attr,
  	&sensor_dev_attr_pwm1_enable.dev_attr.attr,
  	&sensor_dev_attr_pwm1_mode.dev_attr.attr,
  	&sensor_dev_attr_pwm2.dev_attr.attr,
  	&sensor_dev_attr_pwm2_enable.dev_attr.attr,
  	&sensor_dev_attr_pwm2_mode.dev_attr.attr,
  	&sensor_dev_attr_in0_input.dev_attr.attr,
  	&sensor_dev_attr_in0_max.dev_attr.attr,
  	&sensor_dev_attr_in0_min.dev_attr.attr,
  	&sensor_dev_attr_in1_input.dev_attr.attr,
  	&sensor_dev_attr_in1_max.dev_attr.attr,
  	&sensor_dev_attr_in1_min.dev_attr.attr,
  	&sensor_dev_attr_in2_input.dev_attr.attr,
  	&sensor_dev_attr_in2_max.dev_attr.attr,
  	&sensor_dev_attr_in2_min.dev_attr.attr,
  	&sensor_dev_attr_in3_input.dev_attr.attr,
  	&sensor_dev_attr_in3_max.dev_attr.attr,
  	&sensor_dev_attr_in3_min.dev_attr.attr,
  	NULL
  };
  
  static const struct attribute_group f75375_group = {
  	.attrs = f75375_attributes,
  };
ff312d07c   Riku Voipio   hwmon: (f75375s) ...
705
706
707
708
  static void f75375_init(struct i2c_client *client, struct f75375_data *data,
  		struct f75375s_platform_data *f75375s_pdata)
  {
  	int nr;
b1b561a22   Guenter Roeck   hwmon: (f75375s) ...
709
710
711
712
713
714
715
716
  
  	if (!f75375s_pdata) {
  		u8 conf, mode;
  		int nr;
  
  		conf = f75375_read8(client, F75375_REG_CONFIG1);
  		mode = f75375_read8(client, F75375_REG_FAN_TIMER);
  		for (nr = 0; nr < 2; nr++) {
f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
  			if (data->kind == f75387) {
  				bool manu, duty;
  
  				if (!(conf & (1 << F75387_FAN_CTRL_LINEAR(nr))))
  					data->pwm_mode[nr] = 1;
  
  				manu = ((mode >> F75387_FAN_MANU_MODE(nr)) & 1);
  				duty = ((mode >> F75387_FAN_DUTY_MODE(nr)) & 1);
  				if (manu && duty)
  					/* speed */
  					data->pwm_enable[nr] = 3;
  				else if (!manu && duty)
  					/* automatic */
  					data->pwm_enable[nr] = 2;
  				else
  					/* manual */
  					data->pwm_enable[nr] = 1;
  			} else {
  				if (!(conf & (1 << F75375_FAN_CTRL_LINEAR(nr))))
  					data->pwm_mode[nr] = 1;
  
  				switch ((mode >> FAN_CTRL_MODE(nr)) & 3) {
  				case 0:		/* speed */
  					data->pwm_enable[nr] = 3;
  					break;
  				case 1:		/* automatic */
  					data->pwm_enable[nr] = 2;
  					break;
  				default:	/* manual */
  					data->pwm_enable[nr] = 1;
  					break;
  				}
b1b561a22   Guenter Roeck   hwmon: (f75375s) ...
749
750
751
752
  			}
  		}
  		return;
  	}
ff312d07c   Riku Voipio   hwmon: (f75375s) ...
753
754
755
756
757
758
759
760
761
  	set_pwm_enable_direct(client, 0, f75375s_pdata->pwm_enable[0]);
  	set_pwm_enable_direct(client, 1, f75375s_pdata->pwm_enable[1]);
  	for (nr = 0; nr < 2; nr++) {
  		data->pwm[nr] = SENSORS_LIMIT(f75375s_pdata->pwm[nr], 0, 255);
  		f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr),
  			data->pwm[nr]);
  	}
  
  }
d2653e927   Jean Delvare   i2c: Add support ...
762
763
  static int f75375_probe(struct i2c_client *client,
  		const struct i2c_device_id *id)
620c142db   Riku Voipio   hwmon: (f75375s) ...
764
  {
51b3e2700   Andrew Klossner   hwmon: (f75375s) ...
765
  	struct f75375_data *data;
ff312d07c   Riku Voipio   hwmon: (f75375s) ...
766
  	struct f75375s_platform_data *f75375s_pdata = client->dev.platform_data;
620c142db   Riku Voipio   hwmon: (f75375s) ...
767
768
769
770
771
  	int err;
  
  	if (!i2c_check_functionality(client->adapter,
  				I2C_FUNC_SMBUS_BYTE_DATA))
  		return -EIO;
4fd826ef9   Guenter Roeck   hwmon: (f75375s) ...
772
773
  	data = kzalloc(sizeof(struct f75375_data), GFP_KERNEL);
  	if (!data)
620c142db   Riku Voipio   hwmon: (f75375s) ...
774
775
776
  		return -ENOMEM;
  
  	i2c_set_clientdata(client, data);
620c142db   Riku Voipio   hwmon: (f75375s) ...
777
  	mutex_init(&data->update_lock);
3760f7367   Jean Delvare   i2c: Convert most...
778
  	data->kind = id->driver_data;
620c142db   Riku Voipio   hwmon: (f75375s) ...
779

4fd826ef9   Guenter Roeck   hwmon: (f75375s) ...
780
781
  	err = sysfs_create_group(&client->dev.kobj, &f75375_group);
  	if (err)
620c142db   Riku Voipio   hwmon: (f75375s) ...
782
  		goto exit_free;
76e83bef1   Riku Voipio   hwmon: (f75375s) ...
783
784
785
786
787
788
789
790
791
792
793
794
  	if (data->kind == f75375) {
  		err = sysfs_chmod_file(&client->dev.kobj,
  			&sensor_dev_attr_pwm1_mode.dev_attr.attr,
  			S_IRUGO | S_IWUSR);
  		if (err)
  			goto exit_remove;
  		err = sysfs_chmod_file(&client->dev.kobj,
  			&sensor_dev_attr_pwm2_mode.dev_attr.attr,
  			S_IRUGO | S_IWUSR);
  		if (err)
  			goto exit_remove;
  	}
620c142db   Riku Voipio   hwmon: (f75375s) ...
795
796
797
798
799
  	data->hwmon_dev = hwmon_device_register(&client->dev);
  	if (IS_ERR(data->hwmon_dev)) {
  		err = PTR_ERR(data->hwmon_dev);
  		goto exit_remove;
  	}
b1b561a22   Guenter Roeck   hwmon: (f75375s) ...
800
  	f75375_init(client, data, f75375s_pdata);
ff312d07c   Riku Voipio   hwmon: (f75375s) ...
801

620c142db   Riku Voipio   hwmon: (f75375s) ...
802
803
804
805
806
807
  	return 0;
  
  exit_remove:
  	sysfs_remove_group(&client->dev.kobj, &f75375_group);
  exit_free:
  	kfree(data);
620c142db   Riku Voipio   hwmon: (f75375s) ...
808
809
810
811
812
813
814
815
  	return err;
  }
  
  static int f75375_remove(struct i2c_client *client)
  {
  	struct f75375_data *data = i2c_get_clientdata(client);
  	hwmon_device_unregister(data->hwmon_dev);
  	sysfs_remove_group(&client->dev.kobj, &f75375_group);
84f1e4429   Riku Voipio   hwmon: Add f75375...
816
817
818
  	kfree(data);
  	return 0;
  }
935ada8c4   Jean Delvare   hwmon: (f75375s) ...
819
  /* Return 0 if detection is successful, -ENODEV otherwise */
310ec7921   Jean Delvare   i2c: Drop the kin...
820
  static int f75375_detect(struct i2c_client *client,
935ada8c4   Jean Delvare   hwmon: (f75375s) ...
821
  			 struct i2c_board_info *info)
84f1e4429   Riku Voipio   hwmon: Add f75375...
822
  {
935ada8c4   Jean Delvare   hwmon: (f75375s) ...
823
  	struct i2c_adapter *adapter = client->adapter;
52df6440a   Jean Delvare   hwmon: Clean up d...
824
825
826
  	u16 vendid, chipid;
  	u8 version;
  	const char *name;
84f1e4429   Riku Voipio   hwmon: Add f75375...
827

52df6440a   Jean Delvare   hwmon: Clean up d...
828
829
  	vendid = f75375_read16(client, F75375_REG_VENDOR);
  	chipid = f75375_read16(client, F75375_CHIP_ID);
f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
830
831
832
833
  	if (vendid != 0x1934)
  		return -ENODEV;
  
  	if (chipid == 0x0306)
84f1e4429   Riku Voipio   hwmon: Add f75375...
834
  		name = "f75375";
f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
835
  	else if (chipid == 0x0204)
84f1e4429   Riku Voipio   hwmon: Add f75375...
836
  		name = "f75373";
f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
837
838
  	else if (chipid == 0x0410)
  		name = "f75387";
52df6440a   Jean Delvare   hwmon: Clean up d...
839
840
841
842
  	else
  		return -ENODEV;
  
  	version = f75375_read8(client, F75375_REG_VERSION);
84f1e4429   Riku Voipio   hwmon: Add f75375...
843
844
  	dev_info(&adapter->dev, "found %s version: %02X
  ", name, version);
935ada8c4   Jean Delvare   hwmon: (f75375s) ...
845
  	strlcpy(info->type, name, I2C_NAME_SIZE);
84f1e4429   Riku Voipio   hwmon: Add f75375...
846

84f1e4429   Riku Voipio   hwmon: Add f75375...
847
  	return 0;
84f1e4429   Riku Voipio   hwmon: Add f75375...
848
849
850
851
  }
  
  static int __init sensors_f75375_init(void)
  {
935ada8c4   Jean Delvare   hwmon: (f75375s) ...
852
  	return i2c_add_driver(&f75375_driver);
84f1e4429   Riku Voipio   hwmon: Add f75375...
853
854
855
856
857
858
  }
  
  static void __exit sensors_f75375_exit(void)
  {
  	i2c_del_driver(&f75375_driver);
  }
b26e0ed49   Riku Voipio   trivial: Update m...
859
  MODULE_AUTHOR("Riku Voipio");
84f1e4429   Riku Voipio   hwmon: Add f75375...
860
  MODULE_LICENSE("GPL");
f58c44e69   Björn Gerhart   hwmon: (f75375s) ...
861
  MODULE_DESCRIPTION("F75373/F75375/F75387 hardware monitoring driver");
84f1e4429   Riku Voipio   hwmon: Add f75375...
862
863
864
  
  module_init(sensors_f75375_init);
  module_exit(sensors_f75375_exit);