Skip to content

Commit

Permalink
Merge branch 'hwmon-next' of git://git.kernel.org/pub/scm/linux/kerne…
Browse files Browse the repository at this point in the history
…l/git/groeck/linux-staging.git
  • Loading branch information
sfrothwell committed Sep 16, 2021
2 parents ccd951f + ec3c3d1 commit 8c1b0fe
Show file tree
Hide file tree
Showing 9 changed files with 717 additions and 67 deletions.
37 changes: 37 additions & 0 deletions Documentation/devicetree/bindings/hwmon/iio-hwmon.yaml
@@ -0,0 +1,37 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: "http://devicetree.org/schemas/hwmon/iio-hwmon.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"

title: ADC-attached Hardware Sensor Device Tree Bindings

maintainers:
- Jonathan Cameron <jic23@kernel.org>

description: >
Bindings for hardware monitoring devices connected to ADC controllers
supporting the Industrial I/O bindings.
properties:
compatible:
const: iio-hwmon

io-channels:
minItems: 1
maxItems: 8 # Should be enough
description: >
List of phandles to ADC channels to read the monitoring values
required:
- compatible
- io-channels

additionalProperties: false

examples:
- |
iio-hwmon {
compatible = "iio-hwmon";
io-channels = <&adc 1>, <&adc 2>;
};
1 change: 1 addition & 0 deletions Documentation/hwmon/index.rst
Expand Up @@ -130,6 +130,7 @@ Hardware Monitoring Kernel Drivers
max31785
max31790
max34440
max6620
max6639
max6642
max6650
Expand Down
46 changes: 46 additions & 0 deletions Documentation/hwmon/max6620.rst
@@ -0,0 +1,46 @@
.. SPDX-License-Identifier: GPL-2.0-or-later
Kernel driver max6620
=====================

Supported chips:

Maxim MAX6620

Prefix: 'max6620'

Addresses scanned: none

Datasheet: http://pdfserv.maxim-ic.com/en/ds/MAX6620.pdf

Authors:
- L\. Grunenberg <contact@lgrunenberg.de>
- Cumulus Networks <support@cumulusnetworks.com>
- Shuotian Cheng <shuche@microsoft.com>
- Arun Saravanan Balachandran <Arun_Saravanan_Balac@dell.com>

Description
-----------

This driver implements support for Maxim MAX6620 fan controller.

The driver configures the fan controller in RPM mode. To give the readings more
range or accuracy, the desired value can be set by a programmable register
(1, 2, 4, 8, 16 or 32). Set higher values for larger speeds.

The driver provides the following sensor access in sysfs:

================ ======= =====================================================
fan[1-4]_alarm ro Fan alarm.
fan[1-4]_div rw Sets the nominal RPM range of the fan. Valid values
are 1, 2, 4, 8, 16 and 32.
fan[1-4]_input ro Fan speed in RPM.
fan[1-4]_target rw Desired fan speed in RPM.
================ ======= =====================================================

Usage notes
-----------

This driver does not auto-detect devices. You will have to instantiate the
devices explicitly. Please see Documentation/i2c/instantiating-devices.rst for
details.
10 changes: 10 additions & 0 deletions drivers/hwmon/Kconfig
Expand Up @@ -1032,6 +1032,16 @@ config SENSORS_MAX31730
This driver can also be built as a module. If so, the module
will be called max31730.

config SENSORS_MAX6620
tristate "Maxim MAX6620 fan controller"
depends on I2C
help
If you say yes here you get support for the MAX6620
fan controller.

This driver can also be built as a module. If so, the module
will be called max6620.

config SENSORS_MAX6621
tristate "Maxim MAX6621 sensor chip"
depends on I2C
Expand Down
1 change: 1 addition & 0 deletions drivers/hwmon/Makefile
Expand Up @@ -135,6 +135,7 @@ obj-$(CONFIG_SENSORS_MAX1668) += max1668.o
obj-$(CONFIG_SENSORS_MAX197) += max197.o
obj-$(CONFIG_SENSORS_MAX31722) += max31722.o
obj-$(CONFIG_SENSORS_MAX31730) += max31730.o
obj-$(CONFIG_SENSORS_MAX6620) += max6620.o
obj-$(CONFIG_SENSORS_MAX6621) += max6621.o
obj-$(CONFIG_SENSORS_MAX6639) += max6639.o
obj-$(CONFIG_SENSORS_MAX6642) += max6642.o
Expand Down
114 changes: 61 additions & 53 deletions drivers/hwmon/i5500_temp.c
Expand Up @@ -5,14 +5,14 @@
* Copyright (C) 2012, 2014 Jean Delvare <jdelvare@suse.de>
*/

#include <linux/bitops.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/device.h>
#include <linux/pci.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>

