From patchwork Mon Dec 26 12:36:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 13081800 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id F0DA2C46467 for ; Mon, 26 Dec 2022 12:50:07 +0000 (UTC) Received: by smtp.kernel.org (Postfix) id B06B1C433F0; Mon, 26 Dec 2022 12:50:07 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 745BEC433F2; Mon, 26 Dec 2022 12:50:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672059007; bh=7/N4YIZhZubazKHjeckRsmjdQbBIBlpeTV0c+tJDTcE=; h=From:To:List-Id:Cc:Subject:Date:In-Reply-To:References:From; b=IWX724E1qoYmsHLVBCgPIYH2WzbmTaT+71Pph/cuLGnh+tK72EHD1uz03zR8q8Sup v5SyNfNWVUrTqbq+KfWoWsXDJxCs0eKuLe5dTgBVghHToes6rcmU4xSIyRrpIaBJSZ 3FXEf7iLNh2YNY+r3NV/rxl2ZRswvyqkYzHjGPNs67ncYCUZmRZEGpdW55zL3EVu70 iaq+FVJhTCzU54I58o6Vtq+ucmaU6YasORwEBnAz3Rnyh7lkzSdRmVq2Yj3MA+CO/M I+Gz4Qv7vQL/kGz6Xog7w87Q4RpMCHFhat6NB8xnxImZtcp8Z6eoi2PUe36zOzGkl7 VOf8b6xDybHFQ== Received: by pali.im (Postfix) id 09B959E4; Mon, 26 Dec 2022 13:50:05 +0100 (CET) From: =?utf-8?q?Pali_Roh=C3=A1r?= To: "Arnd Bergmann" , Linus Walleij List-Id: Cc: soc@kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH RESEND 1/8] dt-bindings: leds: register-bit-led: Add active-low property Date: Mon, 26 Dec 2022 13:36:23 +0100 Message-Id: <20221226123630.6515-2-pali@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20221226123630.6515-1-pali@kernel.org> References: <20221226123630.6515-1-pali@kernel.org> MIME-Version: 1.0 Allow to define inverted logic (0 - enable LED, 1 - disable LED) via active-low property. Signed-off-by: Pali Rohár Reviewed-by: Linus Walleij Reviewed-by: 19th of August --- Documentation/devicetree/bindings/leds/register-bit-led.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/leds/register-bit-led.yaml b/Documentation/devicetree/bindings/leds/register-bit-led.yaml index ed26ec19ecbd..418130b29caa 100644 --- a/Documentation/devicetree/bindings/leds/register-bit-led.yaml +++ b/Documentation/devicetree/bindings/leds/register-bit-led.yaml @@ -43,6 +43,11 @@ properties: 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000, 0x2000000, 0x4000000, 0x8000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000 ] + active-low: + $ref: /schemas/types.yaml#/definitions/flag + description: + LED is ON when bit in register is not set + offset: description: register offset to the register controlling this LED From patchwork Mon Dec 26 12:36:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 13081799 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A980EC3DA7D for ; Mon, 26 Dec 2022 12:50:07 +0000 (UTC) Received: by smtp.kernel.org (Postfix) id 88922C433EF; Mon, 26 Dec 2022 12:50:07 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 51899C433F1; Mon, 26 Dec 2022 12:50:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672059007; bh=pP+4wtVGKbIsOAg8Ek+NQSpQr5Q1Uw027OLYSi9iPXc=; h=From:To:List-Id:Cc:Subject:Date:In-Reply-To:References:From; b=ko6A8bgm9WlLTNaUxbAKj2EeW5kSkFEldNx2cBtE7iOVxPoz21nFP9oHmuwXh6L2D KfH/M/VWUYUXb8k6wrys5zpSrUQfRh0utRQgZYHdTz9wsKBG28APqhqt0M4FL3rWqG blVwfcjJvoWegQsjQO125+Wot9W6WMtEdEiDqm3KU3bkiSuTJwH6jkxfp6UfYB9CsP qLYLx/n5xSOpPrrgzN7WwZNl1hU8ID91Mud7pVI5ik3ozmXp6sMX4PUch5U/rXXZ1L xva4l467UJN8Q4+R40UuivJTZdoPkoUpwJLu/KCF7YZz5QlkkgDJSNTI+u5zXvHVz3 59I+4JQ2+Tq6g== Received: by pali.im (Postfix) id 0CF999D7; Mon, 26 Dec 2022 13:50:07 +0100 (CET) From: =?utf-8?q?Pali_Roh=C3=A1r?= To: "Arnd Bergmann" , Linus Walleij List-Id: Cc: soc@kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH RESEND 2/8] leds: syscon: Implement support for active-low property Date: Mon, 26 Dec 2022 13:36:24 +0100 Message-Id: <20221226123630.6515-3-pali@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20221226123630.6515-1-pali@kernel.org> References: <20221226123630.6515-1-pali@kernel.org> MIME-Version: 1.0 This new active-low property specify that LED has inverted logic (0 - enable LED, 1 - disable LED). Signed-off-by: Pali Rohár Acked-by: Linus Walleij Reviewed-by: Lee Jones --- drivers/leds/leds-syscon.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/leds/leds-syscon.c b/drivers/leds/leds-syscon.c index 7eddb8ecb44e..5e605d8438e9 100644 --- a/drivers/leds/leds-syscon.c +++ b/drivers/leds/leds-syscon.c @@ -29,6 +29,7 @@ struct syscon_led { struct regmap *map; u32 offset; u32 mask; + bool active_low; bool state; }; @@ -41,10 +42,10 @@ static void syscon_led_set(struct led_classdev *led_cdev, int ret; if (value == LED_OFF) { - val = 0; + val = sled->active_low ? sled->mask : 0; sled->state = false; } else { - val = sled->mask; + val = sled->active_low ? 0 : sled->mask; sled->state = true; } @@ -85,6 +86,8 @@ static int syscon_led_probe(struct platform_device *pdev) return -EINVAL; if (of_property_read_u32(np, "mask", &sled->mask)) return -EINVAL; + if (of_find_property(np, "active-low", NULL)) + sled->active_low = true; state = of_get_property(np, "default-state", NULL); if (state) { @@ -95,17 +98,20 @@ static int syscon_led_probe(struct platform_device *pdev) if (ret < 0) return ret; sled->state = !!(val & sled->mask); + if (sled->active_low) + sled->state = !sled->state; } else if (!strcmp(state, "on")) { sled->state = true; ret = regmap_update_bits(map, sled->offset, sled->mask, - sled->mask); + sled->active_low ? 0 : sled->mask); if (ret < 0) return ret; } else { sled->state = false; ret = regmap_update_bits(map, sled->offset, - sled->mask, 0); + sled->mask, + sled->active_low ? sled->mask : 0); if (ret < 0) return ret; } From patchwork Mon Dec 26 12:36:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 13081801 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 11E1AC3DA79 for ; Mon, 26 Dec 2022 12:50:09 +0000 (UTC) Received: by smtp.kernel.org (Postfix) id EB275C433D2; Mon, 26 Dec 2022 12:50:08 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 89418C433EF; Mon, 26 Dec 2022 12:50:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672059008; bh=YPY06obe0MedVa58r1HJyLm9vowmANV4jsSHamcMWHc=; h=From:To:List-Id:Cc:Subject:Date:In-Reply-To:References:From; b=Te9ryBgpbRqgTBJ5K3qG9ex36jiuy6wowgDFf/ZO7RiNLHh2xF4nicvSnkAouxNid D2B8JGUYtv+w49w5SbUK4hlkwHb+1D/PQQyBSo6QyQTVJ0P7EsBcrJYxEklB+4kP7R NJkBrv40YeaXYUdKvy8KndEWUHof9vpg/jUAKuy2pU+9cwzBsglyCdovexE1PN1KH2 S5HVkPRVbzgfP6Xc2JvUlXtWcPsGSGEkUQdex7UCcMpoivPFcAdcx7bfOc61jR7Ajf mYpMBERIXFq7D8lQ7dxeKvw0MxLmeepN0N4QHJJLnYxo4Yi/NfNwcOkxVV55Q9tfas ISTL3c1I/KkwQ== Received: by pali.im (Postfix) id 440739D7; Mon, 26 Dec 2022 13:50:08 +0100 (CET) From: =?utf-8?q?Pali_Roh=C3=A1r?= To: "Arnd Bergmann" , Linus Walleij List-Id: Cc: soc@kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH RESEND 3/8] powerpc/85xx: DTS: Add CPLD definitions for P1021RDB Combo Board CPL Design Date: Mon, 26 Dec 2022 13:36:25 +0100 Message-Id: <20221226123630.6515-4-pali@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20221226123630.6515-1-pali@kernel.org> References: <20221226123630.6515-1-pali@kernel.org> MIME-Version: 1.0 P1021RDB Combo Board CPLD Design is used on following Freescale boards: P1021RDB-PC, P1020RDB-PD, P1020MBG-PC, P1020UTM-PC and P2020RDB-PCA. Add CPLD definitions for all these boards for which already exist DTS file. CPLD has bank size 128kB, it is connected via CS3 on LBC and mapped to memory range 0xFFA00000~0xFFA1FFFF. As CPLD firmware is common on all these boards, use just one compatible string "fsl,p1021rdb-pc-cpld". In some DTS files is CPLD already defined, but definition is either incomplete or wrong. So fix it. All these boards have via CPLD connected max6370 watchdog at offset 0x2 with GPIO 11, status led at offset 0x8 and reset controller at offset 0xd. Additionally P1020MBG-PC and P1020RDB-PD boards have FXO led at offset 0x9 and FXS leds at offset 0xa. Signed-off-by: Pali Rohár --- arch/powerpc/boot/dts/fsl/p1020mbg-pc.dtsi | 92 +++++++++++++++++++ arch/powerpc/boot/dts/fsl/p1020mbg-pc_32b.dts | 6 +- arch/powerpc/boot/dts/fsl/p1020mbg-pc_36b.dts | 6 +- arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts | 44 +++++++-- arch/powerpc/boot/dts/fsl/p1020utm-pc.dtsi | 37 ++++++++ arch/powerpc/boot/dts/fsl/p1020utm-pc_32b.dts | 4 +- arch/powerpc/boot/dts/fsl/p1020utm-pc_36b.dts | 4 +- arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi | 37 ++++++++ arch/powerpc/boot/dts/fsl/p1021rdb-pc_32b.dts | 5 +- arch/powerpc/boot/dts/fsl/p1021rdb-pc_36b.dts | 5 +- arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi | 33 ++++++- 11 files changed, 251 insertions(+), 22 deletions(-) diff --git a/arch/powerpc/boot/dts/fsl/p1020mbg-pc.dtsi b/arch/powerpc/boot/dts/fsl/p1020mbg-pc.dtsi index a24699cfea9c..cad670c41572 100644 --- a/arch/powerpc/boot/dts/fsl/p1020mbg-pc.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1020mbg-pc.dtsi @@ -83,6 +83,95 @@ compatible = "vitesse-7385"; reg = <0x2 0x0 0x20000>; }; + + cpld@3,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,p1021rdb-pc-cpld", "simple-bus", "syscon"; + reg = <0x3 0x0 0x20000>; + ranges = <0x0 0x3 0x0 0x20000>; + + watchdog@2 { + compatible = "maxim,max6370"; + reg = <0x2 0x1>; + gpios = <&gpio 11 1>; + }; + + led@8,0 { + compatible = "register-bit-led"; + reg = <0x8 0x1>; + offset = <0x8>; + mask = <0x1>; + active-low; + default-state = "keep"; + label = "status"; + function = "status"; + color = <6>; /* LED_COLOR_ID_YELLOW */ + }; + + led@9,0 { + compatible = "register-bit-led"; + reg = <0x9 0x1>; + offset = <0x9>; + mask = <0x1>; + active-low; + default-state = "keep"; + label = "fxo"; + color = <2>; /* LED_COLOR_ID_GREEN */ + }; + + led@a,0 { + compatible = "register-bit-led"; + reg = <0xa 0x1>; + offset = <0xa>; + mask = <0x1>; + active-low; + default-state = "keep"; + label = "fxs0"; + color = <2>; /* LED_COLOR_ID_GREEN */ + }; + + led@a,1 { + compatible = "register-bit-led"; + reg = <0xa 0x1>; + offset = <0xa>; + mask = <0x2>; + active-low; + default-state = "keep"; + label = "fxs1"; + color = <2>; /* LED_COLOR_ID_GREEN */ + }; + + led@a,2 { + compatible = "register-bit-led"; + reg = <0xa 0x1>; + offset = <0xa>; + mask = <0x4>; + active-low; + default-state = "keep"; + label = "fxs2"; + color = <2>; /* LED_COLOR_ID_GREEN */ + }; + + led@a,3 { + compatible = "register-bit-led"; + reg = <0xa 0x1>; + offset = <0xa>; + mask = <0x8>; + active-low; + default-state = "keep"; + label = "fxs3"; + color = <2>; /* LED_COLOR_ID_GREEN */ + }; + + reboot@d { + compatible = "syscon-reboot"; + reg = <0xd 0x1>; + offset = <0xd>; + mask = <0x1>; + value = <0x1>; + }; + }; }; &soc { @@ -93,6 +182,9 @@ }; }; + gpio: gpio-controller@fc00 { + }; + mdio@24000 { phy0: ethernet-phy@0 { interrupts = <3 1 0 0>; diff --git a/arch/powerpc/boot/dts/fsl/p1020mbg-pc_32b.dts b/arch/powerpc/boot/dts/fsl/p1020mbg-pc_32b.dts index b29d1fcb5e6b..29847d395f1f 100644 --- a/arch/powerpc/boot/dts/fsl/p1020mbg-pc_32b.dts +++ b/arch/powerpc/boot/dts/fsl/p1020mbg-pc_32b.dts @@ -44,10 +44,10 @@ lbc: localbus@ffe05000 { reg = <0x0 0xffe05000 0x0 0x1000>; - /* NOR and L2 switch */ + /* NOR, L2 switch and CPLD */ ranges = <0x0 0x0 0x0 0xec000000 0x04000000 - 0x1 0x0 0x0 0xffa00000 0x00040000 - 0x2 0x0 0x0 0xffb00000 0x00020000>; + 0x2 0x0 0x0 0xffb00000 0x00020000 + 0x3 0x0 0x0 0xffa00000 0x00040000>; }; soc: soc@ffe00000 { diff --git a/arch/powerpc/boot/dts/fsl/p1020mbg-pc_36b.dts b/arch/powerpc/boot/dts/fsl/p1020mbg-pc_36b.dts index 678d0eec24e2..b0ce561c38ff 100644 --- a/arch/powerpc/boot/dts/fsl/p1020mbg-pc_36b.dts +++ b/arch/powerpc/boot/dts/fsl/p1020mbg-pc_36b.dts @@ -44,10 +44,10 @@ lbc: localbus@fffe05000 { reg = <0xf 0xffe05000 0x0 0x1000>; - /* NOR and L2 switch */ + /* NOR, L2 switch and CPLD */ ranges = <0x0 0x0 0xf 0xec000000 0x04000000 - 0x1 0x0 0xf 0xffa00000 0x00040000 - 0x2 0x0 0xf 0xffb00000 0x00020000>; + 0x2 0x0 0xf 0xffb00000 0x00020000 + 0x3 0x0 0xf 0xffa00000 0x00040000>; }; soc: soc@fffe00000 { diff --git a/arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts b/arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts index f2dc6c09be52..c318a3cc124b 100644 --- a/arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts +++ b/arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts @@ -47,8 +47,8 @@ /* NOR, NAND flash, L2 switch and CPLD */ ranges = <0x0 0x0 0x0 0xec000000 0x04000000 0x1 0x0 0x0 0xff800000 0x00040000 - 0x2 0x0 0x0 0xffa00000 0x00020000 - 0x3 0x0 0x0 0xffb00000 0x00020000>; + 0x2 0x0 0x0 0xffb00000 0x00020000 + 0x3 0x0 0x0 0xffa00000 0x00020000>; nor@0,0 { #address-cells = <1>; @@ -128,16 +128,45 @@ }; }; - cpld@2,0 { - compatible = "fsl,p1020rdb-pd-cpld"; + L2switch@2,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "vitesse-7385"; reg = <0x2 0x0 0x20000>; }; - L2switch@3,0 { + cpld@3,0 { #address-cells = <1>; #size-cells = <1>; - compatible = "vitesse-7385"; + compatible = "fsl,p1021rdb-pc-cpld", "simple-bus", "syscon"; reg = <0x3 0x0 0x20000>; + ranges = <0x0 0x3 0x0 0x20000>; + + watchdog@2 { + compatible = "maxim,max6370"; + reg = <0x2 0x1>; + gpios = <&gpio 11 1>; + }; + + led@8,0 { + compatible = "register-bit-led"; + reg = <0x8 0x1>; + offset = <0x8>; + mask = <0x1>; + active-low; + default-state = "keep"; + label = "status"; + function = "status"; + color = <6>; /* LED_COLOR_ID_YELLOW */ + }; + + reboot@d { + compatible = "syscon-reboot"; + reg = <0xd 0x1>; + offset = <0xd>; + mask = <0x1>; + value = <0x1>; + }; }; }; @@ -199,6 +228,9 @@ }; }; + gpio: gpio-controller@fc00 { + }; + mdio@24000 { phy0: ethernet-phy@0 { interrupts = <3 1 0 0>; diff --git a/arch/powerpc/boot/dts/fsl/p1020utm-pc.dtsi b/arch/powerpc/boot/dts/fsl/p1020utm-pc.dtsi index 7ea85eabcc5c..8a52548b83c0 100644 --- a/arch/powerpc/boot/dts/fsl/p1020utm-pc.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1020utm-pc.dtsi @@ -68,6 +68,40 @@ read-only; }; }; + + cpld@3,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,p1021rdb-pc-cpld", "simple-bus", "syscon"; + reg = <0x3 0x0 0x20000>; + ranges = <0x0 0x3 0x0 0x20000>; + + watchdog@2 { + compatible = "maxim,max6370"; + reg = <0x2 0x1>; + gpios = <&gpio 11 1>; + }; + + led@8,0 { + compatible = "register-bit-led"; + reg = <0x8 0x1>; + offset = <0x8>; + mask = <0x1>; + active-low; + default-state = "keep"; + label = "status"; + function = "status"; + color = <6>; /* LED_COLOR_ID_YELLOW */ + }; + + reboot@d { + compatible = "syscon-reboot"; + reg = <0xd 0x1>; + offset = <0xd>; + mask = <0x1>; + value = <0x1>; + }; + }; }; &soc { @@ -78,6 +112,9 @@ }; }; + gpio: gpio-controller@fc00 { + }; + mdio@24000 { phy0: ethernet-phy@0 { interrupts = <3 1 0 0>; diff --git a/arch/powerpc/boot/dts/fsl/p1020utm-pc_32b.dts b/arch/powerpc/boot/dts/fsl/p1020utm-pc_32b.dts index bc03ef611f98..9cc8f6726ca7 100644 --- a/arch/powerpc/boot/dts/fsl/p1020utm-pc_32b.dts +++ b/arch/powerpc/boot/dts/fsl/p1020utm-pc_32b.dts @@ -46,8 +46,8 @@ /* NOR */ ranges = <0x0 0x0 0x0 0xec000000 0x02000000 - 0x1 0x0 0x0 0xffa00000 0x00040000 - 0x2 0x0 0x0 0xffb00000 0x00020000>; + 0x2 0x0 0x0 0xffb00000 0x00020000 + 0x3 0x0 0x0 0xffa00000 0x00040000>; }; soc: soc@ffe00000 { diff --git a/arch/powerpc/boot/dts/fsl/p1020utm-pc_36b.dts b/arch/powerpc/boot/dts/fsl/p1020utm-pc_36b.dts index 32766f6a475e..d60fb898399f 100644 --- a/arch/powerpc/boot/dts/fsl/p1020utm-pc_36b.dts +++ b/arch/powerpc/boot/dts/fsl/p1020utm-pc_36b.dts @@ -46,8 +46,8 @@ /* NOR */ ranges = <0x0 0x0 0xf 0xec000000 0x02000000 - 0x1 0x0 0xf 0xffa00000 0x00040000 - 0x2 0x0 0xf 0xffb00000 0x00020000>; + 0x2 0x0 0xf 0xffb00000 0x00020000 + 0x3 0x0 0xf 0xffa00000 0x00040000>; }; soc: soc@fffe00000 { diff --git a/arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi b/arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi index 18f9b31602d0..878624ebe392 100644 --- a/arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi @@ -136,6 +136,40 @@ compatible = "vitesse-7385"; reg = <0x2 0x0 0x20000>; }; + + cpld@3,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,p1021rdb-pc-cpld", "simple-bus", "syscon"; + reg = <0x3 0x0 0x20000>; + ranges = <0x0 0x3 0x0 0x20000>; + + watchdog@2 { + compatible = "maxim,max6370"; + reg = <0x2 0x1>; + gpios = <&gpio 11 1>; + }; + + led@8,0 { + compatible = "register-bit-led"; + reg = <0x8 0x1>; + offset = <0x8>; + mask = <0x1>; + active-low; + default-state = "keep"; + label = "status"; + function = "status"; + color = <6>; /* LED_COLOR_ID_YELLOW */ + }; + + reboot@d { + compatible = "syscon-reboot"; + reg = <0xd 0x1>; + offset = <0xd>; + mask = <0x1>; + value = <0x1>; + }; + }; }; &soc { @@ -187,6 +221,9 @@ }; }; + gpio: gpio-controller@fc00 { + }; + usb@22000 { phy_type = "ulpi"; }; diff --git a/arch/powerpc/boot/dts/fsl/p1021rdb-pc_32b.dts b/arch/powerpc/boot/dts/fsl/p1021rdb-pc_32b.dts index d2b4710357ac..9721e5ecc86b 100644 --- a/arch/powerpc/boot/dts/fsl/p1021rdb-pc_32b.dts +++ b/arch/powerpc/boot/dts/fsl/p1021rdb-pc_32b.dts @@ -44,10 +44,11 @@ lbc: localbus@ffe05000 { reg = <0 0xffe05000 0 0x1000>; - /* NOR, NAND Flashes and Vitesse 5 port L2 switch */ + /* NOR, NAND Flashes, Vitesse 5 port L2 switch and CPLD */ ranges = <0x0 0x0 0x0 0xef000000 0x01000000 0x1 0x0 0x0 0xff800000 0x00040000 - 0x2 0x0 0x0 0xffb00000 0x00020000>; + 0x2 0x0 0x0 0xffb00000 0x00020000 + 0x3 0x0 0x0 0xffa00000 0x00020000>; }; soc: soc@ffe00000 { diff --git a/arch/powerpc/boot/dts/fsl/p1021rdb-pc_36b.dts b/arch/powerpc/boot/dts/fsl/p1021rdb-pc_36b.dts index e298c29e5606..edea14e5d806 100644 --- a/arch/powerpc/boot/dts/fsl/p1021rdb-pc_36b.dts +++ b/arch/powerpc/boot/dts/fsl/p1021rdb-pc_36b.dts @@ -44,10 +44,11 @@ lbc: localbus@fffe05000 { reg = <0xf 0xffe05000 0 0x1000>; - /* NOR, NAND Flashes and Vitesse 5 port L2 switch */ + /* NOR, NAND Flashes, Vitesse 5 port L2 switch and CPLD */ ranges = <0x0 0x0 0xf 0xef000000 0x01000000 0x1 0x0 0xf 0xff800000 0x00040000 - 0x2 0x0 0xf 0xffb00000 0x00020000>; + 0x2 0x0 0xf 0xffb00000 0x00020000 + 0x3 0x0 0xf 0xffa00000 0x00020000>; }; soc: soc@fffe00000 { diff --git a/arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi b/arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi index 03c9afc82436..1d3e8a6639a0 100644 --- a/arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi +++ b/arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi @@ -133,9 +133,35 @@ cpld@3,0 { #address-cells = <1>; #size-cells = <1>; - compatible = "cpld"; + compatible = "fsl,p1021rdb-pc-cpld", "simple-bus", "syscon"; reg = <0x3 0x0 0x20000>; - read-only; + ranges = <0x0 0x3 0x0 0x20000>; + + watchdog@2 { + compatible = "maxim,max6370"; + reg = <0x2 0x1>; + gpios = <&gpio 11 1>; + }; + + led@8,0 { + compatible = "register-bit-led"; + reg = <0x8 0x1>; + offset = <0x8>; + mask = <0x1>; + active-low; + default-state = "keep"; + label = "status"; + function = "status"; + color = <6>; /* LED_COLOR_ID_YELLOW */ + }; + + reboot@d { + compatible = "syscon-reboot"; + reg = <0xd 0x1>; + offset = <0xd>; + mask = <0x1>; + value = <0x1>; + }; }; }; @@ -188,6 +214,9 @@ }; }; + gpio: gpio-controller@fc00 { + }; + usb@22000 { phy_type = "ulpi"; }; From patchwork Mon Dec 26 12:36:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 13081802 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2BBA0C4708D for ; Mon, 26 Dec 2022 12:50:10 +0000 (UTC) Received: by smtp.kernel.org (Postfix) id 036A7C433A8; Mon, 26 Dec 2022 12:50:10 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 95896C433F1; Mon, 26 Dec 2022 12:50:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672059009; bh=EFzVdiaH+zHs4e97fcsUZrZMSEeaqc3cPEhzJR5+8O0=; h=From:To:List-Id:Cc:Subject:Date:In-Reply-To:References:From; b=WuIo+Uf9f3K7tGcluGeiIndGmvox+0Y7W/AWXWKrjBxzyRbI/4Zqh3wgyRA6diFfN LW33duwgkF398G5ni0TF989X1l+RKTclmo/bhDMWxDJAcHFp8CQJP05bWX1QotE/HI nisIbLYvoGik36ilDPDh9cBpZT+ba88kxINjbH4ejftWqVtj/9Bn47agG53G1iB8ny zqNrsUPFP2zzW479l44o9bVzHecc3k7XF2XtzofOdA6mj+AdvgRHtR3nZTEnKC5qCM w13zbO6fnBcfEM2VYxKa+twDjwUCn1xlyi4ENDHbSzLFCOqqflb4ZkDNzVo92yJCZq B8MJZMTHCEY8A== Received: by pali.im (Postfix) id 50A989D7; Mon, 26 Dec 2022 13:50:09 +0100 (CET) From: =?utf-8?q?Pali_Roh=C3=A1r?= To: "Arnd Bergmann" , Linus Walleij List-Id: Cc: soc@kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH RESEND 4/8] dt-bindings: leds: Add cznic,turris1x-leds.yaml binding Date: Mon, 26 Dec 2022 13:36:26 +0100 Message-Id: <20221226123630.6515-5-pali@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20221226123630.6515-1-pali@kernel.org> References: <20221226123630.6515-1-pali@kernel.org> MIME-Version: 1.0 Add device-tree bindings documentation for Turris 1.x RGB LEDs. Signed-off-by: Pali Rohár --- .../bindings/leds/cznic,turris1x-leds.yaml | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/cznic,turris1x-leds.yaml diff --git a/Documentation/devicetree/bindings/leds/cznic,turris1x-leds.yaml b/Documentation/devicetree/bindings/leds/cznic,turris1x-leds.yaml new file mode 100644 index 000000000000..bcaab5b03128 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/cznic,turris1x-leds.yaml @@ -0,0 +1,118 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/cznic,turris1x-leds.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: CZ.NIC's Turris 1.x LEDs driver + +maintainers: + - Pali Rohár + +description: + This module adds support for the RGB LEDs found on the front panel of the + Turris 1.x routers. There are 8 RGB LEDs that are controlled by CZ.NIC CPLD + firmware running on Lattice FPGA. Firmware is open source and available at + https://gitlab.nic.cz/turris/hw/turris_cpld/-/blob/master/CZ_NIC_Router_CPLD.v + +properties: + compatible: + const: cznic,turris1x-leds + + reg: + description: CPLD address range where LED registers are mapped + maxItems: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + +patternProperties: + "^multi-led@[0-7]$": + type: object + $ref: leds-class-multicolor.yaml# + unevaluatedProperties: false + + properties: + reg: + minimum: 0 + maximum: 7 + + required: + - reg + +additionalProperties: false + +examples: + - | + #include + + cpld@3,0 { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x3 0x0 0x00020000>; + + led-controller@13 { + compatible = "cznic,turris1x-leds"; + reg = <0x13 0x1d>; + #address-cells = <1>; + #size-cells = <0>; + + multi-led@0 { + reg = <0x0>; + color = ; + function = LED_FUNCTION_WAN; + }; + + multi-led@1 { + reg = <0x1>; + color = ; + function = LED_FUNCTION_LAN; + function-enumerator = <5>; + }; + + multi-led@2 { + reg = <0x2>; + color = ; + function = LED_FUNCTION_LAN; + function-enumerator = <4>; + }; + + multi-led@3 { + reg = <0x3>; + color = ; + function = LED_FUNCTION_LAN; + function-enumerator = <3>; + }; + + multi-led@4 { + reg = <0x4>; + color = ; + function = LED_FUNCTION_LAN; + function-enumerator = <2>; + }; + + multi-led@5 { + reg = <0x5>; + color = ; + function = LED_FUNCTION_LAN; + function-enumerator = <1>; + }; + + multi-led@6 { + reg = <0x6>; + color = ; + function = LED_FUNCTION_WLAN; + }; + + multi-led@7 { + reg = <0x7>; + color = ; + function = LED_FUNCTION_POWER; + }; + }; + }; + +... From patchwork Mon Dec 26 12:36:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 13081803 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 346B6C3DA7D for ; Mon, 26 Dec 2022 12:50:11 +0000 (UTC) Received: by smtp.kernel.org (Postfix) id 15CF3C433F0; Mon, 26 Dec 2022 12:50:11 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A7F91C433D2; Mon, 26 Dec 2022 12:50:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672059011; bh=lOGM5Xzgmyic9i/qJ7eB+ZF1fcJ7SMURLCvZP+jhTho=; h=From:To:List-Id:Cc:Subject:Date:In-Reply-To:References:From; b=pNLLSRmLdSZklm0hoJNGVuYcBaYeyB41Gj1j65ILAMms+fevoEct1r5Sb8Q5owv1P brzetwfj0oXaMTHot8eSrU+aAIKLatY0RaM7rAbJtstduU7hpmTYxXdpkGU3YcjjAD hgmkmNckIgIptMWLDz9hKRlxEiabyN3ZhrklnRQ4BP/jsE+udvh2V+h/hw7ryzl4/A 0RlCjKVQ43YNCsAO0C0gngYr7TDHQr3U5NUAhNniALKHDkNWON5TK831WZiF1+qizc ZVKgqjoaS9ONQVwTwatOBrCrdZRwmACqPabzH2Y+GFY8SZdU4BPHbWKELUXySc1YUo tjFIcfGS1HDKA== Received: by pali.im (Postfix) id 5F33B9D7; Mon, 26 Dec 2022 13:50:10 +0100 (CET) From: =?utf-8?q?Pali_Roh=C3=A1r?= To: "Arnd Bergmann" , Linus Walleij List-Id: Cc: soc@kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH RESEND 5/8] leds: Add support for Turris 1.x LEDs Date: Mon, 26 Dec 2022 13:36:27 +0100 Message-Id: <20221226123630.6515-6-pali@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20221226123630.6515-1-pali@kernel.org> References: <20221226123630.6515-1-pali@kernel.org> MIME-Version: 1.0 This adds support for the RGB LEDs found on the front panel of the Turris 1.x routers. There are 8 RGB LEDs that are controlled by CZ.NIC CPLD firmware running on Lattice FPGA. CPLD firmware provides HW triggering mode for all LEDs except WiFi LED which is automatically enabled after power on reset. LAN LEDs share HW registers for RGB colors settings, so it is not possible to set different colors for individual LAN LEDs. CZ.NIC CPLD firmware is open source and available at: https://gitlab.nic.cz/turris/hw/turris_cpld/-/blob/master/CZ_NIC_Router_CPLD.v This driver uses the multicolor LED framework and HW led triggers. Signed-off-by: Pali Rohár Reviewed-by: Marek Behún --- .../testing/sysfs-class-led-driver-turris1x | 31 ++ drivers/leds/Kconfig | 9 + drivers/leds/Makefile | 1 + drivers/leds/leds-turris-1x.c | 474 ++++++++++++++++++ 4 files changed, 515 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-class-led-driver-turris1x create mode 100644 drivers/leds/leds-turris-1x.c diff --git a/Documentation/ABI/testing/sysfs-class-led-driver-turris1x b/Documentation/ABI/testing/sysfs-class-led-driver-turris1x new file mode 100644 index 000000000000..272695ae400b --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-led-driver-turris1x @@ -0,0 +1,31 @@ +What: /sys/class/leds//device/brightness +Date: July 2022 +KernelVersion: 6.3 +Contact: Pali Rohár +Description: (RW) On the back size of the Turris 1.x routers there is also + a button which can be used to control the intensity of all the + LEDs at once, so that if they are too bright, user can dim them. + + The CPLD firmware cycles between 8 levels of this global + brightness, but this setting can have any integer value between + 0 and 255. It is therefore convenient to be able to change this + setting from software. + + Format: %u + +What: /sys/class/leds//device/brightness_level +Date: July 2022 +KernelVersion: 6.3 +Contact: Pali Rohár +Description: (RW) Current brightness level value (0-7). + + Format: %u + +What: /sys/class/leds//device/brightness_values +Date: July 2022 +KernelVersion: 6.3 +Contact: Pali Rohár +Description: (RW) Values of all 8 levels between which CPLD firmware cycles + when brightness button is pressed. + + Format: %u %u %u %u %u %u %u %u diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 499d0f215a8b..6f78764e20aa 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -157,6 +157,15 @@ config LEDS_EL15203000 To compile this driver as a module, choose M here: the module will be called leds-el15203000. +config LEDS_TURRIS_1X + tristate "LED support for CZ.NIC's Turris 1.x" + depends on LEDS_CLASS_MULTICOLOR + depends on OF + select LEDS_TRIGGERS + help + This option enables support for LEDs found on the front side of + CZ.NIC's Turris 1.x routers. + config LEDS_TURRIS_OMNIA tristate "LED support for CZ.NIC's Turris Omnia" depends on LEDS_CLASS_MULTICOLOR diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 4fd2f92cd198..de08083dbbca 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -82,6 +82,7 @@ obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o obj-$(CONFIG_LEDS_TI_LMU_COMMON) += leds-ti-lmu-common.o obj-$(CONFIG_LEDS_TLC591XX) += leds-tlc591xx.o obj-$(CONFIG_LEDS_TPS6105X) += leds-tps6105x.o +obj-$(CONFIG_LEDS_TURRIS_1X) += leds-turris-1x.o obj-$(CONFIG_LEDS_TURRIS_OMNIA) += leds-turris-omnia.o obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o diff --git a/drivers/leds/leds-turris-1x.c b/drivers/leds/leds-turris-1x.c new file mode 100644 index 000000000000..cf7567b64306 --- /dev/null +++ b/drivers/leds/leds-turris-1x.c @@ -0,0 +1,474 @@ +// SPDX-License-Identifier: GPL-2.0 +// (C) 2022 Pali Rohár +// +// CZ.NIC's Turris 1.x LEDs driver, controlled by CPLD firmware: +// https://gitlab.nic.cz/turris/hw/turris_cpld/-/blob/master/CZ_NIC_Router_CPLD.v + +#include +#include +#include +#include +#include +#include +#include "leds.h" + +/* LED registers starts at byte 0x13 in CPLD memory map */ +#define TURRIS1X_LED_REG_OFF(reg) ((reg)-0x13) + +/* LEDs 1-5 share common register for setting brightness */ +#define TURRIS1X_LED_BRIGHTNESS_OFF(idx) ({ const u8 _idx = (idx) & 7; \ + (_idx == 0) ? 0 : \ + (_idx <= 5) ? 1 : \ + (_idx - 4); }) + +#define TURRIS1X_LED_BRIGHTNESS_REG(idx, color) TURRIS1X_LED_REG_OFF(0x13 + \ + 3 * TURRIS1X_LED_BRIGHTNESS_OFF(idx) + \ + ((color) & 3)) +#define TURRIS1X_LED_GLOBAL_LEVEL_REG TURRIS1X_LED_REG_OFF(0x20) +#define TURRIS1X_LED_GET_GLOBAL_BRIGHTNESS_REG TURRIS1X_LED_REG_OFF(0x21) +#define TURRIS1X_LED_SW_OVERRIDE_REG TURRIS1X_LED_REG_OFF(0x22) +#define TURRIS1X_LED_SW_DISABLE_REG TURRIS1X_LED_REG_OFF(0x23) +#define TURRIS1X_LED_GLOBAL_BRIGHTNESS_REG(lvl) TURRIS1X_LED_REG_OFF(0x28 + ((lvl) & 7)) + +struct turris1x_led { + struct led_classdev_mc mc_cdev; + struct mc_subled subled_info[3]; + u32 reg; + bool registered; +}; + +#define to_turris1x_led(l) container_of(l, struct turris1x_led, mc_cdev) + +struct turris1x_leds { + void __iomem *regs; + struct mutex lock; + struct turris1x_led leds[8]; +}; + +static struct led_hw_trigger_type turris1x_hw_trigger_type; + +static int turris1x_hwtrig_activate(struct led_classdev *cdev) +{ + struct turris1x_leds *leds = dev_get_drvdata(cdev->dev->parent); + struct turris1x_led *led = to_turris1x_led(lcdev_to_mccdev(cdev)); + u8 val; + + /* Disable software control of LED */ + mutex_lock(&leds->lock); + val = readb(leds->regs + TURRIS1X_LED_SW_OVERRIDE_REG); + val &= ~BIT(led->reg); + writeb(val, leds->regs + TURRIS1X_LED_SW_OVERRIDE_REG); + mutex_unlock(&leds->lock); + + return 0; +} + +static void turris1x_hwtrig_deactivate(struct led_classdev *cdev) +{ + struct turris1x_leds *leds = dev_get_drvdata(cdev->dev->parent); + struct turris1x_led *led = to_turris1x_led(lcdev_to_mccdev(cdev)); + u8 val; + + /* Enable software control of LED */ + mutex_lock(&leds->lock); + val = readb(leds->regs + TURRIS1X_LED_SW_OVERRIDE_REG); + val |= BIT(led->reg); + writeb(val, leds->regs + TURRIS1X_LED_SW_OVERRIDE_REG); + mutex_unlock(&leds->lock); +} + +static struct led_trigger turris1x_hw_trigger = { + .name = "turris1x-cpld", + .activate = turris1x_hwtrig_activate, + .deactivate = turris1x_hwtrig_deactivate, + .trigger_type = &turris1x_hw_trigger_type, +}; + +static enum led_brightness turris1x_led_brightness_get(struct led_classdev *cdev) +{ + struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev); + struct turris1x_leds *leds = dev_get_drvdata(cdev->dev->parent); + struct turris1x_led *led = to_turris1x_led(mc_cdev); + + if (!(readb(leds->regs + TURRIS1X_LED_SW_OVERRIDE_REG) & BIT(led->reg))) + return 1; + else if (!(readb(leds->regs + TURRIS1X_LED_SW_DISABLE_REG) & BIT(led->reg))) + return 1; + else + return 0; +} + +static void turris1x_led_brightness_set(struct led_classdev *cdev, + enum led_brightness brightness) +{ + struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev); + struct turris1x_leds *leds = dev_get_drvdata(cdev->dev->parent); + struct turris1x_led *led = to_turris1x_led(mc_cdev); + int i, j; + u8 val; + + mutex_lock(&leds->lock); + + /* Set new brightness value for each color when LED is enabled */ + if (brightness) { + led_mc_calc_color_components(mc_cdev, brightness); + for (i = 0; i < ARRAY_SIZE(led->subled_info); i++) + writeb(mc_cdev->subled_info[i].brightness, + leds->regs + TURRIS1X_LED_BRIGHTNESS_REG(led->reg, i)); + + /* + * LEDs 1-5 (LAN) share common color settings in same sets + * of HW registers and therefore it is not possible to set + * different colors. So when chaning color of one LED then + * reflect color change for all of them. + */ + if (led->reg >= 1 && led->reg <= 5) { + for (j = 0; j < ARRAY_SIZE(leds->leds); j++) { + if (leds->leds[j].reg < 1 || + leds->leds[j].reg > 5 || + leds->leds[j].reg == led->reg) + continue; + for (i = 0; i < ARRAY_SIZE(led->subled_info); i++) + leds->leds[j].mc_cdev.subled_info[i].intensity = + mc_cdev->subled_info[i].intensity; + } + } + } + + /* Enable / disable LED for software control */ + val = readb(leds->regs + TURRIS1X_LED_SW_DISABLE_REG); + if (brightness && (val & BIT(led->reg))) + writeb(val & ~BIT(led->reg), + leds->regs + TURRIS1X_LED_SW_DISABLE_REG); + else if (!brightness && !(val & BIT(led->reg))) + writeb(val | BIT(led->reg), + leds->regs + TURRIS1X_LED_SW_DISABLE_REG); + + mutex_unlock(&leds->lock); +} + +static int turris1x_led_register(struct device *dev, struct turris1x_leds *leds, + struct device_node *np, u8 val_sw_override, + u8 val_sw_disable) +{ + struct led_init_data init_data = {}; + struct led_classdev *cdev; + struct turris1x_led *led; + int ret, color; + u32 reg; + int i; + + const unsigned int colors[ARRAY_SIZE(led->subled_info)] = { + LED_COLOR_ID_RED, LED_COLOR_ID_GREEN, LED_COLOR_ID_BLUE + }; + + ret = of_property_read_u32(np, "reg", ®); + if (ret || reg >= ARRAY_SIZE(leds->leds)) { + dev_err(dev, + "Node %pOF: must contain 'reg' property with values between 0 and %u\n", + np, (unsigned int)ARRAY_SIZE(leds->leds) - 1); + return -EINVAL; + } + + ret = of_property_read_u32(np, "color", &color); + if (ret || color != LED_COLOR_ID_RGB) { + dev_err(dev, + "Node %pOF: must contain 'color' property with value LED_COLOR_ID_RGB\n", + np); + return -EINVAL; + } + + led = &leds->leds[reg]; + + if (led->registered) { + dev_err(dev, "Node %pOF: duplicate 'reg' property %u\n", + np, reg); + return -EINVAL; + } + + led->registered = true; + led->reg = reg; + + /* Set initial colors to what are currently in use */ + for (i = 0; i < ARRAY_SIZE(led->subled_info); i++) { + led->subled_info[i].intensity = + readb(leds->regs + TURRIS1X_LED_BRIGHTNESS_REG(reg, i)); + led->subled_info[i].color_index = colors[i]; + led->subled_info[i].channel = i; + } + + led->mc_cdev.subled_info = led->subled_info; + led->mc_cdev.num_colors = ARRAY_SIZE(led->subled_info); + + init_data.fwnode = &np->fwnode; + + cdev = &led->mc_cdev.led_cdev; + cdev->max_brightness = 1; + cdev->brightness_get = turris1x_led_brightness_get; + cdev->brightness_set = turris1x_led_brightness_set; + + /* All LEDs except LED 6 (WiFi) can be controller by hardware trigger */ + if (reg != 6) + cdev->trigger_type = &turris1x_hw_trigger_type; + + /* Disable hardware trigger for LED 6 (WiFi) - allow software control */ + if (reg == 6 && !(val_sw_override & BIT(6))) { + if (!(val_sw_disable & BIT(6))) { + val_sw_disable |= BIT(6); + writeb(val_sw_disable, + leds->regs + TURRIS1X_LED_SW_DISABLE_REG); + } + val_sw_override |= BIT(6); + writeb(val_sw_override, + leds->regs + TURRIS1X_LED_SW_OVERRIDE_REG); + } + + if (!(val_sw_override & BIT(reg))) + cdev->default_trigger = turris1x_hw_trigger.name; + + if (!(val_sw_override & BIT(reg)) || !(val_sw_disable & BIT(reg))) + cdev->brightness = 1; + + ret = devm_led_classdev_multicolor_register_ext(dev, &led->mc_cdev, + &init_data); + if (ret) { + dev_err(dev, "Cannot register LED %pOF: %i\n", np, ret); + return ret; + } + + return 0; +} + +static ssize_t brightness_show(struct device *dev, struct device_attribute *a, + char *buf) +{ + struct turris1x_leds *leds = dev_get_drvdata(dev); + unsigned int brightness; + + /* + * Current brightness value is available in read-only register + * TURRIS1X_LED_GET_GLOBAL_BRIGHTNESS_REG. Equivalent code is: + * level = readb(leds->regs + TURRIS1X_LED_GLOBAL_LEVEL_REG) & 7; + * brightness = readb(leds->regs + TURRIS1X_LED_GLOBAL_BRIGHTNESS_REG(level)); + */ + brightness = readb(leds->regs + TURRIS1X_LED_GET_GLOBAL_BRIGHTNESS_REG); + + return sprintf(buf, "%u\n", brightness); +} + +static ssize_t brightness_store(struct device *dev, struct device_attribute *a, + const char *buf, size_t count) +{ + struct turris1x_leds *leds = dev_get_drvdata(dev); + int best_error, error, level, value; + unsigned long brightness; + u8 best_level; + + if (kstrtoul(buf, 10, &brightness)) + return -EINVAL; + + if (brightness > 255) + return -EINVAL; + + /* + * Brightness can be set only to one of 8 predefined value levels + * available in TURRIS1X_LED_GLOBAL_BRIGHTNESS_REG(level) registers. + * Choose level which has nearest value to the specified brightness. + */ + best_level = 0; + best_error = INT_MAX; + for (level = 0; level < 8; level++) { + value = readb(leds->regs + + TURRIS1X_LED_GLOBAL_BRIGHTNESS_REG(level)); + error = abs(value - (int)brightness); + if (best_error > error) { + best_error = error; + best_level = level; + } + } + + writeb(best_level, leds->regs + TURRIS1X_LED_GLOBAL_LEVEL_REG); + + return count; +} +static DEVICE_ATTR_RW(brightness); + +static ssize_t brightness_level_show(struct device *dev, + struct device_attribute *a, char *buf) +{ + struct turris1x_leds *leds = dev_get_drvdata(dev); + unsigned int level; + + level = readb(leds->regs + TURRIS1X_LED_GLOBAL_LEVEL_REG) & 7; + + return sprintf(buf, "%u\n", level); +} + +static ssize_t brightness_level_store(struct device *dev, + struct device_attribute *a, + const char *buf, size_t count) +{ + struct turris1x_leds *leds = dev_get_drvdata(dev); + unsigned long level; + + if (kstrtoul(buf, 10, &level)) + return -EINVAL; + + if (level > 7) + return -EINVAL; + + writeb(level, leds->regs + TURRIS1X_LED_GLOBAL_LEVEL_REG); + + return count; +} +static DEVICE_ATTR_RW(brightness_level); + +static ssize_t brightness_values_show(struct device *dev, + struct device_attribute *a, char *buf) +{ + struct turris1x_leds *leds = dev_get_drvdata(dev); + unsigned int vals[8]; + int i; + + for (i = 0; i < 8; i++) + vals[i] = readb(leds->regs + + TURRIS1X_LED_GLOBAL_BRIGHTNESS_REG(i)); + + return sprintf(buf, "%u %u %u %u %u %u %u %u\n", vals[0], vals[1], + vals[2], vals[3], vals[4], vals[5], vals[6], vals[7]); +} + +static ssize_t brightness_values_store(struct device *dev, + struct device_attribute *a, + const char *buf, size_t count) +{ + struct turris1x_leds *leds = dev_get_drvdata(dev); + unsigned int vals[8]; + int nchars; + int i; + + if (sscanf(buf, "%u %u %u %u %u %u %u %u%n", &vals[0], &vals[1], + &vals[2], &vals[3], &vals[4], &vals[5], &vals[6], &vals[7], + &nchars) != 8 || nchars + 1 < count) + return -EINVAL; + + for (i = 0; i < 8; i++) + writeb(vals[i], + leds->regs + TURRIS1X_LED_GLOBAL_BRIGHTNESS_REG(i)); + + return count; +} +static DEVICE_ATTR_RW(brightness_values); + +static struct attribute *turris1x_leds_controller_attrs[] = { + &dev_attr_brightness.attr, + &dev_attr_brightness_level.attr, + &dev_attr_brightness_values.attr, + NULL, +}; +ATTRIBUTE_GROUPS(turris1x_leds_controller); + +static int turris1x_leds_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev_of_node(dev); + struct device_node *child; + struct turris1x_leds *leds; + struct resource *res; + void __iomem *regs; + u8 val_sw_override; + u8 val_sw_disable; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + regs = devm_ioremap_resource(dev, res); + if (IS_ERR(regs)) + return PTR_ERR(regs); + + leds = devm_kzalloc(dev, sizeof(*leds), GFP_KERNEL); + if (!leds) + return -ENOMEM; + + platform_set_drvdata(pdev, leds); + + leds->regs = regs; + mutex_init(&leds->lock); + + ret = devm_led_trigger_register(dev, &turris1x_hw_trigger); + if (ret) { + dev_err(dev, "Cannot register private LED trigger: %d\n", ret); + return ret; + } + + val_sw_override = readb(leds->regs + TURRIS1X_LED_SW_OVERRIDE_REG); + val_sw_disable = readb(leds->regs + TURRIS1X_LED_SW_DISABLE_REG); + + for_each_available_child_of_node(np, child) { + ret = turris1x_led_register(dev, leds, child, + val_sw_override, val_sw_disable); + if (ret) { + of_node_put(child); + return ret; + } + } + + ret = devm_device_add_groups(dev, turris1x_leds_controller_groups); + if (ret) { + dev_err(dev, "Could not add attribute group!\n"); + return ret; + } + + return 0; +} + +static void turris1x_leds_shutdown(struct platform_device *pdev) +{ + struct turris1x_leds *leds = platform_get_drvdata(pdev); + int i, j; + u8 val; + + /* + * LED registers are persisent across board resets. + * So reset LEDs to default state before kernel reboots. + */ + + /* Disable software control of all LEDs except LED 6 (WiFi) */ + writeb(BIT(6), leds->regs + TURRIS1X_LED_SW_OVERRIDE_REG); + + /* Turn off LED 6 (WiFi) as there is no hardware trigger for it */ + val = readb(leds->regs + TURRIS1X_LED_SW_DISABLE_REG); + writeb(val | BIT(6), leds->regs + TURRIS1X_LED_SW_DISABLE_REG); + + /* Reset colors of all LEDs to default values */ + for (i = 0; i < ARRAY_SIZE(leds->leds); i++) { + /* Skip LAN2-LAN5 LEDs which share color register with LAN1 */ + if (i >= 2 && i <= 5) + continue; + for (j = 0; j < ARRAY_SIZE(leds->leds[i].subled_info); j++) + writeb(0xff, + leds->regs + TURRIS1X_LED_BRIGHTNESS_REG(i, j)); + } +} + +static const struct of_device_id of_turris1x_leds_match[] = { + { .compatible = "cznic,turris1x-leds" }, + {}, +}; + +static struct platform_driver turris1x_leds_driver = { + .probe = turris1x_leds_probe, + .shutdown = turris1x_leds_shutdown, + .driver = { + .name = "turris1x_leds", + .of_match_table = of_turris1x_leds_match, + }, +}; +module_platform_driver(turris1x_leds_driver); + +MODULE_AUTHOR("Pali Rohár "); +MODULE_DESCRIPTION("CZ.NIC's Turris 1.x LEDs"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:turris1x_leds"); From patchwork Mon Dec 26 12:36:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 13081804 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2B951C3DA79 for ; Mon, 26 Dec 2022 12:50:12 +0000 (UTC) Received: by smtp.kernel.org (Postfix) id 13550C433EF; Mon, 26 Dec 2022 12:50:12 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9C4F0C433F0; Mon, 26 Dec 2022 12:50:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672059012; bh=jJWOnvE0lCioIKf8jVQUOC7rfQ2VDErkyaCeqTladMw=; h=From:To:List-Id:Cc:Subject:Date:In-Reply-To:References:From; b=lHAeIszNmGMBALZHCcxaC0dHzUWfU8D1QjYGAEXaYJuGMNph4D3+E5zKlrUQJgNMr 1BP2xO+2w5RS97iM+hSTETxWj3o+s45OvybJJ3+dZSnjgBLD3GokZqf8BjyMex+VZ+ Fe+pwgpudMzWpqOR4gIJeeug6VcKEys7Nk9WBZNMPz39RPfEoBaqBIz9JXnzmXjYc0 EPt1nAAJ707cxXROhGzaBCT8AdTdAsZit4IsBLTx+ztbHoez6LlGzf5dGQMWB1+cOb AxNAIsuKDZAZDNTZMsBEhhlWP/IzrG9dAUUJTeLC/eJ0MEcrNBbrp5VeLBXu30K+b4 OdoYHfpsr4XBg== Received: by pali.im (Postfix) id 57E459D7; Mon, 26 Dec 2022 13:50:11 +0100 (CET) From: =?utf-8?q?Pali_Roh=C3=A1r?= To: "Arnd Bergmann" , Linus Walleij List-Id: Cc: soc@kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH RESEND 6/8] leds: turris-omnia: support HW controlled mode via private trigger Date: Mon, 26 Dec 2022 13:36:28 +0100 Message-Id: <20221226123630.6515-7-pali@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20221226123630.6515-1-pali@kernel.org> References: <20221226123630.6515-1-pali@kernel.org> MIME-Version: 1.0 From: Marek Behún Add support for enabling MCU controlled mode of the Turris Omnia LEDs via a LED private trigger called "omnia-mcu". When in MCU controlled mode, the user can still set LED color, but the blinking is done by MCU, which does different things for various LEDs: - WAN LED is blinked according to the LED[0] pin of the WAN PHY - LAN LEDs are blinked according to the LED[0] output of corresponding port of the LAN switch - PCIe LEDs are blinked according to the logical OR of the MiniPCIe port LED pins For a long time I wanted to actually do this differently: I wanted to make the netdev trigger to transparently offload the blinking to the HW if user set compatible settings for the netdev trigger. There was some work on this, and hopefully we will be able to complete it sometime, but since there are various complications, it will probably not be soon. In the meantime let's support HW controlled mode via this private LED trigger. If, in the future, we manage to complete the netdev trigger offloading, we can still keep this private trigger for backwards compatibility, if needed. We also set "omnia-mcu" to cdev->default_trigger, so that the MCU keeps control until the user first wants to take over it. If a different default trigger is specified in device-tree via the `linux,default-trigger` property, LED class will overwrite cdev->default_trigger, and so the DT property will be respected. Signed-off-by: Marek Behún Fixes: 40624346b7ae ("ARM: dts: turris-omnia: enable LED controller node") Reviewed-by: Pali Rohár --- drivers/leds/Kconfig | 1 + drivers/leds/leds-turris-omnia.c | 41 ++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 6f78764e20aa..f957b86411de 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -172,6 +172,7 @@ config LEDS_TURRIS_OMNIA depends on I2C depends on MACH_ARMADA_38X || COMPILE_TEST depends on OF + select LEDS_TRIGGERS help This option enables basic support for the LEDs found on the front side of CZ.NIC's Turris Omnia router. There are 12 RGB LEDs on the diff --git a/drivers/leds/leds-turris-omnia.c b/drivers/leds/leds-turris-omnia.c index c7c9851c894a..bb7af9e59ad6 100644 --- a/drivers/leds/leds-turris-omnia.c +++ b/drivers/leds/leds-turris-omnia.c @@ -41,6 +41,39 @@ struct omnia_leds { struct omnia_led leds[]; }; +static struct led_hw_trigger_type omnia_hw_trigger_type; + +static int omnia_hwtrig_activate(struct led_classdev *cdev) +{ + struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent); + struct omnia_led *led = to_omnia_led(lcdev_to_mccdev(cdev)); + + /* put the LED into MCU controlled mode */ + return i2c_smbus_write_byte_data(leds->client, CMD_LED_MODE, + CMD_LED_MODE_LED(led->reg)); +} + +static void omnia_hwtrig_deactivate(struct led_classdev *cdev) +{ + struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent); + struct omnia_led *led = to_omnia_led(lcdev_to_mccdev(cdev)); + int ret; + + /* put the LED into software mode */ + ret = i2c_smbus_write_byte_data(leds->client, CMD_LED_MODE, + CMD_LED_MODE_LED(led->reg) | + CMD_LED_MODE_USER); + if (ret < 0) + dev_err(cdev->dev, "Cannot put to software mode: %i\n", ret); +} + +static struct led_trigger omnia_hw_trigger = { + .name = "omnia-mcu", + .activate = omnia_hwtrig_activate, + .deactivate = omnia_hwtrig_deactivate, + .trigger_type = &omnia_hw_trigger_type, +}; + static int omnia_led_brightness_set_blocking(struct led_classdev *cdev, enum led_brightness brightness) { @@ -112,6 +145,8 @@ static int omnia_led_register(struct i2c_client *client, struct omnia_led *led, cdev = &led->mc_cdev.led_cdev; cdev->max_brightness = 255; cdev->brightness_set_blocking = omnia_led_brightness_set_blocking; + cdev->trigger_type = &omnia_hw_trigger_type; + cdev->default_trigger = omnia_hw_trigger.name; /* put the LED into software mode */ ret = i2c_smbus_write_byte_data(client, CMD_LED_MODE, @@ -228,6 +263,12 @@ static int omnia_leds_probe(struct i2c_client *client, mutex_init(&leds->lock); + ret = devm_led_trigger_register(dev, &omnia_hw_trigger); + if (ret < 0) { + dev_err(dev, "Cannot register private LED trigger: %d\n", ret); + return ret; + } + led = &leds->leds[0]; for_each_available_child_of_node(np, child) { ret = omnia_led_register(client, led, child); From patchwork Mon Dec 26 12:36:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 13081805 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E8461C46467 for ; Mon, 26 Dec 2022 12:50:12 +0000 (UTC) Received: by smtp.kernel.org (Postfix) id CE243C433EF; Mon, 26 Dec 2022 12:50:12 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 96CF1C433F2; Mon, 26 Dec 2022 12:50:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672059012; bh=ia6Uzbrx7WpjS0aHDUCS047277ftVQz0RijvAmVbW3Y=; h=From:To:List-Id:Cc:Subject:Date:In-Reply-To:References:From; b=fzw39cSfLfAsjOmx6FWZOXI1PSu4IKHuMTxUu6n3RgVb3OYHlADZAKtSTVPrfin9J vezv1oFX5ofMJRDEr10HVocfY+67SYZALPD++wZLXBKwH79XTB8WODsrBCPF+omG1Y uLQTh29G7vKHomaa6HnB7q3K4x2vy2tD9PLJsRPUQOlDnuy7PDAWOid4jNU9ib42/U BWCJ9IMntQL8cuSWG4ZzJtvKBR8O9NerQYEXCt2l4D9npIdwI4m99S8noP/45B1hiY mcLBqlvbtQFD7g+7v8M4/RW4oVKj5LcFGAica7kSpPQIlh+ANaok0WMzPJE4vMi0+m 5UQ1qUrKgQ0ug== Received: by pali.im (Postfix) id 528109D7; Mon, 26 Dec 2022 13:50:12 +0100 (CET) From: =?utf-8?q?Pali_Roh=C3=A1r?= To: "Arnd Bergmann" , Linus Walleij List-Id: Cc: soc@kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH RESEND 7/8] leds: turris-omnia: initialize multi-intensity to full Date: Mon, 26 Dec 2022 13:36:29 +0100 Message-Id: <20221226123630.6515-8-pali@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20221226123630.6515-1-pali@kernel.org> References: <20221226123630.6515-1-pali@kernel.org> MIME-Version: 1.0 From: Marek Behún The default color of each LED before driver probe (255, 255, 255). Initialize multi_intensity to this value, so that it corresponds to the reality. Signed-off-by: Marek Behún Fixes: 089381b27abe ("leds: initial support for Turris Omnia LEDs") Reviewed-by: Pali Rohár Reviewed-by: Lee Jones --- drivers/leds/leds-turris-omnia.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/leds/leds-turris-omnia.c b/drivers/leds/leds-turris-omnia.c index bb7af9e59ad6..71340dec492a 100644 --- a/drivers/leds/leds-turris-omnia.c +++ b/drivers/leds/leds-turris-omnia.c @@ -131,10 +131,13 @@ static int omnia_led_register(struct i2c_client *client, struct omnia_led *led, } led->subled_info[0].color_index = LED_COLOR_ID_RED; + led->subled_info[0].intensity = 255; led->subled_info[0].channel = 0; led->subled_info[1].color_index = LED_COLOR_ID_GREEN; + led->subled_info[1].intensity = 255; led->subled_info[1].channel = 1; led->subled_info[2].color_index = LED_COLOR_ID_BLUE; + led->subled_info[2].intensity = 255; led->subled_info[2].channel = 2; led->mc_cdev.subled_info = led->subled_info; From patchwork Mon Dec 26 12:36:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 13081806 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id F283DC3DA79 for ; Mon, 26 Dec 2022 12:50:13 +0000 (UTC) Received: by smtp.kernel.org (Postfix) id D7F5CC433EF; Mon, 26 Dec 2022 12:50:13 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A0872C433D2; Mon, 26 Dec 2022 12:50:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672059013; bh=vATcvRfVKP16s74F3jAS0bM/o2WoniPhrwR2tCLy/ZE=; h=From:To:List-Id:Cc:Subject:Date:In-Reply-To:References:From; b=S3PAMjL513n0WGxZu6T+wV4VK+ITr8YcjCrcclBWDYZjhOgRRmXNXSm5RiWD2X2qm mR0qvNv8AQfHmsLY0ZRkONc9mXswx/3L+dOIVeVP5GN4UU/OsJFcQCsI/t7eKt0CtK bXoy30jOziHcDJ+7+ru5O6en/NyIgyYV6bW5iTLNtpsPTS5BMKIniggN+Tk/ZEBTJu jm7nxar+91YBhO8ZJgLRPXhSeklUagvnz2/2bpjbD4oeghdmW7AiXz2p1ozn3RVsQb mmpUSPAYvqkeiE3E/PVcUt0tvylJMVQ84nXu7X20NTwjUMyKesO/tyfuDjU+8T42ZZ TwY1zGGdG98JQ== Received: by pali.im (Postfix) id 5C2AE9D7; Mon, 26 Dec 2022 13:50:13 +0100 (CET) From: =?utf-8?q?Pali_Roh=C3=A1r?= To: "Arnd Bergmann" , Linus Walleij List-Id: Cc: soc@kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH RESEND 8/8] leds: turris-omnia: change max brightness from 255 to 1 Date: Mon, 26 Dec 2022 13:36:30 +0100 Message-Id: <20221226123630.6515-9-pali@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20221226123630.6515-1-pali@kernel.org> References: <20221226123630.6515-1-pali@kernel.org> MIME-Version: 1.0 From: Marek Behún Using binary brightness makes more sense for this controller, because internally in the MCU it works that way: the LED has a color, and a state whether it is ON or OFF. The resulting brightness computation with led_mc_calc_color_components() will now always result in either (0, 0, 0) or the multi_intensity value. Signed-off-by: Marek Behún Fixes: 089381b27abe ("leds: initial support for Turris Omnia LEDs") Reviewed-by: Pali Rohár --- drivers/leds/leds-turris-omnia.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/leds/leds-turris-omnia.c b/drivers/leds/leds-turris-omnia.c index 71340dec492a..04f01ae46c27 100644 --- a/drivers/leds/leds-turris-omnia.c +++ b/drivers/leds/leds-turris-omnia.c @@ -146,7 +146,7 @@ static int omnia_led_register(struct i2c_client *client, struct omnia_led *led, init_data.fwnode = &np->fwnode; cdev = &led->mc_cdev.led_cdev; - cdev->max_brightness = 255; + cdev->max_brightness = 1; cdev->brightness_set_blocking = omnia_led_brightness_set_blocking; cdev->trigger_type = &omnia_hw_trigger_type; cdev->default_trigger = omnia_hw_trigger.name;