hwmon: (w83l785ts) Fix multi-line comments
[deliverable/linux.git] / drivers / hwmon / w83l786ng.c
CommitLineData
85f03bcc
KL
1/*
2 w83l786ng.c - Linux kernel driver for hardware monitoring
3 Copyright (c) 2007 Kevin Lo <kevlo@kevlo.org>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation - version 2.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301 USA.
18*/
19
20/*
21 Supports following chips:
22
23 Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
24 w83l786ng 3 2 2 2 0x7b 0x5ca3 yes no
25*/
26
27#include <linux/module.h>
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <linux/i2c.h>
31#include <linux/hwmon.h>
32#include <linux/hwmon-vid.h>
33#include <linux/hwmon-sysfs.h>
34#include <linux/err.h>
35#include <linux/mutex.h>
36
37/* Addresses to scan */
25e9c86d 38static const unsigned short normal_i2c[] = { 0x2e, 0x2f, I2C_CLIENT_END };
85f03bcc
KL
39
40/* Insmod parameters */
85f03bcc 41
90ab5ee9 42static bool reset;
85f03bcc
KL
43module_param(reset, bool, 0);
44MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended");
45
46#define W83L786NG_REG_IN_MIN(nr) (0x2C + (nr) * 2)
47#define W83L786NG_REG_IN_MAX(nr) (0x2B + (nr) * 2)
48#define W83L786NG_REG_IN(nr) ((nr) + 0x20)
49
50#define W83L786NG_REG_FAN(nr) ((nr) + 0x28)
51#define W83L786NG_REG_FAN_MIN(nr) ((nr) + 0x3B)
52
53#define W83L786NG_REG_CONFIG 0x40
54#define W83L786NG_REG_ALARM1 0x41
ca3ccad8 55#define W83L786NG_REG_ALARM2 0x42
85f03bcc
KL
56#define W83L786NG_REG_GPIO_EN 0x47
57#define W83L786NG_REG_MAN_ID2 0x4C
58#define W83L786NG_REG_MAN_ID1 0x4D
59#define W83L786NG_REG_CHIP_ID 0x4E
60
61#define W83L786NG_REG_DIODE 0x53
62#define W83L786NG_REG_FAN_DIV 0x54
63#define W83L786NG_REG_FAN_CFG 0x80
64
65#define W83L786NG_REG_TOLERANCE 0x8D
66
67static const u8 W83L786NG_REG_TEMP[2][3] = {
68 { 0x25, /* TEMP 0 in DataSheet */
69 0x35, /* TEMP 0 Over in DataSheet */
70 0x36 }, /* TEMP 0 Hyst in DataSheet */
71 { 0x26, /* TEMP 1 in DataSheet */
72 0x37, /* TEMP 1 Over in DataSheet */
73 0x38 } /* TEMP 1 Hyst in DataSheet */
74};
75
76static const u8 W83L786NG_PWM_MODE_SHIFT[] = {6, 7};
77static const u8 W83L786NG_PWM_ENABLE_SHIFT[] = {2, 4};
78
79/* FAN Duty Cycle, be used to control */
80static const u8 W83L786NG_REG_PWM[] = {0x81, 0x87};
81
82
83static inline u8
84FAN_TO_REG(long rpm, int div)
85{
86 if (rpm == 0)
87 return 255;
88 rpm = SENSORS_LIMIT(rpm, 1, 1000000);
89 return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
90}
91
ca3ccad8 92#define FAN_FROM_REG(val, div) ((val) == 0 ? -1 : \
85f03bcc
KL
93 ((val) == 255 ? 0 : \
94 1350000 / ((val) * (div))))
95
96/* for temp */
ca3ccad8
GR
97#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val) < 0 ? \
98 (val) + 0x100 * 1000 \
99 : (val)) / 1000, 0, 0xff))
100#define TEMP_FROM_REG(val) (((val) & 0x80 ? \
101 (val) - 0x100 : (val)) * 1000)
85f03bcc
KL
102
103/* The analog voltage inputs have 8mV LSB. Since the sysfs output is
104 in mV as would be measured on the chip input pin, need to just
105 multiply/divide by 8 to translate from/to register values. */
ca3ccad8 106#define IN_TO_REG(val) (SENSORS_LIMIT((((val) + 4) / 8), 0, 255))
85f03bcc
KL
107#define IN_FROM_REG(val) ((val) * 8)
108
109#define DIV_FROM_REG(val) (1 << (val))
110
111static inline u8
112DIV_TO_REG(long val)
113{
114 int i;
115 val = SENSORS_LIMIT(val, 1, 128) >> 1;
116 for (i = 0; i < 7; i++) {
117 if (val == 0)
118 break;
119 val >>= 1;
120 }
7fe83ad8 121 return (u8)i;
85f03bcc
KL
122}
123
124struct w83l786ng_data {
85f03bcc
KL
125 struct device *hwmon_dev;
126 struct mutex update_lock;
127 char valid; /* !=0 if following fields are valid */
128 unsigned long last_updated; /* In jiffies */
129 unsigned long last_nonvolatile; /* In jiffies, last time we update the
130 nonvolatile registers */
131
132 u8 in[3];
133 u8 in_max[3];
134 u8 in_min[3];
135 u8 fan[2];
136 u8 fan_div[2];
137 u8 fan_min[2];
138 u8 temp_type[2];
139 u8 temp[2][3];
140 u8 pwm[2];
141 u8 pwm_mode[2]; /* 0->DC variable voltage
142 1->PWM variable duty cycle */
143
144 u8 pwm_enable[2]; /* 1->manual
145 2->thermal cruise (also called SmartFan I) */
146 u8 tolerance[2];
147};
148
33468e76
JD
149static int w83l786ng_probe(struct i2c_client *client,
150 const struct i2c_device_id *id);
310ec792 151static int w83l786ng_detect(struct i2c_client *client,
33468e76
JD
152 struct i2c_board_info *info);
153static int w83l786ng_remove(struct i2c_client *client);
85f03bcc
KL
154static void w83l786ng_init_client(struct i2c_client *client);
155static struct w83l786ng_data *w83l786ng_update_device(struct device *dev);
156
33468e76 157static const struct i2c_device_id w83l786ng_id[] = {
1f86df49 158 { "w83l786ng", 0 },
33468e76
JD
159 { }
160};
161MODULE_DEVICE_TABLE(i2c, w83l786ng_id);
162
85f03bcc 163static struct i2c_driver w83l786ng_driver = {
33468e76 164 .class = I2C_CLASS_HWMON,
85f03bcc
KL
165 .driver = {
166 .name = "w83l786ng",
167 },
33468e76
JD
168 .probe = w83l786ng_probe,
169 .remove = w83l786ng_remove,
170 .id_table = w83l786ng_id,
171 .detect = w83l786ng_detect,
c3813d6a 172 .address_list = normal_i2c,
85f03bcc
KL
173};
174
175static u8
176w83l786ng_read_value(struct i2c_client *client, u8 reg)
177{
178 return i2c_smbus_read_byte_data(client, reg);
179}
180
181static int
182w83l786ng_write_value(struct i2c_client *client, u8 reg, u8 value)
183{
184 return i2c_smbus_write_byte_data(client, reg, value);
185}
186
187/* following are the sysfs callback functions */
188#define show_in_reg(reg) \
189static ssize_t \
190show_##reg(struct device *dev, struct device_attribute *attr, \
ca3ccad8 191 char *buf) \
85f03bcc
KL
192{ \
193 int nr = to_sensor_dev_attr(attr)->index; \
194 struct w83l786ng_data *data = w83l786ng_update_device(dev); \
ca3ccad8 195 return sprintf(buf, "%d\n", IN_FROM_REG(data->reg[nr])); \
85f03bcc
KL
196}
197
198show_in_reg(in)
199show_in_reg(in_min)
200show_in_reg(in_max)
201
202#define store_in_reg(REG, reg) \
203static ssize_t \
ca3ccad8
GR
204store_in_##reg(struct device *dev, struct device_attribute *attr, \
205 const char *buf, size_t count) \
85f03bcc
KL
206{ \
207 int nr = to_sensor_dev_attr(attr)->index; \
208 struct i2c_client *client = to_i2c_client(dev); \
209 struct w83l786ng_data *data = i2c_get_clientdata(client); \
ca3ccad8
GR
210 unsigned long val; \
211 int err = kstrtoul(buf, 10, &val); \
212 if (err) \
213 return err; \
85f03bcc
KL
214 mutex_lock(&data->update_lock); \
215 data->in_##reg[nr] = IN_TO_REG(val); \
216 w83l786ng_write_value(client, W83L786NG_REG_IN_##REG(nr), \
217 data->in_##reg[nr]); \
218 mutex_unlock(&data->update_lock); \
219 return count; \
220}
221
222store_in_reg(MIN, min)
223store_in_reg(MAX, max)
224
225static struct sensor_device_attribute sda_in_input[] = {
226 SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0),
227 SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1),
228 SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2),
229};
230
231static struct sensor_device_attribute sda_in_min[] = {
232 SENSOR_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 0),
233 SENSOR_ATTR(in1_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 1),
234 SENSOR_ATTR(in2_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 2),
235};
236
237static struct sensor_device_attribute sda_in_max[] = {
238 SENSOR_ATTR(in0_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 0),
239 SENSOR_ATTR(in1_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 1),
240 SENSOR_ATTR(in2_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 2),
241};
242
243#define show_fan_reg(reg) \
244static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
245 char *buf) \
246{ \
247 int nr = to_sensor_dev_attr(attr)->index; \
248 struct w83l786ng_data *data = w83l786ng_update_device(dev); \
ca3ccad8
GR
249 return sprintf(buf, "%d\n", \
250 FAN_FROM_REG(data->fan[nr], DIV_FROM_REG(data->fan_div[nr]))); \
85f03bcc
KL
251}
252
253show_fan_reg(fan);
254show_fan_reg(fan_min);
255
256static ssize_t
257store_fan_min(struct device *dev, struct device_attribute *attr,
258 const char *buf, size_t count)
259{
260 int nr = to_sensor_dev_attr(attr)->index;
261 struct i2c_client *client = to_i2c_client(dev);
262 struct w83l786ng_data *data = i2c_get_clientdata(client);
ca3ccad8
GR
263 unsigned long val;
264 int err;
265
266 err = kstrtoul(buf, 10, &val);
267 if (err)
268 return err;
85f03bcc 269
85f03bcc
KL
270 mutex_lock(&data->update_lock);
271 data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
272 w83l786ng_write_value(client, W83L786NG_REG_FAN_MIN(nr),
273 data->fan_min[nr]);
274 mutex_unlock(&data->update_lock);
275
276 return count;
277}
278
279static ssize_t
280show_fan_div(struct device *dev, struct device_attribute *attr,
281 char *buf)
282{
283 int nr = to_sensor_dev_attr(attr)->index;
284 struct w83l786ng_data *data = w83l786ng_update_device(dev);
285 return sprintf(buf, "%u\n", DIV_FROM_REG(data->fan_div[nr]));
286}
287
288/* Note: we save and restore the fan minimum here, because its value is
289 determined in part by the fan divisor. This follows the principle of
290 least surprise; the user doesn't expect the fan minimum to change just
291 because the divisor changed. */
292static ssize_t
293store_fan_div(struct device *dev, struct device_attribute *attr,
294 const char *buf, size_t count)
295{
296 int nr = to_sensor_dev_attr(attr)->index;
297 struct i2c_client *client = to_i2c_client(dev);
298 struct w83l786ng_data *data = i2c_get_clientdata(client);
299
300 unsigned long min;
301 u8 tmp_fan_div;
302 u8 fan_div_reg;
303 u8 keep_mask = 0;
304 u8 new_shift = 0;
305
ca3ccad8
GR
306 unsigned long val;
307 int err;
308
309 err = kstrtoul(buf, 10, &val);
310 if (err)
311 return err;
312
85f03bcc
KL
313 /* Save fan_min */
314 mutex_lock(&data->update_lock);
315 min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr]));
316
ca3ccad8 317 data->fan_div[nr] = DIV_TO_REG(val);
85f03bcc
KL
318
319 switch (nr) {
320 case 0:
321 keep_mask = 0xf8;
322 new_shift = 0;
323 break;
324 case 1:
325 keep_mask = 0x8f;
326 new_shift = 4;
327 break;
328 }
329
330 fan_div_reg = w83l786ng_read_value(client, W83L786NG_REG_FAN_DIV)
331 & keep_mask;
332
333 tmp_fan_div = (data->fan_div[nr] << new_shift) & ~keep_mask;
334
335 w83l786ng_write_value(client, W83L786NG_REG_FAN_DIV,
336 fan_div_reg | tmp_fan_div);
337
338 /* Restore fan_min */
339 data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
340 w83l786ng_write_value(client, W83L786NG_REG_FAN_MIN(nr),
341 data->fan_min[nr]);
342 mutex_unlock(&data->update_lock);
343
344 return count;
345}
346
347static struct sensor_device_attribute sda_fan_input[] = {
348 SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0),
349 SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1),
350};
351
352static struct sensor_device_attribute sda_fan_min[] = {
353 SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min,
354 store_fan_min, 0),
355 SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min,
356 store_fan_min, 1),
357};
358
359static struct sensor_device_attribute sda_fan_div[] = {
360 SENSOR_ATTR(fan1_div, S_IWUSR | S_IRUGO, show_fan_div,
361 store_fan_div, 0),
362 SENSOR_ATTR(fan2_div, S_IWUSR | S_IRUGO, show_fan_div,
363 store_fan_div, 1),
364};
365
366
367/* read/write the temperature, includes measured value and limits */
368
369static ssize_t
370show_temp(struct device *dev, struct device_attribute *attr, char *buf)
371{
372 struct sensor_device_attribute_2 *sensor_attr =
373 to_sensor_dev_attr_2(attr);
374 int nr = sensor_attr->nr;
375 int index = sensor_attr->index;
376 struct w83l786ng_data *data = w83l786ng_update_device(dev);
377 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr][index]));
378}
379
380static ssize_t
381store_temp(struct device *dev, struct device_attribute *attr,
382 const char *buf, size_t count)
383{
384 struct sensor_device_attribute_2 *sensor_attr =
385 to_sensor_dev_attr_2(attr);
386 int nr = sensor_attr->nr;
387 int index = sensor_attr->index;
388 struct i2c_client *client = to_i2c_client(dev);
389 struct w83l786ng_data *data = i2c_get_clientdata(client);
ca3ccad8
GR
390 long val;
391 int err;
392
393 err = kstrtol(buf, 10, &val);
394 if (err)
395 return err;
85f03bcc 396
85f03bcc
KL
397 mutex_lock(&data->update_lock);
398 data->temp[nr][index] = TEMP_TO_REG(val);
399 w83l786ng_write_value(client, W83L786NG_REG_TEMP[nr][index],
400 data->temp[nr][index]);
401 mutex_unlock(&data->update_lock);
402
ca3ccad8 403 return count;
85f03bcc
KL
404}
405
406static struct sensor_device_attribute_2 sda_temp_input[] = {
407 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
408 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 1, 0),
409};
410
411static struct sensor_device_attribute_2 sda_temp_max[] = {
412 SENSOR_ATTR_2(temp1_max, S_IRUGO | S_IWUSR,
413 show_temp, store_temp, 0, 1),
414 SENSOR_ATTR_2(temp2_max, S_IRUGO | S_IWUSR,
415 show_temp, store_temp, 1, 1),
416};
417
418static struct sensor_device_attribute_2 sda_temp_max_hyst[] = {
419 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO | S_IWUSR,
420 show_temp, store_temp, 0, 2),
421 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO | S_IWUSR,
422 show_temp, store_temp, 1, 2),
423};
424
425#define show_pwm_reg(reg) \
ca3ccad8
GR
426static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
427 char *buf) \
85f03bcc
KL
428{ \
429 struct w83l786ng_data *data = w83l786ng_update_device(dev); \
430 int nr = to_sensor_dev_attr(attr)->index; \
431 return sprintf(buf, "%d\n", data->reg[nr]); \
432}
433
434show_pwm_reg(pwm_mode)
435show_pwm_reg(pwm_enable)
436show_pwm_reg(pwm)
437
438static ssize_t
439store_pwm_mode(struct device *dev, struct device_attribute *attr,
440 const char *buf, size_t count)
441{
442 int nr = to_sensor_dev_attr(attr)->index;
443 struct i2c_client *client = to_i2c_client(dev);
444 struct w83l786ng_data *data = i2c_get_clientdata(client);
85f03bcc 445 u8 reg;
ca3ccad8
GR
446 unsigned long val;
447 int err;
448
449 err = kstrtoul(buf, 10, &val);
450 if (err)
451 return err;
85f03bcc
KL
452
453 if (val > 1)
454 return -EINVAL;
455 mutex_lock(&data->update_lock);
456 data->pwm_mode[nr] = val;
457 reg = w83l786ng_read_value(client, W83L786NG_REG_FAN_CFG);
458 reg &= ~(1 << W83L786NG_PWM_MODE_SHIFT[nr]);
459 if (!val)
460 reg |= 1 << W83L786NG_PWM_MODE_SHIFT[nr];
461 w83l786ng_write_value(client, W83L786NG_REG_FAN_CFG, reg);
462 mutex_unlock(&data->update_lock);
463 return count;
464}
465
466static ssize_t
467store_pwm(struct device *dev, struct device_attribute *attr,
468 const char *buf, size_t count)
469{
470 int nr = to_sensor_dev_attr(attr)->index;
471 struct i2c_client *client = to_i2c_client(dev);
472 struct w83l786ng_data *data = i2c_get_clientdata(client);
ca3ccad8
GR
473 unsigned long val;
474 int err;
475
476 err = kstrtoul(buf, 10, &val);
477 if (err)
478 return err;
479 val = SENSORS_LIMIT(val, 0, 255);
85f03bcc
KL
480
481 mutex_lock(&data->update_lock);
482 data->pwm[nr] = val;
483 w83l786ng_write_value(client, W83L786NG_REG_PWM[nr], val);
484 mutex_unlock(&data->update_lock);
485 return count;
486}
487
488static ssize_t
489store_pwm_enable(struct device *dev, struct device_attribute *attr,
490 const char *buf, size_t count)
491{
492 int nr = to_sensor_dev_attr(attr)->index;
493 struct i2c_client *client = to_i2c_client(dev);
494 struct w83l786ng_data *data = i2c_get_clientdata(client);
85f03bcc 495 u8 reg;
ca3ccad8
GR
496 unsigned long val;
497 int err;
85f03bcc 498
ca3ccad8
GR
499 err = kstrtoul(buf, 10, &val);
500 if (err)
501 return err;
502
503 if (!val || val > 2) /* only modes 1 and 2 are supported */
85f03bcc
KL
504 return -EINVAL;
505
506 mutex_lock(&data->update_lock);
507 reg = w83l786ng_read_value(client, W83L786NG_REG_FAN_CFG);
508 data->pwm_enable[nr] = val;
509 reg &= ~(0x02 << W83L786NG_PWM_ENABLE_SHIFT[nr]);
510 reg |= (val - 1) << W83L786NG_PWM_ENABLE_SHIFT[nr];
511 w83l786ng_write_value(client, W83L786NG_REG_FAN_CFG, reg);
512 mutex_unlock(&data->update_lock);
513 return count;
514}
515
516static struct sensor_device_attribute sda_pwm[] = {
517 SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0),
518 SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1),
519};
520
521static struct sensor_device_attribute sda_pwm_mode[] = {
522 SENSOR_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
523 store_pwm_mode, 0),
524 SENSOR_ATTR(pwm2_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
525 store_pwm_mode, 1),
526};
527
528static struct sensor_device_attribute sda_pwm_enable[] = {
529 SENSOR_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
530 store_pwm_enable, 0),
531 SENSOR_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
532 store_pwm_enable, 1),
533};
534
535/* For Smart Fan I/Thermal Cruise and Smart Fan II */
536static ssize_t
537show_tolerance(struct device *dev, struct device_attribute *attr, char *buf)
538{
539 int nr = to_sensor_dev_attr(attr)->index;
540 struct w83l786ng_data *data = w83l786ng_update_device(dev);
541 return sprintf(buf, "%ld\n", (long)data->tolerance[nr]);
542}
543
544static ssize_t
545store_tolerance(struct device *dev, struct device_attribute *attr,
546 const char *buf, size_t count)
547{
548 int nr = to_sensor_dev_attr(attr)->index;
549 struct i2c_client *client = to_i2c_client(dev);
550 struct w83l786ng_data *data = i2c_get_clientdata(client);
85f03bcc 551 u8 tol_tmp, tol_mask;
ca3ccad8
GR
552 unsigned long val;
553 int err;
85f03bcc 554
ca3ccad8
GR
555 err = kstrtoul(buf, 10, &val);
556 if (err)
557 return err;
85f03bcc
KL
558
559 mutex_lock(&data->update_lock);
560 tol_mask = w83l786ng_read_value(client,
561 W83L786NG_REG_TOLERANCE) & ((nr == 1) ? 0x0f : 0xf0);
562 tol_tmp = SENSORS_LIMIT(val, 0, 15);
563 tol_tmp &= 0x0f;
564 data->tolerance[nr] = tol_tmp;
ca3ccad8 565 if (nr == 1)
85f03bcc 566 tol_tmp <<= 4;
85f03bcc
KL
567
568 w83l786ng_write_value(client, W83L786NG_REG_TOLERANCE,
569 tol_mask | tol_tmp);
570 mutex_unlock(&data->update_lock);
571 return count;
572}
573
574static struct sensor_device_attribute sda_tolerance[] = {
575 SENSOR_ATTR(pwm1_tolerance, S_IWUSR | S_IRUGO,
576 show_tolerance, store_tolerance, 0),
577 SENSOR_ATTR(pwm2_tolerance, S_IWUSR | S_IRUGO,
578 show_tolerance, store_tolerance, 1),
579};
580
581
582#define IN_UNIT_ATTRS(X) \
583 &sda_in_input[X].dev_attr.attr, \
584 &sda_in_min[X].dev_attr.attr, \
585 &sda_in_max[X].dev_attr.attr
586
587#define FAN_UNIT_ATTRS(X) \
588 &sda_fan_input[X].dev_attr.attr, \
589 &sda_fan_min[X].dev_attr.attr, \
590 &sda_fan_div[X].dev_attr.attr
591
592#define TEMP_UNIT_ATTRS(X) \
593 &sda_temp_input[X].dev_attr.attr, \
594 &sda_temp_max[X].dev_attr.attr, \
595 &sda_temp_max_hyst[X].dev_attr.attr
596
597#define PWM_UNIT_ATTRS(X) \
598 &sda_pwm[X].dev_attr.attr, \
599 &sda_pwm_mode[X].dev_attr.attr, \
600 &sda_pwm_enable[X].dev_attr.attr
601
602#define TOLERANCE_UNIT_ATTRS(X) \
603 &sda_tolerance[X].dev_attr.attr
604
605static struct attribute *w83l786ng_attributes[] = {
606 IN_UNIT_ATTRS(0),
607 IN_UNIT_ATTRS(1),
608 IN_UNIT_ATTRS(2),
609 FAN_UNIT_ATTRS(0),
610 FAN_UNIT_ATTRS(1),
611 TEMP_UNIT_ATTRS(0),
612 TEMP_UNIT_ATTRS(1),
613 PWM_UNIT_ATTRS(0),
614 PWM_UNIT_ATTRS(1),
615 TOLERANCE_UNIT_ATTRS(0),
616 TOLERANCE_UNIT_ATTRS(1),
617 NULL
618};
619
620static const struct attribute_group w83l786ng_group = {
621 .attrs = w83l786ng_attributes,
622};
623
624static int
310ec792 625w83l786ng_detect(struct i2c_client *client, struct i2c_board_info *info)
85f03bcc 626{
33468e76 627 struct i2c_adapter *adapter = client->adapter;
52df6440
JD
628 u16 man_id;
629 u8 chip_id;
85f03bcc 630
ca3ccad8 631 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
33468e76 632 return -ENODEV;
85f03bcc 633
52df6440
JD
634 /* Detection */
635 if ((w83l786ng_read_value(client, W83L786NG_REG_CONFIG) & 0x80)) {
636 dev_dbg(&adapter->dev, "W83L786NG detection failed at 0x%02x\n",
637 client->addr);
638 return -ENODEV;
85f03bcc
KL
639 }
640
52df6440
JD
641 /* Identification */
642 man_id = (w83l786ng_read_value(client, W83L786NG_REG_MAN_ID1) << 8) +
643 w83l786ng_read_value(client, W83L786NG_REG_MAN_ID2);
644 chip_id = w83l786ng_read_value(client, W83L786NG_REG_CHIP_ID);
645
646 if (man_id != 0x5CA3 || /* Winbond */
647 chip_id != 0x80) { /* W83L786NG */
648 dev_dbg(&adapter->dev,
649 "Unsupported chip (man_id=0x%04X, chip_id=0x%02X)\n",
650 man_id, chip_id);
651 return -ENODEV;
85f03bcc
KL
652 }
653
33468e76 654 strlcpy(info->type, "w83l786ng", I2C_NAME_SIZE);
85f03bcc 655
33468e76
JD
656 return 0;
657}
658
659static int
660w83l786ng_probe(struct i2c_client *client, const struct i2c_device_id *id)
661{
662 struct device *dev = &client->dev;
663 struct w83l786ng_data *data;
664 int i, err = 0;
665 u8 reg_tmp;
666
667 data = kzalloc(sizeof(struct w83l786ng_data), GFP_KERNEL);
668 if (!data) {
669 err = -ENOMEM;
670 goto exit;
671 }
672
673 i2c_set_clientdata(client, data);
674 mutex_init(&data->update_lock);
85f03bcc
KL
675
676 /* Initialize the chip */
677 w83l786ng_init_client(client);
678
679 /* A few vars need to be filled upon startup */
680 for (i = 0; i < 2; i++) {
681 data->fan_min[i] = w83l786ng_read_value(client,
682 W83L786NG_REG_FAN_MIN(i));
683 }
684
685 /* Update the fan divisor */
686 reg_tmp = w83l786ng_read_value(client, W83L786NG_REG_FAN_DIV);
687 data->fan_div[0] = reg_tmp & 0x07;
688 data->fan_div[1] = (reg_tmp >> 4) & 0x07;
689
690 /* Register sysfs hooks */
ca3ccad8
GR
691 err = sysfs_create_group(&client->dev.kobj, &w83l786ng_group);
692 if (err)
85f03bcc
KL
693 goto exit_remove;
694
695 data->hwmon_dev = hwmon_device_register(dev);
696 if (IS_ERR(data->hwmon_dev)) {
697 err = PTR_ERR(data->hwmon_dev);
698 goto exit_remove;
699 }
700
701 return 0;
702
703 /* Unregister sysfs hooks */
704
705exit_remove:
706 sysfs_remove_group(&client->dev.kobj, &w83l786ng_group);
85f03bcc
KL
707 kfree(data);
708exit:
709 return err;
710}
711
712static int
33468e76 713w83l786ng_remove(struct i2c_client *client)
85f03bcc
KL
714{
715 struct w83l786ng_data *data = i2c_get_clientdata(client);
85f03bcc
KL
716
717 hwmon_device_unregister(data->hwmon_dev);
718 sysfs_remove_group(&client->dev.kobj, &w83l786ng_group);
719
85f03bcc
KL
720 kfree(data);
721
722 return 0;
723}
724
725static void
726w83l786ng_init_client(struct i2c_client *client)
727{
728 u8 tmp;
729
730 if (reset)
731 w83l786ng_write_value(client, W83L786NG_REG_CONFIG, 0x80);
732
733 /* Start monitoring */
734 tmp = w83l786ng_read_value(client, W83L786NG_REG_CONFIG);
735 if (!(tmp & 0x01))
736 w83l786ng_write_value(client, W83L786NG_REG_CONFIG, tmp | 0x01);
737}
738
739static struct w83l786ng_data *w83l786ng_update_device(struct device *dev)
740{
741 struct i2c_client *client = to_i2c_client(dev);
742 struct w83l786ng_data *data = i2c_get_clientdata(client);
743 int i, j;
744 u8 reg_tmp, pwmcfg;
745
746 mutex_lock(&data->update_lock);
747 if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
748 || !data->valid) {
749 dev_dbg(&client->dev, "Updating w83l786ng data.\n");
750
751 /* Update the voltages measured value and limits */
752 for (i = 0; i < 3; i++) {
753 data->in[i] = w83l786ng_read_value(client,
754 W83L786NG_REG_IN(i));
755 data->in_min[i] = w83l786ng_read_value(client,
756 W83L786NG_REG_IN_MIN(i));
757 data->in_max[i] = w83l786ng_read_value(client,
758 W83L786NG_REG_IN_MAX(i));
759 }
760
761 /* Update the fan counts and limits */
762 for (i = 0; i < 2; i++) {
763 data->fan[i] = w83l786ng_read_value(client,
764 W83L786NG_REG_FAN(i));
765 data->fan_min[i] = w83l786ng_read_value(client,
766 W83L786NG_REG_FAN_MIN(i));
767 }
768
769 /* Update the fan divisor */
770 reg_tmp = w83l786ng_read_value(client, W83L786NG_REG_FAN_DIV);
771 data->fan_div[0] = reg_tmp & 0x07;
772 data->fan_div[1] = (reg_tmp >> 4) & 0x07;
773
774 pwmcfg = w83l786ng_read_value(client, W83L786NG_REG_FAN_CFG);
775 for (i = 0; i < 2; i++) {
776 data->pwm_mode[i] =
777 ((pwmcfg >> W83L786NG_PWM_MODE_SHIFT[i]) & 1)
778 ? 0 : 1;
779 data->pwm_enable[i] =
780 ((pwmcfg >> W83L786NG_PWM_ENABLE_SHIFT[i]) & 2) + 1;
781 data->pwm[i] = w83l786ng_read_value(client,
782 W83L786NG_REG_PWM[i]);
783 }
784
785
786 /* Update the temperature sensors */
787 for (i = 0; i < 2; i++) {
788 for (j = 0; j < 3; j++) {
789 data->temp[i][j] = w83l786ng_read_value(client,
790 W83L786NG_REG_TEMP[i][j]);
791 }
792 }
793
794 /* Update Smart Fan I/II tolerance */
795 reg_tmp = w83l786ng_read_value(client, W83L786NG_REG_TOLERANCE);
796 data->tolerance[0] = reg_tmp & 0x0f;
797 data->tolerance[1] = (reg_tmp >> 4) & 0x0f;
798
799 data->last_updated = jiffies;
800 data->valid = 1;
801
802 }
803
804 mutex_unlock(&data->update_lock);
805
806 return data;
807}
808
f0967eea 809module_i2c_driver(w83l786ng_driver);
85f03bcc
KL
810
811MODULE_AUTHOR("Kevin Lo");
812MODULE_DESCRIPTION("w83l786ng driver");
813MODULE_LICENSE("GPL");
This page took 0.376814 seconds and 5 git commands to generate.