2023-05-12 11:31:08

by Matyas, Daniel

[permalink] [raw]
Subject: [PATCH v8 1/2] dt-bindings: hwmon: add MAX31827

MAX31827 is a low-power temperature switch with I2C interface.

The device is a ±1°C accuracy from -40°C to +125°C
(12 bits) local temperature switch and sensor with I2C/SM-
Bus interface. The combination of small 6-bump wafer-lev-
el package (WLP) and high accuracy makes this temper-
ature sensor/switch ideal for a wide range of applications.

Signed-off-by: Daniel Matyas <[email protected]>
Reviewed-by: Rob Herring <[email protected]>
---

v7 -> v8: Added '--base=[Linux 6.4-rc1 commmit]' when using 'git
format-patch'

.../bindings/hwmon/adi,max31827.yaml | 54 +++++++++++++++++++
MAINTAINERS | 7 +++
2 files changed, 61 insertions(+)
create mode 100644 Documentation/devicetree/bindings/hwmon/adi,max31827.yaml

diff --git a/Documentation/devicetree/bindings/hwmon/adi,max31827.yaml b/Documentation/devicetree/bindings/hwmon/adi,max31827.yaml
new file mode 100644
index 000000000000..2dc8b07b4d3b
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwmon/adi,max31827.yaml
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hwmon/adi,max31827.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices MAX31827, MAX31828, MAX31829 Low-Power Temperature Switch
+
+maintainers:
+ - Daniel Matyas <[email protected]>
+
+description: |
+ Analog Devices MAX31827, MAX31828, MAX31829 Low-Power Temperature Switch with
+ I2C Interface
+ https://www.analog.com/media/en/technical-documentation/data-sheets/MAX31827-MAX31829.pdf
+
+properties:
+ compatible:
+ oneOf:
+ - const: adi,max31827
+ - items:
+ - enum:
+ - adi,max31828
+ - adi,max31829
+ - const: adi,max31827
+
+ reg:
+ maxItems: 1
+
+ vref-supply:
+ description:
+ Must have values in the interval (1.6V; 3.6V) in order for the device to
+ function correctly.
+
+required:
+ - compatible
+ - reg
+ - vref-supply
+
+additionalProperties: false
+
+examples:
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ temperature-sensor@42 {
+ compatible = "adi,max31827";
+ reg = <0x42>;
+ vref-supply = <&reg_vdd>;
+ };
+ };
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index e0ad886d3163..5d5359f59af5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12617,6 +12617,13 @@ F: Documentation/userspace-api/media/drivers/max2175.rst
F: drivers/media/i2c/max2175*
F: include/uapi/linux/max2175.h

+MAX31827 TEMPERATURE SWITCH DRIVER
+M: Daniel Matyas <[email protected]>
+L: [email protected]
+S: Supported
+W: http://ez.analog.com/community/linux-device-drivers
+F: Documentation/devicetree/bindings/hwmon/adi,max31827.yaml
+
MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER
L: [email protected]
S: Orphan

