Skip to content

Commit 3f83a8b

Browse files
committed
shell: add kctl_list command
Add 'sof kctl_list', a read-only walker over the IPC component list that prints, per component, the comp_id, pipeline_id, core, decoded module name (volume / gain / mixin / mixout / eqiir / src / ...) taken from cd->drv->tctx->uuid_p->name, a coarse 'kind' tag (volume / mixer / blob / config) for control-bearing modules, and the current comp_state. Module-adapter components all share SOF_COMP_MODULE_ADAPTER for drv->type, so the UUID-derived name string is the only stable per-module label available in firmware. This is enough to identify which comp_id carries which control before driving the value through host-side tools. kctl_get / kctl_set are intentionally not implemented in firmware: control values flow through per-module IPC4 large_config blobs (set_configuration / get_configuration), each with their own config_id namespace and TLV layout, which would duplicate the host-side tplg / IPC marshalling. Use tinymix / sof-ctl for that. New Kconfig (default y, depends on SHELL): CONFIG_SOF_SHELL_KCTL_LIST This concludes the documented quick-win list in zephyr/shell.md. Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
1 parent b54c365 commit 3f83a8b

3 files changed

Lines changed: 167 additions & 2 deletions

File tree

zephyr/Kconfig

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,26 @@ config SOF_SHELL_DMA_STATUS
597597
free bytes, read/write positions and total_copied. Pairs well
598598
with 'sof dai_list' for diagnosing P2M/M2P paths.
599599

600+
config SOF_SHELL_KCTL_LIST
601+
bool "kcontrol introspection command"
602+
default y
603+
depends on SHELL
604+
help
605+
Enables 'sof kctl_list' which walks the IPC component list and
606+
prints, per component, the comp_id, pipeline_id, core, decoded
607+
module name (volume / gain / mixin / mixout / eqiir / src /
608+
...) taken from the trace UUID context, a coarse 'kind' tag
609+
(volume / mixer / blob / config) for control-bearing modules,
610+
and the current comp_state.
611+
612+
This is read-only on purpose. Actual kcontrol get/set values
613+
flow through per-module IPC4 large_config blobs
614+
(set_configuration / get_configuration) which need
615+
module-specific marshalling and are intentionally left to host
616+
tools (tinymix, sof-ctl). Use this command together with 'sof
617+
module_status' to identify which comp_id carries which control
618+
before going through the host path.
619+
600620
endmenu # SOF shell commands
601621

602622
config SOF_VREGIONS

zephyr/shell.md

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ debug or testing. Items get ticked off as commands land on `topic/shell`.
6969

7070
| Area | Suggested commands | Status |
7171
|---|---|---|
72-
| kcontrols / mixer | `kctl_list`, `kctl_get <id>`, `kctl_set <id> <val>` | TODO |
72+
| **kcontrols / mixer** | `kctl_list`, `kctl_get <id>`, `kctl_set <id> <val>` | **DONE (task 8)** &mdash; `kctl_list` decodes module names + kind for every component. `kctl_get/set` deferred (per-module IPC4 large_config blobs &mdash; use host tools). |
7373
| Module runtime config | `mod_config_get/set <mod_id> <inst> <param_id>` | TODO |
7474
| Stream / copier | `stream_list`, `stream_pause/resume <id>`, `copier_gain_set` | TODO |
7575
| Clocks (extend `clock_status`) | `clock_set <core> <freq>`, `clock_force <pll>` | TODO |
@@ -116,7 +116,7 @@ debug or testing. Items get ticked off as commands land on `topic/shell`.
116116
5. **`mailbox_hex` / `dbgwin_dump`** &mdash; DONE (was originally `crash_log`/`bt`; pivoted because SOF panic.c isn't built on Zephyr and `bt` of a running CPU from itself isn't meaningful).
117117
6. **`perf_status`** &mdash; DONE.
118118
7. **`dai_list` / `dma_status`** &mdash; DONE.
119-
8. `kctl_get/set` &mdash; today only doable via tplg/IPC.
119+
8. **`kctl_get/set`** &mdash; DONE (`kctl_list` only; values stay on host).
120120

