]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
dpll: add mode setting support
authorPetr Oros <poros@redhat.com>
Thu, 29 Jan 2026 11:28:49 +0000 (12:28 +0100)
committerDavid Ahern <dsahern@kernel.org>
Fri, 30 Jan 2026 15:51:51 +0000 (08:51 -0700)
Add ability to set DPLL device operating mode (automatic/manual)
through "dpll device set id ID mode MODE" command.

In automatic mode, the DPLL autonomously selects the best input
source based on priority and quality. In manual mode, the input
source must be explicitly configured.

The implementation adds dpll_mode_map for string-to-enum conversion,
str_to_dpll_mode() and dpll_parse_mode() functions, and refactors
dpll_mode_name() to use str_map_lookup_uint() for consistency.

Man page and bash completion updated accordingly.

Signed-off-by: Petr Oros <poros@redhat.com>
Tested-by: Ivan Vecera <ivecera@redhat.com>
Signed-off-by: David Ahern <dsahern@kernel.org>
bash-completion/dpll
dpll/dpll.c
man/man8/dpll.8

index 6e4d39a5b5b6bbe6454d86f59b8f145ae02372a7..caf86a36f2adf37920d212ef15848ec83cc9c923 100644 (file)
@@ -73,6 +73,10 @@ _dpll_device()
                         "$(_dpll_direct_complete device_id)" -- "$cur" ) )
                     return 0
                     ;;
+                mode)
+                    COMPREPLY=( $( compgen -W "automatic manual" -- "$cur" ) )
+                    return 0
+                    ;;
                 phase-offset-monitor)
                     COMPREPLY=( $( compgen -W "enable disable true false 0 1" -- "$cur" ) )
                     return 0
@@ -82,7 +86,7 @@ _dpll_device()
                     return 0
                     ;;
                 *)
-                    COMPREPLY=( $( compgen -W "id phase-offset-monitor \
+                    COMPREPLY=( $( compgen -W "id mode phase-offset-monitor \
                         phase-offset-avg-factor" -- "$cur" ) )
                     return 0
                     ;;
index 846ad4b04c63d22bc97368845bc4d18648280dbd..9dc3f8db373d28583c03085e9246c61d74f19035 100644 (file)
@@ -42,6 +42,14 @@ static const char *str_enable_disable(bool v)
        return v ? "enable" : "disable";
 }
 
+static struct str_num_map dpll_mode_map[] = {
+       { .str = "automatic", .num = DPLL_MODE_AUTOMATIC },
+       { .str = "manual", .num = DPLL_MODE_MANUAL },
+       {
+               .str = NULL,
+       },
+};
+
 static struct str_num_map pin_state_map[] = {
        { .str = "connected", .num = DPLL_PIN_STATE_CONNECTED },
        { .str = "disconnected", .num = DPLL_PIN_STATE_DISCONNECTED },
@@ -132,6 +140,17 @@ static bool dpll_no_arg(struct dpll *dpll)
        return dpll_argc(dpll) == 0;
 }
 
+static int str_to_dpll_mode(const char *mode_str, __u32 *mode)
+{
+       int num;
+
+       num = str_map_lookup_str(dpll_mode_map, mode_str);
+       if (num < 0)
+               return num;
+       *mode = num;
+       return 0;
+}
+
 static int str_to_dpll_pin_state(const char *state_str, __u32 *state)
 {
        int num;
@@ -154,6 +173,18 @@ static int str_to_dpll_pin_type(const char *type_str, __u32 *type)
        return 0;
 }
 
+static int dpll_parse_mode(struct dpll *dpll, __u32 *mode)
+{
+       const char *str = dpll_argv(dpll);
+
+       if (str_to_dpll_mode(str, mode)) {
+               pr_err("invalid state: %s (use automatic/manual)\n", str);
+               return -EINVAL;
+       }
+       dpll_arg_inc(dpll);
+       return 0;
+}
+
 static int dpll_parse_state(struct dpll *dpll, __u32 *state)
 {
        const char *str = dpll_argv(dpll);
@@ -585,21 +616,18 @@ dpll_free:
 static void cmd_device_help(void)
 {
        pr_err("Usage: dpll device show [ id DEVICE_ID ]\n");
-       pr_err("       dpll device set id DEVICE_ID [ phase-offset-monitor { enable | disable } ]\n");
-       pr_err("                                      [ phase-offset-avg-factor NUM ]\n");
+       pr_err("       dpll device set id DEVICE_ID [ mode { automatic | manual } ]\n");
+       pr_err("                                    [ phase-offset-monitor { enable | disable } ]\n");
+       pr_err("                                    [ phase-offset-avg-factor NUM ]\n");
        pr_err("       dpll device id-get [ module-name NAME ] [ clock-id ID ] [ type TYPE ]\n");
 }
 
 static const char *dpll_mode_name(__u32 mode)
 {
-       switch (mode) {
-       case DPLL_MODE_MANUAL:
-               return "manual";
-       case DPLL_MODE_AUTOMATIC:
-               return "automatic";
-       default:
-               return "unknown";
-       }
+       const char *str;
+
+       str = str_map_lookup_uint(dpll_mode_map, mode);
+       return str ? str : "unknown";
 }
 
 static const char *dpll_lock_status_name(__u32 status)
@@ -839,6 +867,10 @@ static int cmd_device_set(struct dpll *dpll)
                                return -EINVAL;
                        mnl_attr_put_u32(nlh, DPLL_A_ID, id);
                        has_id = true;
+               } else if (dpll_argv_match_inc(dpll, "mode")) {
+                       if (dpll_parse_attr_enum(dpll, nlh, "mode", DPLL_A_MODE,
+                                                dpll_parse_mode))
+                               return -EINVAL;
                } else if (dpll_argv_match(dpll, "phase-offset-monitor")) {
                        const char *str = dpll_argv_next(dpll);
                        bool val;
index fcc1c4a67af5d9f480def0dc0782c6e3eeea4851..e82f083feac64b986cb5e0f8140ae174c6fec875 100644 (file)
@@ -88,7 +88,7 @@ Temperature (if supported)
 Type (PPS or EEC)
 .RE
 
-.SS dpll device set id ID [ phase-offset-monitor { enable | disable } ] [ phase-offset-avg-factor FACTOR ]
+.SS dpll device set id ID [ mode { automatic | manual } ] [ phase-offset-monitor { enable | disable } ] [ phase-offset-avg-factor FACTOR ]
 
 Configure DPLL device parameters.
 
@@ -96,6 +96,17 @@ Configure DPLL device parameters.
 .BI id " ID"
 Specifies which device to configure (required).
 
+.TP
+.BI mode " { automatic | manual }"
+Set the operating mode of the DPLL device.
+In
+.B automatic
+mode, the DPLL autonomously selects the best available input source
+based on priority and quality. In
+.B manual
+mode, the input source must be explicitly configured and the DPLL
+will not automatically switch sources.
+
 .TP
 .BI phase-offset-monitor " { enable | disable | true | false | 0 | 1 }"
 Enable or disable phase offset monitoring between the device and its pins.
@@ -283,6 +294,11 @@ Press Ctrl+C to stop monitoring.
 .B dpll -j device show id 0
 .fi
 
+.SS Set device 0 to manual mode
+.nf
+.B dpll device set id 0 mode manual
+.fi
+
 .SS Enable phase offset monitoring on device 0
 .nf
 .B dpll device set id 0 phase-offset-monitor enable