Apple Silicon devices integrate a vast array of sensors, monitoring
current, power, temperature, and voltage across almost every part of
the system. The sensors themselves are all connected to the System
Management Controller (SMC). The SMC firmware exposes the data
reported by these sensors via its standard FourCC-based key-value
API. The SMC is also responsible for monitoring and controlling any
fans connected to the system, exposing them in the same way.
For reasons known only to Apple, each device exposes its sensors with
an almost totally unique set of keys. This is true even for devices
which share an SoC. An M1 Mac mini, for example, will report its core
temperatures on different keys to an M1 MacBook Pro. Worse still, the
SMC does not provide a way to enumerate the available keys at runtime,
nor do the keys follow any sort of reasonable or consistent naming
rules that could be used to deduce their purpose. We must therefore
know which keys are present on any given device, and which function
they serve, ahead of time.
Add a schema so that we can describe the available sensors for a given
Apple Silicon device in the Devicetree.
Signed-off-by: James Calligeros <jcalligeros99@gmail.com>
---
.../bindings/hwmon/apple,smc-hwmon.yaml | 148 +++++++++++++++++++++++++
.../bindings/mfd/apple,smc.yaml | 45 ++++++++
2 files changed, 193 insertions(+)
diff --git a/Documentation/devicetree/bindings/hwmon/apple,smc-hwmon.yaml b/Documentation/devicetree/bindings/hwmon/apple,smc-hwmon.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..3ebc0463be4e1ce54005418feaa87ec7254dab6e
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwmon/apple,smc-hwmon.yaml
@@ -0,0 +1,148 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hwmon/apple,smc-hwmon.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple SMC Hardware Monitoring
+
+description:
+ Apple's System Management Controller (SMC) exposes a vast array of
+ hardware monitoring sensors, including temperature probes, current and
+ voltage sense, power meters, and fan speeds. It also provides endpoints
+ to manually control the speed of each fan individually. Each Apple
+ Silicon device exposes a different set of endpoints via SMC keys. This
+ is true even when two machines share an SoC. The CPU core temperature
+ sensor keys on an M1 Mac mini are different to those on an M1 MacBook
+ Pro, for example.
+
+maintainers:
+ - James Calligeros <jcalligeros99@gmail.com>
+
+properties:
+ compatible:
+ const: apple,smc-hwmon
+
+ current:
+ description: SMC current sense endpoints
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^current-[A-Za-z0-9]{4}":
+ type: object
+ additionalProperties: false
+ required:
+ - apple,key-id
+ properties:
+ apple,key-id:
+ $ref: /schemas/types.yaml#/definitions/string
+ pattern: "^[A-Za-z0-9]{4}"
+ description: The SMC FourCC key of the desired current sensor.
+ Should match the node's suffix, but doesn't have to.
+ label:
+ $ref: /schemas/types.yaml#/definitions/string
+ description: Human-readable name for the sensor
+
+ fan:
+ description: SMC fan control endpoints. A fan is made up of five
+ SMC keys - the fan's current speed, its minimum speed, its maximum
+ speed, a writeable target speed, and a writeable mode. The SMC will
+ automatically manage system fans unless a 1 is written to the fan's
+ mode key.
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^fan-[A-Za-z0-9]{4}":
+ type: object
+ additionalProperties: false
+ required:
+ - apple,key-id
+ properties:
+ apple,key-id:
+ $ref: /schemas/types.yaml#/definitions/string
+ pattern: "^[A-Za-z0-9]{4}"
+ description: The SMC FourCC key of the desired fan. This is the
+ main key, which reports the fan's current speed. Sould match
+ the node's suffix, but doesn't have to.
+ apple,fan-minimum:
+ $ref: /schemas/types.yaml#/definitions/string
+ pattern: "^[A-Za-z0-9]{4}"
+ description: The minimum speed the current fan can run at
+ apple,fan-maximum:
+ $ref: /schemas/types.yaml#/definitions/string
+ pattern: "^[A-Za-z0-9]{4}"
+ description: The maximum speed the current fan can run at
+ apple,fan-target:
+ $ref: /schemas/types.yaml#/definitions/string
+ pattern: "^[A-Za-z0-9]{4}"
+ description: Writeable endpoint for setting desired fan speed
+ apple,fan-mode:
+ $ref: /schemas/types.yaml#/definitions/string
+ pattern: "^[A-Za-z0-9]{4}"
+ description: Writeable endpoint to enable/disable manual fan
+ control
+ label:
+ $ref: /schemas/types.yaml#/definitions/string
+ description: Human-readable name for the sensor
+
+ power:
+ description: SMC power meter endpoints
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^power-[A-Za-z0-9]{4}":
+ type: object
+ additionalProperties: false
+ required:
+ - apple,key-id
+ properties:
+ apple,key-id:
+ $ref: /schemas/types.yaml#/definitions/string
+ pattern: "^[A-Za-z0-9]{4}"
+ description: The SMC FourCC key of the desired power meter.
+ Should match the node's suffix, but doesn't have to.
+ label:
+ $ref: /schemas/types.yaml#/definitions/string
+ description: Human-readable name for the sensor
+
+ temperature:
+ description: SMC temperature sensor endpoints
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^temperature-[A-Za-z0-9]{4}":
+ type: object
+ additionalProperties: false
+ required:
+ - apple,key-id
+ properties:
+ apple,key-id:
+ $ref: /schemas/types.yaml#/definitions/string
+ pattern: "^[A-Za-z0-9]{4}"
+ description: The SMC FourCC key of the desired temperature
+ sensor. Should match the node's suffix, but doesn't have to.
+ label:
+ $ref: /schemas/types.yaml#/definitions/string
+ description: Human-readable name for the sensor
+
+ voltage:
+ description: SMC voltage sensor endpoints
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^voltage-[A-Za-z0-9]{4}":
+ type: object
+ additionalProperties: false
+ required:
+ - apple,key-id
+ properties:
+ apple,key-id:
+ $ref: /schemas/types.yaml#/definitions/string
+ pattern: "^[A-Za-z0-9]{4}"
+ description: The SMC FourCC key of the desired voltage
+ sensor. Should match the node's suffix, but doesn't have to.
+ label:
+ $ref: /schemas/types.yaml#/definitions/string
+ description: Human-readable name for the sensor
+
+additionalProperties: false
diff --git a/Documentation/devicetree/bindings/mfd/apple,smc.yaml b/Documentation/devicetree/bindings/mfd/apple,smc.yaml
index 38f077867bdeedba8a486a63e366e9c943a75681..370928bb42010edca17839faf0bda4630611a7a2 100644
--- a/Documentation/devicetree/bindings/mfd/apple,smc.yaml
+++ b/Documentation/devicetree/bindings/mfd/apple,smc.yaml
@@ -44,6 +44,9 @@ properties:
rtc:
$ref: /schemas/rtc/apple,smc-rtc.yaml
+ hwmon:
+ $ref: /schemas/hwmon/apple,smc-hwmon.yaml
+
additionalProperties: false
required:
@@ -84,5 +87,47 @@ examples:
nvmem-cells = <&rtc_offset>;
nvmem-cell-names = "rtc_offset";
};
+
+ hwmon {
+ compatible = "apple,smc-hwmon";
+ current {
+ current-ID0R {
+ apple,key-id = "ID0R";
+ label = "AC Input Current";
+ };
+ };
+
+ fan {
+ fan-F0Ac {
+ apple,key-id = "F0Ac";
+ apple,fan-minimum = "F0Mn";
+ apple,fan-maximum = "F0Mx";
+ apple,fan-target = "F0Tg";
+ apple,fan-mode = "F0Md";
+ label = "Fan 1";
+ };
+ };
+
+ power {
+ power-PSTR {
+ apple,key-id = "PSTR";
+ label = "Total System Power";
+ };
+ };
+
+ temperature {
+ temperature-TW0P {
+ apple,key-id = "TW0P";
+ label = "WiFi/BT Module Temperature";
+ };
+ };
+
+ voltage {
+ voltage-VD0R {
+ apple,key-id = "VD0R";
+ label = "AC Input Voltage";
+ };
+ };
+ };
};
};
--
2.50.1
On Tue, Aug 19, 2025 at 09:47:54PM +1000, James Calligeros wrote: > Apple Silicon devices integrate a vast array of sensors, monitoring > current, power, temperature, and voltage across almost every part of > the system. The sensors themselves are all connected to the System > Management Controller (SMC). The SMC firmware exposes the data > reported by these sensors via its standard FourCC-based key-value > API. The SMC is also responsible for monitoring and controlling any > fans connected to the system, exposing them in the same way. > > For reasons known only to Apple, each device exposes its sensors with > an almost totally unique set of keys. This is true even for devices > which share an SoC. An M1 Mac mini, for example, will report its core > temperatures on different keys to an M1 MacBook Pro. Worse still, the > SMC does not provide a way to enumerate the available keys at runtime, > nor do the keys follow any sort of reasonable or consistent naming > rules that could be used to deduce their purpose. We must therefore > know which keys are present on any given device, and which function > they serve, ahead of time. I'm confused because you say this, but then the .dtsi files are common. > > Add a schema so that we can describe the available sensors for a given > Apple Silicon device in the Devicetree. > > Signed-off-by: James Calligeros <jcalligeros99@gmail.com> > --- > .../bindings/hwmon/apple,smc-hwmon.yaml | 148 +++++++++++++++++++++++++ > .../bindings/mfd/apple,smc.yaml | 45 ++++++++ > 2 files changed, 193 insertions(+) > > diff --git a/Documentation/devicetree/bindings/hwmon/apple,smc-hwmon.yaml b/Documentation/devicetree/bindings/hwmon/apple,smc-hwmon.yaml > new file mode 100644 > index 0000000000000000000000000000000000000000..3ebc0463be4e1ce54005418feaa87ec7254dab6e > --- /dev/null > +++ b/Documentation/devicetree/bindings/hwmon/apple,smc-hwmon.yaml > @@ -0,0 +1,148 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/hwmon/apple,smc-hwmon.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Apple SMC Hardware Monitoring > + > +description: > + Apple's System Management Controller (SMC) exposes a vast array of > + hardware monitoring sensors, including temperature probes, current and > + voltage sense, power meters, and fan speeds. It also provides endpoints > + to manually control the speed of each fan individually. Each Apple > + Silicon device exposes a different set of endpoints via SMC keys. This > + is true even when two machines share an SoC. The CPU core temperature > + sensor keys on an M1 Mac mini are different to those on an M1 MacBook > + Pro, for example. > + > +maintainers: > + - James Calligeros <jcalligeros99@gmail.com> > + > +properties: > + compatible: > + const: apple,smc-hwmon > + > + current: I don't see any need to group these and I would remove the intermediate node. We have an iterator to iterate over a matching node name prefix if that was the reasoning. > + description: SMC current sense endpoints > + type: object > + additionalProperties: false blank line > + patternProperties: > + "^current-[A-Za-z0-9]{4}": Missing a '$' anchor on the end. > + type: object > + additionalProperties: false blank line. > + required: > + - apple,key-id 'required' goes after 'properties'. blank lines in between. > + properties: > + apple,key-id: > + $ref: /schemas/types.yaml#/definitions/string > + pattern: "^[A-Za-z0-9]{4}" > + description: The SMC FourCC key of the desired current sensor. > + Should match the node's suffix, but doesn't have to. blank line > + label: > + $ref: /schemas/types.yaml#/definitions/string Already has a type, don't need to re-define it. > + description: Human-readable name for the sensor Instead of duplicating these properties, You can do it once under a '$defs' key and then reference it here. > + > + fan: > + description: SMC fan control endpoints. A fan is made up of five > + SMC keys - the fan's current speed, its minimum speed, its maximum > + speed, a writeable target speed, and a writeable mode. The SMC will > + automatically manage system fans unless a 1 is written to the fan's > + mode key. > + type: object > + additionalProperties: false blank line. And so on... > + patternProperties: > + "^fan-[A-Za-z0-9]{4}": > + type: object > + additionalProperties: false > + required: > + - apple,key-id > + properties: > + apple,key-id: > + $ref: /schemas/types.yaml#/definitions/string > + pattern: "^[A-Za-z0-9]{4}" > + description: The SMC FourCC key of the desired fan. This is the > + main key, which reports the fan's current speed. Sould match typo > + the node's suffix, but doesn't have to. Why can't we require that they match? (Other than we can't express that in schema?) > + apple,fan-minimum: > + $ref: /schemas/types.yaml#/definitions/string > + pattern: "^[A-Za-z0-9]{4}" > + description: The minimum speed the current fan can run at This is not the speed, but the identifier key to retrieve the min speed, right? That's not clear. It's a bit odd that everything is a key id, but one property has that in the name and the others don't. I don't have any better suggestion though... > + apple,fan-maximum: > + $ref: /schemas/types.yaml#/definitions/string > + pattern: "^[A-Za-z0-9]{4}" > + description: The maximum speed the current fan can run at > + apple,fan-target: > + $ref: /schemas/types.yaml#/definitions/string > + pattern: "^[A-Za-z0-9]{4}" > + description: Writeable endpoint for setting desired fan speed > + apple,fan-mode: > + $ref: /schemas/types.yaml#/definitions/string > + pattern: "^[A-Za-z0-9]{4}" > + description: Writeable endpoint to enable/disable manual fan > + control > + label: > + $ref: /schemas/types.yaml#/definitions/string > + description: Human-readable name for the sensor Surely more than apple,key-id is required? How would it be useful with only that? You can know how many fans you have, but have no info or control over them? Rob
Hi Rob, On Wed, Aug 20, 2025 at 6:15 AM Rob Herring <robh@kernel.org> wrote: > > On Tue, Aug 19, 2025 at 09:47:54PM +1000, James Calligeros wrote: > > Apple Silicon devices integrate a vast array of sensors, monitoring > > current, power, temperature, and voltage across almost every part of > > the system. The sensors themselves are all connected to the System > > Management Controller (SMC). The SMC firmware exposes the data > > reported by these sensors via its standard FourCC-based key-value > > API. The SMC is also responsible for monitoring and controlling any > > fans connected to the system, exposing them in the same way. > > > > For reasons known only to Apple, each device exposes its sensors with > > an almost totally unique set of keys. This is true even for devices > > which share an SoC. An M1 Mac mini, for example, will report its core > > temperatures on different keys to an M1 MacBook Pro. Worse still, the > > SMC does not provide a way to enumerate the available keys at runtime, > > nor do the keys follow any sort of reasonable or consistent naming > > rules that could be used to deduce their purpose. We must therefore > > know which keys are present on any given device, and which function > > they serve, ahead of time. > > I'm confused because you say this, but then the .dtsi files are common. The SMC exposes dozens of sensors, and figuring out which one is which when all we have to go by are cryptic FourCCs is proving very time consuming. This is made worse by the fact that even sensors which you'd think should be consistent across devices with a given SoC are often not. For example, the M1 Mac mini exposes the application core temperature sensors on different keys to the M1 MacBook Pro. We have only included the minimal subset of sensors/fans that we know are common to most devices to validate our approach with and make the driver itself useful. > > + patternProperties: > > + "^fan-[A-Za-z0-9]{4}": > > + type: object > > + additionalProperties: false > > + required: > > + - apple,key-id > > + properties: > > + apple,key-id: > > + $ref: /schemas/types.yaml#/definitions/string > > + pattern: "^[A-Za-z0-9]{4}" > > + description: The SMC FourCC key of the desired fan. This is the > > + main key, which reports the fan's current speed. Sould match > > typo > > > + the node's suffix, but doesn't have to. > > Why can't we require that they match? (Other than we can't express that > in schema?) I made this optional mostly because these subnode names are inconsequential. It's the apple,key-id property that matters. If it makes more sense to say that the node name and property 'must' match instead of 'should' then there's no reason we can't do that. Another option is to just have a numbered sequence, e.g. fan-01, temperature-01, etc. > > + apple,fan-minimum: > > + $ref: /schemas/types.yaml#/definitions/string > > + pattern: "^[A-Za-z0-9]{4}" > > + description: The minimum speed the current fan can run at > > This is not the speed, but the identifier key to retrieve the min speed, > right? That's not clear. It's a bit odd that everything is a key id, but > one property has that in the name and the others don't. I don't have any > better suggestion though... Would it make sense to append '-key' to all of the optional fan properties to make this clearer? > > + apple,fan-maximum: > > + $ref: /schemas/types.yaml#/definitions/string > > + pattern: "^[A-Za-z0-9]{4}" > > + description: The maximum speed the current fan can run at > > + apple,fan-target: > > + $ref: /schemas/types.yaml#/definitions/string > > + pattern: "^[A-Za-z0-9]{4}" > > + description: Writeable endpoint for setting desired fan speed > > + apple,fan-mode: > > + $ref: /schemas/types.yaml#/definitions/string > > + pattern: "^[A-Za-z0-9]{4}" > > + description: Writeable endpoint to enable/disable manual fan > > + control > > + label: > > + $ref: /schemas/types.yaml#/definitions/string > > + description: Human-readable name for the sensor > > Surely more than apple,key-id is required? How would it be useful with > only that? You can know how many fans you have, but have no info or > control over them? The key specified in apple,key-id is the fan's current speed, which is the only key strictly required to enumerate the presence of a fan in the system. All of the other keys are optional information that are only really useful when implementing manual fan control, which is itself optional as the platform really expects the SMC firmware to have control over fan speeds at all times. > Rob Regards, James
On 20.08.25 01:22, James Calligeros wrote: > Hi Rob, > > On Wed, Aug 20, 2025 at 6:15 AM Rob Herring <robh@kernel.org> wrote: >> [...] >>> + apple,fan-maximum: >>> + $ref: /schemas/types.yaml#/definitions/string >>> + pattern: "^[A-Za-z0-9]{4}" >>> + description: The maximum speed the current fan can run at >>> + apple,fan-target: >>> + $ref: /schemas/types.yaml#/definitions/string >>> + pattern: "^[A-Za-z0-9]{4}" >>> + description: Writeable endpoint for setting desired fan speed >>> + apple,fan-mode: >>> + $ref: /schemas/types.yaml#/definitions/string >>> + pattern: "^[A-Za-z0-9]{4}" >>> + description: Writeable endpoint to enable/disable manual fan >>> + control >>> + label: >>> + $ref: /schemas/types.yaml#/definitions/string >>> + description: Human-readable name for the sensor >> >> Surely more than apple,key-id is required? How would it be useful with >> only that? You can know how many fans you have, but have no info or >> control over them? > > The key specified in apple,key-id is the fan's current speed, which is the > only key strictly required to enumerate the presence of a fan in the system. > All of the other keys are optional information that are only really useful > when implementing manual fan control, which is itself optional as the platform > really expects the SMC firmware to have control over fan speeds at all times. Can we at least also require the label? Then we have the SMC key and a human readable representation which is already useful. Sven
© 2016 - 2025 Red Hat, Inc.