121121
---
122122

@@ -392,3 +392,40 @@ debug or testing. Items get ticked off as commands land on `topic/shell`.
392392
ships its own `dma` shell when `CONFIG_DMA_SHELL=y`, but that one
393393
walks Zephyr DMA devices and exposes raw register pokes, so the
394394
two are complementary.
395+
396+
## Task 8 &mdash; `kctl_list`
397+
398+
### Commands
399+
400+
| Command | Description |
401+
|---|---|
402+
| `sof kctl_list` | Walk every component in the IPC topology and print `comp_id`, `pipeline_id`, `core`, the decoded module name (`volume`, `gain`, `mixin`, `mixout`, `eqiir`, `src`, ...), a coarse `kind` tag for control-bearing modules (`volume` / `mixer` / `blob` / `config`) and the current `comp_state`. |
403+
404+
### Implementation
405+
406+
- Module-adapter components all share `SOF_COMP_MODULE_ADAPTER` for
407+
`drv->type`, so the only stable per-module label available in
408+
firmware is the UUID name string from
409+
`cd->drv->tctx->uuid_p->name` (the same name the LDC tool prints).
410+
`kctl_drv_name()` reads that, `kctl_drv_kind()` maps known module
411+
names to a coarse control-family tag.
412+
- New Kconfig (default `y`, depends on `SHELL`):
413+
`CONFIG_SOF_SHELL_KCTL_LIST`.
414+
- Shell command in [zephyr/sof_shell.c](zephyr/sof_shell.c).
415+
416+
### Notes / follow-ups
417+
418+
- Read-only on purpose. `kctl_get` / `kctl_set` are intentionally
419+
not implemented in firmware. Control values flow through
420+
per-module IPC4 large_config blobs
421+
(`set_configuration` / `get_configuration` in
422+
[src/include/module/module/interface.h](src/include/module/module/interface.h)),
423+
each with their own `config_id` namespace and TLV layout.
424+
Marshalling that from the shell would essentially duplicate the
425+
host-side tplg / IPC code path. Use `tinymix` /
426+
[sof-ctl](tools/ctl) on the host instead, and pair with
427+
`sof module_status` for raw component state.
428+
- This concludes the documented quick-win list. Future shell
429+
commands should follow the same pattern: small, read-only,
430+
Kconfig-gated, and complementary to (not a replacement for) the
431+
host control plane.

