From mboxrd@z Thu Jan 1 00:00:00 1970 Delivery-date: Tue, 28 Jul 2026 19:48:02 +0200 Received: from mx1.white.stw.pengutronix.de ([185.203.200.13]) by lore.white.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1woluM-003rrw-0B for lore@lore.pengutronix.de; Tue, 28 Jul 2026 19:48:02 +0200 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by mx1.white.stw.pengutronix.de (Postfix) with ESMTPS id D9D5B2020AF for ; Tue, 28 Jul 2026 19:47:57 +0200 (CEST) Authentication-Results: mx1.white.stw.pengutronix.de; dkim=pass header.d=lists.infradead.org header.s=bombadil.20210309 header.b=Pr3QCXr9; dkim=pass header.d=kernel.org header.s=k20201202 header.b=dgoTIRbq; spf=pass (mx1.white.stw.pengutronix.de: domain of "barebox-bounces+lore=pengutronix.de@lists.infradead.org" designates 2607:7c80:54:3::133 as permitted sender) smtp.mailfrom="barebox-bounces+lore=pengutronix.de@lists.infradead.org"; dmarc=pass (policy=quarantine) header.from=kernel.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:Reply-To:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To: References:Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version: Subject:Date:From:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=YzE/8Hvjy9zZb6sMFoHpGZZfEkaxW4L1+e7YbvDaRB4=; b=Pr3QCXr9vWLloftyeKAu8XvMFZ fBhL9GuNxmhDiXQnQo5P0MQMeeZsGls8QEstAN0UXFYcduAVnNNk+sAhtosxYMDuIP9FtllSYi0xs cVwsvrD7vsi1ojZSTNGevTArrDD4p12UnuHoewrOF9hvDsimw/HInfJbI8IgNYyuQH2sn9dq999AD M+gzFfLNQjZNTtBHeGMVjpb8DkIW1mdEaTaKiybGZXknhJeDYJGRNlQ8pYnvks6IT58EPXcLYZhMJ ed57/3u8FpVVKdkzoYmH4EhNwHft3z+mpIRfAPMbmJd2719HRFYztRl9shmFqJRporYR5zG7XPfmo MzrY7iMA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1wolp9-0000000612v-3UBb; Tue, 28 Jul 2026 17:42:39 +0000 Received: from sea.source.kernel.org ([172.234.252.31]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1wolp8-0000000611P-09J1 for barebox@lists.infradead.org; Tue, 28 Jul 2026 17:42:38 +0000 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sea.source.kernel.org (Postfix) with ESMTP id ABC0943D2A; Tue, 28 Jul 2026 17:42:37 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPS id 8C83BC2BCF6; Tue, 28 Jul 2026 17:42:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1785260557; bh=ZnmxW3sGRCqUNzbd7yjJqxVUPfKDZriH4qgOOwXKOfg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=dgoTIRbquPXoVF3Lr5o7ajwnc/sKwU6vV1TjpLNcFmnsp1zGsrxs/nW0+rVno/YFP a51TQZrFegI74oz5hC6RbW9Xw6fKzbGK8jEmJ1UCCW62BZSDpUlsxs8D8GWEvOB+t+ ZhKmqEkJkiy8zlTq9JgLWnwuk7rNfmpp2IywIjPIY8vxuPe1A08btwjVsiK20knBx9 lDdFpzixidL7APl6kMDekE+7g7nrNhrKONqNjgnCC84KRg4BT5D5pFip28zUGkob4W A3vQbgVkHc3JwLosvsHCIMQAYdqgSTfPVGsKIeCI8e4zXPROQbsPdMvtYPBVOXb4tW D7BllEm+WtEtw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7A04BC54F55; Tue, 28 Jul 2026 17:42:37 +0000 (UTC) From: Luca Lauro via B4 Relay Date: Tue, 28 Jul 2026 19:43:18 +0200 Subject: [PATCH v2 06/10] commands: add fan control command MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260728-rn102-rn104-series-v2-6-ae31f55b7bc8@gmail.com> References: <20260728-rn102-rn104-series-v2-0-ae31f55b7bc8@gmail.com> In-Reply-To: <20260728-rn102-rn104-series-v2-0-ae31f55b7bc8@gmail.com> To: Sascha Hauer , "open list:BAREBOX" Cc: Luca Lauro X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1785260594; l=14476; i=famlauro93l@gmail.com; s=20260723; h=from:subject:message-id; bh=+mWd6c6Mcia5eauBarNCfgJepLLSGh4eKLnkaNZuzpE=; b=rIyYauqJ1UgdPP547ghSJMFp/jtmGYbsldJcIjM441+qTl0/BVP+J5uOuiPbec5mUAKPjGIa9 GseFSIUJdpiDMwYo1Pmf99Hgr2ALCEgfIiFtI04BRY0BM45bXnsQd/t X-Developer-Key: i=famlauro93l@gmail.com; a=ed25519; pk=OAJlcD69ugQCl99Vy6w+Aeu+ZUb1IVGcz1Ijxo6Ch78= X-Endpoint-Received: by B4 Relay for famlauro93l@gmail.com/20260723 with auth_id=892 X-Original-From: Luca Lauro X-BeenThere: barebox@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: famlauro93l@gmail.com Sender: "barebox" X-Rspamd-Action: no action X-Rspamd-Server: mx1 X-Stat-Signature: ptu7yyh5sbajixnhjd8tgnhz1irmuwgh X-Spamd-Result: default: False [-6.91 / 15.00]; DWL_DNSWL_MED(-4.00)[kernel.org:dkim,infradead.org:dkim]; BAYES_HAM(-3.00)[100.00%]; FREEMAIL_REPLYTO_NEQ_FROM(2.00)[]; RCVD_DKIM_ARC_DNSWL_MED(-0.50)[]; DMARC_POLICY_ALLOW(-0.50)[kernel.org,quarantine]; R_SPF_ALLOW(-0.20)[+mx:c]; RCVD_IN_DNSWL_MED(-0.20)[2607:7c80:54:3::133:from]; MAILLIST(-0.20)[mailman]; R_DKIM_ALLOW(-0.20)[lists.infradead.org:s=bombadil.20210309,kernel.org:s=k20201202]; MIME_GOOD(-0.10)[text/plain]; HAS_LIST_UNSUB(-0.01)[]; RCVD_TLS_LAST(0.00)[]; TO_DN_ALL(0.00)[]; FORWARDED(0.00)[barebox@lists.infradead.org]; MIME_TRACE(0.00)[0:+]; ARC_NA(0.00)[]; RECEIVED_HELO_LOCALHOST(0.00)[]; FORGED_SENDER(0.00)[devnull@kernel.org,barebox-bounces@lists.infradead.org]; FREEMAIL_REPLYTO(0.00)[gmail.com]; TAGGED_FROM(0.00)[lore=pengutronix.de,famlauro93l.gmail.com]; REPLYTO_DOM_NEQ_FROM_DOM(0.00)[]; DKIM_TRACE(0.00)[lists.infradead.org:+,kernel.org:+]; FORGED_SENDER_FORWARDING(0.00)[]; RCVD_COUNT_FIVE(0.00)[5]; FROM_NEQ_ENVFROM(0.00)[devnull@kernel.org,barebox-bounces@lists.infradead.org]; FROM_HAS_DN(0.00)[]; FREEMAIL_CC(0.00)[gmail.com]; NEURAL_HAM(-0.00)[-1.000]; ASN(0.00)[asn:7247, ipnet:2607:7c80:54::/48, country:US]; FORGED_SENDER_MAILLIST(0.00)[]; REPLYTO_DOM_NEQ_TO_DOM(0.00)[]; RCPT_COUNT_THREE(0.00)[3]; HAS_REPLYTO(0.00)[famlauro93l@gmail.com] X-Rspamd-Queue-Id: D9D5B2020AF From: Luca Lauro Signed-off-by: Luca Lauro --- commands/fan.c | 286 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 286 insertions(+) diff --git a/commands/fan.c b/commands/fan.c new file mode 100644 index 0000000000..1581751d51 --- /dev/null +++ b/commands/fan.c @@ -0,0 +1,286 @@ +#include +#include +#include +#include +#include + +static int do_fan(int argc, char *argv[]) +{ + struct fan_device *fan; + char buf[32]; + unsigned long val; + int ret = 0; + + + if (argc < 3) { + return COMMAND_ERROR_USAGE; + } + + fan = fan_device_find(argv[2]); + if (IS_ERR(fan)) { + printf("Device not found: %s\n", argv[2]); + return PTR_ERR(fan); + } + if (!fan->ops) { + printf("Fan driver ops not initialized\n"); + return -ENODEV; + } + + if (!strcmp(argv[1], "get")) { + if (argc == 4) { + if (!strcmp(argv[3], "startv") && fan->ops->get_fan_startv) { + ret = fan->ops->get_fan_startv(fan->dev, buf); + printf("Fan startup voltage mode: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "gearmult") && fan->ops->get_gear_multiplier) { + ret = fan->ops->get_gear_multiplier(fan->dev, buf); + printf("Gear multiplier: %s\n", ret >= 0 ? buf : "N/A"); +} + else if (!strcmp(argv[3], "outmode") && fan->ops->get_output_mode) { + ret = fan->ops->get_output_mode(fan->dev, buf); + printf("Output mode: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "ppr") && fan->ops->get_fan_ppr) { + ret = fan->ops->get_fan_ppr(fan->dev, buf); + printf("Pulses per revolution: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "pwmpol") && fan->ops->get_pwm_polarity) { + ret = fan->ops->get_pwm_polarity(fan->dev, buf); + printf("PWM polarity: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "clkfreq") && fan->ops->get_clk_freq) { + ret = fan->ops->get_clk_freq(fan->dev, buf); + printf("Clock frequency: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "clkdiv") && fan->ops->get_clk_div) { + ret = fan->ops->get_clk_div(fan->dev, buf); + printf("Clock divider: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "ctrlmode") && fan->ops->get_control_mode) { + ret = fan->ops->get_control_mode(fan->dev, buf); + printf("Control mode: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "outmode") && fan->ops->get_output_mode) { + ret = fan->ops->get_output_mode(fan->dev, buf); + printf("Output mode: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "oocdet") && fan->ops->get_ooc_detection) { + ret = fan->ops->get_ooc_detection(fan->dev, buf); + printf("Out of control detection: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "faultdet") && fan->ops->get_failure_detection) { + ret = fan->ops->get_failure_detection(fan->dev, buf); + printf("Failure detection: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "oocstate") && fan->ops->get_ooc_state) { + ret = fan->ops->get_ooc_state(fan->dev, buf); + printf("Fan out of control state: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "faultstate") && fan->ops->get_failure_state) { + ret = fan->ops->get_failure_state(fan->dev, buf); + printf("Fan failure state: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "speed") && fan->ops->get_fan_speed) { + ret = fan->ops->get_fan_speed(fan->dev, buf); + printf("Fan speed: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "rpm") && fan->ops->get_fan_rpm) { + ret = fan->ops->get_fan_rpm(fan->dev, buf); + printf("Fan rpm: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "level") && fan->ops->get_fan_level) { + ret = fan->ops->get_fan_level(fan->dev, buf); + printf("Fan level: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "all")) { + if (fan->ops->get_fan_startv) { + ret = fan->ops->get_fan_startv(fan->dev, buf); + printf("Fan startup voltage mode: %s\n", ret >= 0 ? buf : "N/A"); + } + if (fan->ops->get_gear_multiplier) { + ret = fan->ops->get_gear_multiplier(fan->dev, buf); + printf("Gear multiplier: %s\n", ret >= 0 ? buf : "N/A"); + } + if (fan->ops->get_fan_ppr) { + ret = fan->ops->get_fan_ppr(fan->dev, buf); + printf("Pulses per revolution: %s\n", ret >= 0 ? buf : "N/A"); + } + if (fan->ops->get_pwm_polarity) { + ret = fan->ops->get_pwm_polarity(fan->dev, buf); + printf("PWM polarity: %s\n", ret >= 0 ? buf : "N/A"); + } + if (fan->ops->get_clk_freq) { + ret = fan->ops->get_clk_freq(fan->dev, buf); + printf("Clock frequency: %s\n", ret >= 0 ? buf : "N/A"); + } + if (fan->ops->get_clk_div) { + ret = fan->ops->get_clk_div(fan->dev, buf); + printf("Clock divider: %s\n", ret >= 0 ? buf : "N/A"); + } + if (fan->ops->get_control_mode) { + ret = fan->ops->get_control_mode(fan->dev, buf); + printf("Control mode: %s\n", ret >= 0 ? buf : "N/A"); + } + if (fan->ops->get_output_mode) { + ret = fan->ops->get_output_mode(fan->dev, buf); + printf("Output mode: %s\n", ret >= 0 ? buf : "N/A"); + } + if (fan->ops->get_ooc_detection) { + ret = fan->ops->get_ooc_detection(fan->dev, buf); + printf("Out of control detection: %s\n", ret >= 0 ? buf : "N/A"); + } + if (fan->ops->get_failure_detection) { + ret = fan->ops->get_failure_detection(fan->dev, buf); + printf("Failure detection: %s\n", ret >= 0 ? buf : "N/A"); + } + if (fan->ops->get_failure_state) { + ret = fan->ops->get_failure_state(fan->dev, buf); + printf("Fan failure state: %s\n", ret >= 0 ? buf : "N/A"); + } + if (fan->ops->get_ooc_state) { + ret = fan->ops->get_ooc_state(fan->dev, buf); + printf("Fan out of control state: %s\n", ret >= 0 ? buf : "N/A"); + } + if (fan->ops->get_fan_speed) { + ret = fan->ops->get_fan_speed(fan->dev, buf); + printf("Fan speed: %s\n", ret >= 0 ? buf : "N/A"); + } + if (fan->ops->get_fan_rpm) { + ret = fan->ops->get_fan_rpm(fan->dev, buf); + printf("Fan rpm: %s\n", ret >= 0 ? buf : "N/A"); + } + if (fan->ops->get_fan_level) { + ret = fan->ops->get_fan_level(fan->dev, buf); + printf("Fan level: %s\n", ret >= 0 ? buf : "N/A"); + } + } + else { + printf("Invalid parameter: %s\n", argv[3]); + return COMMAND_ERROR_USAGE; + } + } + else { + printf("Invalid number of arguments for %s cmd\n", argv[1]); + return COMMAND_ERROR_USAGE; + } + } + else if (!strcmp(argv[1], "set")) { + if (argc == 5) { + val = simple_strtoul(argv[4], NULL, 10); + snprintf(buf, sizeof(buf), "%lu", val); + + if (!strcmp(argv[3], "startv") && fan->ops->set_fan_startv) { + ret = fan->ops->set_fan_startv(fan->dev, val); + printf("Fan startup voltage set to: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "gearmult") && fan->ops->set_gear_multiplier) { + ret = fan->ops->set_gear_multiplier(fan->dev, val); + printf("Gear multiplier set to: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "ppr") && fan->ops->set_fan_ppr) { + ret = fan->ops->set_fan_ppr(fan->dev, val); + printf("Pulses per revolution set to: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "pwmpol") && fan->ops->set_pwm_polarity) { + ret = fan->ops->set_pwm_polarity(fan->dev, val); + printf("PWM polarity set to: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "clkfreq") && fan->ops->set_clk_freq) { + ret = fan->ops->set_clk_freq(fan->dev, val); + printf("Clock frequency set to: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "clkdiv") && fan->ops->set_clk_div) { + ret = fan->ops->set_clk_div(fan->dev, val); + printf("Clock divider set to: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "ctrlmode") && fan->ops->set_control_mode) { + ret = fan->ops->set_control_mode(fan->dev, val); + printf("Control mode set to: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "outmode") && fan->ops->set_output_mode) { + ret = fan->ops->set_output_mode(fan->dev, val); + printf("Output mode set to: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "ooc") && fan->ops->set_ooc_detection) { + ret = fan->ops->set_ooc_detection(fan->dev, val); + printf("Out of control detection set to: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "fault") && fan->ops->set_failure_detection) { + ret = fan->ops->set_failure_detection(fan->dev, val); + printf("Failure detection set to: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "speed") && fan->ops->set_fan_speed) { + ret = fan->ops->set_fan_speed(fan->dev, val); + printf("Fan speed set to: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "rpm") && fan->ops->set_fan_rpm) { + ret = fan->ops->set_fan_rpm(fan->dev, val); + printf("Fan rpm set to: %s\n", ret >= 0 ? buf : "N/A"); + } + else if (!strcmp(argv[3], "level") && fan->ops->set_fan_level) { + ret = fan->ops->set_fan_level(fan->dev, val); + printf("Fan level set to: %s\n", ret >= 0 ? buf : "N/A"); + } + else { + printf("Invalid parameter: %s\n", argv[3]); + return COMMAND_ERROR_USAGE; + } + } + else { + printf("Invalid number of arguments for %s cmd\n", argv[1]); + return COMMAND_ERROR_USAGE; + } + } + else if (!strcmp(argv[1], "init")) { + if (argc == 3) { + if (fan->ops->fan_init) { + ret = fan->ops->fan_init(fan->dev); + printf("Fan initialization: %s\n", ret >= 0 ? "successful" : "N/A"); + } + } + else { + printf("Invalid number of arguments for %s cmd\n", argv[1]); + return COMMAND_ERROR_USAGE; + } + } + else { + printf("Invalid cmd: %s\n", argv[1]); + return COMMAND_ERROR_USAGE; + } + + return ret; +} + +BAREBOX_CMD_HELP_START(fan) +BAREBOX_CMD_HELP_TEXT("cmd options:\n") +BAREBOX_CMD_HELP_OPT("get", "get fan parameter") +BAREBOX_CMD_HELP_OPT("set", "set fan parameter") +BAREBOX_CMD_HELP_OPT("init", "initialize fan") + +BAREBOX_CMD_HELP_TEXT("\nparameter options:\n") +BAREBOX_CMD_HELP_OPT("outmode", "fan controller ouptut mode [0 (adc)|1 (pwm)]") +BAREBOX_CMD_HELP_OPT("clkdiv", "fan controller prescaler value [1|2|4|8]") +BAREBOX_CMD_HELP_OPT("clkfreq", "input clock frequency (Hz)") +BAREBOX_CMD_HELP_OPT("ppr", "fan tachometer pulses per revolution [2|4]") +BAREBOX_CMD_HELP_OPT("ctrlmode", "fan control mode [0 (open-loop)|1 (closed-loop)]") +BAREBOX_CMD_HELP_OPT("speed", "fan speed register value [0:255]") +BAREBOX_CMD_HELP_OPT("rpm", "fan rpm [0:(max fan rpm)]") +BAREBOX_CMD_HELP_OPT("level", "fan speed percentage [0:100]") +BAREBOX_CMD_HELP_OPT("startv", "fan startup voltage [0|1|2|3]") +BAREBOX_CMD_HELP_OPT("gearmult", "gear multiplier [0|1|2]") +BAREBOX_CMD_HELP_OPT("pwmpol", "PWM polarity [0 (positive)|1 (negative)]") +BAREBOX_CMD_HELP_OPT("faultdet", "enable/disable failure detection [0|1]") +BAREBOX_CMD_HELP_OPT("oocdet", "enable/disable out-of-control detection [0|1]") +BAREBOX_CMD_HELP_OPT("fault", "fan failure flag [0 (ok)|1 (fault)]") +BAREBOX_CMD_HELP_OPT("ooc", "fan out of control flag [1 (ok):0 (ooc)]") +BAREBOX_CMD_HELP_OPT("all", "print all fan parameters") +BAREBOX_CMD_HELP_TEXT("\n") +BAREBOX_CMD_HELP_END + +BAREBOX_CMD_START(fan) + .cmd = do_fan, + BAREBOX_CMD_DESC("fan management") + BAREBOX_CMD_OPTS(" [value]") + BAREBOX_CMD_GROUP(CMD_GRP_HWMANIP) + BAREBOX_CMD_HELP(cmd_fan_help) +BAREBOX_CMD_END \ No newline at end of file -- 2.47.3