From f89ce2706d8341c921b96e13a00b951a10eed308 Mon Sep 17 00:00:00 2001 From: Aravind Gopalakrishnan Date: Thu, 14 Aug 2014 18:15:27 -0500 Subject: hwmon: (k10temp) Add support for F15h M60h This patch adds temperature monitoring support for F15h M60h processor. - Add new pci device id for the relevant processor - The functionality of REG_REPORTED_TEMPERATURE is moved to D0F0xBC_xD820_0CA4 [Reported Temperature Control] - So, use this to get CUR_TEMP value - Since we need an indirect register access, protect this with a mutex lock - Add Kconfig, Doc entries to indicate support for this processor. Signed-off-by: Aravind Gopalakrishnan Acked-by: Borislav Petkov Acked-by: Clemens Ladisch [Guenter Roeck: Declare new mutex and function static] Signed-off-by: Guenter Roeck --- Documentation/hwmon/k10temp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/hwmon/k10temp b/Documentation/hwmon/k10temp index ee6d30ec1522..254d2f55345a 100644 --- a/Documentation/hwmon/k10temp +++ b/Documentation/hwmon/k10temp @@ -11,7 +11,7 @@ Supported chips: Socket S1G2: Athlon (X2), Sempron (X2), Turion X2 (Ultra) * AMD Family 12h processors: "Llano" (E2/A4/A6/A8-Series) * AMD Family 14h processors: "Brazos" (C/E/G/Z-Series) -* AMD Family 15h processors: "Bulldozer" (FX-Series), "Trinity", "Kaveri" +* AMD Family 15h processors: "Bulldozer" (FX-Series), "Trinity", "Kaveri", "Carrizo" * AMD Family 16h processors: "Kabini", "Mullins" Prefix: 'k10temp' -- cgit v1.2.3 From c08860ffe5c0e986e208e8217dae8191c0b40b24 Mon Sep 17 00:00:00 2001 From: Jonghwa Lee Date: Wed, 17 Sep 2014 14:54:37 +0900 Subject: hwmon: (ntc_thermistor) Add ntc thermistor to thermal subsystem as a sensor. To get more comprehensive and integrated thermal management, it adds ntc thermistor to thermal framework as a thermal sensor. It's governed thermal susbsystem only if it is described in DT node. Otherwise, it just notifies temperature to userspace via sysfs as it used to be. Signed-off-by: Jonghwa Lee Signed-off-by: Guenter Roeck --- .../devicetree/bindings/hwmon/ntc_thermistor.txt | 3 +++ drivers/hwmon/Kconfig | 1 + drivers/hwmon/ntc_thermistor.c | 25 ++++++++++++++++++++++ 3 files changed, 29 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/hwmon/ntc_thermistor.txt b/Documentation/devicetree/bindings/hwmon/ntc_thermistor.txt index 2391e5c41999..fcca8e744f41 100644 --- a/Documentation/devicetree/bindings/hwmon/ntc_thermistor.txt +++ b/Documentation/devicetree/bindings/hwmon/ntc_thermistor.txt @@ -25,6 +25,9 @@ Requires node properties: - "io-channels" Channel node of ADC to be used for conversion. +Optional node properties: +- "#thermal-sensor-cells" Used to expose itself to thermal fw. + Read more about iio bindings at Documentation/devicetree/bindings/iio/iio-bindings.txt diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 4289a4fa1a03..f790b41283d0 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1077,6 +1077,7 @@ config SENSORS_PC87427 config SENSORS_NTC_THERMISTOR tristate "NTC thermistor support from Murata" depends on !OF || IIO=n || IIO + depends on THERMAL || !THERMAL_OF help This driver supports NTC thermistors sensor reading and its interpretation. The driver can also monitor the temperature and diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c index bd410722cd4b..4ff89b2482e4 100644 --- a/drivers/hwmon/ntc_thermistor.c +++ b/drivers/hwmon/ntc_thermistor.c @@ -38,6 +38,7 @@ #include #include +#include struct ntc_compensation { int temp_c; @@ -182,6 +183,7 @@ struct ntc_data { struct device *dev; int n_comp; char name[PLATFORM_NAME_SIZE]; + struct thermal_zone_device *tz; }; #if defined(CONFIG_OF) && IS_ENABLED(CONFIG_IIO) @@ -428,6 +430,20 @@ static int ntc_thermistor_get_ohm(struct ntc_data *data) return -EINVAL; } +static int ntc_read_temp(void *dev, long *temp) +{ + struct ntc_data *data = dev_get_drvdata(dev); + int ohm; + + ohm = ntc_thermistor_get_ohm(data); + if (ohm < 0) + return ohm; + + *temp = get_temp_mc(data, ohm); + + return 0; +} + static ssize_t ntc_show_name(struct device *dev, struct device_attribute *attr, char *buf) { @@ -562,6 +578,13 @@ static int ntc_thermistor_probe(struct platform_device *pdev) dev_info(&pdev->dev, "Thermistor type: %s successfully probed.\n", pdev_id->name); + data->tz = thermal_zone_of_sensor_register(data->dev, 0, data->dev, + ntc_read_temp, NULL); + if (IS_ERR(data->tz)) { + dev_dbg(&pdev->dev, "Failed to register to thermal fw.\n"); + data->tz = NULL; + } + return 0; err_after_sysfs: sysfs_remove_group(&data->dev->kobj, &ntc_attr_group); @@ -578,6 +601,8 @@ static int ntc_thermistor_remove(struct platform_device *pdev) sysfs_remove_group(&data->dev->kobj, &ntc_attr_group); ntc_iio_channel_release(pdata); + thermal_zone_of_sensor_unregister(data->dev, data->tz); + return 0; } -- cgit v1.2.3 From 964356938fcd3c0001a786f55b9f0a0fbe47656a Mon Sep 17 00:00:00 2001 From: Andreas Werner Date: Wed, 27 Aug 2014 19:53:06 +0200 Subject: hwmon: (menf21bmc) Introduce MEN14F021P00 BMC HWMON driver Added driver to support the 14F021P00 BMC Hardware Monitoring. The BMC is a Board Management Controller including monitoring of the board voltages. Signed-off-by: Andreas Werner Reviewed-by: Guenter Roeck Signed-off-by: Lee Jones --- Documentation/hwmon/menf21bmc | 50 +++++++++ drivers/hwmon/Kconfig | 10 ++ drivers/hwmon/Makefile | 1 + drivers/hwmon/menf21bmc_hwmon.c | 230 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 291 insertions(+) create mode 100644 Documentation/hwmon/menf21bmc create mode 100644 drivers/hwmon/menf21bmc_hwmon.c (limited to 'Documentation') diff --git a/Documentation/hwmon/menf21bmc b/Documentation/hwmon/menf21bmc new file mode 100644 index 000000000000..2a273a065c5e --- /dev/null +++ b/Documentation/hwmon/menf21bmc @@ -0,0 +1,50 @@ +Kernel driver menf21bmc_hwmon +============================= + +Supported chips: + * MEN 14F021P00 + Prefix: 'menf21bmc_hwmon' + Adresses scanned: - + +Author: Andreas Werner + +Description +----------- + +The menf21bmc is a Board Management Controller (BMC) which provides an I2C +interface to the host to access the features implemented in the BMC. + +This driver gives access to the voltage monitoring feature of the main +voltages of the board. +The voltage sensors are connected to the ADC inputs of the BMC which is +a PIC16F917 Mikrocontroller. + +Usage Notes +----------- + +This driver is part of the MFD driver named "menf21bmc" and does +not auto-detect devices. +You will have to instantiate the MFD driver explicitly. +Please see Documentation/i2c/instantiating-devices for +details. + +Sysfs entries +------------- + +The following attributes are supported. All attributes are read only +The Limits are read once by the driver. + +in0_input +3.3V input voltage +in1_input +5.0V input voltage +in2_input +12.0V input voltage +in3_input +5V Standby input voltage +in4_input VBAT (on board battery) + +in[0-4]_min Minimum voltage limit +in[0-4]_max Maximum voltage limit + +in0_label "MON_3_3V" +in1_label "MON_5V" +in2_label "MON_12V" +in3_label "5V_STANDBY" +in4_label "VBAT" diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index f00d048aa583..c08d172bbab4 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -839,6 +839,16 @@ config SENSORS_MCP3021 This driver can also be built as a module. If so, the module will be called mcp3021. +config SENSORS_MENF21BMC_HWMON + tristate "MEN 14F021P00 BMC Hardware Monitoring" + depends on MFD_MENF21BMC + help + Say Y here to include support for the MEN 14F021P00 BMC + hardware monitoring. + + This driver can also be built as a module. If so the module + will be called menf21bmc_hwmon. + config SENSORS_ADCXX tristate "National Semiconductor ADCxxxSxxx" depends on SPI_MASTER diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index be28152c9848..c90a7611efaa 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -115,6 +115,7 @@ obj-$(CONFIG_SENSORS_MAX6650) += max6650.o obj-$(CONFIG_SENSORS_MAX6697) += max6697.o obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o obj-$(CONFIG_SENSORS_MCP3021) += mcp3021.o +obj-$(CONFIG_SENSORS_MENF21BMC_HWMON) += menf21bmc_hwmon.o obj-$(CONFIG_SENSORS_NCT6683) += nct6683.o obj-$(CONFIG_SENSORS_NCT6775) += nct6775.o obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o diff --git a/drivers/hwmon/menf21bmc_hwmon.c b/drivers/hwmon/menf21bmc_hwmon.c new file mode 100644 index 000000000000..c92229d321c9 --- /dev/null +++ b/drivers/hwmon/menf21bmc_hwmon.c @@ -0,0 +1,230 @@ +/* + * MEN 14F021P00 Board Management Controller (BMC) hwmon driver. + * + * This is the core hwmon driver of the MEN 14F021P00 BMC. + * The BMC monitors the board voltages which can be access with this + * driver through sysfs. + * + * Copyright (C) 2014 MEN Mikro Elektronik Nuernberg GmbH + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "menf21bmc_hwmon" + +#define BMC_VOLT_COUNT 5 +#define MENF21BMC_V33 0 +#define MENF21BMC_V5 1 +#define MENF21BMC_V12 2 +#define MENF21BMC_V5_SB 3 +#define MENF21BMC_VBAT 4 + +#define IDX_TO_VOLT_MIN_CMD(idx) (0x40 + idx) +#define IDX_TO_VOLT_MAX_CMD(idx) (0x50 + idx) +#define IDX_TO_VOLT_INP_CMD(idx) (0x60 + idx) + +struct menf21bmc_hwmon { + bool valid; + struct i2c_client *i2c_client; + unsigned long last_update; + int in_val[BMC_VOLT_COUNT]; + int in_min[BMC_VOLT_COUNT]; + int in_max[BMC_VOLT_COUNT]; +}; + +static const char *const input_names[] = { + [MENF21BMC_V33] = "MON_3_3V", + [MENF21BMC_V5] = "MON_5V", + [MENF21BMC_V12] = "MON_12V", + [MENF21BMC_V5_SB] = "5V_STANDBY", + [MENF21BMC_VBAT] = "VBAT" +}; + +static struct menf21bmc_hwmon *menf21bmc_hwmon_update(struct device *dev) +{ + int i; + int val; + struct menf21bmc_hwmon *drv_data = dev_get_drvdata(dev); + struct menf21bmc_hwmon *data_ret = drv_data; + + if (time_after(jiffies, drv_data->last_update + HZ) + || !drv_data->valid) { + for (i = 0; i < BMC_VOLT_COUNT; i++) { + val = i2c_smbus_read_word_data(drv_data->i2c_client, + IDX_TO_VOLT_INP_CMD(i)); + if (val < 0) { + data_ret = ERR_PTR(val); + goto abort; + } + drv_data->in_val[i] = val; + } + drv_data->last_update = jiffies; + drv_data->valid = true; + } +abort: + return data_ret; +} + +static int menf21bmc_hwmon_get_volt_limits(struct menf21bmc_hwmon *drv_data) +{ + int i, val; + + for (i = 0; i < BMC_VOLT_COUNT; i++) { + val = i2c_smbus_read_word_data(drv_data->i2c_client, + IDX_TO_VOLT_MIN_CMD(i)); + if (val < 0) + return val; + + drv_data->in_min[i] = val; + + val = i2c_smbus_read_word_data(drv_data->i2c_client, + IDX_TO_VOLT_MAX_CMD(i)); + if (val < 0) + return val; + + drv_data->in_max[i] = val; + } + return 0; +} + +static ssize_t +show_label(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + + return sprintf(buf, "%s\n", input_names[attr->index]); +} + +static ssize_t +show_in(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct menf21bmc_hwmon *drv_data = menf21bmc_hwmon_update(dev); + + if (IS_ERR(drv_data)) + return PTR_ERR(drv_data); + + return sprintf(buf, "%d\n", drv_data->in_val[attr->index]); +} + +static ssize_t +show_min(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct menf21bmc_hwmon *drv_data = dev_get_drvdata(dev); + + return sprintf(buf, "%d\n", drv_data->in_min[attr->index]); +} + +static ssize_t +show_max(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct menf21bmc_hwmon *drv_data = dev_get_drvdata(dev); + + return sprintf(buf, "%d\n", drv_data->in_max[attr->index]); +} + +#define create_voltage_sysfs(idx) \ +static SENSOR_DEVICE_ATTR(in##idx##_input, S_IRUGO, \ + show_in, NULL, idx); \ +static SENSOR_DEVICE_ATTR(in##idx##_min, S_IRUGO, \ + show_min, NULL, idx); \ +static SENSOR_DEVICE_ATTR(in##idx##_max, S_IRUGO, \ + show_max, NULL, idx); \ +static SENSOR_DEVICE_ATTR(in##idx##_label, S_IRUGO, \ + show_label, NULL, idx); + +create_voltage_sysfs(0); +create_voltage_sysfs(1); +create_voltage_sysfs(2); +create_voltage_sysfs(3); +create_voltage_sysfs(4); + +static struct attribute *menf21bmc_hwmon_attrs[] = { + &sensor_dev_attr_in0_input.dev_attr.attr, + &sensor_dev_attr_in0_min.dev_attr.attr, + &sensor_dev_attr_in0_max.dev_attr.attr, + &sensor_dev_attr_in0_label.dev_attr.attr, + + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in1_min.dev_attr.attr, + &sensor_dev_attr_in1_max.dev_attr.attr, + &sensor_dev_attr_in1_label.dev_attr.attr, + + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in2_min.dev_attr.attr, + &sensor_dev_attr_in2_max.dev_attr.attr, + &sensor_dev_attr_in2_label.dev_attr.attr, + + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_in3_min.dev_attr.attr, + &sensor_dev_attr_in3_max.dev_attr.attr, + &sensor_dev_attr_in3_label.dev_attr.attr, + + &sensor_dev_attr_in4_input.dev_attr.attr, + &sensor_dev_attr_in4_min.dev_attr.attr, + &sensor_dev_attr_in4_max.dev_attr.attr, + &sensor_dev_attr_in4_label.dev_attr.attr, + NULL +}; + +ATTRIBUTE_GROUPS(menf21bmc_hwmon); + +static int menf21bmc_hwmon_probe(struct platform_device *pdev) +{ + int ret; + struct menf21bmc_hwmon *drv_data; + struct i2c_client *i2c_client = to_i2c_client(pdev->dev.parent); + struct device *hwmon_dev; + + drv_data = devm_kzalloc(&pdev->dev, sizeof(struct menf21bmc_hwmon), + GFP_KERNEL); + if (!drv_data) + return -ENOMEM; + + drv_data->i2c_client = i2c_client; + + ret = menf21bmc_hwmon_get_volt_limits(drv_data); + if (ret) { + dev_err(&pdev->dev, "failed to read sensor limits"); + return ret; + } + + hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, + "menf21bmc", drv_data, + menf21bmc_hwmon_groups); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); + + dev_info(&pdev->dev, "MEN 14F021P00 BMC hwmon device enabled"); + + return 0; +} + +static struct platform_driver menf21bmc_hwmon = { + .probe = menf21bmc_hwmon_probe, + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, +}; + +module_platform_driver(menf21bmc_hwmon); + +MODULE_AUTHOR("Andreas Werner "); +MODULE_DESCRIPTION("MEN 14F021P00 BMC hwmon"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:menf21bmc_hwmon"); -- cgit v1.2.3