base-commit: ac9a78681b921877518763ba0e89202254349d1b
prerequisite-patch-id: 7a4b4994760cfa8c07187d319e53e9956a8b639e
prerequisite-patch-id: af1a81cb4ad3137780afb102586a3489f9615303
prerequisite-patch-id: a4ed1db487f0ee9506b3aa7bb672595a7b793cca
prerequisite-patch-id: 421416a1110c5cc09e11afe2db6528cbca6d9492
prerequisite-patch-id: 8ced9e002e35952cd614acc0e2108f17a502a5fc
prerequisite-patch-id: 82d101227b696dc95c11bca8594f80b438537359
prerequisite-patch-id: dfe7b1d583daa8dbb2d2af8fc993622b65f83826
prerequisite-patch-id: 431a19e35c672a668b696858eace775c56f1e1e7
prerequisite-patch-id: 0b485820cf1c980bba3adedb9fd88b87ee3cc157
prerequisite-patch-id: 8d767b2e1313428538bea1490032f639cd1ccff1
prerequisite-patch-id: c1ef543ae6716d6ccad416250ca68c8a0eec058f
prerequisite-patch-id: 4c78ac1e346676b76fd8850f8edc2b08bdb78f52
prerequisite-patch-id: e6fa20eba19f686b0f4133b1c7bd5894f703498f
prerequisite-patch-id: 83d74aa2b6f8cfefeb14dd5e90705982b952a757
prerequisite-patch-id: 4ac1c2c31de74af80624f66489fcc87e533dd32a
prerequisite-patch-id: 77a377c5214f2cddd3455d1fcda34ccf28973883
prerequisite-patch-id: 2edf34328d29191533344d36f43abdc7479b4ae2
prerequisite-patch-id: 77e8f55f78744797df7efdc0d2b18740cfe099b9
prerequisite-patch-id: ab123ba97f1abe14016c30fae72b55a87363d5ef
prerequisite-patch-id: 7323aaafb0edd7edd51a5c6f8be1bb275f9dba9c
prerequisite-patch-id: 4a61b49c7ab4522967fd122f8bf38d679022df57
prerequisite-patch-id: 869ae6fe33242cbc0373cf1e1e92c7b240f9e1ee
prerequisite-patch-id: 12f8d3b3d21ea08368246f7cf3d42ec920297953
prerequisite-patch-id: 3cdfc61d4d0aa70f68d095a7df4e814259e9cc47
prerequisite-patch-id: 726807583bfd50c10a1090f067261266efbc6aa9
prerequisite-patch-id: eea50a388d43e8447a5ef2969af5df7a354e356c
prerequisite-patch-id: db216360c53cefee67966e28397efcd0591601e7
prerequisite-patch-id: ff327329d945c9502df11b15f4d037d355bee546
prerequisite-patch-id: a197064fc6a5e20d4c9ef5f508491b457d2564ca
prerequisite-patch-id: c0d5d63ae43075a035a632d61975ad1e1bba4e69
prerequisite-patch-id: 2c4053f5cf0ab2707bd528a36a926f49d3e678ba
prerequisite-patch-id: 2bc0059cb68aa397ea841c153b2f6bfc4e998de8
prerequisite-patch-id: d5e64ab8afa8a2761a51ec295709ed25b65f450c
prerequisite-patch-id: c8d1ca12e9e502f366bf04d98b1011b299433d65
prerequisite-patch-id: 955a12cb7b43bb60c913c097f58c6bd6d131962e
prerequisite-patch-id: 142599135b7ffa62f14d96755c3a5c2db45140b9
prerequisite-patch-id: d8415b405107d9d024566a415ad1b03a4606f9e2
prerequisite-patch-id: 0ecb6a8d2c011477889ba4db43a79fe8b0031b5a
prerequisite-patch-id: e755275a6776660db45f4c77e83100df26b714e6
prerequisite-patch-id: 61989ab7e10a1fb21144ae314bb01772fceee65c
prerequisite-patch-id: 42f546d2579f59ae937ca266ad104a745141317a
prerequisite-patch-id: 8b3afdd0e40d71a10a8170dd1be45232838cea0b
prerequisite-patch-id: dd4a4ad7eed59aff993717ec6e4552e2220125a2
prerequisite-patch-id: 02012f5d2e0f147338b267a23ed715ca452ecea4
prerequisite-patch-id: fff041f18c7d7b462d4b4c89ec5259e19ad07307
prerequisite-patch-id: 419d0a8254089778c04f24cc702caa3d365ea375
prerequisite-patch-id: 4bcb80ddab7867c8186f340897583aab541642a8
prerequisite-patch-id: 2968cce365bedd0affbb1d3b2fbf41dce3027de7
prerequisite-patch-id: 075f35a92da9f1df4040e2ede8904016276a72fd
prerequisite-patch-id: 435f2b1401e4d6bd611b1467dd95619cc58f7e94
prerequisite-patch-id: 3da11fd73cf9d6eb84a73fe2cad1865869b02506
prerequisite-patch-id: dccbed28650f98e89823e795468752613872c3a2
prerequisite-patch-id: 04589ce94898a31f50e44bc65065644651cd37bf
prerequisite-patch-id: b72c5f8e20711683185cc841913502fd0ee4e9c7
prerequisite-patch-id: a0b0736241e379dd9183620099389193118ab36e
prerequisite-patch-id: 57993217073c627364964ff45e9bda1f6466ab2c
prerequisite-patch-id: af1650070543b7eaa9196015c3ed80d02434c33f
prerequisite-patch-id: 72b63d356271003082e578ffe7664db8cd79086a
prerequisite-patch-id: 895a854faf88359013784d2b63c17876ae2afeca
prerequisite-patch-id: 0957d914360db266f0a8434542516e187739d53e
prerequisite-patch-id: a5c3cf2b3336198b7d7cc511d94b6dd093e0280b
prerequisite-patch-id: 0db3a4c3a542799cdedd61aebf4e8ae876674173
prerequisite-patch-id: 296a53f101dd57c4f932a70c57ba38fd2b787c17
prerequisite-patch-id: 0fd3d04fcb0a3cac132e978f3debbba16ae04a02
prerequisite-patch-id: fafa7c3b6daaf039bd60f5164cd2afeae88a2958
prerequisite-patch-id: c8dede88dbfb842524a21c61dc1adbe6ec2d5e2b
prerequisite-patch-id: 6c03e7d35c4f81bfe0f7897d40738c4ddfeeb327
prerequisite-patch-id: 95a510d6e4a37ae1fa3e6718281ba7f8bf296578
prerequisite-patch-id: e484fc1845969ef3556e47bd7923f827fb0314a3
prerequisite-patch-id: f3a231db2fbb4575045b246a0639af8ddee51743
prerequisite-patch-id: fa976c8bcea009372c77a66d31471654dedd1b9a
prerequisite-patch-id: 93cb412ad243b4ce378ee2cbaf842573091a7939
prerequisite-patch-id: ae93263bd307ec0709b73f2a5e27fc62e7d66c01
prerequisite-patch-id: a412aec7b2a33927a1fba5639ba65ee4b6fbd06d
prerequisite-patch-id: 5505ba1ffab06c2c65aece8f67c3fd622b41bbd9
prerequisite-patch-id: 49cf1b6bf4557be2664aa732c4dfec09d49f4223
prerequisite-patch-id: c36e546a903a76df4f347852cf98bcb5a5bd9ef3
prerequisite-patch-id: 91d94d46d985d5223d7990c3c4b56e564cd1b29b
prerequisite-patch-id: 4e3b1188de3758e6f78159f419dc8cf878bdc758
prerequisite-patch-id: adef43035108d6d0803b33ea47e2479d48768d74
prerequisite-patch-id: 6574822878421fa57e477c1d03eef02f1d1c99a2
prerequisite-patch-id: 814de8fe08a1a87455be7999ff2b5a9b16172ea7
prerequisite-patch-id: c51ad04c37f0c394ddeff7a6a81ff11ec79cc337
prerequisite-patch-id: b574d288c12dfa34cd28e7a13f97dce1ac49c5b2
prerequisite-patch-id: 9eeeb28a9379c54ed7df313427586d22c3fa2b0b
prerequisite-patch-id: 4e3917a7957cb01a7fc16786896437db15cd2f37
prerequisite-patch-id: 6c56a4f9cd863730d6a373252a89c168144c74fc
prerequisite-patch-id: 35ba8113f4a35ed06fdced77b486beebcf832051
prerequisite-patch-id: bacc1b8d2c13f0e3d5b9415f137d9485790bd02d
prerequisite-patch-id: 120f0081316830ddbb2a578c84d2fbb4d0a0bbf6
prerequisite-patch-id: c07ec668fd051742fa7c95c3837757a46e61c506
prerequisite-patch-id: 5e19ba08b46189498be3887fed503a948ac45fdd
prerequisite-patch-id: b80fecfdf09d662023b8aaf2172ff233e4dd6e3c
prerequisite-patch-id: f26f40b3ad3583c79e0e1e1a96e097858eba5969
--
2.34.1



