hwmon: PMBus device driver
This driver adds support for hardware monitoring features of various PMBus devices. Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com> Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
This commit is contained in:
parent
06923f8442
commit
442aba7872
6 changed files with 2218 additions and 0 deletions
|
@ -756,6 +756,31 @@ config SENSORS_PCF8591
|
|||
These devices are hard to detect and rarely found on mainstream
|
||||
hardware. If unsure, say N.
|
||||
|
||||
config PMBUS
|
||||
tristate "PMBus support"
|
||||
depends on I2C && EXPERIMENTAL
|
||||
default n
|
||||
help
|
||||
Say yes here if you want to enable PMBus support.
|
||||
|
||||
This driver can also be built as a module. If so, the module will
|
||||
be called pmbus_core.
|
||||
|
||||
if PMBUS
|
||||
|
||||
config SENSORS_PMBUS
|
||||
tristate "Generic PMBus devices"
|
||||
default n
|
||||
help
|
||||
If you say yes here you get hardware monitoring support for generic
|
||||
PMBus devices, including but not limited to BMR450, BMR451, BMR453,
|
||||
BMR454, and LTC2978.
|
||||
|
||||
This driver can also be built as a module. If so, the module will
|
||||
be called pmbus.
|
||||
|
||||
endif # PMBUS
|
||||
|
||||
config SENSORS_SHT15
|
||||
tristate "Sensiron humidity and temperature sensors. SHT15 and compat."
|
||||
depends on GENERIC_GPIO
|
||||
|
|
|
@ -114,6 +114,10 @@ obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o
|
|||
obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o
|
||||
obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o
|
||||
|
||||
# PMBus drivers
|
||||
obj-$(CONFIG_PMBUS) += pmbus_core.o
|
||||
obj-$(CONFIG_SENSORS_PMBUS) += pmbus.o
|
||||
|
||||
ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y)
|
||||
EXTRA_CFLAGS += -DDEBUG
|
||||
endif
|
||||
|
|
203
drivers/hwmon/pmbus.c
Normal file
203
drivers/hwmon/pmbus.c
Normal file
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
* Hardware monitoring driver for PMBus devices
|
||||
*
|
||||
* Copyright (c) 2010, 2011 Ericsson AB.
|
||||
*
|
||||
* 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/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/i2c.h>
|
||||
#include "pmbus.h"
|
||||
|
||||
/*
|
||||
* Find sensor groups and status registers on each page.
|
||||
*/
|
||||
static void pmbus_find_sensor_groups(struct i2c_client *client,
|
||||
struct pmbus_driver_info *info)
|
||||
{
|
||||
int page;
|
||||
|
||||
/* Sensors detected on page 0 only */
|
||||
if (pmbus_check_word_register(client, 0, PMBUS_READ_VIN))
|
||||
info->func[0] |= PMBUS_HAVE_VIN;
|
||||
if (pmbus_check_word_register(client, 0, PMBUS_READ_VCAP))
|
||||
info->func[0] |= PMBUS_HAVE_VCAP;
|
||||
if (pmbus_check_word_register(client, 0, PMBUS_READ_IIN))
|
||||
info->func[0] |= PMBUS_HAVE_IIN;
|
||||
if (pmbus_check_word_register(client, 0, PMBUS_READ_PIN))
|
||||
info->func[0] |= PMBUS_HAVE_PIN;
|
||||
if (info->func[0]
|
||||
&& pmbus_check_byte_register(client, 0, PMBUS_STATUS_INPUT))
|
||||
info->func[0] |= PMBUS_HAVE_STATUS_INPUT;
|
||||
if (pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) {
|
||||
info->func[0] |= PMBUS_HAVE_FAN12;
|
||||
if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_12))
|
||||
info->func[0] |= PMBUS_HAVE_STATUS_FAN12;
|
||||
}
|
||||
if (pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_3)) {
|
||||
info->func[0] |= PMBUS_HAVE_FAN34;
|
||||
if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_34))
|
||||
info->func[0] |= PMBUS_HAVE_STATUS_FAN34;
|
||||
}
|
||||
if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1)) {
|
||||
info->func[0] |= PMBUS_HAVE_TEMP;
|
||||
if (pmbus_check_byte_register(client, 0,
|
||||
PMBUS_STATUS_TEMPERATURE))
|
||||
info->func[0] |= PMBUS_HAVE_STATUS_TEMP;
|
||||
}
|
||||
|
||||
/* Sensors detected on all pages */
|
||||
for (page = 0; page < info->pages; page++) {
|
||||
if (pmbus_check_word_register(client, page, PMBUS_READ_VOUT)) {
|
||||
info->func[page] |= PMBUS_HAVE_VOUT;
|
||||
if (pmbus_check_byte_register(client, page,
|
||||
PMBUS_STATUS_VOUT))
|
||||
info->func[page] |= PMBUS_HAVE_STATUS_VOUT;
|
||||
}
|
||||
if (pmbus_check_word_register(client, page, PMBUS_READ_IOUT)) {
|
||||
info->func[page] |= PMBUS_HAVE_IOUT;
|
||||
if (pmbus_check_byte_register(client, 0,
|
||||
PMBUS_STATUS_IOUT))
|
||||
info->func[page] |= PMBUS_HAVE_STATUS_IOUT;
|
||||
}
|
||||
if (pmbus_check_word_register(client, page, PMBUS_READ_POUT))
|
||||
info->func[page] |= PMBUS_HAVE_POUT;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Identify chip parameters.
|
||||
*/
|
||||
static int pmbus_identify(struct i2c_client *client,
|
||||
struct pmbus_driver_info *info)
|
||||
{
|
||||
if (!info->pages) {
|
||||
/*
|
||||
* Check if the PAGE command is supported. If it is,
|
||||
* keep setting the page number until it fails or until the
|
||||
* maximum number of pages has been reached. Assume that
|
||||
* this is the number of pages supported by the chip.
|
||||
*/
|
||||
if (pmbus_check_byte_register(client, 0, PMBUS_PAGE)) {
|
||||
int page;
|
||||
|
||||
for (page = 1; page < PMBUS_PAGES; page++) {
|
||||
if (pmbus_set_page(client, page) < 0)
|
||||
break;
|
||||
}
|
||||
pmbus_set_page(client, 0);
|
||||
info->pages = page;
|
||||
} else {
|
||||
info->pages = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We should check if the COEFFICIENTS register is supported.
|
||||
* If it is, and the chip is configured for direct mode, we can read
|
||||
* the coefficients from the chip, one set per group of sensor
|
||||
* registers.
|
||||
*
|
||||
* To do this, we will need access to a chip which actually supports the
|
||||
* COEFFICIENTS command, since the command is too complex to implement
|
||||
* without testing it.
|
||||
*/
|
||||
|
||||
/* Try to find sensor groups */
|
||||
pmbus_find_sensor_groups(client, info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pmbus_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct pmbus_driver_info *info;
|
||||
int ret;
|
||||
|
||||
info = kzalloc(sizeof(struct pmbus_driver_info), GFP_KERNEL);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
info->pages = id->driver_data;
|
||||
info->identify = pmbus_identify;
|
||||
|
||||
ret = pmbus_do_probe(client, id, info);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
return 0;
|
||||
|
||||
out:
|
||||
kfree(info);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pmbus_remove(struct i2c_client *client)
|
||||
{
|
||||
int ret;
|
||||
const struct pmbus_driver_info *info;
|
||||
|
||||
info = pmbus_get_driver_info(client);
|
||||
ret = pmbus_do_remove(client);
|
||||
kfree(info);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use driver_data to set the number of pages supported by the chip.
|
||||
*/
|
||||
static const struct i2c_device_id pmbus_id[] = {
|
||||
{"bmr450", 1},
|
||||
{"bmr451", 1},
|
||||
{"bmr453", 1},
|
||||
{"bmr454", 1},
|
||||
{"ltc2978", 8},
|
||||
{"pmbus", 0},
|
||||
{}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, pmbus_id);
|
||||
|
||||
/* This is the driver that will be inserted */
|
||||
static struct i2c_driver pmbus_driver = {
|
||||
.driver = {
|
||||
.name = "pmbus",
|
||||
},
|
||||
.probe = pmbus_probe,
|
||||
.remove = pmbus_remove,
|
||||
.id_table = pmbus_id,
|
||||
};
|
||||
|
||||
static int __init pmbus_init(void)
|
||||
{
|
||||
return i2c_add_driver(&pmbus_driver);
|
||||
}
|
||||
|
||||
static void __exit pmbus_exit(void)
|
||||
{
|
||||
i2c_del_driver(&pmbus_driver);
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Guenter Roeck");
|
||||
MODULE_DESCRIPTION("Generic PMBus driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
module_init(pmbus_init);
|
||||
module_exit(pmbus_exit);
|
313
drivers/hwmon/pmbus.h
Normal file
313
drivers/hwmon/pmbus.h
Normal file
|
@ -0,0 +1,313 @@
|
|||
/*
|
||||
* pmbus.h - Common defines and structures for PMBus devices
|
||||
*
|
||||
* Copyright (c) 2010, 2011 Ericsson AB.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef PMBUS_H
|
||||
#define PMBUS_H
|
||||
|
||||
/*
|
||||
* Registers
|
||||
*/
|
||||
#define PMBUS_PAGE 0x00
|
||||
#define PMBUS_OPERATION 0x01
|
||||
#define PMBUS_ON_OFF_CONFIG 0x02
|
||||
#define PMBUS_CLEAR_FAULTS 0x03
|
||||
#define PMBUS_PHASE 0x04
|
||||
|
||||
#define PMBUS_CAPABILITY 0x19
|
||||
#define PMBUS_QUERY 0x1A
|
||||
|
||||
#define PMBUS_VOUT_MODE 0x20
|
||||
#define PMBUS_VOUT_COMMAND 0x21
|
||||
#define PMBUS_VOUT_TRIM 0x22
|
||||
#define PMBUS_VOUT_CAL_OFFSET 0x23
|
||||
#define PMBUS_VOUT_MAX 0x24
|
||||
#define PMBUS_VOUT_MARGIN_HIGH 0x25
|
||||
#define PMBUS_VOUT_MARGIN_LOW 0x26
|
||||
#define PMBUS_VOUT_TRANSITION_RATE 0x27
|
||||
#define PMBUS_VOUT_DROOP 0x28
|
||||
#define PMBUS_VOUT_SCALE_LOOP 0x29
|
||||
#define PMBUS_VOUT_SCALE_MONITOR 0x2A
|
||||
|
||||
#define PMBUS_COEFFICIENTS 0x30
|
||||
#define PMBUS_POUT_MAX 0x31
|
||||
|
||||
#define PMBUS_FAN_CONFIG_12 0x3A
|
||||
#define PMBUS_FAN_COMMAND_1 0x3B
|
||||
#define PMBUS_FAN_COMMAND_2 0x3C
|
||||
#define PMBUS_FAN_CONFIG_34 0x3D
|
||||
#define PMBUS_FAN_COMMAND_3 0x3E
|
||||
#define PMBUS_FAN_COMMAND_4 0x3F
|
||||
|
||||
#define PMBUS_VOUT_OV_FAULT_LIMIT 0x40
|
||||
#define PMBUS_VOUT_OV_FAULT_RESPONSE 0x41
|
||||
#define PMBUS_VOUT_OV_WARN_LIMIT 0x42
|
||||
#define PMBUS_VOUT_UV_WARN_LIMIT 0x43
|
||||
#define PMBUS_VOUT_UV_FAULT_LIMIT 0x44
|
||||
#define PMBUS_VOUT_UV_FAULT_RESPONSE 0x45
|
||||
#define PMBUS_IOUT_OC_FAULT_LIMIT 0x46
|
||||
#define PMBUS_IOUT_OC_FAULT_RESPONSE 0x47
|
||||
#define PMBUS_IOUT_OC_LV_FAULT_LIMIT 0x48
|
||||
#define PMBUS_IOUT_OC_LV_FAULT_RESPONSE 0x49
|
||||
#define PMBUS_IOUT_OC_WARN_LIMIT 0x4A
|
||||
#define PMBUS_IOUT_UC_FAULT_LIMIT 0x4B
|
||||
#define PMBUS_IOUT_UC_FAULT_RESPONSE 0x4C
|
||||
|
||||
#define PMBUS_OT_FAULT_LIMIT 0x4F
|
||||
#define PMBUS_OT_FAULT_RESPONSE 0x50
|
||||
#define PMBUS_OT_WARN_LIMIT 0x51
|
||||
#define PMBUS_UT_WARN_LIMIT 0x52
|
||||
#define PMBUS_UT_FAULT_LIMIT 0x53
|
||||
#define PMBUS_UT_FAULT_RESPONSE 0x54
|
||||
#define PMBUS_VIN_OV_FAULT_LIMIT 0x55
|
||||
#define PMBUS_VIN_OV_FAULT_RESPONSE 0x56
|
||||
#define PMBUS_VIN_OV_WARN_LIMIT 0x57
|
||||
#define PMBUS_VIN_UV_WARN_LIMIT 0x58
|
||||
#define PMBUS_VIN_UV_FAULT_LIMIT 0x59
|
||||
|
||||
#define PMBUS_IIN_OC_FAULT_LIMIT 0x5B
|
||||
#define PMBUS_IIN_OC_WARN_LIMIT 0x5D
|
||||
|
||||
#define PMBUS_POUT_OP_FAULT_LIMIT 0x68
|
||||
#define PMBUS_POUT_OP_WARN_LIMIT 0x6A
|
||||
#define PMBUS_PIN_OP_WARN_LIMIT 0x6B
|
||||
|
||||
#define PMBUS_STATUS_BYTE 0x78
|
||||
#define PMBUS_STATUS_WORD 0x79
|
||||
#define PMBUS_STATUS_VOUT 0x7A
|
||||
#define PMBUS_STATUS_IOUT 0x7B
|
||||
#define PMBUS_STATUS_INPUT 0x7C
|
||||
#define PMBUS_STATUS_TEMPERATURE 0x7D
|
||||
#define PMBUS_STATUS_CML 0x7E
|
||||
#define PMBUS_STATUS_OTHER 0x7F
|
||||
#define PMBUS_STATUS_MFR_SPECIFIC 0x80
|
||||
#define PMBUS_STATUS_FAN_12 0x81
|
||||
#define PMBUS_STATUS_FAN_34 0x82
|
||||
|
||||
#define PMBUS_READ_VIN 0x88
|
||||
#define PMBUS_READ_IIN 0x89
|
||||
#define PMBUS_READ_VCAP 0x8A
|
||||
#define PMBUS_READ_VOUT 0x8B
|
||||
#define PMBUS_READ_IOUT 0x8C
|
||||
#define PMBUS_READ_TEMPERATURE_1 0x8D
|
||||
#define PMBUS_READ_TEMPERATURE_2 0x8E
|
||||
#define PMBUS_READ_TEMPERATURE_3 0x8F
|
||||
#define PMBUS_READ_FAN_SPEED_1 0x90
|
||||
#define PMBUS_READ_FAN_SPEED_2 0x91
|
||||
#define PMBUS_READ_FAN_SPEED_3 0x92
|
||||
#define PMBUS_READ_FAN_SPEED_4 0x93
|
||||
#define PMBUS_READ_DUTY_CYCLE 0x94
|
||||
#define PMBUS_READ_FREQUENCY 0x95
|
||||
#define PMBUS_READ_POUT 0x96
|
||||
#define PMBUS_READ_PIN 0x97
|
||||
|
||||
#define PMBUS_REVISION 0x98
|
||||
#define PMBUS_MFR_ID 0x99
|
||||
#define PMBUS_MFR_MODEL 0x9A
|
||||
#define PMBUS_MFR_REVISION 0x9B
|
||||
#define PMBUS_MFR_LOCATION 0x9C
|
||||
#define PMBUS_MFR_DATE 0x9D
|
||||
#define PMBUS_MFR_SERIAL 0x9E
|
||||
|
||||
/*
|
||||
* CAPABILITY
|
||||
*/
|
||||
#define PB_CAPABILITY_SMBALERT (1<<4)
|
||||
#define PB_CAPABILITY_ERROR_CHECK (1<<7)
|
||||
|
||||
/*
|
||||
* VOUT_MODE
|
||||
*/
|
||||
#define PB_VOUT_MODE_MODE_MASK 0xe0
|
||||
#define PB_VOUT_MODE_PARAM_MASK 0x1f
|
||||
|
||||
#define PB_VOUT_MODE_LINEAR 0x00
|
||||
#define PB_VOUT_MODE_VID 0x20
|
||||
#define PB_VOUT_MODE_DIRECT 0x40
|
||||
|
||||
/*
|
||||
* Fan configuration
|
||||
*/
|
||||
#define PB_FAN_2_PULSE_MASK ((1 << 0) | (1 << 1))
|
||||
#define PB_FAN_2_RPM (1 << 2)
|
||||
#define PB_FAN_2_INSTALLED (1 << 3)
|
||||
#define PB_FAN_1_PULSE_MASK ((1 << 4) | (1 << 5))
|
||||
#define PB_FAN_1_RPM (1 << 6)
|
||||
#define PB_FAN_1_INSTALLED (1 << 7)
|
||||
|
||||
/*
|
||||
* STATUS_BYTE, STATUS_WORD (lower)
|
||||
*/
|
||||
#define PB_STATUS_NONE_ABOVE (1<<0)
|
||||
#define PB_STATUS_CML (1<<1)
|
||||
#define PB_STATUS_TEMPERATURE (1<<2)
|
||||
#define PB_STATUS_VIN_UV (1<<3)
|
||||
#define PB_STATUS_IOUT_OC (1<<4)
|
||||
#define PB_STATUS_VOUT_OV (1<<5)
|
||||
#define PB_STATUS_OFF (1<<6)
|
||||
#define PB_STATUS_BUSY (1<<7)
|
||||
|
||||
/*
|
||||
* STATUS_WORD (upper)
|
||||
*/
|
||||
#define PB_STATUS_UNKNOWN (1<<8)
|
||||
#define PB_STATUS_OTHER (1<<9)
|
||||
#define PB_STATUS_FANS (1<<10)
|
||||
#define PB_STATUS_POWER_GOOD_N (1<<11)
|
||||
#define PB_STATUS_WORD_MFR (1<<12)
|
||||
#define PB_STATUS_INPUT (1<<13)
|
||||
#define PB_STATUS_IOUT_POUT (1<<14)
|
||||
#define PB_STATUS_VOUT (1<<15)
|
||||
|
||||
/*
|
||||
* STATUS_IOUT
|
||||
*/
|
||||
#define PB_POUT_OP_WARNING (1<<0)
|
||||
#define PB_POUT_OP_FAULT (1<<1)
|
||||
#define PB_POWER_LIMITING (1<<2)
|
||||
#define PB_CURRENT_SHARE_FAULT (1<<3)
|
||||
#define PB_IOUT_UC_FAULT (1<<4)
|
||||
#define PB_IOUT_OC_WARNING (1<<5)
|
||||
#define PB_IOUT_OC_LV_FAULT (1<<6)
|
||||
#define PB_IOUT_OC_FAULT (1<<7)
|
||||
|
||||
/*
|
||||
* STATUS_VOUT, STATUS_INPUT
|
||||
*/
|
||||
#define PB_VOLTAGE_UV_FAULT (1<<4)
|
||||
#define PB_VOLTAGE_UV_WARNING (1<<5)
|
||||
#define PB_VOLTAGE_OV_WARNING (1<<6)
|
||||
#define PB_VOLTAGE_OV_FAULT (1<<7)
|
||||
|
||||
/*
|
||||
* STATUS_INPUT
|
||||
*/
|
||||
#define PB_PIN_OP_WARNING (1<<0)
|
||||
#define PB_IIN_OC_WARNING (1<<1)
|
||||
#define PB_IIN_OC_FAULT (1<<2)
|
||||
|
||||
/*
|
||||
* STATUS_TEMPERATURE
|
||||
*/
|
||||
#define PB_TEMP_UT_FAULT (1<<4)
|
||||
#define PB_TEMP_UT_WARNING (1<<5)
|
||||
#define PB_TEMP_OT_WARNING (1<<6)
|
||||
#define PB_TEMP_OT_FAULT (1<<7)
|
||||
|
||||
/*
|
||||
* STATUS_FAN
|
||||
*/
|
||||
#define PB_FAN_AIRFLOW_WARNING (1<<0)
|
||||
#define PB_FAN_AIRFLOW_FAULT (1<<1)
|
||||
#define PB_FAN_FAN2_SPEED_OVERRIDE (1<<2)
|
||||
#define PB_FAN_FAN1_SPEED_OVERRIDE (1<<3)
|
||||
#define PB_FAN_FAN2_WARNING (1<<4)
|
||||
#define PB_FAN_FAN1_WARNING (1<<5)
|
||||
#define PB_FAN_FAN2_FAULT (1<<6)
|
||||
#define PB_FAN_FAN1_FAULT (1<<7)
|
||||
|
||||
/*
|
||||
* CML_FAULT_STATUS
|
||||
*/
|
||||
#define PB_CML_FAULT_OTHER_MEM_LOGIC (1<<0)
|
||||
#define PB_CML_FAULT_OTHER_COMM (1<<1)
|
||||
#define PB_CML_FAULT_PROCESSOR (1<<3)
|
||||
#define PB_CML_FAULT_MEMORY (1<<4)
|
||||
#define PB_CML_FAULT_PACKET_ERROR (1<<5)
|
||||
#define PB_CML_FAULT_INVALID_DATA (1<<6)
|
||||
#define PB_CML_FAULT_INVALID_COMMAND (1<<7)
|
||||
|
||||
enum pmbus_sensor_classes {
|
||||
PSC_VOLTAGE_IN = 0,
|
||||
PSC_VOLTAGE_OUT,
|
||||
PSC_CURRENT_IN,
|
||||
PSC_CURRENT_OUT,
|
||||
PSC_POWER,
|
||||
PSC_TEMPERATURE,
|
||||
PSC_FAN,
|
||||
PSC_NUM_CLASSES /* Number of power sensor classes */
|
||||
};
|
||||
|
||||
#define PMBUS_PAGES 32 /* Per PMBus specification */
|
||||
|
||||
/* Functionality bit mask */
|
||||
#define PMBUS_HAVE_VIN (1 << 0)
|
||||
#define PMBUS_HAVE_VCAP (1 << 1)
|
||||
#define PMBUS_HAVE_VOUT (1 << 2)
|
||||
#define PMBUS_HAVE_IIN (1 << 3)
|
||||
#define PMBUS_HAVE_IOUT (1 << 4)
|
||||
#define PMBUS_HAVE_PIN (1 << 5)
|
||||
#define PMBUS_HAVE_POUT (1 << 6)
|
||||
#define PMBUS_HAVE_FAN12 (1 << 7)
|
||||
#define PMBUS_HAVE_FAN34 (1 << 8)
|
||||
#define PMBUS_HAVE_TEMP (1 << 9)
|
||||
#define PMBUS_HAVE_TEMP2 (1 << 10)
|
||||
#define PMBUS_HAVE_TEMP3 (1 << 11)
|
||||
#define PMBUS_HAVE_STATUS_VOUT (1 << 12)
|
||||
#define PMBUS_HAVE_STATUS_IOUT (1 << 13)
|
||||
#define PMBUS_HAVE_STATUS_INPUT (1 << 14)
|
||||
#define PMBUS_HAVE_STATUS_TEMP (1 << 15)
|
||||
#define PMBUS_HAVE_STATUS_FAN12 (1 << 16)
|
||||
#define PMBUS_HAVE_STATUS_FAN34 (1 << 17)
|
||||
|
||||
struct pmbus_driver_info {
|
||||
int pages; /* Total number of pages */
|
||||
bool direct[PSC_NUM_CLASSES];
|
||||
/* true if device uses direct data format
|
||||
for the given sensor class */
|
||||
/*
|
||||
* Support one set of coefficients for each sensor type
|
||||
* Used for chips providing data in direct mode.
|
||||
*/
|
||||
int m[PSC_NUM_CLASSES]; /* mantissa for direct data format */
|
||||
int b[PSC_NUM_CLASSES]; /* offset */
|
||||
int R[PSC_NUM_CLASSES]; /* exponent */
|
||||
|
||||
u32 func[PMBUS_PAGES]; /* Functionality, per page */
|
||||
/*
|
||||
* The get_status function maps manufacturing specific status values
|
||||
* into PMBus standard status values.
|
||||
* This function is optional and only necessary if chip specific status
|
||||
* register values have to be mapped into standard PMBus status register
|
||||
* values.
|
||||
*/
|
||||
int (*get_status)(struct i2c_client *client, int page, int reg);
|
||||
/*
|
||||
* The identify function determines supported PMBus functionality.
|
||||
* This function is only necessary if a chip driver supports multiple
|
||||
* chips, and the chip functionality is not pre-determined.
|
||||
*/
|
||||
int (*identify)(struct i2c_client *client,
|
||||
struct pmbus_driver_info *info);
|
||||
};
|
||||
|
||||
/* Function declarations */
|
||||
|
||||
int pmbus_set_page(struct i2c_client *client, u8 page);
|
||||
int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg);
|
||||
void pmbus_clear_faults(struct i2c_client *client);
|
||||
bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg);
|
||||
bool pmbus_check_word_register(struct i2c_client *client, int page, int reg);
|
||||
int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id,
|
||||
struct pmbus_driver_info *info);
|
||||
int pmbus_do_remove(struct i2c_client *client);
|
||||
const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client
|
||||
*client);
|
||||
|
||||
#endif /* PMBUS_H */
|
1628
drivers/hwmon/pmbus_core.c
Normal file
1628
drivers/hwmon/pmbus_core.c
Normal file
File diff suppressed because it is too large
Load diff
45
include/linux/i2c/pmbus.h
Normal file
45
include/linux/i2c/pmbus.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Hardware monitoring driver for PMBus devices
|
||||
*
|
||||
* Copyright (c) 2010, 2011 Ericsson AB.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _PMBUS_H_
|
||||
#define _PMBUS_H_
|
||||
|
||||
/* flags */
|
||||
|
||||
/*
|
||||
* PMBUS_SKIP_STATUS_CHECK
|
||||
*
|
||||
* During register detection, skip checking the status register for
|
||||
* communication or command errors.
|
||||
*
|
||||
* Some PMBus chips respond with valid data when trying to read an unsupported
|
||||
* register. For such chips, checking the status register is mandatory when
|
||||
* trying to determine if a chip register exists or not.
|
||||
* Other PMBus chips don't support the STATUS_CML register, or report
|
||||
* communication errors for no explicable reason. For such chips, checking
|
||||
* the status register must be disabled.
|
||||
*/
|
||||
#define PMBUS_SKIP_STATUS_CHECK (1 << 0)
|
||||
|
||||
struct pmbus_platform_data {
|
||||
u32 flags; /* Device specific flags */
|
||||
};
|
||||
|
||||
#endif /* _PMBUS_H_ */
|
Loading…
Reference in a new issue