.../bindings/sound/qcom,wcd9378-sdw.yaml | 201 +++ include/sound/sdca.h | 2 +- sound/soc/codecs/Kconfig | 12 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/wcd9378-sdca.c | 1202 +++++++++++++++++ sound/soc/sdca/Kconfig | 6 +- sound/soc/sdca/sdca_asoc.c | 84 +- sound/soc/sdca/sdca_class.c | 83 +- sound/soc/sdca/sdca_class.h | 41 + sound/soc/sdca/sdca_class_function.c | 80 +- sound/soc/sdca/sdca_device.c | 4 + sound/soc/sdca/sdca_function_device.c | 2 +- sound/soc/sdca/sdca_functions.c | 4 + 13 files changed, 1710 insertions(+), 13 deletions(-) create mode 100644 Documentation/devicetree/bindings/sound/qcom,wcd9378-sdw.yaml create mode 100644 sound/soc/codecs/wcd9378-sdca.c
Hi all,
At Linux Plumbers 2025 in the Devicetree MC I raised the "SDCA and the
classic ACPI-DT problem" [1]: MIPI SDCA is built around ACPI/DisCo
firmware descriptors, and the in-tree ASoC SDCA framework
(sound/soc/sdca/) enumerates functions, entities, controls and PDEs by
walking those tables. On ARM64 DT platforms there is no DisCo, so the
framework is unreachable and sdca codecs will not be able to use the
generic sdca drivers and duplicating.
The direction from that discussion was to let DT platforms reuse the
same class/function auxiliary driver plumbing and have codec drivers
supply the small amount of static function/entity metadata that DisCo
would otherwise carry, plus hooks for device-specific bring-up. This
series is a first cut at that, with the Qualcomm WCD9378 ("Tambora")
SDCA codec on the Glymur CRD as the first consumer. Static table that in
part of this codec is generated from acpi tables.
About WCD9378: the same silicon ships in two very different platform
modes. In "mobile mode" (Qualcomm phone/tablet SoCs) is enumerated as
as tx and rx device, each of which has dedicated control and data lines.
mobile mode is addressed by Jorijn's posting [2].
In "compute mode" (Qualcomm compute platforms such as Glymur / X2 Elite)
the same part is enumerated as a single standard MIPI SDCA class device
on SoundWire and is driven purely through the SDCA framework, which
is what this series covers. Both modes share the same MIPI class ID
and, in DT, the same compatible; qcom,compute-mode selects which
driver path is taken.
Framework enablement (patches 1-6):
* 1: hw_params fix for OT DAI upstream Input Terminals (found while
bringing up Tambora capture).
* 2: allow sound/soc/sdca/ to build without ACPI.
* 3: turn sdca_class into an exported library and introduce
struct sdca_class_hw_ops with hw_init + get_function_data, so a
codec driver registers its own sdw_driver, supplies static function
descriptors when there is no DisCo node, and owns regulators/reset
at probe time. The built-in class_sdw_driver stays for
pure-generic parts (hw_ops = NULL).
* 4: pde_pre_pmu / pde_post_pmu hooks in hw_ops so vendor drivers
can stage/commit register writes around PDE PS0 transitions.
* 5: of_xlate_dai_name that resolves sound-dai cells by entity index
rather than positional DAI order.
* 6: register SDCA_FUNCTION_TYPE_SIMPLE_JACK in the class function
driver.
First consumer (patches 7-8):
* 7: WCD9378 SoundWire slave binding. Compatible is shared with
Jorijn's mobile WCD9378 posting [2]; qcom,compute-mode selects the
SDCA/compute-mode probe path and gates the compute-only properties.
* 8: Tambora codec driver - registers its own sdw_driver, calls into
the class library, supplies SimpleJack + HID functions via
get_function_data, owns supplies/reset/mic-bias in hw_init, uses
pde_*_pmu for the FU + IT_USAGE writes the PDE sequencer needs.
RFC because patches 1-6 touch the SDCA framework, is what I
would most like feedback on. Tested on Qualcomm Glymur CRD:
headphone playback, capture work end-to-end via the Tambora
codec over the mulit master SoundWire bus.
Platform bits (LPASS clock controller, SoundWire aggregate
controller, machine-driver DT, defconfig, ...) are held back for a
separate posting once this shape is agreed.
Next steps
==========
The most obvious follow-up is figuring out how the mobile-mode and
compute-mode WCD9378 drivers coexist under one compatible. Jorijn's
mobile driver [2] and this compute-mode driver target the same silicon
and register the same MIPI class ID on the SoundWire bus, and today
they discriminate purely on the qcom,compute-mode DT property. We
need to agree on a cleaner arbitration. Probably a shared
sdw_driver stub in wcd9378-common that reads the mode and dispatches
to the mobile or compute code path - so that both drivers can live in
tree without racing to bind the same slave. I would like to line this
uip with Jorijn as a follow-up to this series. Cleanup some of the
static volume setting to a proper volume control.
Links
=====
[1] LPC 2025, Devicetree MC:
"DeviceTrees - MIPI SoundWire Device Class for Audio (SDCA) and
classic ACPI-DT problem"
https://lpc.events/event/19/contributions/2024/
[2] Jorijn Rikhof, mobile-mode WCD9378 posting:
https://lwn.net/Articles/1081648/
Thanks,
Srini
Srinivas Kandagatla (8):
ASoC: SDCA: hw_params: program upstream Input Terminals for OT DAI
ASoC: SDCA: allow building without ACPI
ASoC: SDCA: expose class helpers with hw_ops for non-DisCo platforms
ASoC: SDCA: add PDE pre/post-pmu hooks to hw_ops
ASoC: SDCA: class_function: xlate sound-dai cell by entity index
ASoC: SDCA: register SDCA_FUNCTION_TYPE_SIMPLE_JACK in class function
driver
dt-bindings: sound: qcom: add Tambora WCD9378 SDCA codec
ASoC: codecs: add Qualcomm Tambora (WCD9378) SDCA codec
.../bindings/sound/qcom,wcd9378-sdw.yaml | 201 +++
include/sound/sdca.h | 2 +-
sound/soc/codecs/Kconfig | 12 +
sound/soc/codecs/Makefile | 2 +
sound/soc/codecs/wcd9378-sdca.c | 1202 +++++++++++++++++
sound/soc/sdca/Kconfig | 6 +-
sound/soc/sdca/sdca_asoc.c | 84 +-
sound/soc/sdca/sdca_class.c | 83 +-
sound/soc/sdca/sdca_class.h | 41 +
sound/soc/sdca/sdca_class_function.c | 80 +-
sound/soc/sdca/sdca_device.c | 4 +
sound/soc/sdca/sdca_function_device.c | 2 +-
sound/soc/sdca/sdca_functions.c | 4 +
13 files changed, 1710 insertions(+), 13 deletions(-)
create mode 100644 Documentation/devicetree/bindings/sound/qcom,wcd9378-sdw.yaml
create mode 100644 sound/soc/codecs/wcd9378-sdca.c
--
2.53.0
On Thu, Jul 23, 2026 at 12:42:10AM +0100, Srinivas Kandagatla wrote:
> At Linux Plumbers 2025 in the Devicetree MC I raised the "SDCA and the
> classic ACPI-DT problem" [1]: MIPI SDCA is built around ACPI/DisCo
> firmware descriptors, and the in-tree ASoC SDCA framework
> (sound/soc/sdca/) enumerates functions, entities, controls and PDEs by
> walking those tables. On ARM64 DT platforms there is no DisCo, so the
> framework is unreachable and sdca codecs will not be able to use the
> generic sdca drivers and duplicating.
>
> The direction from that discussion was to let DT platforms reuse the
> same class/function auxiliary driver plumbing and have codec drivers
> supply the small amount of static function/entity metadata that DisCo
> would otherwise carry, plus hooks for device-specific bring-up. This
> series is a first cut at that, with the Qualcomm WCD9378 ("Tambora")
> SDCA codec on the Glymur CRD as the first consumer. Static table that in
> part of this codec is generated from acpi tables.
Fascinating, a shame I missed the discussion. Main question
I have is what was the reasoning behind using static tables
rather than just putting the data in device tree? All the core
code uses the generic firmware parsing function so should be
perfectly capable of parsing the data out of device tree. The
only bit that is missing is really the sdca_lookup_functions
bit you ifdef out, but updating that to also support DT should
be pretty simple.
Looking through your presentation (thanks for linking that),
am I to guess this was mostly a device tree people didn't like
the stuff SDCA contains problem? I do see that some of the SDCA
stuff isn't an exact match for how Linux has traditionally liked
to handle DT but also really not sure I see any benefit to DT
and ACPI support being different.
I guess there is also a slightly risk the standard committee
eventually get round to device tree and adds support differently,
but an existing large user would be an excellent steer on them.
> * 1: hw_params fix for OT DAI upstream Input Terminals (found while
> bringing up Tambora capture).
Thanks that is indeed something that needs some work.
> * 2: allow sound/soc/sdca/ to build without ACPI.
> * 3: turn sdca_class into an exported library and introduce
> struct sdca_class_hw_ops with hw_init + get_function_data, so a
> codec driver registers its own sdw_driver, supplies static function
> descriptors when there is no DisCo node, and owns regulators/reset
> at probe time. The built-in class_sdw_driver stays for
> pure-generic parts (hw_ops = NULL).
Yeah, we have not really implemented any XU type stuff yet. Some
discussion about whether we want to proceed with adding custom
callbacks into the class driver or just call the core functions
from the end driver. The later was really the original intention
although I do grant that there has ended up being slightly more
boiler plate in the class driver than would have been ideal.
> * 4: pde_pre_pmu / pde_post_pmu hooks in hw_ops so vendor drivers
> can stage/commit register writes around PDE PS0 transitions.
> * 5: of_xlate_dai_name that resolves sound-dai cells by entity index
> rather than positional DAI order.
> * 6: register SDCA_FUNCTION_TYPE_SIMPLE_JACK in the class function
> driver.
We can probably just merge the simple jack support as is. I will
have a look.
Going to likely take me a few days to work my way through things,
but please bear with me. Great to see the SDCA stuff getting some
proper usage outside of us :-)
Thanks,
Charles
Thanks Charles, for the feedback.
On 7/23/26 11:17 AM, Charles Keepax wrote:
> On Thu, Jul 23, 2026 at 12:42:10AM +0100, Srinivas Kandagatla wrote:
>> At Linux Plumbers 2025 in the Devicetree MC I raised the "SDCA and the
>> classic ACPI-DT problem" [1]: MIPI SDCA is built around ACPI/DisCo
>> firmware descriptors, and the in-tree ASoC SDCA framework
>> (sound/soc/sdca/) enumerates functions, entities, controls and PDEs by
>> walking those tables. On ARM64 DT platforms there is no DisCo, so the
>> framework is unreachable and sdca codecs will not be able to use the
>> generic sdca drivers and duplicating.
>>
>> The direction from that discussion was to let DT platforms reuse the
>> same class/function auxiliary driver plumbing and have codec drivers
>> supply the small amount of static function/entity metadata that DisCo
>> would otherwise carry, plus hooks for device-specific bring-up. This
>> series is a first cut at that, with the Qualcomm WCD9378 ("Tambora")
>> SDCA codec on the Glymur CRD as the first consumer. Static table that in
>> part of this codec is generated from acpi tables.
>
> Fascinating, a shame I missed the discussion. Main question
> I have is what was the reasoning behind using static tables
> rather than just putting the data in device tree? All the core
> code uses the generic firmware parsing function so should be
> perfectly capable of parsing the data out of device tree. The
> only bit that is missing is really the sdca_lookup_functions
> bit you ifdef out, but updating that to also support DT should
> be pretty simple.
Two reasons
1. This is laptop platform primarily works on windows with proper acpi
tables, These tables are directly derived for ACPI asl tables in
windows. Ideally I want to use it the way it is supposed to work.
2. replicating full Disco specs in DT is going to be challenge, Because
DT describes hardware but not necessarily at a level of register init
tables or to an extent where class drivers need it.
>
> Looking through your presentation (thanks for linking that),
> am I to guess this was mostly a device tree people didn't like
> the stuff SDCA contains problem? I do see that some of the SDCA
> stuff isn't an exact match for how Linux has traditionally liked
> to handle DT but also really not sure I see any benefit to DT
> and ACPI support being different.
I think there is fine line on what can go into DT, some of the hardware
init tables are big No No i guess, Power and other ACPI things are not
something DT does.
I will let DT maintainers comment on this.
>
> I guess there is also a slightly risk the standard committee
> eventually get round to device tree and adds support differently,
> but an existing large user would be an excellent steer on them.
>
I think whole Disco has not considered DT at all.
>> * 1: hw_params fix for OT DAI upstream Input Terminals (found while
>> bringing up Tambora capture).
>
> Thanks that is indeed something that needs some work.
>
>> * 2: allow sound/soc/sdca/ to build without ACPI.
>> * 3: turn sdca_class into an exported library and introduce
>> struct sdca_class_hw_ops with hw_init + get_function_data, so a
>> codec driver registers its own sdw_driver, supplies static function
>> descriptors when there is no DisCo node, and owns regulators/reset
>> at probe time. The built-in class_sdw_driver stays for
>> pure-generic parts (hw_ops = NULL).
>
> Yeah, we have not really implemented any XU type stuff yet. Some
> discussion about whether we want to proceed with adding custom
> callbacks into the class driver or just call the core functions
> from the end driver. The later was really the original intention
> although I do grant that there has ended up being slightly more
> boiler plate in the class driver than would have been ideal.
XU should be opaque to class drivers.
>
>> * 4: pde_pre_pmu / pde_post_pmu hooks in hw_ops so vendor drivers
>> can stage/commit register writes around PDE PS0 transitions.
>> * 5: of_xlate_dai_name that resolves sound-dai cells by entity index
>> rather than positional DAI order.
>> * 6: register SDCA_FUNCTION_TYPE_SIMPLE_JACK in the class function
>> driver.
>
> We can probably just merge the simple jack support as is. I will
> have a look.
>
> Going to likely take me a few days to work my way through things,
> but please bear with me. Great to see the SDCA stuff getting some
> proper usage outside of us :-)
Thanks for the positive note.
Plan is to get all the Qualcomm SDCA codecs to use existing sdca drivers
than writing duplicate code.
We do have couple of more SDCA drivers, the one I could include in next
version is a Simple Amp driver which has pretty much in similar lines
WCD9378 codec, everything leveraged from generic drivers.
--srini
>
> Thanks,
> Charles
On Thu, Jul 23, 2026 at 02:24:19PM +0100, Srinivas Kandagatla wrote:
> Thanks Charles, for the feedback.
> On 7/23/26 11:17 AM, Charles Keepax wrote:
> > On Thu, Jul 23, 2026 at 12:42:10AM +0100, Srinivas Kandagatla wrote:
> >> The direction from that discussion was to let DT platforms reuse the
> >> same class/function auxiliary driver plumbing and have codec drivers
> >> supply the small amount of static function/entity metadata that DisCo
> >> would otherwise carry, plus hooks for device-specific bring-up. This
> >> series is a first cut at that, with the Qualcomm WCD9378 ("Tambora")
> >> SDCA codec on the Glymur CRD as the first consumer. Static table that in
> >> part of this codec is generated from acpi tables.
> >
> > Fascinating, a shame I missed the discussion. Main question
> > I have is what was the reasoning behind using static tables
> > rather than just putting the data in device tree? All the core
> > code uses the generic firmware parsing function so should be
> > perfectly capable of parsing the data out of device tree. The
> > only bit that is missing is really the sdca_lookup_functions
> > bit you ifdef out, but updating that to also support DT should
> > be pretty simple.
> Two reasons
>
> 1. This is laptop platform primarily works on windows with proper acpi
> tables, These tables are directly derived for ACPI asl tables in
> windows. Ideally I want to use it the way it is supposed to work.
This is a little confusing, could we not just the ACPI in those
cases?
> 2. replicating full Disco specs in DT is going to be challenge, Because
> DT describes hardware but not necessarily at a level of register init
> tables or to an extent where class drivers need it.
>
> > Looking through your presentation (thanks for linking that),
> > am I to guess this was mostly a device tree people didn't like
> > the stuff SDCA contains problem? I do see that some of the SDCA
> > stuff isn't an exact match for how Linux has traditionally liked
> > to handle DT but also really not sure I see any benefit to DT
> > and ACPI support being different.
>
> I think there is fine line on what can go into DT, some of the hardware
> init tables are big No No i guess, Power and other ACPI things are not
> something DT does.
>
> I will let DT maintainers comment on this.
Yeah agree be good to get the DT guys thoughts on this. It seems
like a misstep to me to insist that the SDCA spec implements a
completely different system of storing information for DT. SDCA
is what SDCA is now, and supporting two different parsers seems
like work no one needs when the one parser we have would work
fine for both.
That said I don't totally object to the idea of an option to
supply a static block of information as you are in the series. It
could be useful for transitional and work around situations. But
it doesn't seem like a good choice for SDCA on DT going forward,
it is basically going back to the board files that DT was saving
us from.
Thanks,
Charles
On 7/24/26 1:36 PM, Charles Keepax wrote:
> On Thu, Jul 23, 2026 at 02:24:19PM +0100, Srinivas Kandagatla wrote:
>> Thanks Charles, for the feedback.
>> On 7/23/26 11:17 AM, Charles Keepax wrote:
>>> On Thu, Jul 23, 2026 at 12:42:10AM +0100, Srinivas Kandagatla wrote:
>>>> The direction from that discussion was to let DT platforms reuse the
>>>> same class/function auxiliary driver plumbing and have codec drivers
>>>> supply the small amount of static function/entity metadata that DisCo
>>>> would otherwise carry, plus hooks for device-specific bring-up. This
>>>> series is a first cut at that, with the Qualcomm WCD9378 ("Tambora")
>>>> SDCA codec on the Glymur CRD as the first consumer. Static table that in
>>>> part of this codec is generated from acpi tables.
>>>
>>> Fascinating, a shame I missed the discussion. Main question
>>> I have is what was the reasoning behind using static tables
>>> rather than just putting the data in device tree? All the core
>>> code uses the generic firmware parsing function so should be
>>> perfectly capable of parsing the data out of device tree. The
>>> only bit that is missing is really the sdca_lookup_functions
>>> bit you ifdef out, but updating that to also support DT should
>>> be pretty simple.
>> Two reasons
>>
>> 1. This is laptop platform primarily works on windows with proper acpi
>> tables, These tables are directly derived for ACPI asl tables in
>> windows. Ideally I want to use it the way it is supposed to work.
>
> This is a little confusing, could we not just the ACPI in those
> cases?
On Qualcomm platforms, ACPI contains many vendor-specific PiP (Platform
Integrated Peripherals) methods that don't follow standard conventions.
This breaks ACPI compatibility on Linux. Consequently, Qualcomm-based
laptops designed for Windows that are run on Linux have to use Device
Trees for hardware description—a temporary solution until the ACPI
implementation becomes standards-compliant.
>
>> 2. replicating full Disco specs in DT is going to be challenge, Because
>> DT describes hardware but not necessarily at a level of register init
>> tables or to an extent where class drivers need it.
>>
>>> Looking through your presentation (thanks for linking that),
>>> am I to guess this was mostly a device tree people didn't like
>>> the stuff SDCA contains problem? I do see that some of the SDCA
>>> stuff isn't an exact match for how Linux has traditionally liked
>>> to handle DT but also really not sure I see any benefit to DT
>>> and ACPI support being different.
>>
>> I think there is fine line on what can go into DT, some of the hardware
>> init tables are big No No i guess, Power and other ACPI things are not
>> something DT does.
>>
>> I will let DT maintainers comment on this.
>
> Yeah agree be good to get the DT guys thoughts on this. It seems
> like a misstep to me to insist that the SDCA spec implements a
> completely different system of storing information for DT. SDCA
> is what SDCA is now, and supporting two different parsers seems
> like work no one needs when the one parser we have would work
> fine for both.
Am not sure I understood the two parser concern, what we are
representing in the table is something that sdca core already does after
parsing acpi tables. So we are reusing the same structures. Its like
result of already parsed acpi tables.
I did try
>
> That said I don't totally object to the idea of an option to
> supply a static block of information as you are in the series. It
> could be useful for transitional and work around situations. But
> it doesn't seem like a good choice for SDCA on DT going forward,
> it is basically going back to the board files that DT was saving
> us from.
Either we have this at driver level or at dt level, both of them have
pros and cons.
If we decide to go with dt, this how the dt entries will look like, this
should give fair bit of idea to DT maintianers for discussion.
soundwire@7630000 {
wcd9378c_sdw: audio-codec@0,3 {
compatible = "sdw20217011000";
reg = <0 3>;
#sound-dai-cells = <1>;
/*
* SDCA / compute-mode slave: this node owns the codec's
* supplies, mic-bias voltages and reset GPIO -- no
* separate top-level codec parent. Existing binding.
*/
qcom,compute-mode;
qcom,port-mapping = <2 2 3 4 5 6 7 8>;
reset-gpios = <&tlmm 191 GPIO_ACTIVE_LOW>;
vdd-buck-supply = <&vreg_l15b_1p8>;
vdd-rxtx-supply = <&vreg_l15b_1p8>;
vdd-io-supply = <&vreg_l18b_1p2>;
vdd-mic-bias-supply = <&vreg_bob1>;
qcom,micbias1-microvolt = <1800000>;
qcom,micbias2-microvolt = <2750000>;
qcom,micbias3-microvolt = <1800000>;
/*
* ================================================
* NEW: SDCA function topology as a child node of the
* slave. A DT walker (see caveat #1 above) picks
* this up during slave probe and hands the fwnode to
* find_sdca_entities()/find_sdca_clusters()/etc.
* ================================================
*/
sdca-function-simple-jack@3 {
reg = <3>;
function-address = <3>; /* mirrors ACPI _ADR[2:0] */
/* DisCo v2.1 in use */
mipi-sdw-sw-interface-revision = <0x00020001>;
/* Errata 01 Item 1: Reset_Function_Now timeout */
mipi-sdca-function-reset-max-delay = <100000>;
/*
* Entity 0 controls: FunctionSdcaVersion, Type,
* ManufacturerId, Id, Version, Status, Action,
* Device{Mfg,Part,Version,SdcaVersion}, ...
* 14 controls at selectors 1,4,5,6,7,8,9,A,10,
* 11,2C,2D,2E,2F.
*/
mipi-sdca-control-list =
/bits/ 64 <0x0000F000000307F2>;
mipi-sdca-control-0x5-subproperties { /* Type */
mipi-sdca-control-access-mode = <0x5>; /* DC */
mipi-sdca-control-access-layer = <0x4>;
mipi-sdca-control-cn-list =
/bits/ 64 <0x1>;
mipi-sdca-control-dc-value = <0x08>;
/* 0x08 = SimpleJack */
};
/* ... 13 more Entity-0 control subnodes ... */
/* -- Entity index & cluster index (Table 9) ---- */
mipi-sdca-entity-id-list = <
0x01 0x02 0x03 0x04 0x07 0x08 0x09 0x0A
0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 0x12
0x13 0x15 0x16 0x17 0x18 0x19
>;
mipi-sdca-cluster-id-list = <0x1 0x2 0x3 0x5>;
/* -- Init table (Table 9 DsdBuffer) ------------ */
/*
* Format: repeating { u32 addr (LE), u8 val }.
* First 5 of 62 entries shown -- the full table
* is the QcSimpleJack.asl BUF0 transcribed:
*/
mipi-sdca-function-initialization-table = [
F0 04 18 40 00
/* 0x401804F0 = 0x00 DIGITAL_PLATFORM_CTL */
6E 04 18 40 10
/* 0x4018046E = 0x10 DIGITAL_INTR_MODE */
4D 00 00 00 01
/* 0x0000004D = 0x01 SCP_BUSCLOCK_BASE */
62 00 00 00 02
/* 0x00000062 = 0x02 SCP_BUSCLOCK_SCALE */
6A 01 18 40 80
/* 0x4018016A = 0x80 CP_DTOP_CTRL_14 */
/* ... 57 more entries ... */
];
/* ============ Entity subnodes ================= */
/* -- 0x01: IT 41 (HPH render input) ------------ */
mipi-sdca-entity-id-0x1-subproperties {
mipi-sdca-entity-type = <0x02>; /* IT */
mipi-sdca-entity-label = "IT 41";
mipi-sdca-terminal-type = <0x0191>;
/* 0x0191 = PDM RENDER STREAM */
mipi-sdca-terminal-clock-connection {
/* Label-based reference, not phandle */
mipi-sdca-entity-label = "CS 41";
};
/* Controls: 4 Usage, 8 Latency,
* 0x10 ClusterIdx, 0x11 DP-sel */
mipi-sdca-control-list =
/bits/ 64 <0x30110>;
mipi-sdca-control-0x4-subproperties {
/* Usage: 7-tuple <usage, CBN, sample_rate,
* width, full_scale, noise_floor, tag>,
* all little-endian u32. Here:
* HIFI, 48 kHz PCM, 16-bit.
*/
mipi-sdca-control-access-mode = <0x0>;
mipi-sdca-control-access-layer = <0x4>;
mipi-sdca-control-cn-list =
/bits/ 64 <0x1>;
mipi-sdca-control-range = [
07 00 01 00 /* 7x1 */
02 00 00 00
D0 02 00 00
80 BB 00 00 /* 48000 */
10 00 00 00 /* 16 */
00 00 00 00
00 00 00 00
00 00 00 00
];
};
/*
* DataPort selector for IT 41 is a 16-col x
* 4-row range where row-0 col-6 = 0x06 (DP6)
* and everything else = 0xFFFFFFFF. 260 raw
* bytes; omitted here.
*/
};
/* -- 0x02: CS 41 (48 kHz clock source) --------- */
mipi-sdca-entity-id-0x2-subproperties {
mipi-sdca-entity-type = <0x0B>; /* CS */
mipi-sdca-entity-label = "CS 41";
mipi-sdca-cs-type = <0x0>;
mipi-sdca-control-list =
/bits/ 64 <0x10000>;
mipi-sdca-control-0x10-subproperties {
/* SampleRateIndex: idx 1 -> 48000 Hz */
mipi-sdca-control-access-mode = <0x5>;
mipi-sdca-control-access-layer = <0x4>;
mipi-sdca-control-cn-list =
/bits/ 64 <0x1>;
mipi-sdca-control-dc-value = <0x1>;
mipi-sdca-control-range = [
02 00 01 00
01 00 00 00 80 BB 00 00
];
};
};
/* -- 0x03: MFPU 21 (multi-source via pin list) - */
mipi-sdca-entity-id-0x3-subproperties {
mipi-sdca-entity-type = <0x22>; /* MFPU */
mipi-sdca-entity-label = "MFPU 21";
/* Input pins 1 and 2 wired */
mipi-sdca-input-pin-list =
/bits/ 64 <0x6>;
mipi-sdca-control-list =
/bits/ 64 <0x2>;
mipi-sdca-input-pin-1 {
mipi-sdca-entity-label = "IT 41";
};
mipi-sdca-input-pin-2 {
mipi-sdca-entity-label = "IT 131";
};
mipi-sdca-control-0x1-subproperties {
/* Bypass = 1 */
mipi-sdca-control-access-mode = <0x5>;
mipi-sdca-control-access-layer = <0x4>;
mipi-sdca-control-cn-list =
/bits/ 64 <0x1>;
mipi-sdca-control-dc-value = <0x1>;
};
};
/* -- 0x07: SU 43 (selector, driven by GE 35) --- */
mipi-sdca-entity-id-0x7-subproperties {
mipi-sdca-entity-type = <0x06>; /* SU */
mipi-sdca-entity-label = "SU 43";
mipi-sdca-input-pin-list =
/bits/ 64 <0x2>;
mipi-sdca-control-list =
/bits/ 64 <0x2>;
mipi-sdca-input-pin-1 {
mipi-sdca-entity-label = "XU 42";
};
mipi-sdca-control-0x1-subproperties {
mipi-sdca-control-access-mode = <0x3>;
/* RO, DEVICE layer -- GE writes it */
mipi-sdca-control-access-layer = <0x10>;
mipi-sdca-control-cn-list =
/bits/ 64 <0x1>;
mipi-sdca-control-range = [
01 00 02 00
00 00 00 00 01 00 00 00
];
};
};
/* -- 0x09: PDE 47 (HPH power domain) ----------- */
mipi-sdca-entity-id-0x9-subproperties {
mipi-sdca-entity-type = <0x11>; /* PDE */
mipi-sdca-entity-label = "PDE 47";
/* Managed IT/OT entity IDs */
mipi-sdca-powerdomain-managed-list = <0xA 0xB>;
/* Delay triplets: <from_ps, to_ps, us> */
mipi-sdca-powerdomain-transition-typical-delay =
<3 0 30000>, <0 3 30000>;
mipi-sdca-powerdomain-transition-max-delay =
<3 0 30000>, <0 3 30000>;
/*
* Bits 1 (REQ_PS), 16 (ACTUAL_PS) plus bits
* 48..53 for six pseudo-controls (0x30..0x35)
* that only exist to anchor HPH OCP/CNP/SURGE
* interrupt virqs. WCD9378 quirk with no ASL
* analogue; a real binding would model these
* via a separate interrupt property, not by
* inventing control selectors.
*/
mipi-sdca-control-list =
/bits/ 64 <0x003F000000010002>;
mipi-sdca-control-0x1-subproperties {
/* Requested_PS -- range PS0 or PS3 */
mipi-sdca-control-access-mode = <0x0>;
mipi-sdca-control-access-layer = <0x4>;
mipi-sdca-control-cn-list =
/bits/ 64 <0x1>;
mipi-sdca-control-range = [
01 00 02 00
00 00 00 00 03 00 00 00
];
};
/* Actual_PS (0x10 RO) + six 0x30..0x35 IRQ
* anchor subnodes omitted */
};
/* -- 0x0A: OT 43 (Headphone jack, no controls) - */
mipi-sdca-entity-id-0xA-subproperties {
mipi-sdca-entity-type = <0x03>; /* OT */
mipi-sdca-entity-label = "OT 43";
mipi-sdca-terminal-type = <0x06C0>;
/* 0x06C0 = HEADPHONE JACK */
mipi-sdca-input-pin-list =
/bits/ 64 <0x2>;
mipi-sdca-control-list = /bits/ 64 <0x0>;
mipi-sdca-input-pin-1 {
mipi-sdca-entity-label = "IT 41";
};
};
/* -- 0x0C: GE 35 (jack detection group) -------- */
mipi-sdca-entity-id-0xC-subproperties {
mipi-sdca-entity-type = <0x12>; /* GE */
mipi-sdca-entity-label = "GE 35";
mipi-sdca-control-list = /bits/ 64 <0x6>;
/*
* Table 18 packed blob:
* u8 mode_count
* per mode: u8 val, u8 ctrl_count
* per ctrl: u8 ent_id, u8 sel, u8 cn,
* u32 val (LE)
*
* The mode 0/1 entries route "unplugged" and
* "unknown" to the same SU45 selector as
* mode 4 (headphone) -- WCD9378 firmware
* workaround, not a spec behaviour.
*/
mipi-sdca-ge-selectedmode-controls-affected = [
04 /* 4 modes */
00 01 08 01 00 01 00 00 00 /* 0 -> SU45 */
01 01 08 01 00 01 00 00 00 /* 1 -> SU45 */
03 01 07 01 00 01 00 00 00 /* 3 -> SU43 */
04 01 08 01 00 01 00 00 00 /* 4 -> SU45 */
];
mipi-sdca-control-0x1-subproperties {
/* SelectedMode: mode -> terminal-type
* range, 2 cols x 4 rows */
mipi-sdca-control-access-mode = <0x0>;
mipi-sdca-control-access-layer = <0x4>;
mipi-sdca-control-cn-list =
/bits/ 64 <0x1>;
mipi-sdca-control-range = [
02 00 04 00
00 00 00 00 C0 06 00 00 /* unplug */
01 00 00 00 C0 06 00 00 /* unknwn */
03 00 00 00 D0 06 00 00 /* h-set */
04 00 00 00 C0 06 00 00 /* h-phon */
];
};
mipi-sdca-control-0x2-subproperties {
/* DetectedMode -- RO, drives SDCA_4 IRQ */
mipi-sdca-control-access-mode = <0x3>;
mipi-sdca-control-access-layer = <0x4>;
mipi-sdca-control-cn-list =
/bits/ 64 <0x1>;
mipi-sdca-control-interrupt-position = <4>;
};
};
/* -- 0x11: FU 33 (mic feature unit, no ctrls) -- */
mipi-sdca-entity-id-0x11-subproperties {
mipi-sdca-entity-type = <0x07>; /* FU */
mipi-sdca-entity-label = "FU 33";
mipi-sdca-input-pin-list =
/bits/ 64 <0x2>;
mipi-sdca-control-list = /bits/ 64 <0x0>;
mipi-sdca-input-pin-1 {
mipi-sdca-entity-label = "IT 33";
};
};
/*
* Remaining entities elided -- IT 131, IT 33,
* PDE 34, XU 42, SU 45, OT 45, CS {131,36,236},
* SU 35, XU 36, OT 36, MFPU 236, OT 236 -- all
* follow one of the shapes shown above.
*/
/* -- Cluster 0x1: stereo HPH render ------------ */
mipi-sdca-cluster-id-0x1-subproperties {
mipi-sdca-channel-count = <2>;
mipi-sdca-channel-1-subproperties {
mipi-sdca-cluster-channel-id = <0x1>;
mipi-sdca-cluster-channel-purpose = <0x1>;
mipi-sdca-cluster-channel-relationship =
<0x2>; /* Left */
};
mipi-sdca-channel-2-subproperties {
mipi-sdca-cluster-channel-id = <0x2>;
mipi-sdca-cluster-channel-purpose = <0x1>;
mipi-sdca-cluster-channel-relationship =
<0x3>; /* Right */
};
};
/*
* Clusters 0x2 (mic mono), 0x3 (opt RX, 3ch) and
* 0x5 (opt TX mono) elided -- same shape.
*/
};
};
};
>
> Thanks,
> Charles
On Fri, Jul 24, 2026 at 03:31:51PM +0100, Srinivas Kandagatla wrote: > On 7/24/26 1:36 PM, Charles Keepax wrote: > > On Thu, Jul 23, 2026 at 02:24:19PM +0100, Srinivas Kandagatla wrote: > >> Thanks Charles, for the feedback. > >> On 7/23/26 11:17 AM, Charles Keepax wrote: > >>> On Thu, Jul 23, 2026 at 12:42:10AM +0100, Srinivas Kandagatla wrote: > > Yeah agree be good to get the DT guys thoughts on this. It seems > > like a misstep to me to insist that the SDCA spec implements a > > completely different system of storing information for DT. SDCA > > is what SDCA is now, and supporting two different parsers seems > > like work no one needs when the one parser we have would work > > fine for both. > Am not sure I understood the two parser concern, what we are > representing in the table is something that sdca core already does after > parsing acpi tables. So we are reusing the same structures. Its like > result of already parsed acpi tables. > > I did try Apologies for not being clear. It wasn't strictly a review comment on the code in the series. It was a wider point that at some point the world likely will want to put SDCA data in DT, when that happens there are basically two choices: 1) Use the "same" representation as ACPI, in this case we can share all the parsing code we have now. But some of the things might be a little unusual for DT. 2) Do something more idiomatic for DT, which would likely end up looking very different. But this would require a whole new parser and lengthy standardisation process. Mostly what I am interested in here is getting at what the end goal is. The impression I got was that really everyone from Plumbers was really more aligned to 2). I am not sure I agree that is the right choice, although willing to be convinced here. > > That said I don't totally object to the idea of an option to > > supply a static block of information as you are in the series. It > > could be useful for transitional and work around situations. But > > it doesn't seem like a good choice for SDCA on DT going forward, > > it is basically going back to the board files that DT was saving > > us from. > > Either we have this at driver level or at dt level, both of them have > pros and cons. > > If we decide to go with dt, this how the dt entries will look like, this > should give fair bit of idea to DT maintianers for discussion. Thank you so much for mocking this up, that is very helpful. Are there additional constraints from your side pushing you one way or another on this? Or are you happy to do either? I am thinking things like DT needing to be flashed onto systems that have now shipped or something. Thanks, Charles
On 7/24/26 4:40 PM, Charles Keepax wrote: > On Fri, Jul 24, 2026 at 03:31:51PM +0100, Srinivas Kandagatla wrote: >> On 7/24/26 1:36 PM, Charles Keepax wrote: >>> On Thu, Jul 23, 2026 at 02:24:19PM +0100, Srinivas Kandagatla wrote: >>>> Thanks Charles, for the feedback. >>>> On 7/23/26 11:17 AM, Charles Keepax wrote: >>>>> On Thu, Jul 23, 2026 at 12:42:10AM +0100, Srinivas Kandagatla wrote: >>> Yeah agree be good to get the DT guys thoughts on this. It seems >>> like a misstep to me to insist that the SDCA spec implements a >>> completely different system of storing information for DT. SDCA >>> is what SDCA is now, and supporting two different parsers seems >>> like work no one needs when the one parser we have would work >>> fine for both. >> Am not sure I understood the two parser concern, what we are >> representing in the table is something that sdca core already does after >> parsing acpi tables. So we are reusing the same structures. Its like >> result of already parsed acpi tables. >> >> I did try > > Apologies for not being clear. It wasn't strictly a review > comment on the code in the series. It was a wider point that at > some point the world likely will want to put SDCA data in DT, > when that happens there are basically two choices: > > 1) Use the "same" representation as ACPI, in this case we can > share all the parsing code we have now. But some of the things > might be a little unusual for DT. > > 2) Do something more idiomatic for DT, which would likely end > up looking very different. But this would require a whole new > parser and lengthy standardisation process. > I'm inclined to go with this approach as well, provided the Device Tree maintainers are satisfied with the initialization sequences. The rest of the topology bindings appears solid. This decision would also establish a precedent for handling other DisCo-based devices in Device Trees. > Mostly what I am interested in here is getting at what the end > goal is. The impression I got was that really everyone from > Plumbers was really more aligned to 2). I am not sure I agree > that is the right choice, although willing to be convinced here. > >>> That said I don't totally object to the idea of an option to >>> supply a static block of information as you are in the series. It >>> could be useful for transitional and work around situations. But >>> it doesn't seem like a good choice for SDCA on DT going forward, >>> it is basically going back to the board files that DT was saving >>> us from. >> >> Either we have this at driver level or at dt level, both of them have >> pros and cons. >> >> If we decide to go with dt, this how the dt entries will look like, this >> should give fair bit of idea to DT maintianers for discussion. > > Thank you so much for mocking this up, that is very helpful. > > Are there additional constraints from your side pushing you > one way or another on this? Or are you happy to do either? I am > thinking things like DT needing to be flashed onto systems that > have now shipped or something. No restrictions as such, its just consensuses with DT maintainers. --srini > > Thanks, > Charles
Hi Srini,
On Thu, 23 Jul 2026 00:42:10 +0100, Srinivas Kandagatla wrote:
> The most obvious follow-up is figuring out how the mobile-mode and
> compute-mode WCD9378 drivers coexist under one compatible. Jorijn's
[...]
> tree without racing to bind the same slave. I would like to line this
> uip with Jorijn as a follow-up to this series.
Happy to line this up. To ground the discussion I ported the series
onto my FP6 tree and have mobile-mode capture working end-to-end
through the class framework, including PipeWire in Plasma — findings
and a proposal below.
1) Arbitration, near term
Your probe already returns -ENODEV when qcom,compute-mode is absent;
v2 of my mobile series will add the mirror check, so neither driver
can bind the other's slaves regardless of probe order. If a single
owner of the modalias is preferred instead, a small wcd9378-common
stub dispatching on the property also works for me — your call.
Either path can later sanity-check the fused mode the way the
downstream driver does (EFUSE_REG_29 PLATFORM_BLOWN, else
PLATFORM_CTL MODE) once register access is up.
One mobile-specific data point for the split: in mobile mode the SDCA
control space is only decoded on the TX slave. On the FP6, a paged
read of DEV_MANU_ID/DEV_PART_ID (0x40100060/0x40100068) via the TX
slave returns 0x0217/0x0110, while the same reads via the RX slave
return zeros — with the RX slave's standard SCP DevID registers
reading fine. That matches the downstream driver, which creates its
only regmap on the TX device and drives the render dataports through
the RX slave. So for mobile RX playback the function control and its
dataports live on *different* slaves; a per-dataport slave mapping
(or similar) would be needed in the class framework for that. Capture
doesn't have this problem — the TX dataports sit on the control
slave, so no cross-slave mapping is needed there.
2) Bindings — one file
Patch 7 adds the same new file as my series
(Documentation/devicetree/bindings/sound/qcom,wcd9378-sdw.yaml), so
one of us should carry a merged version and the other drop it.
Suggestion: the mobile side keeps my v1's tx/rx split shape, with
the v2 changes already committed on my binding thread
(qcom,{tx,rx}-port-mapping staying optional, matching
qcom,wcd938x-sdw.yaml; qcom,{tx,rx}-channel-mapping dropped). The
compute side keeps your qcom,compute-mode if/then, extended to also
cover qcom,port-mapping and #sound-dai-cells. As posted, patch 7's mobile shape wouldn't
validate my mobile DTS: it defines a combined qcom,port-mapping but
the description references qcom,tx/rx-port-mapping, and
#sound-dai-cells is required unconditionally while the mobile DAIs
live on the top-level codec node. I'm happy to carry the merged file
in my v2 so your v2 can drop patch 7 — or the reverse, whichever you
prefer.
3) Prototype findings on patches 1-6 (mobile capture, FP6)
What I ran: your 8 patches on my 7.1.2-based tree, plus a new
wcd9378-sdca-mobile codec registering its own sdw_driver for the TX
slave, static sdca_function_data for the SmartMic0 function
(IT11 -> OT10 on DP1, with PDE11 as the power domain), and hw_ops
doing the vendor bring-up
(micbias routing, bus-clock indication, a clock-stop hold; supplies
stay on the mobile top-level codec node, so hw_init has nothing to
do — that part of the design accommodates the mobile supply model
as-is). Capture works: the card binds, PDE11 reaches PS0 through the
DAPM supply widget, and a 1 kHz tone played from the speakers
captures at ~46% of full scale through the SDCA path. The bus-clock
indication in hw_ops is partly a stopgap: the core path discussed
with Pierre-Louis on my driver thread needs the qcom controller to
set prop.mclk_freq, and that patch is still on my list. The
prototype branch (your series + the mobile codec on a 7.1.2 base) is
at https://forgejo.catcrafts.net/Catcrafts/milos-linux, branch
sdca-mobile, if useful.
Findings:
a) PDM dataports. class_function_sdw_add_peripheral() derives the
SoundWire stream/port config from the host-visible PCM params via
snd_sdw_params_to_config(), but the WCD9378 mic dataports carry
1-bit PDM on a single channel (the working mobile driver programs
sconfig.bps = 1 and port ch_mask = BIT(0)). Result with the
generic path: "bps not matching" from the qcom master and silence
on the capture while the PDE sits happily in PS0. I prototyped
optional per-dataport overrides in sdca_entity_iot
(sdw_bps/sdw_ch_mask) consumed in add_peripheral, which fixed it;
maybe DisCo has a proper home for this, but something is needed
for PDM parts.
b) The IT33 micbias cache-vs-hardware workaround in your patch 8
(drop cache + rewrite from pde_pre_pmu) ported directly to the
mobile part's IT11; I carried it prophylactically and haven't yet
isolated whether mobile strictly needs it. If it does turn out to
be family behavior, it might argue for the class handling
has_default controls on PDE power-up generically.
Userspace needed no changes beyond UCM: the class-driver card works
with a ControlExists conditional in the same profile (the stock
branch of the conditional is the unchanged stock sequence).
On interrupts: sdca_irq_allocate() got a valid IRQ out of the box on
my board via the bus irq domain; I haven't exercised actual SDCA
interrupt delivery (capture doesn't need it), so I can't yet say
whether the INTSTAT dispatch issue in your patch-8 comment reproduces
here.
Longer term: until the framework covers mobile end-to-end (the PDM
transport and the cross-slave RX question), my posted mobile series
stays the working mobile path — the v2 above is about the two
drivers coexisting cleanly in the meantime. Mobile capture converging
on the class framework looks realistic (my static tables came
straight from the posted mobile driver); I'll keep using the FP6 as
the mobile-mode test vehicle for the next revisions.
One dependency note for your platform posting: SDCA register access
on Qualcomm controllers needs the SCP address paging support now in
soundwire next, commit 999f80904763 ("soundwire: qcom: add SCP
address paging support").
One small nit: link [2] in the cover credits "Jorijn Rikhof" — the
surname is van der Graaf.
Thanks,
Jorijn
On 7/23/26 8:40 PM, Jorijn van der Graaf wrote:
> Hi Srini,
>
> On Thu, 23 Jul 2026 00:42:10 +0100, Srinivas Kandagatla wrote:
>> The most obvious follow-up is figuring out how the mobile-mode and
>> compute-mode WCD9378 drivers coexist under one compatible. Jorijn's
> [...]
>> tree without racing to bind the same slave. I would like to line this
>> uip with Jorijn as a follow-up to this series.
>
> Happy to line this up. To ground the discussion I ported the series
> onto my FP6 tree and have mobile-mode capture working end-to-end
> through the class framework, including PipeWire in Plasma — findings
> and a proposal below.
Thanks Jorijn for trying out and confirming that capture works.
>
> 1) Arbitration, near term
>
> Your probe already returns -ENODEV when qcom,compute-mode is absent;
> v2 of my mobile series will add the mirror check, so neither driver
> can bind the other's slaves regardless of probe order. If a single
> owner of the modalias is preferred instead, a small wcd9378-common
> stub dispatching on the property also works for me — your call.
> Either path can later sanity-check the fused mode the way the
> downstream driver does (EFUSE_REG_29 PLATFORM_BLOWN, else
> PLATFORM_CTL MODE) once register access is up.
We need single entry point, if not we will endup with two modalias. Yes
current RFC driver was only tested for compute.
I agree we should have a common so that we can leverage some code from
both modes.
>
> One mobile-specific data point for the split: in mobile mode the SDCA
> control space is only decoded on the TX slave. On the FP6, a paged
> read of DEV_MANU_ID/DEV_PART_ID (0x40100060/0x40100068) via the TX
> slave returns 0x0217/0x0110, while the same reads via the RX slave
That is expected on WCD codecs. only TX has CSR registers space.
RX can not read/write any of the codec register space.
However the soundwire SCP address space is accessible and expected to
set data ports for both tx and rx.
> return zeros — with the RX slave's standard SCP DevID registers
> reading fine. That matches the downstream driver, which creates its
> only regmap on the TX device and drives the render dataports through
> the RX slave. So for mobile RX playback the function control and its
> dataports live on *different* slaves; a per-dataport slave mapping
> (or similar) would be needed in the class framework for that. Capture
> doesn't have this problem — the TX dataports sit on the control
> slave, so no cross-slave mapping is needed there.
>
> 2) Bindings — one file
>
> Patch 7 adds the same new file as my series
> (Documentation/devicetree/bindings/sound/qcom,wcd9378-sdw.yaml), so
> one of us should carry a merged version and the other drop it.
> Suggestion: the mobile side keeps my v1's tx/rx split shape, with
> the v2 changes already committed on my binding thread
> (qcom,{tx,rx}-port-mapping staying optional, matching
> qcom,wcd938x-sdw.yaml; qcom,{tx,rx}-channel-mapping dropped). The
> compute side keeps your qcom,compute-mode if/then, extended to also
> cover qcom,port-mapping and #sound-dai-cells. As posted, patch 7's mobile shape wouldn't
> validate my mobile DTS: it defines a combined qcom,port-mapping but
> the description references qcom,tx/rx-port-mapping, and
> #sound-dai-cells is required unconditionally while the mobile DAIs
> live on the top-level codec node. I'm happy to carry the merged file
> in my v2 so your v2 can drop patch 7 — or the reverse, whichever you
> prefer.
Thanks that would be nice, Also am thinking that we should just have
qcom,port-mapping for both modes and mark one of the device as
qcom,control-device which is tx in mobile case. That way we have some
level of clean bindings that overlap. But I will leave it up to you.
>
> 3) Prototype findings on patches 1-6 (mobile capture, FP6)
>
> What I ran: your 8 patches on my 7.1.2-based tree, plus a new
> wcd9378-sdca-mobile codec registering its own sdw_driver for the TX
> slave, static sdca_function_data for the SmartMic0 function
> (IT11 -> OT10 on DP1, with PDE11 as the power domain), and hw_ops
> doing the vendor bring-up
> (micbias routing, bus-clock indication, a clock-stop hold; supplies
> stay on the mobile top-level codec node, so hw_init has nothing to
> do — that part of the design accommodates the mobile supply model
> as-is). Capture works: the card binds, PDE11 reaches PS0 through the
> DAPM supply widget, and a 1 kHz tone played from the speakers
> captures at ~46% of full scale through the SDCA path. The bus-clock
> indication in hw_ops is partly a stopgap: the core path discussed
> with Pierre-Louis on my driver thread needs the qcom controller to
> set prop.mclk_freq, and that patch is still on my list. The
> prototype branch (your series + the mobile codec on a 7.1.2 base) is
> at https://forgejo.catcrafts.net/Catcrafts/milos-linux, branch
> sdca-mobile, if useful.
Yes, This is definitely an useful experiment, I was trying something
similar with both tx and rx side on mobile mode, things got really
complex because the sdw stream has to be handled by rx codec where as tx
side will be handled by sdca side.. it was really messy.
>
> Findings:
>
> a) PDM dataports. class_function_sdw_add_peripheral() derives the
> SoundWire stream/port config from the host-visible PCM params via
> snd_sdw_params_to_config(), but the WCD9378 mic dataports carry
> 1-bit PDM on a single channel (the working mobile driver programs
> sconfig.bps = 1 and port ch_mask = BIT(0)). Result with the
> generic path: "bps not matching" from the qcom master and silence
> on the capture while the PDE sits happily in PS0. I prototyped
> optional per-dataport overrides in sdca_entity_iot
> (sdw_bps/sdw_ch_mask) consumed in add_peripheral, which fixed it;
> maybe DisCo has a proper home for this, but something is needed
> for PDM parts.
>
> b) The IT33 micbias cache-vs-hardware workaround in your patch 8
> (drop cache + rewrite from pde_pre_pmu) ported directly to the
> mobile part's IT11; I carried it prophylactically and haven't yet
> isolated whether mobile strictly needs it. If it does turn out to
> be family behavior, it might argue for the class handling
> has_default controls on PDE power-up generically.
>
> Userspace needed no changes beyond UCM: the class-driver card works
> with a ControlExists conditional in the same profile (the stock
> branch of the conditional is the unchanged stock sequence).
>
> On interrupts: sdca_irq_allocate() got a valid IRQ out of the box on
> my board via the bus irq domain; I haven't exercised actual SDCA
> interrupt delivery (capture doesn't need it), so I can't yet say
> whether the INTSTAT dispatch issue in your patch-8 comment reproduces
> here.
>
> Longer term: until the framework covers mobile end-to-end (the PDM
> transport and the cross-slave RX question), my posted mobile series
> stays the working mobile path — the v2 above is about the two
> drivers coexisting cleanly in the meantime. Mobile capture converging
> on the class framework looks realistic (my static tables came
> straight from the posted mobile driver); I'll keep using the FP6 as
> the mobile-mode test vehicle for the next revisions.
>
I think you should continue to do the mobile mode driver as it was done
in v1 not think about sdca. Function setup on mobile mode are dynamic
user can set sys_usage based on usecase so the sdca functions will
change, this is not static anymore so its not really worth thinking of
sdca for mobile atm, but we could try to see if we can get some leverage
from sdca helpers.
Sorry for the noise i hope it was a worth experiment on mobile mode.
> One dependency note for your platform posting: SDCA register access
> on Qualcomm controllers needs the SCP address paging support now in
> soundwire next, commit 999f80904763 ("soundwire: qcom: add SCP
> address paging support").
>
> One small nit: link [2] in the cover credits "Jorijn Rikhof" — the
> surname is van der Graaf.
Am really Sorry not sure how I missed that.
--srini
>
> Thanks,
> Jorijn
Hi Srini, On Fri, 24 Jul 2026 13:17:06 +0100, Srinivas Kandagatla wrote: > > Your probe already returns -ENODEV when qcom,compute-mode is absent; > > v2 of my mobile series will add the mirror check, so neither driver > > can bind the other's slaves regardless of probe order. If a single > > owner of the modalias is preferred instead, a small wcd9378-common > > stub dispatching on the property also works for me — your call. > [...] > We need single entry point, if not we will endup with two modalias. Yes > current RFC driver was only tested for compute. > I agree we should have a common so that we can leverage some code from > both modes. Single entry point it is — that replaces the mirror check I had queued above. My v2 will add the common stub instead: one sdw_driver owning the 0x0217/0x0110 ID table, probe dispatching on the DT mode properties (qcom,compute-mode -> compute, otherwise the mobile TX/RX paths), with the compute branch returning -ENODEV until your driver lands. Happy to shape the factoring to whatever slots into your v2 best, and shared code can accumulate in the common module as it shows up. > That is expected on WCD codecs. only TX has CSR registers space. > RX can not read/write any of the codec register space. > However the soundwire SCP address space is accessible and expected to > set data ports for both tx and rx. Thanks, good to have that confirmed. > Thanks that would be nice, Also am thinking that we should just have > qcom,port-mapping for both modes and mark one of the device as > qcom,control-device which is tx in mobile case. That way we have some > level of clean bindings that overlap. But I will leave it up to you. Let's use your shape. The merged file then has a single qcom,port-mapping (still optional, as the wcd938x mappings are) on both slave nodes, and qcom,control-device marking the TX slave in the mobile presentation — the explicit flag takes over the TX/RX discrimination that the split property names provided in my v1, and it doubles as dispatch information for the common stub. Compute-only requirements (#sound-dai-cells on the slave nodes, and whatever else your v2 needs there) go behind if: qcom,compute-mode. I'll carry the merged file in my v2 so your v2 can drop patch 7. > Yes, This is definitely an useful experiment, I was trying something > similar with both tx and rx side on mobile mode, things got really > complex because the sdw stream has to be handled by rx codec where as tx > side will be handled by sdca side.. it was really messy. > [...] > I think you should continue to do the mobile mode driver as it was done > in v1 not think about sdca. Function setup on mobile mode are dynamic > user can set sys_usage based on usecase so the sdca functions will > change, this is not static anymore so its not really worth thinking of > sdca for mobile atm, but we could try to see if we can get some leverage > from sdca helpers. > > Sorry for the noise i hope it was a worth experiment on mobile mode. No noise at all — it answered the RX-slave question and produced the coexistence data above, so it paid for itself. Agreed on the direction: mobile v2 stays the v1 approach, no SDCA; where a class helper fits the mobile driver internals I'll borrow rather than reinvent. I'll leave the sdca-mobile branch up, frozen at the RFC state, for reference. > Am really Sorry not sure how I missed that. No worries. So, concretely: my v2 carries the common entry point, the merged binding as above, and the driver review items already queued from the v1 thread; on your side patch 7 goes away and the compute probe hooks into the stub. I'm spinning v2 next, so the merged binding will be on the list for your v2 to reference. Thanks, Jorijn
© 2016 - 2026 Red Hat, Inc.