2023-05-12 11:45:06

by Matyas, Daniel

[permalink] [raw]
Subject: [PATCH v8 2/2] hwmon: max31827: add MAX31827 driver

MAX31827 is a low-power temperature switch with I2C interface.

The device is a ±1°C accuracy from -40°C to +125°C
(12 bits) local temperature switch and sensor with I2C/SM-
Bus interface. The combination of small 6-bump wafer-lev-
el package (WLP) and high accuracy makes this temper-
ature sensor/switch ideal for a wide range of applications.

Signed-off-by: Daniel Matyas <[email protected]>
---

v7 -> v8: Initialised ret in max31827_read function, so that it
has a value, even if 'type == hwmon_chip && attr !=
hwmon_chip_update_interval'. (in reality it will never go there, but
needed to this this, because compiler warning)

Documentation/hwmon/index.rst | 1 +
Documentation/hwmon/max31827.rst | 90 ++++++
MAINTAINERS | 2 +
drivers/hwmon/Kconfig | 11 +
drivers/hwmon/Makefile | 2 +-
drivers/hwmon/max31827.c | 466 +++++++++++++++++++++++++++++++
6 files changed, 571 insertions(+), 1 deletion(-)
create mode 100644 Documentation/hwmon/max31827.rst
create mode 100644 drivers/hwmon/max31827.c

diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index fa1208c62855..8cc0922f3b36 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -140,6 +140,7 @@ Hardware Monitoring Kernel Drivers
max31760
max31785
max31790
+ max31827
max34440
max6620
max6639
diff --git a/Documentation/hwmon/max31827.rst b/Documentation/hwmon/max31827.rst
new file mode 100644
index 000000000000..b0971d05b8a4
--- /dev/null
+++ b/Documentation/hwmon/max31827.rst
@@ -0,0 +1,90 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Kernel driver max31827
+======================
+
+Supported chips:
+
+ * Maxim MAX31827
+
+ Prefix: 'max31827'
+
+ Addresses scanned: I2C 0x40 - 0x5f
+
+ Datasheet: Publicly available at the Analog Devices website
+
+ * Maxim MAX31828
+
+ Prefix: 'max31828'
+
+ Addresses scanned: I2C 0x40 - 0x5f
+
+ Datasheet: Publicly available at the Analog Devices website
+
+ * Maxim MAX31829
+
+ Prefix: 'max31829'
+
+ Addresses scanned: I2C 0x40 - 0x5f
+
+ Datasheet: Publicly available at the Analog Devices website
+
+
+Authors:
+ - Daniel Matyas <[email protected]>
+
+Description
+-----------
+
+The chips supported by this driver are quite similar. The only difference
+between them is found in the default power-on behaviour of the chips. While the
+MAX31827's fault queue is set to 1, the other two chip's fault queue is set to
+4. Besides this, the MAX31829's alarm active state is high, while the other two
+chip's alarms are active on low. It is important to note that the chips can be
+configured to operate in the same manner with 1 write operation to the
+configuration register. From here on, we will refer to all these chips as
+MAX31827.
+
+MAX31827 implements a temperature sensor with a 6 WLP packaging scheme. This
+sensor measures the temperature of the chip itself.
+
+MAX31827 has low and over temperature alarms with an effective value and a
+hysteresis value: -40 and -30 degrees for under temperature alarm and +100 and
++90 degrees for over temperature alarm.
+
+The alarm can be configured in comparator and interrupt mode. Currently only
+comparator mode is implemented. In Comparator mode, the OT/UT status bits have a
+value of 1 when the temperature rises above the TH value or falls below TL,
+which is also subject to the Fault Queue selection. OT status returns to 0 when
+the temperature drops below the TH_HYST value or when shutdown mode is entered.
+Similarly, UT status returns to 0 when the temperature rises above TL_HYST value
+or when shutdown mode is entered.
+
+Putting the MAX31827 into shutdown mode also resets the OT/UT status bits. Note
+that if the mode is changed while OT/UT status bits are set, an OT/UT status
+reset may be required before it begins to behave normally. To prevent this,
+it is recommended to perform a read of the configuration/status register to
+clear the status bits before changing the operating mode.
+
+The conversions can be manual with the one-shot functionality and automatic with
+a set frequency. When powered on, the chip measures temperatures with 1 conv/s.
+Enabling the device when it is already enabled has the side effect of setting
+the conversion frequency to 1 conv/s. The conversion time varies depending on
+the resolution. The conversion time doubles with every bit of increased
+resolution. For 10 bit resolution 35ms are needed, while for 12 bit resolution
+(default) 140ms. When chip is in shutdown mode and a read operation is
+requested, one-shot is triggered, the device waits for 140 (conversion time) + 1
+(error) ms, and only after that is the temperature value register read.
+
+The LSB of the temperature values is 0.0625 degrees Celsius, but the values of
+the temperatures are displayed in milli-degrees. This means, that some data is
+lost. The step between 2 consecutive values is 62 or 63. This effect can be seen
+in the writing of alarm values too. For positive numbers the user-input value
+will always be rounded down to the nearest possible value, for negative numbers
+the user-input will always be rounded up to the nearest possible value.
+
+Notes
+-----
+
+Currently fault queue, alarm polarity and resolution cannot be modified.
+PEC is not implemented either.
diff --git a/MAINTAINERS b/MAINTAINERS
index 5d5359f59af5..9c300a3ebb66 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12623,6 +12623,8 @@ L: [email protected]
S: Supported
W: http://ez.analog.com/community/linux-device-drivers
F: Documentation/devicetree/bindings/hwmon/adi,max31827.yaml
+F: Documentation/hwmon/max31827.rst
+F: drivers/hwmon/max31827.c

MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER
L: [email protected]
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index fc640201a2de..12bd17075dc4 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1097,6 +1097,17 @@ config SENSORS_MAX31760
This driver can also be built as a module. If so, the module
will be called max31760.

+config MAX31827
+ tristate "MAX31827 low-power temperature switch and similar devices"
+ depends on I2C
+ select REGMAP_I2C
+ help
+ If you say yes here you get support for MAX31827, MAX31828 and
+ MAX31829 low-power temperature switches and sensors connected with I2C.
+
+ This driver can also be built as a module. If so, the module
+ will be called max31827.
+
config SENSORS_MAX6620
tristate "Maxim MAX6620 fan controller"
depends on I2C
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index cd8c568c80a9..8a8021f9ca9e 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -149,6 +149,7 @@ obj-$(CONFIG_SENSORS_MAX6642) += max6642.o
obj-$(CONFIG_SENSORS_MAX6650) += max6650.o
obj-$(CONFIG_SENSORS_MAX6697) += max6697.o
obj-$(CONFIG_SENSORS_MAX31790) += max31790.o
+obj-$(CONFIG_MAX31827) += max31827.o
obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o
obj-$(CONFIG_SENSORS_MC34VR500) += mc34vr500.o
obj-$(CONFIG_SENSORS_MCP3021) += mcp3021.o
@@ -224,4 +225,3 @@ obj-$(CONFIG_SENSORS_PECI) += peci/
obj-$(CONFIG_PMBUS) += pmbus/