Expand All @@ -29,69 +29,78 @@
#define REG_CTCTRL 0xF7
#define REG_TSTIMER 0xF8

/*
* Sysfs stuff
*/

/* Sensor resolution : 0.5 degree C */
static ssize_t temp1_input_show(struct device *dev,
struct device_attribute *devattr, char *buf)
static umode_t i5500_is_visible(const void *drvdata, enum hwmon_sensor_types type, u32 attr,
int channel)
{
struct pci_dev *pdev = to_pci_dev(dev->parent);
long temp;
u16 tsthrhi;
s8 tsfsc;

pci_read_config_word(pdev, REG_TSTHRHI, &tsthrhi);
pci_read_config_byte(pdev, REG_TSFSC, &tsfsc);
temp = ((long)tsthrhi - tsfsc) * 500;

return sprintf(buf, "%ld\n", temp);
return 0444;
}

static ssize_t thresh_show(struct device *dev,
struct device_attribute *devattr, char *buf)
static int i5500_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel,
long *val)
{
struct pci_dev *pdev = to_pci_dev(dev->parent);
int reg = to_sensor_dev_attr(devattr)->index;
long temp;
u16 tsthr;
s8 tsfsc;
u8 ctsts;

pci_read_config_word(pdev, reg, &tsthr);
temp = tsthr * 500;
switch (type) {
case hwmon_temp:
switch (attr) {
/* Sensor resolution : 0.5 degree C */
case hwmon_temp_input:
pci_read_config_word(pdev, REG_TSTHRHI, &tsthr);
pci_read_config_byte(pdev, REG_TSFSC, &tsfsc);
*val = (tsthr - tsfsc) * 500;
return 0;
case hwmon_temp_max:
pci_read_config_word(pdev, REG_TSTHRHI, &tsthr);
*val = tsthr * 500;
return 0;
case hwmon_temp_max_hyst:
pci_read_config_word(pdev, REG_TSTHRLO, &tsthr);
*val = tsthr * 500;
return 0;
case hwmon_temp_crit:
pci_read_config_word(pdev, REG_TSTHRCATA, &tsthr);
*val = tsthr * 500;
return 0;
case hwmon_temp_max_alarm:
pci_read_config_byte(pdev, REG_CTSTS, &ctsts);
*val = !!(ctsts & BIT(1));
return 0;
case hwmon_temp_crit_alarm:
pci_read_config_byte(pdev, REG_CTSTS, &ctsts);
*val = !!(ctsts & BIT(0));
return 0;
default:
break;
}
break;
default:
break;
}

return sprintf(buf, "%ld\n", temp);
return -EOPNOTSUPP;
}

static ssize_t alarm_show(struct device *dev,
struct device_attribute *devattr, char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev->parent);
int nr = to_sensor_dev_attr(devattr)->index;
u8 ctsts;

pci_read_config_byte(pdev, REG_CTSTS, &ctsts);
return sprintf(buf, "%u\n", (unsigned int)ctsts & (1 << nr));
}
static const struct hwmon_ops i5500_ops = {
.is_visible = i5500_is_visible,
.read = i5500_read,
};

static DEVICE_ATTR_RO(temp1_input);
static SENSOR_DEVICE_ATTR_RO(temp1_crit, thresh, 0xE2);
static SENSOR_DEVICE_ATTR_RO(temp1_max_hyst, thresh, 0xEC);
static SENSOR_DEVICE_ATTR_RO(temp1_max, thresh, 0xEE);
static SENSOR_DEVICE_ATTR_RO(temp1_crit_alarm, alarm, 0);
static SENSOR_DEVICE_ATTR_RO(temp1_max_alarm, alarm, 1);

static struct attribute *i5500_temp_attrs[] = {
&dev_attr_temp1_input.attr,
&sensor_dev_attr_temp1_crit.dev_attr.attr,
&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr,
&sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
&sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
static const struct hwmon_channel_info *i5500_info[] = {
HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
HWMON_CHANNEL_INFO(temp,
HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST | HWMON_T_CRIT |
HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM
),
NULL
};

ATTRIBUTE_GROUPS(i5500_temp);
static const struct hwmon_chip_info i5500_chip_info = {
.ops = &i5500_ops,
.info = i5500_info,
};

static const struct pci_device_id i5500_temp_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3438) },
Expand Down Expand Up @@ -121,9 +130,8 @@ static int i5500_temp_probe(struct pci_dev *pdev,
return -ENODEV;
}

hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev,
"intel5500", NULL,
i5500_temp_groups);
hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev, "intel5500", NULL,
&i5500_chip_info, NULL);
return PTR_ERR_OR_ZERO(hwmon_dev);
}

Expand Down

0 comments on commit 8c1b0fe

Please sign in to comment.