aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/max6650.c
diff options
context:
space:
mode:
authorChristian Engelmayer <christian.engelmayer@frequentis.com>2009-06-15 12:39:52 -0400
committerJean Delvare <khali@linux-fr.org>2009-06-15 12:39:52 -0400
commit52b5226f481c09cc499cc28b1e9347d314b340f1 (patch)
tree96cd3e3cdc6fc8128aaad252807abf86aaf7b368 /drivers/hwmon/max6650.c
parent09475d32e652fe60901fe8c9cd50f3f6db0c4933 (diff)
hwmon: (max6650) Add support for alarms
Export the alarm flags provided by the MAX6650/MAX6651 fan-speed regulator and monitor chips via sysfs. Signed-off-by: Christian Engelmayer <christian.engelmayer@frequentis.com> Acked-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon/max6650.c')
-rw-r--r--drivers/hwmon/max6650.c86
1 files changed, 85 insertions, 1 deletions
diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c
index f27af6a9da41..86142a858238 100644
--- a/drivers/hwmon/max6650.c
+++ b/drivers/hwmon/max6650.c
@@ -12,7 +12,7 @@
12 * also work with the MAX6651. It does not distinguish max6650 and max6651 12 * also work with the MAX6651. It does not distinguish max6650 and max6651
13 * chips. 13 * chips.
14 * 14 *
15 * Tha datasheet was last seen at: 15 * The datasheet was last seen at:
16 * 16 *
17 * http://pdfserv.maxim-ic.com/en/ds/MAX6650-MAX6651.pdf 17 * http://pdfserv.maxim-ic.com/en/ds/MAX6650-MAX6651.pdf
18 * 18 *
@@ -98,6 +98,16 @@ I2C_CLIENT_INSMOD_1(max6650);
98#define MAX6650_CFG_MODE_OPEN_LOOP 0x30 98#define MAX6650_CFG_MODE_OPEN_LOOP 0x30
99#define MAX6650_COUNT_MASK 0x03 99#define MAX6650_COUNT_MASK 0x03
100 100
101/*
102 * Alarm status register bits
103 */
104
105#define MAX6650_ALRM_MAX 0x01
106#define MAX6650_ALRM_MIN 0x02
107#define MAX6650_ALRM_TACH 0x04
108#define MAX6650_ALRM_GPIO1 0x08
109#define MAX6650_ALRM_GPIO2 0x10
110
101/* Minimum and maximum values of the FAN-RPM */ 111/* Minimum and maximum values of the FAN-RPM */
102#define FAN_RPM_MIN 240 112#define FAN_RPM_MIN 240
103#define FAN_RPM_MAX 30000 113#define FAN_RPM_MAX 30000
@@ -151,6 +161,7 @@ struct max6650_data
151 u8 tach[4]; 161 u8 tach[4];
152 u8 count; 162 u8 count;
153 u8 dac; 163 u8 dac;
164 u8 alarm;
154}; 165};
155 166
156static ssize_t get_fan(struct device *dev, struct device_attribute *devattr, 167static ssize_t get_fan(struct device *dev, struct device_attribute *devattr,
@@ -418,6 +429,33 @@ static ssize_t set_div(struct device *dev, struct device_attribute *devattr,
418 return count; 429 return count;
419} 430}
420 431
432/*
433 * Get alarm stati:
434 * Possible values:
435 * 0 = no alarm
436 * 1 = alarm
437 */
438
439static ssize_t get_alarm(struct device *dev, struct device_attribute *devattr,
440 char *buf)
441{
442 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
443 struct max6650_data *data = max6650_update_device(dev);
444 struct i2c_client *client = to_i2c_client(dev);
445 int alarm = 0;
446
447 if (data->alarm & attr->index) {
448 mutex_lock(&data->update_lock);
449 alarm = 1;
450 data->alarm &= ~attr->index;
451 data->alarm |= i2c_smbus_read_byte_data(client,
452 MAX6650_REG_ALARM);
453 mutex_unlock(&data->update_lock);
454 }
455
456 return sprintf(buf, "%d\n", alarm);
457}
458
421static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, get_fan, NULL, 0); 459static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, get_fan, NULL, 0);
422static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, get_fan, NULL, 1); 460static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, get_fan, NULL, 1);
423static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, get_fan, NULL, 2); 461static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, get_fan, NULL, 2);
@@ -426,7 +464,41 @@ static DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO, get_target, set_target);
426static DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO, get_div, set_div); 464static DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO, get_div, set_div);
427static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, get_enable, set_enable); 465static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, get_enable, set_enable);
428static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm, set_pwm); 466static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm, set_pwm);
467static SENSOR_DEVICE_ATTR(fan1_max_alarm, S_IRUGO, get_alarm, NULL,
468 MAX6650_ALRM_MAX);
469static SENSOR_DEVICE_ATTR(fan1_min_alarm, S_IRUGO, get_alarm, NULL,
470 MAX6650_ALRM_MIN);
471static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, get_alarm, NULL,
472 MAX6650_ALRM_TACH);
473static SENSOR_DEVICE_ATTR(gpio1_alarm, S_IRUGO, get_alarm, NULL,
474 MAX6650_ALRM_GPIO1);
475static SENSOR_DEVICE_ATTR(gpio2_alarm, S_IRUGO, get_alarm, NULL,
476 MAX6650_ALRM_GPIO2);
477
478static mode_t max6650_attrs_visible(struct kobject *kobj, struct attribute *a,
479 int n)
480{
481 struct device *dev = container_of(kobj, struct device, kobj);
482 struct i2c_client *client = to_i2c_client(dev);
483 u8 alarm_en = i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM_EN);
484 struct device_attribute *devattr;
429 485
486 /*
487 * Hide the alarms that have not been enabled by the firmware
488 */
489
490 devattr = container_of(a, struct device_attribute, attr);
491 if (devattr == &sensor_dev_attr_fan1_max_alarm.dev_attr
492 || devattr == &sensor_dev_attr_fan1_min_alarm.dev_attr
493 || devattr == &sensor_dev_attr_fan1_fault.dev_attr
494 || devattr == &sensor_dev_attr_gpio1_alarm.dev_attr
495 || devattr == &sensor_dev_attr_gpio2_alarm.dev_attr) {
496 if (!(alarm_en & to_sensor_dev_attr(devattr)->index))
497 return 0;
498 }
499
500 return a->mode;
501}
430 502
431static struct attribute *max6650_attrs[] = { 503static struct attribute *max6650_attrs[] = {
432 &sensor_dev_attr_fan1_input.dev_attr.attr, 504 &sensor_dev_attr_fan1_input.dev_attr.attr,
@@ -437,11 +509,17 @@ static struct attribute *max6650_attrs[] = {
437 &dev_attr_fan1_div.attr, 509 &dev_attr_fan1_div.attr,
438 &dev_attr_pwm1_enable.attr, 510 &dev_attr_pwm1_enable.attr,
439 &dev_attr_pwm1.attr, 511 &dev_attr_pwm1.attr,
512 &sensor_dev_attr_fan1_max_alarm.dev_attr.attr,
513 &sensor_dev_attr_fan1_min_alarm.dev_attr.attr,
514 &sensor_dev_attr_fan1_fault.dev_attr.attr,
515 &sensor_dev_attr_gpio1_alarm.dev_attr.attr,
516 &sensor_dev_attr_gpio2_alarm.dev_attr.attr,
440 NULL 517 NULL
441}; 518};
442 519
443static struct attribute_group max6650_attr_grp = { 520static struct attribute_group max6650_attr_grp = {
444 .attrs = max6650_attrs, 521 .attrs = max6650_attrs,
522 .is_visible = max6650_attrs_visible,
445}; 523};
446 524
447/* 525/*
@@ -659,6 +737,12 @@ static struct max6650_data *max6650_update_device(struct device *dev)
659 MAX6650_REG_COUNT); 737 MAX6650_REG_COUNT);
660 data->dac = i2c_smbus_read_byte_data(client, MAX6650_REG_DAC); 738 data->dac = i2c_smbus_read_byte_data(client, MAX6650_REG_DAC);
661 739
740 /* Alarms are cleared on read in case the condition that
741 * caused the alarm is removed. Keep the value latched here
742 * for providing the register through different alarm files. */
743 data->alarm |= i2c_smbus_read_byte_data(client,
744 MAX6650_REG_ALARM);
745
662 data->last_updated = jiffies; 746 data->last_updated = jiffies;
663 data->valid = 1; 747 data->valid = 1;
664 } 748 }