ccflags-$(CONFIG_HWMON_DEBUG_CHIP) := -DDEBUG
-
diff --git a/drivers/hwmon/max31827.c b/drivers/hwmon/max31827.c
new file mode 100644
index 000000000000..fa86e5a72935
--- /dev/null
+++ b/drivers/hwmon/max31827.c
@@ -0,0 +1,466 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * max31827.c - Support for Maxim Low-Power Switch
+ *
+ * Copyright (c) 2023 Daniel Matyas <[email protected]>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/hwmon.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/regmap.h>
+
+#define MAX31827_T_REG 0x0
+#define MAX31827_CONFIGURATION_REG 0x2
+#define MAX31827_TH_REG 0x4
+#define MAX31827_TL_REG 0x6
+#define MAX31827_TH_HYST_REG 0x8
+#define MAX31827_TL_HYST_REG 0xA
+
+#define MAX31827_CONFIGURATION_1SHOT_MASK BIT(0)
+#define MAX31827_CONFIGURATION_CNV_RATE_MASK GENMASK(3, 1)
+#define MAX31827_CONFIGURATION_U_TEMP_STAT_MASK BIT(14)
+#define MAX31827_CONFIGURATION_O_TEMP_STAT_MASK BIT(15)
+
+#define MAX31827_12_BIT_CNV_TIME 141
+
+#define MAX31827_CNV_1_DIV_64_HZ 0x1
+#define MAX31827_CNV_1_DIV_32_HZ 0x2
+#define MAX31827_CNV_1_DIV_16_HZ 0x3
+#define MAX31827_CNV_1_DIV_4_HZ 0x4
+#define MAX31827_CNV_1_HZ 0x5
+#define MAX31827_CNV_4_HZ 0x6
+#define MAX31827_CNV_8_HZ 0x7
+
+#define MAX31827_16_BIT_TO_M_DGR(x) (sign_extend32(x, 15) * 1000 / 16)
+#define MAX31827_M_DGR_TO_16_BIT(x) (((x) << 4) / 1000)
+#define MAX31827_DEVICE_ENABLE(x) ((x) ? 0xA : 0x0)
+
+struct max31827_state {
+ /*
+ * Prevent simultaneous access to the i2c client.
+ */
+ struct mutex lock;
+ struct regmap *regmap;
+ bool enable;
+};
+
+static const struct regmap_config max31827_regmap = {
+ .reg_bits = 8,
+ .val_bits = 16,
+ .max_register = 0xA,
+};
+
+static int write_alarm_val(struct max31827_state *st, unsigned int reg,
+ long val)
+{
+ unsigned int cfg;
+ unsigned int tmp;
+ int ret;
+
+ val = MAX31827_M_DGR_TO_16_BIT(val);
+
+ /*
+ * Before the Temperature Threshold Alarm and Alarm Hysteresis Threshold
+ * register values are changed over I2C, the part must be in shutdown
+ * mode.
+ *
+ * Mutex is used to ensure, that some other process doesn't change the
+ * configuration register.
+ */
+ mutex_lock(&st->lock);
+
+ if (!st->enable) {
+ ret = regmap_write(st->regmap, reg, val);
+ goto unlock;
+ }
+
+ ret = regmap_read(st->regmap, MAX31827_CONFIGURATION_REG, &cfg);
+ if (ret)
+ goto unlock;
+
+ tmp = cfg & ~(MAX31827_CONFIGURATION_1SHOT_MASK |
+ MAX31827_CONFIGURATION_CNV_RATE_MASK);
+ ret = regmap_write(st->regmap, MAX31827_CONFIGURATION_REG, tmp);
+ if (ret)
+ goto unlock;
+
+ ret = regmap_write(st->regmap, reg, val);
+ if (ret)
+ goto unlock;
+
+ ret = regmap_write(st->regmap, MAX31827_CONFIGURATION_REG, cfg);
+
+unlock:
+ mutex_unlock(&st->lock);
+ return ret;
+}
+
+static umode_t max31827_is_visible(const void *state,
+ enum hwmon_sensor_types type, u32 attr,
+ int channel)
+{
+ if (type == hwmon_temp) {
+ switch (attr) {
+ case hwmon_temp_enable:
+ case hwmon_temp_max:
+ case hwmon_temp_min:
+ case hwmon_temp_max_hyst:
+ case hwmon_temp_min_hyst:
+ return 0644;
+ case hwmon_temp_input:
+ case hwmon_temp_min_alarm:
+ case hwmon_temp_max_alarm:
+ return 0444;
+ default:
+ return 0;
+ }
+ } else if (type == hwmon_chip) {
+ if (attr == hwmon_chip_update_interval)
+ return 0644;
+ }
+
+ return 0;
+}
+
+static int max31827_read(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, long *val)
+{
+ struct max31827_state *st = dev_get_drvdata(dev);
+ unsigned int uval;
+ int ret = 0;
+
+ switch (type) {
+ case hwmon_temp:
+ switch (attr) {
+ case hwmon_temp_enable:
+ ret = regmap_read(st->regmap,
+ MAX31827_CONFIGURATION_REG, &uval);
+ if (ret)
+ break;
+
+ uval = FIELD_GET(MAX31827_CONFIGURATION_1SHOT_MASK |
+ MAX31827_CONFIGURATION_CNV_RATE_MASK,
+ uval);
+ *val = !!uval;
+
+ break;
+ case hwmon_temp_input:
+ mutex_lock(&st->lock);
+
+ if (!st->enable) {
+ /*
+ * This operation requires mutex protection,
+ * because the chip configuration should not
+ * be changed during the conversion process.
+ */
+
+ ret = regmap_update_bits(st->regmap,
+ MAX31827_CONFIGURATION_REG,
+ MAX31827_CONFIGURATION_1SHOT_MASK,
+ 1);
+ if (ret) {
+ mutex_unlock(&st->lock);
+ return ret;
+ }
+
+ msleep(MAX31827_12_BIT_CNV_TIME);
+ }
+ ret = regmap_read(st->regmap, MAX31827_T_REG, &uval);
+
+ mutex_unlock(&st->lock);
+
+ if (ret)
+ break;
+
+ *val = MAX31827_16_BIT_TO_M_DGR(uval);
+
+ break;
+ case hwmon_temp_max:
+ ret = regmap_read(st->regmap, MAX31827_TH_REG, &uval);
+ if (ret)
+ break;
+
+ *val = MAX31827_16_BIT_TO_M_DGR(uval);
+ break;
+ case hwmon_temp_max_hyst:
+ ret = regmap_read(st->regmap, MAX31827_TH_HYST_REG,
+ &uval);
+ if (ret)
+ break;
+
+ *val = MAX31827_16_BIT_TO_M_DGR(uval);
+ break;
+ case hwmon_temp_max_alarm:
+ ret = regmap_read(st->regmap,
+ MAX31827_CONFIGURATION_REG, &uval);
+ if (ret)
+ break;
+
+ *val = FIELD_GET(MAX31827_CONFIGURATION_O_TEMP_STAT_MASK,
+ uval);
+ break;
+ case hwmon_temp_min:
+ ret = regmap_read(st->regmap, MAX31827_TL_REG, &uval);
+ if (ret)
+ break;
+
+ *val = MAX31827_16_BIT_TO_M_DGR(uval);
+ break;
+ case hwmon_temp_min_hyst:
+ ret = regmap_read(st->regmap, MAX31827_TL_HYST_REG,
+ &uval);
+ if (ret)
+ break;
+
+ *val = MAX31827_16_BIT_TO_M_DGR(uval);
+ break;
+ case hwmon_temp_min_alarm:
+ ret = regmap_read(st->regmap,
+ MAX31827_CONFIGURATION_REG, &uval);
+ if (ret)
+ break;
+
+ *val = FIELD_GET(MAX31827_CONFIGURATION_U_TEMP_STAT_MASK,
+ uval);
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ break;
+ }
+
+ break;
+
+ case hwmon_chip:
+ if (attr == hwmon_chip_update_interval) {
+ ret = regmap_read(st->regmap,
+ MAX31827_CONFIGURATION_REG, &uval);
+ if (ret)
+ break;
+
+ uval = FIELD_GET(MAX31827_CONFIGURATION_CNV_RATE_MASK,
+ uval);
+ switch (uval) {
+ case MAX31827_CNV_1_DIV_64_HZ:
+ *val = 64000;
+ break;
+ case MAX31827_CNV_1_DIV_32_HZ:
+ *val = 32000;
+ break;
+ case MAX31827_CNV_1_DIV_16_HZ:
+ *val = 16000;
+ break;
+ case MAX31827_CNV_1_DIV_4_HZ:
+ *val = 4000;
+ break;
+ case MAX31827_CNV_1_HZ:
+ *val = 1000;
+ break;
+ case MAX31827_CNV_4_HZ:
+ *val = 250;
+ break;
+ case MAX31827_CNV_8_HZ:
+ *val = 125;
+ break;
+ default:
+ *val = 0;
+ break;
+ }
+ }
+ break;
+
+ default:
+ ret = -EOPNOTSUPP;
+ break;
+ }
+
+ return ret;
+}
+
+static int max31827_write(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, long val)
+{
+ struct max31827_state *st = dev_get_drvdata(dev);
+ int ret;
+
+ switch (type) {
+ case hwmon_temp:
+ switch (attr) {
+ case hwmon_temp_enable:
+ if (val >> 1)
+ return -EOPNOTSUPP;
+
+ mutex_lock(&st->lock);
+ /**
+ * The chip should not be enabled while a conversion is
+ * performed. Neither should the chip be enabled when
+ * the alarm values are changed.
+ */
+
+ st->enable = val;
+
+ ret = regmap_update_bits(st->regmap,
+ MAX31827_CONFIGURATION_REG,
+ MAX31827_CONFIGURATION_1SHOT_MASK |
+ MAX31827_CONFIGURATION_CNV_RATE_MASK,
+ MAX31827_DEVICE_ENABLE(val));
+
+ mutex_unlock(&st->lock);
+
+ return ret;
+
+ case hwmon_temp_max:
+ return write_alarm_val(st, MAX31827_TH_REG, val);
+
+ case hwmon_temp_max_hyst:
+ return write_alarm_val(st, MAX31827_TH_HYST_REG, val);
+
+ case hwmon_temp_min:
+ return write_alarm_val(st, MAX31827_TL_REG, val);
+
+ case hwmon_temp_min_hyst:
+ return write_alarm_val(st, MAX31827_TL_HYST_REG, val);
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ case hwmon_chip:
+ if (attr == hwmon_chip_update_interval) {
+ if (!st->enable)
+ return -EOPNOTSUPP;
+
+ switch (val) {
+ case 125:
+ val = MAX31827_CNV_8_HZ;
+ break;
+ case 250:
+ val = MAX31827_CNV_4_HZ;
+ break;
+ case 1000:
+ val = MAX31827_CNV_1_HZ;
+ break;
+ case 4000:
+ val = MAX31827_CNV_1_DIV_4_HZ;
+ break;
+ case 16000:
+ val = MAX31827_CNV_1_DIV_16_HZ;
+ break;
+ case 32000:
+ val = MAX31827_CNV_1_DIV_32_HZ;
+ break;
+ case 64000:
+ val = MAX31827_CNV_1_DIV_64_HZ;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ val = FIELD_PREP(MAX31827_CONFIGURATION_CNV_RATE_MASK,
+ val);
+
+ return regmap_update_bits(st->regmap,
+ MAX31827_CONFIGURATION_REG,
+ MAX31827_CONFIGURATION_CNV_RATE_MASK,
+ val);
+ }
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return -EOPNOTSUPP;
+}
+
+static int max31827_init_client(struct max31827_state *st)
+{
+ st->enable = true;
+
+ return regmap_update_bits(st->regmap, MAX31827_CONFIGURATION_REG,
+ MAX31827_CONFIGURATION_1SHOT_MASK |
+ MAX31827_CONFIGURATION_CNV_RATE_MASK,
+ MAX31827_DEVICE_ENABLE(1));
+}
+
+static const struct hwmon_channel_info *max31827_info[] = {
+ HWMON_CHANNEL_INFO(temp, HWMON_T_ENABLE | HWMON_T_INPUT | HWMON_T_MIN |
+ HWMON_T_MIN_HYST | HWMON_T_MIN_ALARM |
+ HWMON_T_MAX | HWMON_T_MAX_HYST |
+ HWMON_T_MAX_ALARM),
+ HWMON_CHANNEL_INFO(chip, HWMON_C_UPDATE_INTERVAL),
+ NULL,
+};
+
+static const struct hwmon_ops max31827_hwmon_ops = {
+ .is_visible = max31827_is_visible,
+ .read = max31827_read,
+ .write = max31827_write,
+};
+
+static const struct hwmon_chip_info max31827_chip_info = {
+ .ops = &max31827_hwmon_ops,
+ .info = max31827_info,
+};
+
+static int max31827_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct device *hwmon_dev;
+ struct max31827_state *st;
+ int err;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))
+ return -EOPNOTSUPP;
+
+ st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL);
+ if (!st)
+ return -ENOMEM;
+
+ mutex_init(&st->lock);
+
+ st->regmap = devm_regmap_init_i2c(client, &max31827_regmap);
+ if (IS_ERR(st->regmap))
+ return dev_err_probe(dev, PTR_ERR(st->regmap),
+ "Failed to allocate regmap.\n");
+
+ err = max31827_init_client(st);
+ if (err)
+ return err;
+
+ hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, st,
+ &max31827_chip_info,
+ NULL);
+
+ return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+static const struct i2c_device_id max31827_i2c_ids[] = {
+ { "max31827", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, max31827_i2c_ids);
+
+static const struct of_device_id max31827_of_match[] = {
+ { .compatible = "max31827" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, max31827_of_match);
+
+static struct i2c_driver max31827_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "max31827",
+ .of_match_table = max31827_of_match,
+ },
+ .probe_new = max31827_probe,
+ .id_table = max31827_i2c_ids,
+};
+module_i2c_driver(max31827_driver);
+
+MODULE_AUTHOR("Daniel Matyas <[email protected]>");
+MODULE_DESCRIPTION("Maxim MAX31827 low-power temperature switch driver");
+MODULE_LICENSE("GPL");
--
2.34.1


