aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/pmbus
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2013-01-16 13:31:32 -0500
committerGuenter Roeck <linux@roeck-us.net>2013-02-06 12:58:03 -0500
commitaebcbbfc4955929286a15a04592a2281d3e527db (patch)
treedf81ac0ca3cb59b0c38b8fabc8ae569725c1f393 /drivers/hwmon/pmbus
parent85cfb3a83536ad7f055b45f3a9c227848fa4dc80 (diff)
hwmon: (pmbus) Add support for additional voltage sensor
Some PMBus chips support monitoring an additional non-standard voltage. While this voltage can in many cases be supported by simulating an additional sensor page, this does not work in all cases. Specifically, it is problematic if the data format is linear and the voltage is reported in LINEAR11 format. Since output voltages use LINEAR16, and the exponent for LINEAR16 data is chip-wide and fixed, this can result in overflows. To solve this problem, add support for an additional virtual input voltage, call it 'vmon', and treat this voltage as input voltage (which, when the chip supports linear data format, uses LINEAR11). Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon/pmbus')
-rw-r--r--drivers/hwmon/pmbus/pmbus.h10
-rw-r--r--drivers/hwmon/pmbus/pmbus_core.c54
2 files changed, 55 insertions, 9 deletions
diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h
index 3fe03dc47eb7..164d17706486 100644
--- a/drivers/hwmon/pmbus/pmbus.h
+++ b/drivers/hwmon/pmbus/pmbus.h
@@ -2,6 +2,7 @@
2 * pmbus.h - Common defines and structures for PMBus devices 2 * pmbus.h - Common defines and structures for PMBus devices
3 * 3 *
4 * Copyright (c) 2010, 2011 Ericsson AB. 4 * Copyright (c) 2010, 2011 Ericsson AB.
5 * Copyright (c) 2012 Guenter Roeck
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -177,6 +178,13 @@
177#define PMBUS_VIRT_READ_TEMP2_MAX (PMBUS_VIRT_BASE + 28) 178#define PMBUS_VIRT_READ_TEMP2_MAX (PMBUS_VIRT_BASE + 28)
178#define PMBUS_VIRT_RESET_TEMP2_HISTORY (PMBUS_VIRT_BASE + 29) 179#define PMBUS_VIRT_RESET_TEMP2_HISTORY (PMBUS_VIRT_BASE + 29)
179 180
181#define PMBUS_VIRT_READ_VMON (PMBUS_VIRT_BASE + 30)
182#define PMBUS_VIRT_VMON_UV_WARN_LIMIT (PMBUS_VIRT_BASE + 31)
183#define PMBUS_VIRT_VMON_OV_WARN_LIMIT (PMBUS_VIRT_BASE + 32)
184#define PMBUS_VIRT_VMON_UV_FAULT_LIMIT (PMBUS_VIRT_BASE + 33)
185#define PMBUS_VIRT_VMON_OV_FAULT_LIMIT (PMBUS_VIRT_BASE + 34)
186#define PMBUS_VIRT_STATUS_VMON (PMBUS_VIRT_BASE + 35)
187
180/* 188/*
181 * CAPABILITY 189 * CAPABILITY
182 */ 190 */
@@ -317,6 +325,8 @@ enum pmbus_sensor_classes {
317#define PMBUS_HAVE_STATUS_TEMP (1 << 15) 325#define PMBUS_HAVE_STATUS_TEMP (1 << 15)
318#define PMBUS_HAVE_STATUS_FAN12 (1 << 16) 326#define PMBUS_HAVE_STATUS_FAN12 (1 << 16)
319#define PMBUS_HAVE_STATUS_FAN34 (1 << 17) 327#define PMBUS_HAVE_STATUS_FAN34 (1 << 17)
328#define PMBUS_HAVE_VMON (1 << 18)
329#define PMBUS_HAVE_STATUS_VMON (1 << 19)
320 330
321enum pmbus_data_format { linear = 0, direct, vid }; 331enum pmbus_data_format { linear = 0, direct, vid };
322 332
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index 26b699a6abb9..3b5c24dd0b75 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -2,6 +2,7 @@
2 * Hardware monitoring driver for PMBus devices 2 * Hardware monitoring driver for PMBus devices
3 * 3 *
4 * Copyright (c) 2010, 2011 Ericsson AB. 4 * Copyright (c) 2010, 2011 Ericsson AB.
5 * Copyright (c) 2012 Guenter Roeck
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -37,12 +38,6 @@
37#define PMBUS_ATTR_ALLOC_SIZE 32 38#define PMBUS_ATTR_ALLOC_SIZE 32
38 39
39/* 40/*
40 * status, status_vout, status_iout, status_fans, status_fan34, and status_temp
41 * are paged. status_input is unpaged.
42 */
43#define PB_NUM_STATUS_REG (PMBUS_PAGES * 6 + 1)
44
45/*
46 * Index into status register array, per status register group 41 * Index into status register array, per status register group
47 */ 42 */
48#define PB_STATUS_BASE 0 43#define PB_STATUS_BASE 0
@@ -50,8 +45,11 @@
50#define PB_STATUS_IOUT_BASE (PB_STATUS_VOUT_BASE + PMBUS_PAGES) 45#define PB_STATUS_IOUT_BASE (PB_STATUS_VOUT_BASE + PMBUS_PAGES)
51#define PB_STATUS_FAN_BASE (PB_STATUS_IOUT_BASE + PMBUS_PAGES) 46#define PB_STATUS_FAN_BASE (PB_STATUS_IOUT_BASE + PMBUS_PAGES)
52#define PB_STATUS_FAN34_BASE (PB_STATUS_FAN_BASE + PMBUS_PAGES) 47#define PB_STATUS_FAN34_BASE (PB_STATUS_FAN_BASE + PMBUS_PAGES)
53#define PB_STATUS_INPUT_BASE (PB_STATUS_FAN34_BASE + PMBUS_PAGES) 48#define PB_STATUS_TEMP_BASE (PB_STATUS_FAN34_BASE + PMBUS_PAGES)
54#define PB_STATUS_TEMP_BASE (PB_STATUS_INPUT_BASE + 1) 49#define PB_STATUS_INPUT_BASE (PB_STATUS_TEMP_BASE + PMBUS_PAGES)
50#define PB_STATUS_VMON_BASE (PB_STATUS_INPUT_BASE + 1)
51
52#define PB_NUM_STATUS_REG (PB_STATUS_VMON_BASE + 1)
55 53
56#define PMBUS_NAME_SIZE 24 54#define PMBUS_NAME_SIZE 24
57 55
@@ -379,6 +377,11 @@ static struct pmbus_data *pmbus_update_device(struct device *dev)
379 = _pmbus_read_byte_data(client, 0, 377 = _pmbus_read_byte_data(client, 0,
380 PMBUS_STATUS_INPUT); 378 PMBUS_STATUS_INPUT);
381 379
380 if (info->func[0] & PMBUS_HAVE_STATUS_VMON)
381 data->status[PB_STATUS_VMON_BASE]
382 = _pmbus_read_byte_data(client, 0,
383 PMBUS_VIRT_STATUS_VMON);
384
382 for (sensor = data->sensors; sensor; sensor = sensor->next) { 385 for (sensor = data->sensors; sensor; sensor = sensor->next) {
383 if (!data->valid || sensor->update) 386 if (!data->valid || sensor->update)
384 sensor->data 387 sensor->data
@@ -913,7 +916,7 @@ struct pmbus_limit_attr {
913 * description includes a reference to the associated limit attributes. 916 * description includes a reference to the associated limit attributes.
914 */ 917 */
915struct pmbus_sensor_attr { 918struct pmbus_sensor_attr {
916 u8 reg; /* sensor register */ 919 u16 reg; /* sensor register */
917 enum pmbus_sensor_classes class;/* sensor class */ 920 enum pmbus_sensor_classes class;/* sensor class */
918 const char *label; /* sensor label */ 921 const char *label; /* sensor label */
919 bool paged; /* true if paged sensor */ 922 bool paged; /* true if paged sensor */
@@ -1085,6 +1088,30 @@ static const struct pmbus_limit_attr vin_limit_attrs[] = {
1085 }, 1088 },
1086}; 1089};
1087 1090
1091static const struct pmbus_limit_attr vmon_limit_attrs[] = {
1092 {
1093 .reg = PMBUS_VIRT_VMON_UV_WARN_LIMIT,
1094 .attr = "min",
1095 .alarm = "min_alarm",
1096 .sbit = PB_VOLTAGE_UV_WARNING,
1097 }, {
1098 .reg = PMBUS_VIRT_VMON_UV_FAULT_LIMIT,
1099 .attr = "lcrit",
1100 .alarm = "lcrit_alarm",
1101 .sbit = PB_VOLTAGE_UV_FAULT,
1102 }, {
1103 .reg = PMBUS_VIRT_VMON_OV_WARN_LIMIT,
1104 .attr = "max",
1105 .alarm = "max_alarm",
1106 .sbit = PB_VOLTAGE_OV_WARNING,
1107 }, {
1108 .reg = PMBUS_VIRT_VMON_OV_FAULT_LIMIT,
1109 .attr = "crit",
1110 .alarm = "crit_alarm",
1111 .sbit = PB_VOLTAGE_OV_FAULT,
1112 }
1113};
1114
1088static const struct pmbus_limit_attr vout_limit_attrs[] = { 1115static const struct pmbus_limit_attr vout_limit_attrs[] = {
1089 { 1116 {
1090 .reg = PMBUS_VOUT_UV_WARN_LIMIT, 1117 .reg = PMBUS_VOUT_UV_WARN_LIMIT,
@@ -1136,6 +1163,15 @@ static const struct pmbus_sensor_attr voltage_attributes[] = {
1136 .limit = vin_limit_attrs, 1163 .limit = vin_limit_attrs,
1137 .nlimit = ARRAY_SIZE(vin_limit_attrs), 1164 .nlimit = ARRAY_SIZE(vin_limit_attrs),
1138 }, { 1165 }, {
1166 .reg = PMBUS_VIRT_READ_VMON,
1167 .class = PSC_VOLTAGE_IN,
1168 .label = "vmon",
1169 .func = PMBUS_HAVE_VMON,
1170 .sfunc = PMBUS_HAVE_STATUS_VMON,
1171 .sbase = PB_STATUS_VMON_BASE,
1172 .limit = vmon_limit_attrs,
1173 .nlimit = ARRAY_SIZE(vmon_limit_attrs),
1174 }, {
1139 .reg = PMBUS_READ_VCAP, 1175 .reg = PMBUS_READ_VCAP,
1140 .class = PSC_VOLTAGE_IN, 1176 .class = PSC_VOLTAGE_IN,
1141 .label = "vcap", 1177 .label = "vcap",