From nobody Sat Sep 26 14:37:51 2026 Received: from mta0.migadu.com (out-6.mta0.migadu.com [91.218.175.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E3D64549379 for ; Mon, 31 Aug 2026 13:46:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.6 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788183986; cv=none; b=A8dBJ5NrHzBeHyQsKAQzSBFfGrIidegIQk+Bh641dj7f2aUZqxSyN+QaWBTA1z+zi8/4XzbcOsxE0MqYx2ROeXnaQrPVC/K/ZbbPJePDdhK/VdjNgkdbcbG3+qzGQ0j3iInu+P+Daf/R81K2rtdDgvHo7rxd9rVgL+qGvOgt3n4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788183986; c=relaxed/simple; bh=scBtiNDuToM2DtBv3G6lWHXNT3gA4Po3qt4MWXFmDe4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=QwkWVIBjqoRJRxDQa8/b+8Gn1qc0IH6VIZDaXOWMrtovn8a3metQdL7bSx1xHct9R2FF5SGqSZf2iJJcUV4yVFyMHKdbNUsEQvlrroPUoqWIm/QDpxzrSrLlAeSqXvHLqnbyadDMN7jc+qNzEcTJCdVtEeZxGmSGAJftchK9ZV8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=URUqwe6x; arc=none smtp.client-ip=91.218.175.6 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="URUqwe6x" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=scBtiNDuToM2DtBv3G6lWHXNT3gA4Po3qt4MWXFmDe4=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1788183979; v=1; x=1788788779; b=URUqwe6x4gxi8rdjYpq6jwS9Veg9DbKLiyHLU5MiT79NJU7Lzjz4pyj755D79YxGi8BNdQ3W gjA+6XFfjZE1DCPUuP2NVjHLyLp8+dOVDebhBwoN5ReCAqiG/ykPShRSsIWvylYLYI/61u02WCs PIZGMqo6BLpY5xeo/2KbMhMM= X-Envelope-To: linux-kernel@vger.kernel.org Received: by mta12.migadu.com with ESMTPS id 2c159e777dd25be3; Mon, 31 Aug 2026 13:46:19 +0000 X-Mizu-Trace-ID: 2c159e777dd25be3 X-Migadu-Flow: FLOW_OUT From: Troy Mitchell Date: Mon, 31 Aug 2026 21:45:35 +0800 Subject: [PATCH v4 1/6] dt-bindings: vendor-prefixes: Add Sensylink Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260831-ctl2301-v4-1-b335d52a0570@linux.dev> References: <20260831-ctl2301-v4-0-b335d52a0570@linux.dev> In-Reply-To: <20260831-ctl2301-v4-0-b335d52a0570@linux.dev> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Guenter Roeck , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti , Yixun Lan , Jonathan Corbet , Shuah Khan , Randy Dunlap Cc: Troy Mitchell , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hwmon@vger.kernel.org, linux-riscv@lists.infradead.org, spacemit@lists.linux.dev, linux-doc@vger.kernel.org, Krzysztof Kozlowski X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=944; i=troy.mitchell@linux.dev; h=from:subject:message-id; bh=scBtiNDuToM2DtBv3G6lWHXNT3gA4Po3qt4MWXFmDe4=; b=owGbwMvMwCU2g/N9w09jE33G02pJDFlTW2der51/u3bLjp9vfNcWsbYUOs8uPJSgaF6qtfH1z pSLfqZ3OkpZGMS4GGTFFFm6H/BsK/CJsi0QKPSFmcPKBDKEgYtTACYS28jwP+TRgQ6eHBcL2w8N SqvfSLl+29dy8Ude9cZIoei3fF/2CjL8M9vl8rniTNTZnb+y2zy2uPQwd1pk5xV0fz347MGK/T2 XWQE= X-Developer-Key: i=troy.mitchell@linux.dev; a=openpgp; fpr=3FE5535CF1B0E658E57DB59BAE1C2FBEA7DB42E1 Add the vendor prefix for Sensylink Microelectronics. Link: https://en.sensylink.com/ Acked-by: Krzysztof Kozlowski Signed-off-by: Troy Mitchell --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Docum= entation/devicetree/bindings/vendor-prefixes.yaml index ba2002969373..4a5cf436eb14 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -1495,6 +1495,8 @@ patternProperties: description: Sensirion AG "^sensortek,.*": description: Sensortek Technology Corporation + "^sensylink,.*": + description: Sensylink Microelectronics Technology Co., Ltd. "^sercomm,.*": description: Sercomm (Suzhou) Corporation "^sff,.*": --=20 2.55.0 From nobody Sat Sep 26 14:37:51 2026 Received: from mta0.migadu.com (out-12.mta0.migadu.com [91.218.175.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 66EAF54A7EA for ; Mon, 31 Aug 2026 13:46:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788183993; cv=none; b=kCM4IVTTFJYypaGgDOJfqEzslg+z6IzahDOu32pYyZ9//+ZzYuKOW3zyhsl+kbPIhrBlLZ74f0ERcuaBLepFZWuPkXcD/OOknj7x130fgwqYA277x8co+INz1OvT31XEAkzIOP7G4kdBkU5gIVpov45NcYPN9uuiteXqWtPanXI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788183993; c=relaxed/simple; bh=iGW14hm5r7h49Vg5wNZLdnJWa4OHQc1zf3eCSZ9Fyzg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iEV9HKRbkcYnXnZwTW+5X+QA58KjBcI1oGUser2cUVuqdCD7aLx97UrF6AkFvor7bYNl8ZhljWGwZH6dl+c+yTKqmjc8ydTCFnxH8AuVTAsYAETFW7/ApZCjckC5+U5W7tSVr7Ztt4ICvNzY6lj4dyC5/h/YxgusHnlDrpyj3Sc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=UmtmO1uX; arc=none smtp.client-ip=91.218.175.12 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="UmtmO1uX" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=iGW14hm5r7h49Vg5wNZLdnJWa4OHQc1zf3eCSZ9Fyzg=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1788183984; v=1; x=1788788784; b=UmtmO1uXEsLDfe0nhNJNU9MDd4P7PNxKVLP/On3aIkeAJZ9qa3/kIewofagpDWa1jfpZDTZS 037E4q/P/5IoonUx0C/zLH19fTugMV6qwd6iuzlvzU4Iare/13uJ0BJwOVWX5in93GeKMAdvuVv gOMurFgrNNlrZP1jJxXnSULw= X-Envelope-To: linux-kernel@vger.kernel.org Received: by mta12.migadu.com with ESMTPS id 1fa78ac9957080c4; Mon, 31 Aug 2026 13:46:24 +0000 X-Mizu-Trace-ID: 1fa78ac9957080c4 X-Migadu-Flow: FLOW_OUT From: Troy Mitchell Date: Mon, 31 Aug 2026 21:45:36 +0800 Subject: [PATCH v4 2/6] dt-bindings: hwmon: Move LM63 family to a dedicated binding Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260831-ctl2301-v4-2-b335d52a0570@linux.dev> References: <20260831-ctl2301-v4-0-b335d52a0570@linux.dev> In-Reply-To: <20260831-ctl2301-v4-0-b335d52a0570@linux.dev> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Guenter Roeck , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti , Yixun Lan , Jonathan Corbet , Shuah Khan , Randy Dunlap Cc: Troy Mitchell , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hwmon@vger.kernel.org, linux-riscv@lists.infradead.org, spacemit@lists.linux.dev, linux-doc@vger.kernel.org, Krzysztof Kozlowski X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3138; i=troy.mitchell@linux.dev; h=from:subject:message-id; bh=iGW14hm5r7h49Vg5wNZLdnJWa4OHQc1zf3eCSZ9Fyzg=; b=owGbwMvMwCU2g/N9w09jE33G02pJDFlTW2cZPtvfmr6FYcmbZM7gFpG54a3s/42tL3zjXZlY9 97vzf83HaUsDGJcDLJiiizdD3i2FfhE2RYIFPrCzGFlAhnCwMUpABPZNJGR4eGHaZZ7JE5az1qm U3N64k6W6z5aWslmc1yXrVwkHtOR7s3wv/Yp7/Orpz9+b9V6VK93eN1E+xbnpz7xqvb6+RtK0w8 o8AEA X-Developer-Key: i=troy.mitchell@linux.dev; a=openpgp; fpr=3FE5535CF1B0E658E57DB59BAE1C2FBEA7DB42E1 Move the National Semiconductor LM63, LM64, and LM96163 compatibles out of trivial-devices.yaml and into a dedicated binding. Describe their integrated fan control and preserve the optional interrupt used by the ALERT output. Permit use as thermal cooling devices via #cooling-cells. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Troy Mitchell --- .../devicetree/bindings/hwmon/national,lm63.yaml | 53 ++++++++++++++++++= ++++ .../devicetree/bindings/trivial-devices.yaml | 6 --- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/hwmon/national,lm63.yaml b/D= ocumentation/devicetree/bindings/hwmon/national,lm63.yaml new file mode 100644 index 000000000000..f2e0993cfbef --- /dev/null +++ b/Documentation/devicetree/bindings/hwmon/national,lm63.yaml @@ -0,0 +1,53 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/hwmon/national,lm63.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: LM63-compatible temperature sensors with integrated fan control + +maintainers: + - Guenter Roeck + +description: | + The LM63 family provides local and remote temperature monitoring together + with fan speed monitoring and PWM fan control. Supported devices include + the National Semiconductor LM63, LM64 and LM96163. + +allOf: + - $ref: hwmon-common.yaml# + +properties: + compatible: + enum: + - national,lm63 + - national,lm64 + - national,lm96163 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + "#cooling-cells": + const: 2 + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + i2c { + #address-cells =3D <1>; + #size-cells =3D <0>; + + temperature-sensor@4c { + compatible =3D "national,lm63"; + reg =3D <0x4c>; + #cooling-cells =3D <2>; + }; + }; diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Docum= entation/devicetree/bindings/trivial-devices.yaml index 2de8eb09cb7d..e46912ba2fd6 100644 --- a/Documentation/devicetree/bindings/trivial-devices.yaml +++ b/Documentation/devicetree/bindings/trivial-devices.yaml @@ -368,16 +368,10 @@ properties: - mps,mpq82d00 # Murata D1U74T-W power supply unit - murata,d1u74t - # Temperature sensor with integrated fan control - - national,lm63 - # Temperature sensor with integrated fan control - - national,lm64 # Temperature sensor - national,lm95235 # Temperature sensor - national,lm95245 - # Temperature sensor with integrated fan control - - national,lm96163 # Serial Interface ACPI-Compatible Microprocessor System Hardw= are Monitor - national,lm80 # Serial Interface ACPI-Compatible Microprocessor System Hardw= are Monitor --=20 2.55.0 From nobody Sat Sep 26 14:37:51 2026 Received: from mta1.migadu.com (out-53.mta1.migadu.com [95.215.58.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 20CAE54937E for ; Mon, 31 Aug 2026 13:46:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788183996; cv=none; b=jVEFLiY3gs8nxEAzT/Bj19us95JXNFl754DxQb1lSSHAMPXiDcqE3RR0iXVmGpRYa4VvM+ln6kTTvdJB18w2A76WvhN1GiYfqqQRtyhLgyH9OMS94QA2vjAIDS/ez11HkzmfvduQaXi2sN2AuaabH8B5E9++Yv3s9vqMM/2iJII= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788183996; c=relaxed/simple; bh=yRqRgPijYmsIK6SmmV9Po0rmE7qecT+mk2IoaUzPjf0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SEawoZwfT7Qsz4xLRxK7G6G1hCH+JDBsgGrwRaMXnTVmK1uV2RKLQAQVAz6W7/+c6pCtHvmJjkpK2wURRkMFLGmQyHKmfmLPxUmkKBbwX72b7GO61Mh13c/Pu6XMraoFCH33eKMMtFCAMqJhUinWhgItYc+WUkHAp/P8stlVRf0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=ua0vX6oT; arc=none smtp.client-ip=95.215.58.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="ua0vX6oT" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=yRqRgPijYmsIK6SmmV9Po0rmE7qecT+mk2IoaUzPjf0=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1788183989; v=1; x=1788788789; b=ua0vX6oTRJNXlU4bAIU6ToM90lu0GuSnRtz2vUDdAvKflKt7cV5WM3y1pcBBRNaRoz/0Nf9g AWv0r3ER4d5MHzmaqZKqu2KNpPTt5IAhVKvq5FQguEfyV17OwY2MLZ+FLDbFdIaILWwq1DelLH7 uM5NQ3J0e//qDnKakJkbud4M= X-Envelope-To: linux-kernel@vger.kernel.org Received: by mta12.migadu.com with ESMTPS id d6effb9741c8df24; Mon, 31 Aug 2026 13:46:28 +0000 X-Mizu-Trace-ID: d6effb9741c8df24 X-Migadu-Flow: FLOW_OUT From: Troy Mitchell Date: Mon, 31 Aug 2026 21:45:37 +0800 Subject: [PATCH v4 3/6] dt-bindings: hwmon: Add Sensylink CTF2301 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260831-ctl2301-v4-3-b335d52a0570@linux.dev> References: <20260831-ctl2301-v4-0-b335d52a0570@linux.dev> In-Reply-To: <20260831-ctl2301-v4-0-b335d52a0570@linux.dev> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Guenter Roeck , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti , Yixun Lan , Jonathan Corbet , Shuah Khan , Randy Dunlap Cc: Troy Mitchell , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hwmon@vger.kernel.org, linux-riscv@lists.infradead.org, spacemit@lists.linux.dev, linux-doc@vger.kernel.org, Krzysztof Kozlowski X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1684; i=troy.mitchell@linux.dev; h=from:subject:message-id; bh=yRqRgPijYmsIK6SmmV9Po0rmE7qecT+mk2IoaUzPjf0=; b=kA0DAAoWmAnvgPkzNC8ByyZiAGqVhZyj4hHW3Ytd5gXevNKC/we1F2ZEmdDs/j53zZmht8RD4 Ih1BAAWCgAdFiEEi+AMtnBMWj1wEHFNmAnvgPkzNC8FAmqVhZwACgkQmAnvgPkzNC/e0gEA3YMM ZPqTO+6Ykw8I0GX13qF7QDbWzfwVX5ZBdsrgDmMBAKX0Vo48wN2iNivLubwYrFE7mwsDTXYPj2a kqUgr20wH X-Developer-Key: i=troy.mitchell@linux.dev; a=openpgp; fpr=3FE5535CF1B0E658E57DB59BAE1C2FBEA7DB42E1 Add the Sensylink CTF2301 temperature sensor and fan controller to the LM63 family binding. The chip follows the LM63 register model and can provide a thermal cooling device when #cooling-cells is present. Do not provide a national,lm63 fallback because the CTF2301 is not fully compatible with LM63. It uses different conversion-rate encodings, extended local-temperature registers, additional fan lookup table entries, and device-specific PWM and ALERT/TACH configuration. An older LM63 driver would therefore not operate the device correctly. Acked-by: Krzysztof Kozlowski Signed-off-by: Troy Mitchell --- Documentation/devicetree/bindings/hwmon/national,lm63.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/hwmon/national,lm63.yaml b/D= ocumentation/devicetree/bindings/hwmon/national,lm63.yaml index f2e0993cfbef..4c8d0a15fbd1 100644 --- a/Documentation/devicetree/bindings/hwmon/national,lm63.yaml +++ b/Documentation/devicetree/bindings/hwmon/national,lm63.yaml @@ -12,7 +12,8 @@ maintainers: description: | The LM63 family provides local and remote temperature monitoring together with fan speed monitoring and PWM fan control. Supported devices include - the National Semiconductor LM63, LM64 and LM96163. + the National Semiconductor LM63, LM64 and LM96163, and the Sensylink + CTF2301. =20 allOf: - $ref: hwmon-common.yaml# @@ -23,6 +24,7 @@ properties: - national,lm63 - national,lm64 - national,lm96163 + - sensylink,ctf2301 =20 reg: maxItems: 1 --=20 2.55.0 From nobody Sat Sep 26 14:37:51 2026 Received: from mta0.migadu.com (out-27.mta0.migadu.com [91.218.175.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7A8B84A9D79 for ; Mon, 31 Aug 2026 13:46:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.27 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788184002; cv=none; b=VEzeQ3qLXpXGC1/b3w9g6+IeB14uhsH+Dq/4Qh1ipMQWcDBcKEaAMJzcKbgy1ijoYYbLfVdxARjhwCQ27r4GWj3nEeno7qFUaoMPr3/QFQwyx0EgdW927ZN+dJcgsP5BhSdkgBoTiTC9m/RC5KHjWj2AdXT2E5sHId5ACgLihOY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788184002; c=relaxed/simple; bh=XpKneJ+SIzY6GU3zSESWpBAVtCFHPqRXsgTUbp42hEE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rk3naFKZgcjJR8wmJ2HB4klCqotvlObFty9uaTg+yfuiKZ4HjAkOPLX53GPJM6kltkioURtz6YAFSX4lqL5m6NPrdewJ0aIN8zd+HGHkW3lSbli9zzjLbu0wnvO7k50GBSg2RyTFjoiuCUTRsDJ2oCPjPphxx1Qe9GVlM/VwwkA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=oDCO/xc/; arc=none smtp.client-ip=91.218.175.27 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="oDCO/xc/" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=XpKneJ+SIzY6GU3zSESWpBAVtCFHPqRXsgTUbp42hEE=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1788183994; v=1; x=1788788794; b=oDCO/xc/N8AdH36jVrdcKJKFtiB6xLMAuEB25pmHL1cwOqil5S3OnQnY8U6yRbD00vGgYANx X0etqGIaU0ZFtlnjUzfyLjp+1Zb1SMOXMeSx8aRcm2jTFgTEjjeRucAquW6qFXIgr+pd7UcaCui OshQOP9DtATu1O7wnijH2Lu8= X-Envelope-To: linux-kernel@vger.kernel.org Received: by mta12.migadu.com with ESMTPS id 49261e718890d7b2; Mon, 31 Aug 2026 13:46:33 +0000 X-Mizu-Trace-ID: 49261e718890d7b2 X-Migadu-Flow: FLOW_OUT From: Troy Mitchell Date: Mon, 31 Aug 2026 21:45:38 +0800 Subject: [PATCH v4 4/6] hwmon: (lm63) Add Sensylink CTF2301 support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260831-ctl2301-v4-4-b335d52a0570@linux.dev> References: <20260831-ctl2301-v4-0-b335d52a0570@linux.dev> In-Reply-To: <20260831-ctl2301-v4-0-b335d52a0570@linux.dev> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Guenter Roeck , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti , Yixun Lan , Jonathan Corbet , Shuah Khan , Randy Dunlap Cc: Troy Mitchell , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hwmon@vger.kernel.org, linux-riscv@lists.infradead.org, spacemit@lists.linux.dev, linux-doc@vger.kernel.org, Jean Delvare X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=26266; i=troy.mitchell@linux.dev; h=from:subject:message-id; bh=XpKneJ+SIzY6GU3zSESWpBAVtCFHPqRXsgTUbp42hEE=; b=owGbwMvMwCU2g/N9w09jE33G02pJDFlTW+eumjT9xC3fvkUfnxz44nBs0ZNvb7v2blzm83dP6 fapF6/Wd3WUsjCIcTHIiimydD/g2VbgE2VbIFDoCzOHlQlkCAMXpwBMJJKX4b9Xaequmc8Nz6ga mkVPnNGn5mSfun3Vd4WpnYpJXT02fcaMDNv7z+tEnWK7nZPw2FT3iNdh1wjG70k2/y8l5D4+v/c kIyMA X-Developer-Key: i=troy.mitchell@linux.dev; a=openpgp; fpr=3FE5535CF1B0E658E57DB59BAE1C2FBEA7DB42E1 Add Sensylink CTF2301 support to the LM63 driver. CTF2301 follows the LM63-style temperature, tachometer, and PWM register layout, while using a 12-bit local temperature register and requiring the ALERT/TACH pin to be configured for tachometer input. Register an optional thermal cooling device when the device tree node provides #cooling-cells, allowing thermal zones to control the fan through the existing PWM path without changing behavior for existing LM63-family users. Signed-off-by: Troy Mitchell --- Documentation/hwmon/lm63.rst | 22 +++ drivers/hwmon/Kconfig | 8 +- drivers/hwmon/lm63.c | 426 +++++++++++++++++++++++++++++++++++----= ---- 3 files changed, 377 insertions(+), 79 deletions(-) diff --git a/Documentation/hwmon/lm63.rst b/Documentation/hwmon/lm63.rst index 9e27367d7405..c40bd0dfe591 100644 --- a/Documentation/hwmon/lm63.rst +++ b/Documentation/hwmon/lm63.rst @@ -33,6 +33,16 @@ Supported chips: =20 http://www.national.com/pf/LM/LM96163.html =20 + * Sensylink CTF2301 + + Prefix: 'ctf2301' + + Addresses scanned: none + + Datasheet: https://www.sensylink.com/upload/1/net.sensylink.portal/168= 9557281035.pdf + + Register description: https://github.com/TroyMitchell911/ctf2301-datas= heet + =20 Author: Jean Delvare =20 @@ -62,6 +72,8 @@ value have to be masked out. The value is still 16 bit in= width. =20 All temperature values are given in degrees Celsius. Resolution is 1.0 degree for the local temperature, 0.125 degree for the remote temperature. +The CTF2301 local temperature input and limit have a resolution of 0.0625 +degree. =20 The fan speed is measured using a tachometer. Contrary to most chips which store the value in an 8-bit register and have a selectable clock divider @@ -93,3 +105,13 @@ support these GPIO lines at present. The LM96163 is an enhanced version of LM63 with improved temperature accur= acy and better PWM resolution. For LM96163, the external temperature sensor ty= pe is configurable as CPU embedded diode(1) or 3904 transistor(2). + +The CTF2301 is register-compatible with the LM63 family and provides 12 fan +control lookup table entries. It supports 8-bit PWM resolution when config= ured +for a 22.5 kHz PWM frequency. + +Device tree nodes may declare ``#cooling-cells`` to register the fan contr= oller +with the thermal framework. The cooling state is mapped to the existing +``pwm1`` range from 0 to 255. The driver keeps the current automatic or ma= nual +fan control mode during probe and switches to manual control when the ther= mal +framework first requests a cooling state. diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index fecff8610ea8..5d87ad3e7a20 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1521,10 +1521,10 @@ config SENSORS_LM63 depends on I2C help If you say yes here you get support for the National - Semiconductor LM63, LM64, and LM96163 remote diode digital temperature - sensors with integrated fan control. Such chips are found - on the Tyan S4882 (Thunder K8QS Pro) motherboard, among - others. + Semiconductor LM63, LM64, LM96163, and Sensylink CTF2301 + remote diode digital temperature sensors with integrated fan + control. Such chips are found on the Tyan S4882 (Thunder K8QS + Pro) motherboard, among others. =20 This driver can also be built as a module. If so, the module will be called lm63. diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index da09770c05e7..5a94895242ed 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c @@ -35,13 +35,14 @@ #include #include #include +#include #include =20 /* * Addresses to scan * Address is fully defined internally and cannot be changed except for * LM64 which has one pin dedicated to address selection. - * LM63 and LM96163 have address 0x4c. + * LM63, LM96163, and CTF2301 have address 0x4c. * LM64 can have address 0x18 or 0x4e. */ =20 @@ -70,6 +71,9 @@ static const unsigned short normal_i2c[] =3D { 0x18, 0x4c= , 0x4e, I2C_CLIENT_END }; #define LM63_REG_LOCAL_TEMP 0x00 #define LM63_REG_LOCAL_HIGH 0x05 =20 +#define CTF2301_REG_LOCAL_TEMP_LSB 0x15 +#define CTF2301_REG_LOCAL_HIGH_LSB 0x06 + #define LM63_REG_REMOTE_TEMP_MSB 0x01 #define LM63_REG_REMOTE_TEMP_LSB 0x10 #define LM63_REG_REMOTE_OFFSET_MSB 0x11 @@ -94,6 +98,7 @@ static const unsigned short normal_i2c[] =3D { 0x18, 0x4c= , 0x4e, I2C_CLIENT_END }; =20 #define LM63_PWM_BASE_FAST_HZ 180000 #define LM63_PWM_BASE_SLOW_HZ 700 +#define LM63_MAX_PWM 255 =20 #define LM63_MAX_CONVRATE 9 =20 @@ -121,6 +126,9 @@ static const unsigned short normal_i2c[] =3D { 0x18, 0x= 4c, 0x4e, I2C_CLIENT_END }; 127000), 1000) #define TEMP8U_TO_REG(val) DIV_ROUND_CLOSEST(clamp_val((val), 0, \ 255000), 1000) +#define TEMP12_FROM_REG(reg) DIV_ROUND_CLOSEST((s16)(reg) * 1000, 256) +#define TEMP12_TO_REG(val) DIV_ROUND_CLOSEST(clamp_val((val), -128000, \ + 127937) * 256, 1000) #define TEMP11_FROM_REG(reg) ((reg) / 32 * 125) #define TEMP11_TO_REG(val) (DIV_ROUND_CLOSEST(clamp_val((val), -128000, \ 127875), 125) * 32) @@ -132,7 +140,11 @@ static const unsigned short normal_i2c[] =3D { 0x18, 0= x4c, 0x4e, I2C_CLIENT_END }; #define UPDATE_INTERVAL(max, rate) \ ((1000 << (LM63_MAX_CONVRATE - (rate))) / (max)) =20 -enum chips { lm63, lm64, lm96163 }; +enum chips { ctf2301, lm63, lm64, lm96163 }; + +static const unsigned int ctf2301_update_intervals[] =3D { + 20000, 10000, 4902, 2463, 1000, 615, 307, 154, 107 +}; =20 /* * Client data (each client gets its own) @@ -164,6 +176,8 @@ struct lm63_data { 1: local high limit 2: remote critical limit 3-14: lookup table */ + s16 temp1_input; /* local input for chips with extended resolution */ + s16 temp1_max; /* local limit for chips with extended resolution */ s16 temp11[4]; /* 0: remote input 1: remote low limit 2: remote high limit @@ -229,6 +243,7 @@ static struct lm63_data *lm63_update_device(struct devi= ce *dev) struct lm63_data *data =3D dev_get_drvdata(dev); struct i2c_client *client =3D data->client; unsigned long next_update; + int msb, lsb; =20 mutex_lock(&data->update_lock); =20 @@ -253,10 +268,26 @@ static struct lm63_data *lm63_update_device(struct de= vice *dev) data->pwm1[0] =3D i2c_smbus_read_byte_data(client, LM63_REG_PWM_VALUE); =20 - data->temp8[0] =3D i2c_smbus_read_byte_data(client, - LM63_REG_LOCAL_TEMP); - data->temp8[1] =3D i2c_smbus_read_byte_data(client, - LM63_REG_LOCAL_HIGH); + if (data->kind =3D=3D ctf2301) { + msb =3D i2c_smbus_read_byte_data(client, + LM63_REG_LOCAL_TEMP); + lsb =3D i2c_smbus_read_byte_data(client, + CTF2301_REG_LOCAL_TEMP_LSB); + if (msb >=3D 0 && lsb >=3D 0) + data->temp1_input =3D ((u16)(u8)msb << 8) | lsb; + + msb =3D i2c_smbus_read_byte_data(client, + LM63_REG_LOCAL_HIGH); + lsb =3D i2c_smbus_read_byte_data(client, + CTF2301_REG_LOCAL_HIGH_LSB); + if (msb >=3D 0 && lsb >=3D 0) + data->temp1_max =3D ((u16)(u8)msb << 8) | lsb; + } else { + data->temp8[0] =3D i2c_smbus_read_byte_data(client, + LM63_REG_LOCAL_TEMP); + data->temp8[1] =3D i2c_smbus_read_byte_data(client, + LM63_REG_LOCAL_HIGH); + } =20 /* order matters for temp2_input */ data->temp11[0] =3D i2c_smbus_read_byte_data(client, @@ -276,7 +307,7 @@ static struct lm63_data *lm63_update_device(struct devi= ce *dev) | i2c_smbus_read_byte_data(client, LM63_REG_REMOTE_OFFSET_LSB); =20 - if (data->kind =3D=3D lm96163) + if (data->kind =3D=3D lm96163 || data->kind =3D=3D ctf2301) data->temp11u =3D (i2c_smbus_read_byte_data(client, LM96163_REG_REMOTE_TEMP_U_MSB) << 8) | i2c_smbus_read_byte_data(client, @@ -366,6 +397,49 @@ static ssize_t set_fan(struct device *dev, struct devi= ce_attribute *dummy, return count; } =20 +static int lm63_pwm_from_reg(struct lm63_data *data, u8 reg) +{ + if (data->pwm_highres) + return reg; + + return reg >=3D 2 * data->pwm1_freq ? + LM63_MAX_PWM : + (reg * LM63_MAX_PWM + data->pwm1_freq) / (2 * data->pwm1_freq); +} + +static u8 lm63_pwm_to_reg(struct lm63_data *data, unsigned long val) +{ + val =3D clamp_val(val, 0, LM63_MAX_PWM); + + if (data->pwm_highres) + return val; + + return (val * data->pwm1_freq * 2 + LM63_MAX_PWM / 2) / LM63_MAX_PWM; +} + +static void lm63_update_pwm_highres(struct lm63_data *data, + int config_enhanced) +{ + data->pwm_highres =3D !(data->config_fan & 0x08) && + data->pwm1_freq =3D=3D 8 && + (config_enhanced & 0x10); +} + +static int lm63_write_pwm(struct lm63_data *data, int nr, unsigned long va= l) +{ + struct i2c_client *client =3D data->client; + u8 reg =3D nr ? LM63_REG_LUT_PWM(nr - 1) : LM63_REG_PWM_VALUE; + u8 regval =3D lm63_pwm_to_reg(data, val); + int ret; + + ret =3D i2c_smbus_write_byte_data(client, reg, regval); + if (ret) + return ret; + data->pwm1[nr] =3D regval; + + return 0; +} + static ssize_t show_pwm1(struct device *dev, struct device_attribute *deva= ttr, char *buf) { @@ -375,12 +449,7 @@ static ssize_t show_pwm1(struct device *dev, struct de= vice_attribute *devattr, int pwm; =20 mutex_lock(&data->update_lock); - if (data->pwm_highres) - pwm =3D data->pwm1[nr]; - else - pwm =3D data->pwm1[nr] >=3D 2 * data->pwm1_freq ? - 255 : (data->pwm1[nr] * 255 + data->pwm1_freq) / - (2 * data->pwm1_freq); + pwm =3D lm63_pwm_from_reg(data, data->pwm1[nr]); mutex_unlock(&data->update_lock); =20 return sprintf(buf, "%d\n", pwm); @@ -391,11 +460,9 @@ static ssize_t set_pwm1(struct device *dev, struct dev= ice_attribute *devattr, { struct sensor_device_attribute *attr =3D to_sensor_dev_attr(devattr); struct lm63_data *data =3D dev_get_drvdata(dev); - struct i2c_client *client =3D data->client; int nr =3D attr->index; unsigned long val; int err; - u8 reg; =20 if (!(data->config_fan & 0x20)) /* register is read-only */ return -EPERM; @@ -404,15 +471,11 @@ static ssize_t set_pwm1(struct device *dev, struct de= vice_attribute *devattr, if (err) return err; =20 - reg =3D nr ? LM63_REG_LUT_PWM(nr - 1) : LM63_REG_PWM_VALUE; - val =3D clamp_val(val, 0, 255); - mutex_lock(&data->update_lock); - data->pwm1[nr] =3D data->pwm_highres ? val : - (val * data->pwm1_freq * 2 + 127) / 255; - i2c_smbus_write_byte_data(client, reg, data->pwm1[nr]); + err =3D lm63_write_pwm(data, nr, val); mutex_unlock(&data->update_lock); - return count; + + return err ? err : count; } =20 static ssize_t pwm1_enable_show(struct device *dev, @@ -485,7 +548,9 @@ static ssize_t pwm1_freq_store(struct device *dev, struct lm63_data *data =3D dev_get_drvdata(dev); struct i2c_client *client =3D data->client; unsigned long val, pfr_fast, pfr_slow, err_fast, err_slow, pfr; + u8 config_fan; bool slow_clock; + int config_enhanced =3D 0; int ret; =20 ret =3D kstrtoul(buf, 10, &val); @@ -511,35 +576,58 @@ static ssize_t pwm1_freq_store(struct device *dev, =20 mutex_lock(&data->update_lock); ret =3D i2c_smbus_read_byte_data(client, LM63_REG_CONFIG_FAN); - if (ret < 0) { - mutex_unlock(&data->update_lock); - return ret; - } - data->config_fan =3D ret; + if (ret < 0) + goto unlock; + config_fan =3D ret; + data->config_fan =3D config_fan; =20 - if (!(data->config_fan & 0x20)) { /* register is read-only */ - mutex_unlock(&data->update_lock); - return -EPERM; + if (!(config_fan & 0x20)) { /* register is read-only */ + ret =3D -EPERM; + goto unlock; } =20 - if (data->kind =3D=3D lm96163) { - ret =3D i2c_smbus_read_byte_data(client, LM96163_REG_CONFIG_ENHANCED); - if (ret < 0) { - mutex_unlock(&data->update_lock); - return ret; + if (data->kind =3D=3D lm96163 || data->kind =3D=3D ctf2301) { + ret =3D i2c_smbus_read_byte_data(client, + LM96163_REG_CONFIG_ENHANCED); + if (ret < 0) + goto unlock; + config_enhanced =3D ret; + lm63_update_pwm_highres(data, config_enhanced); + + if (data->kind =3D=3D ctf2301) { + if (!slow_clock && pfr =3D=3D 8) + config_enhanced |=3D 0x10; + else + config_enhanced &=3D ~0x10; + ret =3D i2c_smbus_write_byte_data(client, + LM96163_REG_CONFIG_ENHANCED, + config_enhanced); + if (ret) + goto unlock; + lm63_update_pwm_highres(data, config_enhanced); } - data->pwm_highres =3D !slow_clock && pfr =3D=3D 8 && (ret & 0x10); } =20 if (slow_clock) - data->config_fan |=3D 0x08; + config_fan |=3D 0x08; else - data->config_fan &=3D ~0x08; - i2c_smbus_write_byte_data(client, LM63_REG_CONFIG_FAN, data->config_fan); - i2c_smbus_write_byte_data(client, LM63_REG_PWM_FREQ, pfr); + config_fan &=3D ~0x08; + ret =3D i2c_smbus_write_byte_data(client, LM63_REG_PWM_FREQ, pfr); + if (ret) + goto unlock; data->pwm1_freq =3D pfr; + lm63_update_pwm_highres(data, config_enhanced); + ret =3D i2c_smbus_write_byte_data(client, LM63_REG_CONFIG_FAN, + config_fan); + if (ret) + goto unlock; + + data->config_fan =3D config_fan; + lm63_update_pwm_highres(data, config_enhanced); +unlock: mutex_unlock(&data->update_lock); - return count; + + return ret ? ret : count; } =20 /* @@ -554,7 +642,17 @@ static ssize_t show_local_temp8(struct device *dev, { struct sensor_device_attribute *attr =3D to_sensor_dev_attr(devattr); struct lm63_data *data =3D lm63_update_device(dev); - return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[attr->index])); + int temp; + + mutex_lock(&data->update_lock); + if (data->kind =3D=3D ctf2301) + temp =3D TEMP12_FROM_REG(attr->index ? data->temp1_max : + data->temp1_input); + else + temp =3D TEMP8_FROM_REG(data->temp8[attr->index]); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", temp); } =20 static ssize_t show_remote_temp8(struct device *dev, @@ -594,6 +692,21 @@ static ssize_t set_temp8(struct device *dev, struct de= vice_attribute *devattr, return err; =20 mutex_lock(&data->update_lock); + if (data->kind =3D=3D ctf2301 && nr =3D=3D 1) { + temp =3D TEMP12_TO_REG(val); + err =3D i2c_smbus_write_byte_data(client, LM63_REG_LOCAL_HIGH, + temp >> 8); + if (!err) + err =3D i2c_smbus_write_byte_data(client, + CTF2301_REG_LOCAL_HIGH_LSB, + temp & 0xf0); + if (!err) + data->temp1_max =3D temp; + mutex_unlock(&data->update_lock); + + return err ? err : count; + } + switch (nr) { case 2: reg =3D LM63_REG_REMOTE_TCRIT; @@ -610,10 +723,12 @@ static ssize_t set_temp8(struct device *dev, struct d= evice_attribute *devattr, reg =3D LM63_REG_LUT_TEMP(nr - 3); temp =3D lut_temp_to_reg(data, val); } - data->temp8[nr] =3D temp; - i2c_smbus_write_byte_data(client, reg, temp); + err =3D i2c_smbus_write_byte_data(client, reg, temp); + if (!err) + data->temp8[nr] =3D temp; mutex_unlock(&data->update_lock); - return count; + + return err ? err : count; } =20 static ssize_t show_temp11(struct device *dev, struct device_attribute *de= vattr, @@ -787,11 +902,40 @@ static ssize_t temp2_crit_hyst_store(struct device *d= ev, * Set conversion rate. * client->update_lock must be held when calling this function. */ -static void lm63_set_convrate(struct lm63_data *data, unsigned int interva= l) +static unsigned int lm63_update_interval(struct lm63_data *data, u8 rate) +{ + if (data->kind =3D=3D ctf2301) + return ctf2301_update_intervals[min_t(unsigned int, rate, + ARRAY_SIZE(ctf2301_update_intervals) - 1)]; + + return UPDATE_INTERVAL(data->max_convrate_hz, rate); +} + +static int lm63_set_convrate(struct lm63_data *data, unsigned int interval) { struct i2c_client *client =3D data->client; - unsigned int update_interval; - int i; + unsigned int update_interval, error, best_error =3D ~0U; + unsigned int best =3D 0; + unsigned int i; + int ret; + + if (data->kind =3D=3D ctf2301) { + for (i =3D 0; i < ARRAY_SIZE(ctf2301_update_intervals); i++) { + error =3D abs_diff(interval, ctf2301_update_intervals[i]); + if (error < best_error) { + best_error =3D error; + best =3D i; + } + } + + ret =3D i2c_smbus_write_byte_data(client, LM63_REG_CONVRATE, + best); + if (ret) + return ret; + data->update_interval =3D ctf2301_update_intervals[best]; + + return 0; + } =20 /* Shift calculations to avoid rounding errors */ interval <<=3D 6; @@ -803,8 +947,12 @@ static void lm63_set_convrate(struct lm63_data *data, = unsigned int interval) if (interval >=3D update_interval * 3 / 4) break; =20 - i2c_smbus_write_byte_data(client, LM63_REG_CONVRATE, i); + ret =3D i2c_smbus_write_byte_data(client, LM63_REG_CONVRATE, i); + if (ret) + return ret; data->update_interval =3D UPDATE_INTERVAL(data->max_convrate_hz, i); + + return 0; } =20 static ssize_t update_interval_show(struct device *dev, @@ -828,10 +976,10 @@ static ssize_t update_interval_store(struct device *d= ev, return err; =20 mutex_lock(&data->update_lock); - lm63_set_convrate(data, clamp_val(val, 0, 100000)); + err =3D lm63_set_convrate(data, clamp_val(val, 0, 100000)); mutex_unlock(&data->update_lock); =20 - return count; + return err ? err : count; } =20 static ssize_t temp2_type_show(struct device *dev, @@ -996,6 +1144,75 @@ static DEVICE_ATTR_RO(alarms); =20 static DEVICE_ATTR_RW(update_interval); =20 +static int lm63_get_max_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + *state =3D LM63_MAX_PWM; + + return 0; +} + +static int lm63_get_cur_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + struct lm63_data *data =3D cdev->devdata; + int ret; + + mutex_lock(&data->update_lock); + ret =3D i2c_smbus_read_byte_data(data->client, LM63_REG_PWM_VALUE); + if (ret < 0) + goto unlock; + + data->pwm1[0] =3D ret; + *state =3D lm63_pwm_from_reg(data, data->pwm1[0]); +unlock: + mutex_unlock(&data->update_lock); + + return ret < 0 ? ret : 0; +} + +static int lm63_set_cur_state(struct thermal_cooling_device *cdev, + unsigned long state) +{ + struct lm63_data *data =3D cdev->devdata; + int config_fan; + int ret; + + if (state > LM63_MAX_PWM) + return -EINVAL; + + mutex_lock(&data->update_lock); + config_fan =3D i2c_smbus_read_byte_data(data->client, + LM63_REG_CONFIG_FAN); + if (config_fan < 0) { + ret =3D config_fan; + goto unlock; + } + data->config_fan =3D config_fan; + + if (!(config_fan & 0x20)) { + config_fan |=3D 0x20; + ret =3D i2c_smbus_write_byte_data(data->client, + LM63_REG_CONFIG_FAN, + config_fan); + if (ret) + goto unlock; + data->config_fan =3D config_fan; + } + + ret =3D lm63_write_pwm(data, 0, state); +unlock: + mutex_unlock(&data->update_lock); + + return ret; +} + +static const struct thermal_cooling_device_ops lm63_cooling_ops =3D { + .get_max_state =3D lm63_get_max_state, + .get_cur_state =3D lm63_get_cur_state, + .set_cur_state =3D lm63_set_cur_state, +}; + static struct attribute *lm63_attributes[] =3D { &sensor_dev_attr_pwm1.dev_attr.attr, &dev_attr_pwm1_enable.attr, @@ -1078,8 +1295,8 @@ static const struct attribute_group lm63_group_extra_= lut =3D { * On LM63, temp2_crit can be set only once, which should be job * of the bootloader. * On LM64, temp2_crit can always be set. - * On LM96163, temp2_crit can be set if bit 1 of the configuration - * register is true. + * On LM96163 and CTF2301, temp2_crit can be set if bit 1 of the + * configuration register is true. */ static umode_t lm63_attribute_mode(struct kobject *kobj, struct attribute *attr, int index) @@ -1089,7 +1306,8 @@ static umode_t lm63_attribute_mode(struct kobject *ko= bj, =20 if (attr =3D=3D &sensor_dev_attr_temp2_crit.dev_attr.attr && (data->kind =3D=3D lm64 || - (data->kind =3D=3D lm96163 && (data->config & 0x02)))) + ((data->kind =3D=3D lm96163 || data->kind =3D=3D ctf2301) && + (data->config & 0x02)))) return attr->mode | S_IWUSR; =20 return attr->mode; @@ -1164,29 +1382,48 @@ static int lm63_detect(struct i2c_client *client, * Ideally we shouldn't have to initialize anything, since the BIOS * should have taken care of everything */ -static void lm63_init_client(struct lm63_data *data) +static int lm63_init_client(struct lm63_data *data) { struct i2c_client *client =3D data->client; struct device *dev =3D &client->dev; u8 convrate; + int ret; =20 - data->config =3D i2c_smbus_read_byte_data(client, LM63_REG_CONFIG1); - data->config_fan =3D i2c_smbus_read_byte_data(client, - LM63_REG_CONFIG_FAN); + ret =3D i2c_smbus_read_byte_data(client, LM63_REG_CONFIG1); + if (ret < 0) + return ret; + data->config =3D ret; + ret =3D i2c_smbus_read_byte_data(client, LM63_REG_CONFIG_FAN); + if (ret < 0) + return ret; + data->config_fan =3D ret; =20 /* Start converting if needed */ if (data->config & 0x40) { /* standby */ dev_dbg(dev, "Switching to operational mode\n"); data->config &=3D 0xA7; - i2c_smbus_write_byte_data(client, LM63_REG_CONFIG1, - data->config); + ret =3D i2c_smbus_write_byte_data(client, LM63_REG_CONFIG1, + data->config); + if (ret) + return ret; } /* Tachometer is always enabled on LM64 */ if (data->kind =3D=3D lm64) data->config |=3D 0x04; + if (data->kind =3D=3D ctf2301 && !client->irq && !(data->config & 0x04)) { + dev_dbg(dev, "Configuring ALERT/TACH pin for tachometer input\n"); + data->config |=3D 0x04; + ret =3D i2c_smbus_write_byte_data(client, LM63_REG_CONFIG1, + data->config); + if (ret) + return ret; + } =20 /* We may need pwm1_freq before ever updating the client data */ - data->pwm1_freq =3D i2c_smbus_read_byte_data(client, LM63_REG_PWM_FREQ) &= 0x1f; + ret =3D i2c_smbus_read_byte_data(client, LM63_REG_PWM_FREQ); + if (ret < 0) + return ret; + data->pwm1_freq =3D ret & 0x1f; if (data->pwm1_freq =3D=3D 0) data->pwm1_freq =3D 1; =20 @@ -1199,25 +1436,38 @@ static void lm63_init_client(struct lm63_data *data) case lm96163: data->max_convrate_hz =3D LM96163_MAX_CONVRATE_HZ; data->lut_size =3D 12; - data->trutherm - =3D i2c_smbus_read_byte_data(client, - LM96163_REG_TRUTHERM) & 0x02; + ret =3D i2c_smbus_read_byte_data(client, LM96163_REG_TRUTHERM); + if (ret < 0) + return ret; + data->trutherm =3D ret & 0x02; + break; + case ctf2301: + data->lut_size =3D 12; break; } - convrate =3D i2c_smbus_read_byte_data(client, LM63_REG_CONVRATE); - if (unlikely(convrate > LM63_MAX_CONVRATE)) + ret =3D i2c_smbus_read_byte_data(client, LM63_REG_CONVRATE); + if (ret < 0) + return ret; + convrate =3D ret; + if (data->kind =3D=3D ctf2301 && + convrate >=3D ARRAY_SIZE(ctf2301_update_intervals)) + convrate =3D ARRAY_SIZE(ctf2301_update_intervals) - 1; + else if (unlikely(convrate > LM63_MAX_CONVRATE)) convrate =3D LM63_MAX_CONVRATE; - data->update_interval =3D UPDATE_INTERVAL(data->max_convrate_hz, - convrate); + data->update_interval =3D lm63_update_interval(data, convrate); =20 /* - * For LM96163, check if high resolution PWM + * For LM96163 and CTF2301, check if high resolution PWM * and unsigned temperature format is enabled. */ - if (data->kind =3D=3D lm96163) { - u8 config_enhanced - =3D i2c_smbus_read_byte_data(client, - LM96163_REG_CONFIG_ENHANCED); + if (data->kind =3D=3D lm96163 || data->kind =3D=3D ctf2301) { + u8 config_enhanced; + + ret =3D i2c_smbus_read_byte_data(client, + LM96163_REG_CONFIG_ENHANCED); + if (ret < 0) + return ret; + config_enhanced =3D ret; if (config_enhanced & 0x20) data->lut_temp_highres =3D true; if ((config_enhanced & 0x10) @@ -1238,6 +1488,8 @@ static void lm63_init_client(struct lm63_data *data) dev_dbg(dev, "PWM output active %s, %s mode\n", (data->config_fan & 0x10) ? "low" : "high", (data->config_fan & 0x20) ? "manual" : "auto"); + + return 0; } =20 static const struct i2c_device_id lm63_id[]; @@ -1245,9 +1497,11 @@ static const struct i2c_device_id lm63_id[]; static int lm63_probe(struct i2c_client *client) { struct device *dev =3D &client->dev; + struct thermal_cooling_device *cdev; struct device *hwmon_dev; struct lm63_data *data; int groups =3D 0; + int ret; =20 data =3D devm_kzalloc(dev, sizeof(struct lm63_data), GFP_KERNEL); if (!data) @@ -1262,7 +1516,9 @@ static int lm63_probe(struct i2c_client *client) data->temp2_offset =3D 16000; =20 /* Initialize chip */ - lm63_init_client(data); + ret =3D lm63_init_client(data); + if (ret) + return dev_err_probe(dev, ret, "failed to initialize device\n"); =20 /* Register sysfs hooks */ data->groups[groups++] =3D &lm63_group; @@ -1272,11 +1528,26 @@ static int lm63_probe(struct i2c_client *client) if (data->kind =3D=3D lm96163) { data->groups[groups++] =3D &lm63_group_temp2_type; data->groups[groups++] =3D &lm63_group_extra_lut; + } else if (data->kind =3D=3D ctf2301) { + data->groups[groups++] =3D &lm63_group_extra_lut; } =20 hwmon_dev =3D devm_hwmon_device_register_with_groups(dev, client->name, data, data->groups); - return PTR_ERR_OR_ZERO(hwmon_dev); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); + + if (IS_ENABLED(CONFIG_THERMAL_OF) && + of_property_present(dev->of_node, "#cooling-cells")) { + cdev =3D devm_thermal_of_cooling_device_register(dev, 0, + client->name, + data, + &lm63_cooling_ops); + if (IS_ERR(cdev)) + return PTR_ERR(cdev); + } + + return 0; } =20 /* @@ -1287,6 +1558,7 @@ static const struct i2c_device_id lm63_id[] =3D { { .name =3D "lm63", .driver_data =3D lm63 }, { .name =3D "lm64", .driver_data =3D lm64 }, { .name =3D "lm96163", .driver_data =3D lm96163 }, + { .name =3D "ctf2301", .driver_data =3D ctf2301 }, { } }; MODULE_DEVICE_TABLE(i2c, lm63_id); @@ -1304,6 +1576,10 @@ static const struct of_device_id __maybe_unused lm63= _of_match[] =3D { .compatible =3D "national,lm96163", .data =3D (void *)lm96163 }, + { + .compatible =3D "sensylink,ctf2301", + .data =3D (void *)ctf2301 + }, { }, }; MODULE_DEVICE_TABLE(of, lm63_of_match); --=20 2.55.0 From nobody Sat Sep 26 14:37:51 2026 Received: from mta0.migadu.com (out-36.mta0.migadu.com [91.218.175.36]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7990C54DAFE for ; Mon, 31 Aug 2026 13:46:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.36 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788184004; cv=none; b=sHBeA8ylaL7zc1r0Ylcgn4AqHjVncOhwGzPCX8K2N/9ldEb8x6fvNZp1neTM19hMmvDNXuTsyv3KgS3NzIzXsgujcGNy2k7U1q6RCHkF3EsxCPynGTIhN4ncn7xFh0XROKUr6b2ikYQ0MyKqsJJFFnEskWKW7VaBlMKazaEP+Ss= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788184004; c=relaxed/simple; bh=oPyPhpeTyLPcNCtmwSXuGQluq3E1noUV5NUuvWuVnOg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ERsoxe+oXWvy4mB7iG+nXmeYrm+6VQzXaQx6+NpYZ//+6SRkUUNtAz+i9wX0KHHfJDOXZt7UsBQOrHTXa+8AB1c3Yz31cZEPRs6dkIAtjWy0g4vWwdM0WGnsT+1zkson/aX8iwRjBTopUT3qY5CwCFx3C8hJZ0KRMPcn7ZDySCM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=etGHANe7; arc=none smtp.client-ip=91.218.175.36 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="etGHANe7" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=oPyPhpeTyLPcNCtmwSXuGQluq3E1noUV5NUuvWuVnOg=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1788183999; v=1; x=1788788799; b=etGHANe7dwCumJGjrXQ11nusN6sCNZK2kn441T9zx/K/zoXTy9Kt27ZoK9PJ3fYON5K02bI7 tqAqomxfIz0nizmt/zSzvZR0MEhDXrC/LGTVQpybzr0537wZvUikJJ2tsK8FWXE8Jwmuj0sa9cI uQPSU/0Q/v6sE17xQg2ZjO2k= X-Envelope-To: linux-kernel@vger.kernel.org Received: by mta12.migadu.com with ESMTPS id 78d01d025d72b5ab; Mon, 31 Aug 2026 13:46:38 +0000 X-Mizu-Trace-ID: 78d01d025d72b5ab X-Migadu-Flow: FLOW_OUT From: Troy Mitchell Date: Mon, 31 Aug 2026 21:45:39 +0800 Subject: [PATCH v4 5/6] riscv: dts: spacemit: Add K3 I2C6 pinctrl state Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260831-ctl2301-v4-5-b335d52a0570@linux.dev> References: <20260831-ctl2301-v4-0-b335d52a0570@linux.dev> In-Reply-To: <20260831-ctl2301-v4-0-b335d52a0570@linux.dev> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Guenter Roeck , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti , Yixun Lan , Jonathan Corbet , Shuah Khan , Randy Dunlap Cc: Troy Mitchell , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hwmon@vger.kernel.org, linux-riscv@lists.infradead.org, spacemit@lists.linux.dev, linux-doc@vger.kernel.org X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=994; i=troy.mitchell@linux.dev; h=from:subject:message-id; bh=oPyPhpeTyLPcNCtmwSXuGQluq3E1noUV5NUuvWuVnOg=; b=owGbwMvMwCU2g/N9w09jE33G02pJDFlTW+e9tQ3Oef/55bOeGYtnC1hm1Lw06r5/06Ug+QeL6 7O+lUFBHaUsDGJcDLJiiizdD3i2FfhE2RYIFPrCzGFlAhnCwMUpABMx2sPI0G7wYPdJl7poh42X lnBFvcs8rPchyFruW8lz02tbF/zWFWL4H9ab9n7v8YYMzs/+Yc57///uC/BbPqfI+c7rglk3Nxs HsAEA X-Developer-Key: i=troy.mitchell@linux.dev; a=openpgp; fpr=3FE5535CF1B0E658E57DB59BAE1C2FBEA7DB42E1 Add the K3 I2C6 pinctrl state used by boards that route I2C6 to pads 7 and 8. Use a 25 mA drive strength, which is supported for both K3 IO voltage domains, and leave board-specific IO voltage selection to board files. Signed-off-by: Troy Mitchell --- arch/riscv/boot/dts/spacemit/k3-pinctrl.dtsi | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/riscv/boot/dts/spacemit/k3-pinctrl.dtsi b/arch/riscv/boot= /dts/spacemit/k3-pinctrl.dtsi index 6482d24be139..cb4f4f4e33af 100644 --- a/arch/riscv/boot/dts/spacemit/k3-pinctrl.dtsi +++ b/arch/riscv/boot/dts/spacemit/k3-pinctrl.dtsi @@ -101,6 +101,17 @@ i2c2-1-pins { }; }; =20 + /omit-if-no-ref/ + i2c6_1_cfg: i2c6-1-cfg { + i2c6-1-pins { + pinmux =3D , /* i2c6 scl */ + ; /* i2c6 sda */ + + bias-pull-up =3D <0>; + drive-strength =3D <25>; + }; + }; + /omit-if-no-ref/ i2c8_cfg: i2c8-cfg { i2c8-pins { --=20 2.55.0 From nobody Sat Sep 26 14:37:51 2026 Received: from mta0.migadu.com (out-44.mta0.migadu.com [91.218.175.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EA1CA4AA563 for ; Mon, 31 Aug 2026 13:46:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788184010; cv=none; b=QZ1gdaRUii576ogsjDoZ+G7+RFLoXJwBy/FyChIAO/5sKhb/aXJ9rpWOKeKt1wYyauJ7haHnv/n2fmYwluQ+9ZAETQ7HsaEYaONzIB1vy9A81vMP0gmBvOlonfW62gDLeghPcctOD8sQS/HTf8yJUKFrJo1CZoi38uH7aEo4T8c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788184010; c=relaxed/simple; bh=aJYTFNqOScKS85O+yLyZiMcEgXXBbLJv3BwXF//J3gg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eRYtoQemtyA1DROv7pVqukScCFdChj1tle0VNWz9mWj9EiJYhJ5Ldy5v16wZXfJH5v+W8PHMcRD32yPLRlWlbe39CKkBDF7z8a1fqTTfmdjB1vUjI/w0b00XJWqT4tSuv05tzhLqPINQmRwiSPyoxMJ7WVTiOuQmOXndyaUfYec= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=wkw1Xlg/; arc=none smtp.client-ip=91.218.175.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="wkw1Xlg/" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=aJYTFNqOScKS85O+yLyZiMcEgXXBbLJv3BwXF//J3gg=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1788184003; v=1; x=1788788803; b=wkw1Xlg/XtPK6VPF4HGjbH9EXB2dlRdMfpK+tdrrbPxeYVhRLnqI3K4oUBKfv3gRp1T7RMpG YXX4jwSE7Eh8ux5SBw35SQcRTMyisrmPMYE03PlCnXs1G1Y6c9y88RxlQ5gFJt9406YJaMvbT6g jDv3s0RzSQVPYYMYd679YQa4= X-Envelope-To: linux-kernel@vger.kernel.org Received: by mta12.migadu.com with ESMTPS id d27796f85925d44a; Mon, 31 Aug 2026 13:46:43 +0000 X-Mizu-Trace-ID: d27796f85925d44a X-Migadu-Flow: FLOW_OUT From: Troy Mitchell Date: Mon, 31 Aug 2026 21:45:40 +0800 Subject: [PATCH v4 6/6] riscv: dts: spacemit: Add CTF2301 on K3 CoM260 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260831-ctl2301-v4-6-b335d52a0570@linux.dev> References: <20260831-ctl2301-v4-0-b335d52a0570@linux.dev> In-Reply-To: <20260831-ctl2301-v4-0-b335d52a0570@linux.dev> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Guenter Roeck , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti , Yixun Lan , Jonathan Corbet , Shuah Khan , Randy Dunlap Cc: Troy Mitchell , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hwmon@vger.kernel.org, linux-riscv@lists.infradead.org, spacemit@lists.linux.dev, linux-doc@vger.kernel.org X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1042; i=troy.mitchell@linux.dev; h=from:subject:message-id; bh=aJYTFNqOScKS85O+yLyZiMcEgXXBbLJv3BwXF//J3gg=; b=owGbwMvMwCU2g/N9w09jE33G02pJDFlTW+cHvn14YJr6/o8nOM9mRPr3F0xu/VT9b8Wls12TX +2bOFnEo6OUhUGMi0FWTJGl+wHPtgKfKNsCgUJfmDmsTCBDGLg4BWAiS80Z/qf6nZt0KO3/lMKS S3Nf/7Kra2+e0bRpsf+D0skfL8m+WFTC8D88YqFc9b0UC8cQM9N3Bg9/XFdWVQs9u/nJiZV2ghI OF1kB X-Developer-Key: i=troy.mitchell@linux.dev; a=openpgp; fpr=3FE5535CF1B0E658E57DB59BAE1C2FBEA7DB42E1 Enable I2C6 on the K3 CoM260 module and describe the Sensylink CTF2301 temperature sensor and fan controller at address 0x4c. Override the I2C6 pin power source at board level because the IO rail voltage is board-specific. Signed-off-by: Troy Mitchell --- arch/riscv/boot/dts/spacemit/k3-com260.dtsi | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/riscv/boot/dts/spacemit/k3-com260.dtsi b/arch/riscv/boot/= dts/spacemit/k3-com260.dtsi index 37627963a649..92dea8639779 100644 --- a/arch/riscv/boot/dts/spacemit/k3-com260.dtsi +++ b/arch/riscv/boot/dts/spacemit/k3-com260.dtsi @@ -58,6 +58,23 @@ serial-number { }; }; =20 +&i2c6_1_cfg { + i2c6-1-pins { + power-source =3D <3300>; + }; +}; + +&i2c6 { + pinctrl-names =3D "default"; + pinctrl-0 =3D <&i2c6_1_cfg>; + status =3D "okay"; + + temperature-sensor@4c { + compatible =3D "sensylink,ctf2301"; + reg =3D <0x4c>; + }; +}; + &i2c8 { pinctrl-names =3D "default"; pinctrl-0 =3D <&i2c8_cfg>; --=20 2.55.0