2023-05-12 13:50:27

by Krzysztof Kozlowski

[permalink] [raw]
Subject: Re: [PATCH v8 1/2] dt-bindings: hwmon: add MAX31827

On 12/05/2023 16:20, Daniel Matyas wrote:
> MAX31827 is a low-power temperature switch with I2C interface.
>
> The device is a ±1°C accuracy from -40°C to +125°C
> (12 bits) local temperature switch and sensor with I2C/SM-
> Bus interface. The combination of small 6-bump wafer-lev-
> el package (WLP) and high accuracy makes this temper-
> ature sensor/switch ideal for a wide range of applications.
>
> Signed-off-by: Daniel Matyas <[email protected]>
> Reviewed-by: Rob Herring <[email protected]>
> ---
>
> v7 -> v8: Added '--base=[Linux 6.4-rc1 commmit]' when using 'git
> format-patch'

It does not make much sense in your setup, look below:

(...)


>
> base-commit: ac9a78681b921877518763ba0e89202254349d1b
> prerequisite-patch-id: 7a4b4994760cfa8c07187d319e53e9956a8b639e
> prerequisite-patch-id: af1a81cb4ad3137780afb102586a3489f9615303
> prerequisite-patch-id: a4ed1db487f0ee9506b3aa7bb672595a7b793cca
> prerequisite-patch-id: 421416a1110c5cc09e11afe2db6528cbca6d9492
> prerequisite-patch-id: 8ced9e002e35952cd614acc0e2108f17a502a5fc

