From nobody Sat Oct 3 04:22:53 2026 Received: from out-183.mta0.migadu.com (out-183.mta0.migadu.com [91.218.175.183]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3C5873E1208 for ; Wed, 5 Aug 2026 09:11:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.183 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785921119; cv=none; b=jPw2huAu4blUN1p5ArtLlBwlSNoOCP992KqWB0XRdIfnZdztuR9z68VwbA+Fcl6P39vxJw+s2x81UZMhLrTmASzOzKXMtaGJbDcRd36o+ScKsbNFAFzFf+7kF0DVfCqiDaAgXiSTPrTY0OLQRiSbm0BRXs+cFHBQDOHTmOq7z9k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785921119; c=relaxed/simple; bh=Po1kGrx5EeIEP6xmiLoDE4sxhUkiA/m5kFmOQAaZHUc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc: In-Reply-To:References; b=mt1iq/gir1fnry+zges88VEN67HqyW3C0q+ye26GjzR4aIh1cXT64zOQdNbHqY/M+eua/gFkrN/GVMeM7go3wdkwJA0fzpLSN33U6qdjCPMN/kVEXWmJ4VPnxGohsHd35+BB3lCnkOxzusV3VC+jA8TemoqXZpMPzmOfV0F+4qI= 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=o+Ch8Hg7; arc=none smtp.client-ip=91.218.175.183 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="o+Ch8Hg7" X-Mailbox-Line: From troy.mitchell@linux.dev Wed Aug 5 02:03:29 2026 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1785921115; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=sLTSEYfRh/OPcBA2Yh6WL4PX3iP/fJj9kbntKv+PhPk=; b=o+Ch8Hg7SEZ6tA+UIYwDO52d3OZ9y/06osXf/k6PR3UuHaTecNDho4mX25T4NUOqMV4Anm WUVsMQza4qeIUedeKKaRWvUOGXyxWUuU3Q97Cqu5G5uB1ddh4w2/AdpLxb620Ikik5Szll pNngT6WaDxwc6pDwtbLfCp78MuG9Tfg= X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Troy Mitchell Date: Wed, 05 Aug 2026 02:00:51 -0700 Subject: [PATCH v3 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: <20260805-ctl2301-v3-1-b86c75d1c552@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 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-Developer-Signature: v=1; a=openpgp-sha256; l=874; i=troy.mitchell@linux.dev; h=from:subject:message-id; bh=Po1kGrx5EeIEP6xmiLoDE4sxhUkiA/m5kFmOQAaZHUc=; b=owGbwMvMwCU2g/N9w09jE33G02pJDFlFv4/IX02XPafwbUus3LGUd1XNzBd4Wc4sXlrj0rRde afOU/c9HaUsDGJcDLJiiizdD3i2FfhE2RYIFPrCzGFlAhnCwMUpABOxy2T4Z/zqaLj+oQvmq1YI lSmqKqb5ME59stOveMXy5jXqbfcOODIyrLj3ebGu91Gz5mLR32wLni7wrpjgV3FSNPGpVSif+BN /fgA= X-Developer-Key: i=troy.mitchell@linux.dev; a=openpgp; fpr=3FE5535CF1B0E658E57DB59BAE1C2FBEA7DB42E1 In-Reply-To: <20260805-ctl2301-v3-0-fd4b8ffb5b0d@linux.dev> References: <20260805-ctl2301-v3-0-fd4b8ffb5b0d@linux.dev> X-Migadu-Flow: FLOW_OUT Add the vendor prefix for Sensylink Microelectronics. Link: https://en.sensylink.com/ Signed-off-by: Troy Mitchell Acked-by: Krzysztof Kozlowski --- 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 396044f368e7..22d0d26f1bbd 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -1467,6 +1467,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 Oct 3 04:22:53 2026 Received: from out-182.mta1.migadu.com (mta1.migadu.com [37.59.57.117]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0F0663F44C8; Wed, 5 Aug 2026 09:12:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=37.59.57.117 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785921140; cv=none; b=I2sQe0OtflXXaEt5zY18hFyKGtvvlcIGFC9E9oci5uCi8KFwFM+J+x2wwSPb4rUX2lznttiojei0nj0uNpHQjaZBHAkEH2FIjjECSFZbKyo9ssQVJoGRru9a8TZWx30txWOMb9PRkU+0pafhMjA6iKv/4Zyh7lS0qw7hGeZwdlc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785921140; c=relaxed/simple; bh=h66UPDPeq+8SOvsZ43XgQtxGhVgtvhOir6wqRjV7WNo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc: In-Reply-To:References; b=ov+MylwvSTn8UoWg6mJZR4+crpUqiVUPH5nZjtDeMBzslJ/lpRtwVUXFAOzc+jtQmMJD+C0R2R4CBiEYLY6smZser581WSvIraiw9Lp8XFp7rIilBdlNWt9XIdpBvu7INSYMtmbJ2MEWyXA22n3QddSeLNOUzDZVi0B4pCi5Q3Y= 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=kbc/jtXm; arc=none smtp.client-ip=37.59.57.117 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="kbc/jtXm" X-Mailbox-Line: From troy.mitchell@linux.dev Wed Aug 5 02:03:29 2026 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1785921136; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=G+eLp8JoAcY18XlukudBlKohBC6kmbzaMQpheqGUCy0=; b=kbc/jtXmsOdMN40duYfR2NlYVPVt2NoCKYS9iVo1vS3NaDkjpluMNE3j7GEvhr5iVWuc47 WbyxdubwTpLnbOsjt3z+h/wzQHlk4zOec72h4kXYSJIpNDpy9rE6Skdq82qhLjVzvqhd9o bLWaOrfoT36hwrhUK1cn/DqsvhSQeGQ= X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Troy Mitchell Date: Wed, 05 Aug 2026 02:00:52 -0700 Subject: [PATCH v3 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: <20260805-ctl2301-v3-2-b86c75d1c552@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 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-Developer-Signature: v=1; a=openpgp-sha256; l=3063; i=troy.mitchell@linux.dev; h=from:subject:message-id; bh=h66UPDPeq+8SOvsZ43XgQtxGhVgtvhOir6wqRjV7WNo=; b=owGbwMvMwCU2g/N9w09jE33G02pJDFlFv48q63R871W9ILZk0cnFQZ6P4hW8MxMuzQy5oMwt/ UXy5hXTjlIWBjEuBlkxRZbuBzzbCnyibAsECn1h5rAygQxh4OIUgIn8tWH4w/13ie3xJub0NRJ8 wZau+WkzXPiObZn1NYphW/zWUxV3HjIyrDmp5MfQLfVN8vxruUVyu0PKhM21NH0Ofpd6HtnpK9/ MBwA= X-Developer-Key: i=troy.mitchell@linux.dev; a=openpgp; fpr=3FE5535CF1B0E658E57DB59BAE1C2FBEA7DB42E1 In-Reply-To: <20260805-ctl2301-v3-0-fd4b8ffb5b0d@linux.dev> References: <20260805-ctl2301-v3-0-fd4b8ffb5b0d@linux.dev> X-Migadu-Flow: FLOW_OUT 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. Signed-off-by: Troy Mitchell Reviewed-by: Krzysztof Kozlowski --- .../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 435c4baab436..aa62d245464c 100644 --- a/Documentation/devicetree/bindings/trivial-devices.yaml +++ b/Documentation/devicetree/bindings/trivial-devices.yaml @@ -364,16 +364,10 @@ properties: - mps,mp9945 # 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 Oct 3 04:22:53 2026 Received: from out-174.mta1.migadu.com (out-174.mta1.migadu.com [95.215.58.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1505A3F6C25 for ; Wed, 5 Aug 2026 09:12:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785921169; cv=none; b=Kjpd3wYGk7IAuiz4W6lnAnPpzzMVkaHLmNlRU3K7yVPmuEdk2aRoeDMU1VtfQPgrba6e9f5jv3Hq15JXQfoKEnVMEGtoF5y/+6CAlyk2g8t0Wn2TU/Kwbwcq6EfF59mrMn8B82/Y6XnrAlOvxCbA7yVgDgYzPDhqPT0SKpPJabM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785921169; c=relaxed/simple; bh=KCvIoqp/+fM+IQnsjqs168omOMWHR2iMmUGZC2CmXlo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc: In-Reply-To:References; b=LfSfnVg+WyXw2ed/9Hg8IYU+0dkd5CjWW1zx9IgxlVfwEEu48EWHxXw5zdedVE/iNC0QQ5Djqj9eCPJwVXC0MZZ5yDtfDxxfLFzygC1xZjrtaDyIW1OrvPAy1XIoQSGyPhqVzywzI88FecGEgJBJsQD19iILqguw0ITlMqo/qAk= 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=c+kkjdwI; arc=none smtp.client-ip=95.215.58.174 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="c+kkjdwI" X-Mailbox-Line: From troy.mitchell@linux.dev Wed Aug 5 02:03:29 2026 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1785921165; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=HbQVqT/KW/L2AONpoOSIbgjQbA7VEc8vzMKs12aCiiQ=; b=c+kkjdwIqbVfFxu5b8ro6mxkFsKpVCFP/K0BBKmrToaTBWxqd5IxRQ6JnCqJRIW/Ns6+K+ A8YE8aIu+c68TnirlX+MYh+iSjSJp21dnvoGOD6BJGyXGAiWCY+2uV8eKLpFr4azEjVzKg cPZE69px5B8R1WLXlmCpcK/9QPe015c= X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Troy Mitchell Date: Wed, 05 Aug 2026 02:00:53 -0700 Subject: [PATCH v3 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: <20260805-ctl2301-v3-3-b86c75d1c552@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 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-Developer-Signature: v=1; a=openpgp-sha256; l=1614; i=troy.mitchell@linux.dev; h=from:subject:message-id; bh=KCvIoqp/+fM+IQnsjqs168omOMWHR2iMmUGZC2CmXlo=; b=owGbwMvMwCU2g/N9w09jE33G02pJDFlFv49Jyy4J7RW49X6lXrfHiUgn5Tun06RlN9Wo3D1b/ vjtqUr2jlIWBjEuBlkxRZbuBzzbCnyibAsECn1h5rAygQxh4OIUgIlodDIyrH23UO/fzT0ij1hf 3tbyiJLZcaRuZbXVyvn1exZz6m15sIyR4fjcvdVLns5MMmR/fuNXgvj+D3kFVXtd5zZprTGdptP mwwIA X-Developer-Key: i=troy.mitchell@linux.dev; a=openpgp; fpr=3FE5535CF1B0E658E57DB59BAE1C2FBEA7DB42E1 In-Reply-To: <20260805-ctl2301-v3-0-fd4b8ffb5b0d@linux.dev> References: <20260805-ctl2301-v3-0-fd4b8ffb5b0d@linux.dev> X-Migadu-Flow: FLOW_OUT 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. Signed-off-by: Troy Mitchell Acked-by: Krzysztof Kozlowski --- 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 Oct 3 04:22:53 2026 Received: from out-186.mta0.migadu.com (out-186.mta0.migadu.com [91.218.175.186]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 823873822B1 for ; Wed, 5 Aug 2026 09:23:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.186 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785921796; cv=none; b=bTEAdYHSCs6FlDd25O1G6WHCtSRhCLT5Aseoq3wDnrO0x+PJSXJWIv6UMWAM4nBS8r+/qAso3faUlh6mmtSgkPw33s1nB1QTdFz4wAqNxAfh+562+fo7ApqDrae46Ak74J/dvd8sbooJpfVlEeCO8ZQjLYjFze27GyYkO/q66k8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785921796; c=relaxed/simple; bh=kY/QoUdgZNYjfIPGfsETwouKvftR76s0B6QSb0H3FZ8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc: In-Reply-To:References; b=XxZjEH4qEColpRZWc1QfALbTtyczhxMfyVAWDZkjycOYKryPa9u9ThW+Js8mIQx4xu0dJt6fFHyQ04Uy0Ak+h1L/QzYhdIfc8MLNSXHlJtH1qhlzfMfvyl10rwLrpPXpBsIktO54J+KGI+fJEuiDM9A0d35gTcDZGQ18iUDXtEM= 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=AgsioQ+5; arc=none smtp.client-ip=91.218.175.186 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="AgsioQ+5" X-Mailbox-Line: From troy.mitchell@linux.dev Wed Aug 5 02:03:29 2026 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1785921780; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=x42nUNNMuLAfz7j4uWBeWVYXbdwTnuaXKqmzF2jPQQ8=; b=AgsioQ+5ouSDldWwpNhlXcovMmMA5QNbQyjaTkZAV4ybH9iHR9N6tecBr8JWMAynXkHv5w O8lIY3QKE/6xRj6jJbT13K/R86s1i5tbnQ0u8v32IL//ypLpPpTfjyTkxnrYgBrykkRwll J5GGawUmX7mgk9xyK0HIez2qasrabfI= X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Troy Mitchell Date: Wed, 05 Aug 2026 02:00:54 -0700 Subject: [PATCH v3 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: <20260805-ctl2301-v3-4-b86c75d1c552@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 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-Developer-Signature: v=1; a=openpgp-sha256; l=25765; i=troy.mitchell@linux.dev; h=from:subject:message-id; bh=kY/QoUdgZNYjfIPGfsETwouKvftR76s0B6QSb0H3FZ8=; b=owGbwMvMwCU2g/N9w09jE33G02pJDFlFv09MuXggTzTW9Wfr0kXv9695/8tK3WL/XIuLuw6bN /75znVWuaOUhUGMi0FWTJGl+wHPtgKfKNsCgUJfmDmsTCBDGLg4BWAiCukMfyU/nriz8eWZbi8z OynWDwz5/BWPRUQE1tinls9v45pqOIeR4eS2M7ZMU358mX5m+aetlx5NV7uWtWHbnW2yVr7zGbZ cvcwCAA== X-Developer-Key: i=troy.mitchell@linux.dev; a=openpgp; fpr=3FE5535CF1B0E658E57DB59BAE1C2FBEA7DB42E1 In-Reply-To: <20260805-ctl2301-v3-0-fd4b8ffb5b0d@linux.dev> References: <20260805-ctl2301-v3-0-fd4b8ffb5b0d@linux.dev> X-Migadu-Flow: FLOW_OUT 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 | 414 +++++++++++++++++++++++++++++++++++----= ---- 3 files changed, 366 insertions(+), 78 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 2bfbcc033d59..abb1af8664fb 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1501,10 +1501,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 e2a429e579ac..3887f02b924d 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 { lm63, lm64, lm96163, ctf2301 }; + +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 @@ -254,10 +269,30 @@ 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->temp8[0] =3D msb; + 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->temp8[1] =3D msb; + 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, @@ -277,7 +312,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, @@ -367,6 +402,41 @@ 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 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) { @@ -376,12 +446,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); @@ -392,11 +457,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; @@ -405,15 +468,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, @@ -486,7 +545,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); @@ -512,35 +573,55 @@ 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; =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; + + 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; } - 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; + ret =3D i2c_smbus_write_byte_data(client, LM63_REG_CONFIG_FAN, + config_fan); + if (ret) + goto unlock; + + data->config_fan =3D config_fan; data->pwm1_freq =3D pfr; + data->pwm_highres =3D !slow_clock && pfr =3D=3D 8 && + (config_enhanced & 0x10); +unlock: mutex_unlock(&data->update_lock); - return count; + + return ret ? ret : count; } =20 /* @@ -555,6 +636,11 @@ 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); + + if (data->kind =3D=3D ctf2301) + return sprintf(buf, "%d\n", TEMP12_FROM_REG(attr->index ? + data->temp1_max : data->temp1_input)); + return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[attr->index])); } =20 @@ -595,6 +681,23 @@ 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->temp8[nr] =3D temp >> 8; + data->temp1_max =3D temp; + } + mutex_unlock(&data->update_lock); + + return err ? err : count; + } + switch (nr) { case 2: reg =3D LM63_REG_REMOTE_TCRIT; @@ -611,10 +714,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, @@ -788,11 +893,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; @@ -804,8 +938,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, @@ -829,10 +967,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, @@ -997,6 +1135,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, @@ -1079,8 +1286,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) @@ -1090,7 +1297,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; @@ -1165,29 +1373,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); + ret =3D i2c_smbus_read_byte_data(client, LM63_REG_PWM_FREQ); + if (ret < 0) + return ret; + data->pwm1_freq =3D ret; if (data->pwm1_freq =3D=3D 0) data->pwm1_freq =3D 1; =20 @@ -1200,25 +1427,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) @@ -1239,6 +1479,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[]; @@ -1246,9 +1488,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) @@ -1263,7 +1507,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; @@ -1273,11 +1519,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 /* @@ -1288,6 +1549,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); @@ -1305,6 +1567,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 Oct 3 04:22:53 2026 Received: from out-189.mta0.migadu.com (out-189.mta0.migadu.com [91.218.175.189]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 111292F9D98 for ; Wed, 5 Aug 2026 09:26:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.189 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785921991; cv=none; b=Hjln63lSN2HAdMA5F22UOkPBl2xyfTXeUIDCvJDznodZmFN2m9yfWBMi7cuoxmC+YUWBTlz/HJoBWnLHfKxiE8QxORSvGvGJ2Jc4V6ya1BfYD1fYnGK1gt+Hps8B8zoHWAZ9GHaWgtbVCTF8FeMuLMciJRTods59Br9BundhQLQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785921991; c=relaxed/simple; bh=5PcQb4tYPqg14LJCgWYmntExBwf8V8dZAlN+M5P1nEg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc: In-Reply-To:References; b=c5PTmpWB9jnNPE3yEhwOBFwiUUqFDxTVThcrJKLOLBodpB+Fp5yBAiaN1AxWCPPp4KBjPQw+c6qsYUcKEGxd3zrC6Wrx5R/lqw7gHhLXK9D6MfTupYHK6tErRsOu3AzVDiuiK/MNpQ/Mv4AqFcTJ0TpQYiQ0RiQighEUXShvtbE= 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=mmg7s7OU; arc=none smtp.client-ip=91.218.175.189 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="mmg7s7OU" X-Mailbox-Line: From troy.mitchell@linux.dev Wed Aug 5 02:03:29 2026 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1785921977; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3rrXLP9Gl/9+kZEGTyeSXg9dLTosBnnAR6frYAqGISA=; b=mmg7s7OUrs8f++wIQHtt4bS88b+gf2Fb5ZOGsALIL/+YjBk9Q0HDdkbGDBgwRHFoTC4BBE Q4wDPhHufV2nJ+03ZfdVuq+RKy0kQKmpHAIK4X77TBbjXx2obMOZERzEQTXmt8msVNketb 6M7Kh7GC2+tJDy7HLgD2a8McH/2/EQM= X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Troy Mitchell Date: Wed, 05 Aug 2026 02:00:55 -0700 Subject: [PATCH v3 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: <20260805-ctl2301-v3-5-b86c75d1c552@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 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-Developer-Signature: v=1; a=openpgp-sha256; l=997; i=troy.mitchell@linux.dev; h=from:subject:message-id; bh=5PcQb4tYPqg14LJCgWYmntExBwf8V8dZAlN+M5P1nEg=; b=owGbwMvMwCU2g/N9w09jE33G02pJDFlFv0/OuPKbp8ltCf9Pr8pPZ+yOhGxRVOe89e2qXGXU6 3V8H65odJSyMIhxMciKKbJ0P+DZVuATZVsgUOgLM4eVCWQIAxenAEzEwpDhn16eQy/n2j0yHLvF Xq1XXTG5JeBufIOCj1WacGPNFMNd7Qx/uMU5ervlfkxmudd/9ucMi1+3dl90j2fZtPS5o8hFp72 r2QA= X-Developer-Key: i=troy.mitchell@linux.dev; a=openpgp; fpr=3FE5535CF1B0E658E57DB59BAE1C2FBEA7DB42E1 In-Reply-To: <20260805-ctl2301-v3-0-fd4b8ffb5b0d@linux.dev> References: <20260805-ctl2301-v3-0-fd4b8ffb5b0d@linux.dev> X-Migadu-Flow: FLOW_OUT 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 3ee1471f3798..e50f3e4b5536 100644 --- a/arch/riscv/boot/dts/spacemit/k3-pinctrl.dtsi +++ b/arch/riscv/boot/dts/spacemit/k3-pinctrl.dtsi @@ -78,6 +78,17 @@ gmac1-phy-0-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 Oct 3 04:22:53 2026 Received: from out-185.mta1.migadu.com (out-185.mta1.migadu.com [95.215.58.185]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DD1783EA962 for ; Wed, 5 Aug 2026 09:26:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.185 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785921996; cv=none; b=l+IH9BvOwIdlZ4PWj/O0nj4ECA9KTJZp1nULPbR8ZU5Z9hzKST0E9Sy3IcQXh2Bs+sy4AiqZemyUAqpbr25c+pljnPCueHtAeqELz9bfge6F2JFLBeRVKrMhYn/QzdjgstBpRvTU9Wqd46h+nGxIUHbhucys/2hGI5YyGnlmaYw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785921996; c=relaxed/simple; bh=qkSmO+AW5LxoIXLT9GpKbrSpSAJky3A3GfHMGrIZGak=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc: In-Reply-To:References; b=bQsz84gFj41PQ5IiOyO7xl5gPnBaM9BA65tNVj2HgsKZfAUewgL6KZsNr1bXqbAcO97SDT0FBa7bvrVjdpzKqLfyVqHJqsbKSEjYhF9RTaqehWjiKAXNdjevTT1ojuaVGTvMjXZXKCnOYLPv5epmhkyjEKSUOuXfJiitO1fd8/M= 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=JLV2tluV; arc=none smtp.client-ip=95.215.58.185 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="JLV2tluV" X-Mailbox-Line: From troy.mitchell@linux.dev Wed Aug 5 02:03:29 2026 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1785921992; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=MLkmEy2Qv+au8QUwUsCORU0DDXMr6v1e63PHv69jpg4=; b=JLV2tluVrP6L0K5Jqph3/Gm/ExTCIV44fuCHhLO6HNBThduiWBloGup1CWZZLBRMR4Tg7M XW7X7+DyCyR4zqYr1++Sw5BfHZIqckZKMmoSpKuKiGYGyQjUkh79l4IEeKsTDQnhm7sdNA zldW6xzW+GK4+pK0nl6yc2yVLmL+UzA= X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Troy Mitchell Date: Wed, 05 Aug 2026 02:00:56 -0700 Subject: [PATCH v3 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: <20260805-ctl2301-v3-6-b86c75d1c552@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 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-Developer-Signature: v=1; a=openpgp-sha256; l=1093; i=troy.mitchell@linux.dev; h=from:subject:message-id; bh=qkSmO+AW5LxoIXLT9GpKbrSpSAJky3A3GfHMGrIZGak=; b=owGbwMvMwCU2g/N9w09jE33G02pJDFlFv0/xi1+72ZxzvK+hfKn9jQixffu/FCqt9bfYfWpb2 Syn7cpMHaUsDGJcDLJiiizdD3i2FfhE2RYIFPrCzGFlAhnCwMUpABOp5mRkmKCxsWlS90G2GNMP e+W1Ps39ciVb1lz9/3PttjfGQVuPpDH895CwkJwi7+Zj3Jp5bG/Wf/v3z1auFtutkuLfluZm+nQ ZHwA= X-Developer-Key: i=troy.mitchell@linux.dev; a=openpgp; fpr=3FE5535CF1B0E658E57DB59BAE1C2FBEA7DB42E1 In-Reply-To: <20260805-ctl2301-v3-0-fd4b8ffb5b0d@linux.dev> References: <20260805-ctl2301-v3-0-fd4b8ffb5b0d@linux.dev> X-Migadu-Flow: FLOW_OUT Enable I2C6 on the K3 CoM260 module and describe the Sensylink CTF2301 temperature sensor and fan controller at address 0x4c. Set the I2C6 pin power source in the board-level pinctrl node because the IO rail voltage is board-specific. Signed-off-by: Troy Mitchell --- arch/riscv/boot/dts/spacemit/k3-com260.dtsi | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/arch/riscv/boot/dts/spacemit/k3-com260.dtsi b/arch/riscv/boot/= dts/spacemit/k3-com260.dtsi index a38d7b738258..95a60fbb411f 100644 --- a/arch/riscv/boot/dts/spacemit/k3-com260.dtsi +++ b/arch/riscv/boot/dts/spacemit/k3-com260.dtsi @@ -26,6 +26,25 @@ reg_5v_sys: regulator-5v-sys { }; }; =20 +&pinctrl { + 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