zephyr/sof_shell.c

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2427,6 +2427,108 @@ __cold static int cmd_sof_dma_status(const struct shell *sh,
24272427

24282428
#endif /* CONFIG_SOF_SHELL_DMA_STATUS */
24292429

2430+
#if CONFIG_SOF_SHELL_KCTL_LIST
2431+
2432+
/*
2433+
* Best-effort decoded driver name. Module-adapter components share
2434+
* SOF_COMP_MODULE_ADAPTER for drv->type, so the only stable per-module
2435+
* label available in firmware is the UUID name string from the trace
2436+
* context (which carries the same name printed by the LDC tool).
2437+
*/
2438+
static const char *kctl_drv_name(const struct comp_dev *cd)
2439+
{
2440+
if (cd && cd->drv && cd->drv->tctx && cd->drv->tctx->uuid_p &&
2441+
cd->drv->tctx->uuid_p->name[0])
2442+
return cd->drv->tctx->uuid_p->name;
2443+
return "?";
2444+
}
2445+
2446+
/*
2447+
* Tag the modules that are known to expose ALSA-style kcontrols
2448+
* (volume / gain / mixer-style switches and enums). This is purely a
2449+
* UI hint -- the actual control values live behind per-module
2450+
* config_id blobs that need IPC4 large_config marshalling, which is
2451+
* intentionally out of scope here (see shell.md).
2452+
*/
2453+
static const char *kctl_drv_kind(const char *name)
2454+
{
2455+
if (!name)
2456+
return "";
2457+
if (!strcmp(name, "volume") || !strcmp(name, "gain"))
2458+
return "volume";
2459+
if (!strcmp(name, "mixin") || !strcmp(name, "mixout") ||
2460+
!strcmp(name, "mixer"))
2461+
return "mixer";
2462+
if (!strcmp(name, "eqiir") || !strcmp(name, "eqfir") ||
2463+
!strcmp(name, "drc") || !strcmp(name, "multiband_drc") ||
2464+
!strcmp(name, "dcblock") || !strcmp(name, "tdfb") ||
2465+
!strcmp(name, "crossover") || !strcmp(name, "google_rtc_audio_processing"))
2466+
return "blob";
2467+
if (!strcmp(name, "selector") || !strcmp(name, "src") ||
2468+
!strcmp(name, "asrc"))
2469+
return "config";
2470+
return "";
2471+
}
2472+
2473+
__cold static int cmd_sof_kctl_list(const struct shell *sh,
2474+
size_t argc, char *argv[])
2475+
{
2476+
struct ipc *ipc = sof_get()->ipc;
2477+
struct list_item *clist;
2478+
struct ipc_comp_dev *icd;
2479+
int count = 0;
2480+
2481+
ARG_UNUSED(argc);
2482+
ARG_UNUSED(argv);
2483+
2484+
if (!ipc) {
2485+
shell_print(sh, "No IPC");
2486+
return 0;
2487+
}
2488+
2489+
shell_print(sh, "%-12s %-8s %-5s %-24s %-8s %s",
2490+
"comp_id", "ppl_id", "core", "module", "kind", "state");
2491+
2492+
list_for_item(clist, &ipc->comp_list) {
2493+
const struct comp_dev *cd;
2494+
const char *name;
2495+
2496+
icd = container_of(clist, struct ipc_comp_dev, list);
2497+
if (icd->type != COMP_TYPE_COMPONENT)
2498+
continue;
2499+
2500+
cd = icd->cd;
2501+
name = kctl_drv_name(cd);
2502+
2503+
shell_print(sh, "0x%-10x %-8u %-5u %-24s %-8s %s",
2504+
icd->id,
2505+
cd->pipeline ? cd->pipeline->pipeline_id : 0,
2506+
icd->core, name, kctl_drv_kind(name),
2507+
comp_state_str(cd->state));
2508+
count++;
2509+
}
2510+
2511+
if (!count) {
2512+
shell_print(sh,
2513+
"No components found. Start an audio stream first.");
2514+
return 0;
2515+
}
2516+
2517+
shell_print(sh, "");
2518+
shell_print(sh,
2519+
"kctl get/set is intentionally not exposed here -- control");
2520+
shell_print(sh,
2521+
"values flow through per-module IPC4 large_config blobs");
2522+
shell_print(sh,
2523+
"(set_configuration / get_configuration). Use tinymix /");
2524+
shell_print(sh,
2525+
"sof-ctl on the host, or 'sof module_status' for raw state.");
2526+
2527+
return 0;
2528+
}
2529+
2530+
#endif /* CONFIG_SOF_SHELL_KCTL_LIST */
2531+
24302532
SHELL_STATIC_SUBCMD_SET_CREATE(sof_commands,
24312533
SHELL_CMD(test_inject_sched_gap, NULL,
24322534
"Inject a gap to audio scheduling\n",
@@ -2648,6 +2750,12 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sof_commands,
26482750
cmd_sof_dma_status, 1, 2),
26492751
#endif
26502752

2753+
#if CONFIG_SOF_SHELL_KCTL_LIST
2754+
SHELL_CMD(kctl_list, NULL,
2755+
"List components and their decoded module name / kind\n",
2756+
cmd_sof_kctl_list),
2757+
#endif
2758+
26512759
SHELL_SUBCMD_SET_END
26522760
);
26532761

0 commit comments

Comments
 (0)