All these commits are unknown. It will not help us to create proper base.

> prerequisite-patch-id: 82d101227b696dc95c11bca8594f80b438537359
> prerequisite-patch-id: dfe7b1d583daa8dbb2d2af8fc993622b65f83826
> prerequisite-patch-id: 431a19e35c672a668b696858eace775c56f1e1e7
> prerequisite-patch-id: 0b485820cf1c980bba3adedb9fd88b87ee3cc157
> prerequisite-patch-id: 8d767b2e1313428538bea1490032f639cd1ccff1
> prerequisite-patch-id: c1ef543ae6716d6ccad416250ca68c8a0eec058f
> prerequisite-patch-id: 4c78ac1e346676b76fd8850f8edc2b08bdb78f52
> prerequisite-patch-id: e6fa20eba19f686b0f4133b1c7bd5894f703498f
> prerequisite-patch-id: 83d74aa2b6f8cfefeb14dd5e90705982b952a757
> prerequisite-patch-id: 4ac1c2c31de74af80624f66489fcc87e533dd32a
> prerequisite-patch-id: 77a377c5214f2cddd3455d1fcda34ccf28973883
> prerequisite-patch-id: 2edf34328d29191533344d36f43abdc7479b4ae2
> prerequisite-patch-id: 77e8f55f78744797df7efdc0d2b18740cfe099b9
> prerequisite-patch-id: ab123ba97f1abe14016c30fae72b55a87363d5ef
> prerequisite-patch-id: 7323aaafb0edd7edd51a5c6f8be1bb275f9dba9c
> prerequisite-patch-id: 4a61b49c7ab4522967fd122f8bf38d679022df57
> prerequisite-patch-id: 869ae6fe33242cbc0373cf1e1e92c7b240f9e1ee
> prerequisite-patch-id: 12f8d3b3d21ea08368246f7cf3d42ec920297953
> prerequisite-patch-id: 3cdfc61d4d0aa70f68d095a7df4e814259e9cc47
> prerequisite-patch-id: 726807583bfd50c10a1090f067261266efbc6aa9
> prerequisite-patch-id: eea50a388d43e8447a5ef2969af5df7a354e356c
> prerequisite-patch-id: db216360c53cefee67966e28397efcd0591601e7
> prerequisite-patch-id: ff327329d945c9502df11b15f4d037d355bee546
> prerequisite-patch-id: a197064fc6a5e20d4c9ef5f508491b457d2564ca
> prerequisite-patch-id: c0d5d63ae43075a035a632d61975ad1e1bba4e69
> prerequisite-patch-id: 2c4053f5cf0ab2707bd528a36a926f49d3e678ba
> prerequisite-patch-id: 2bc0059cb68aa397ea841c153b2f6bfc4e998de8
> prerequisite-patch-id: d5e64ab8afa8a2761a51ec295709ed25b65f450c
> prerequisite-patch-id: c8d1ca12e9e502f366bf04d98b1011b299433d65
> prerequisite-patch-id: 955a12cb7b43bb60c913c097f58c6bd6d131962e
> prerequisite-patch-id: 142599135b7ffa62f14d96755c3a5c2db45140b9
> prerequisite-patch-id: d8415b405107d9d024566a415ad1b03a4606f9e2
> prerequisite-patch-id: 0ecb6a8d2c011477889ba4db43a79fe8b0031b5a
> prerequisite-patch-id: e755275a6776660db45f4c77e83100df26b714e6
> prerequisite-patch-id: 61989ab7e10a1fb21144ae314bb01772fceee65c
> prerequisite-patch-id: 42f546d2579f59ae937ca266ad104a745141317a
> prerequisite-patch-id: 8b3afdd0e40d71a10a8170dd1be45232838cea0b
> prerequisite-patch-id: dd4a4ad7eed59aff993717ec6e4552e2220125a2
> prerequisite-patch-id: 02012f5d2e0f147338b267a23ed715ca452ecea4
> prerequisite-patch-id: fff041f18c7d7b462d4b4c89ec5259e19ad07307
> prerequisite-patch-id: 419d0a8254089778c04f24cc702caa3d365ea375
> prerequisite-patch-id: 4bcb80ddab7867c8186f340897583aab541642a8
> prerequisite-patch-id: 2968cce365bedd0affbb1d3b2fbf41dce3027de7
> prerequisite-patch-id: 075f35a92da9f1df4040e2ede8904016276a72fd
> prerequisite-patch-id: 435f2b1401e4d6bd611b1467dd95619cc58f7e94
> prerequisite-patch-id: 3da11fd73cf9d6eb84a73fe2cad1865869b02506
> prerequisite-patch-id: dccbed28650f98e89823e795468752613872c3a2
> prerequisite-patch-id: 04589ce94898a31f50e44bc65065644651cd37bf
> prerequisite-patch-id: b72c5f8e20711683185cc841913502fd0ee4e9c7
> prerequisite-patch-id: a0b0736241e379dd9183620099389193118ab36e
> prerequisite-patch-id: 57993217073c627364964ff45e9bda1f6466ab2c
> prerequisite-patch-id: af1650070543b7eaa9196015c3ed80d02434c33f
> prerequisite-patch-id: 72b63d356271003082e578ffe7664db8cd79086a
> prerequisite-patch-id: 895a854faf88359013784d2b63c17876ae2afeca
> prerequisite-patch-id: 0957d914360db266f0a8434542516e187739d53e
> prerequisite-patch-id: a5c3cf2b3336198b7d7cc511d94b6dd093e0280b
> prerequisite-patch-id: 0db3a4c3a542799cdedd61aebf4e8ae876674173
> prerequisite-patch-id: 296a53f101dd57c4f932a70c57ba38fd2b787c17
> prerequisite-patch-id: 0fd3d04fcb0a3cac132e978f3debbba16ae04a02
> prerequisite-patch-id: fafa7c3b6daaf039bd60f5164cd2afeae88a2958
> prerequisite-patch-id: c8dede88dbfb842524a21c61dc1adbe6ec2d5e2b
> prerequisite-patch-id: 6c03e7d35c4f81bfe0f7897d40738c4ddfeeb327
> prerequisite-patch-id: 95a510d6e4a37ae1fa3e6718281ba7f8bf296578
> prerequisite-patch-id: e484fc1845969ef3556e47bd7923f827fb0314a3
> prerequisite-patch-id: f3a231db2fbb4575045b246a0639af8ddee51743
> prerequisite-patch-id: fa976c8bcea009372c77a66d31471654dedd1b9a
> prerequisite-patch-id: 93cb412ad243b4ce378ee2cbaf842573091a7939
> prerequisite-patch-id: ae93263bd307ec0709b73f2a5e27fc62e7d66c01
> prerequisite-patch-id: a412aec7b2a33927a1fba5639ba65ee4b6fbd06d
> prerequisite-patch-id: 5505ba1ffab06c2c65aece8f67c3fd622b41bbd9
> prerequisite-patch-id: 49cf1b6bf4557be2664aa732c4dfec09d49f4223
> prerequisite-patch-id: c36e546a903a76df4f347852cf98bcb5a5bd9ef3
> prerequisite-patch-id: 91d94d46d985d5223d7990c3c4b56e564cd1b29b
> prerequisite-patch-id: 4e3b1188de3758e6f78159f419dc8cf878bdc758
> prerequisite-patch-id: adef43035108d6d0803b33ea47e2479d48768d74
> prerequisite-patch-id: 6574822878421fa57e477c1d03eef02f1d1c99a2
> prerequisite-patch-id: 814de8fe08a1a87455be7999ff2b5a9b16172ea7
> prerequisite-patch-id: c51ad04c37f0c394ddeff7a6a81ff11ec79cc337
> prerequisite-patch-id: b574d288c12dfa34cd28e7a13f97dce1ac49c5b2
> prerequisite-patch-id: 9eeeb28a9379c54ed7df313427586d22c3fa2b0b
> prerequisite-patch-id: 4e3917a7957cb01a7fc16786896437db15cd2f37
> prerequisite-patch-id: 6c56a4f9cd863730d6a373252a89c168144c74fc
> prerequisite-patch-id: 35ba8113f4a35ed06fdced77b486beebcf832051
> prerequisite-patch-id: bacc1b8d2c13f0e3d5b9415f137d9485790bd02d
> prerequisite-patch-id: 120f0081316830ddbb2a578c84d2fbb4d0a0bbf6
> prerequisite-patch-id: c07ec668fd051742fa7c95c3837757a46e61c506
> prerequisite-patch-id: 5e19ba08b46189498be3887fed503a948ac45fdd
> prerequisite-patch-id: b80fecfdf09d662023b8aaf2172ff233e4dd6e3c
> prerequisite-patch-id: f26f40b3ad3583c79e0e1e1a96e097858eba5969

The patch is fine, but whatever build failures you have, the base is
solution only if they come from patches from maintainer's tree.

Best regards,
Krzysztof