Discussion:
ASoC: Device tree binding to dummy codec
j***@gmail.com
2014-07-26 15:18:27 UTC
Permalink
Allwinner CPUs have an on-chip codec that supports line out. This is a
monolithic block that does not implement anything like standard I2S.
We have implemented this by internally making a soc_card and then
binding the DAI to a dummy NOP codec to make ASoC happy.

But now someone wants to add a MAX9768 amplifier which needs a codec
driver to implement volume control.

So how should this be implemented? You want to use simple-audio-card
when the MAX9768 is present.

But what about the dummy-codec case? Using simple-audio-card to bind
to a dummy-codec clutters things up a lot. Plus the dummy-codec is not
currently exposed to device trees.

And then there is the ordering problem, how do I know for sure MAX9768
is not going to be bound so that it is safe to bind to dummy-codec.
Or should binding to MAX9768 simply override a binding to the
dummy-codec?

If my dummy-codec is exposed into the device trees then this generates
a bunch of NOP clutter in the tree using simple-audio-card to bind it.

Another idea, maybe one of those NOP SDPIF codecs could get an alias
name like NOP or Dummy.
--
Jon Smirl
***@gmail.com
Lars-Peter Clausen
2014-07-28 06:24:39 UTC
Permalink
Cc ASoC maintainers.
Post by j***@gmail.com
Allwinner CPUs have an on-chip codec that supports line out. This is a
monolithic block that does not implement anything like standard I2S.
We have implemented this by internally making a soc_card and then
binding the DAI to a dummy NOP codec to make ASoC happy.
But now someone wants to add a MAX9768 amplifier which needs a codec
driver to implement volume control.
So how should this be implemented? You want to use simple-audio-card
when the MAX9768 is present.
But what about the dummy-codec case? Using simple-audio-card to bind
to a dummy-codec clutters things up a lot. Plus the dummy-codec is not
currently exposed to device trees.
And then there is the ordering problem, how do I know for sure MAX9768
is not going to be bound so that it is safe to bind to dummy-codec.
Or should binding to MAX9768 simply override a binding to the
dummy-codec?
If my dummy-codec is exposed into the device trees then this generates
a bunch of NOP clutter in the tree using simple-audio-card to bind it.
Another idea, maybe one of those NOP SDPIF codecs could get an alias
name like NOP or Dummy.
Hi,

The dummy CODEC is a ASoC specific software construct, it should not appear
in the description of the hardware. The reason why ASoC requires CODEC for
successfully instantiate is due its history. When ASoC was initially
designed and implemented your typical embedded audio system had 3 main
components, the DMA, the I2C or AC97 CPU DAI and the CODEC with the CODEC
DAI. And while the ASoC framework as gained support for more configurations
over the years the basic requirement that at least one CODEC is present in
the system has remained. So the correct solution in this case is to adopt
the framework so it can properly support this new class of device it was
previously not designed to handle. I've been working on removing the
requirement that at least one CODEC needs to be present in the system by
moving the abstraction level in the ASoC core to snd_soc_component level.
This is mostly done and the final missing pieces are scheduled for
submission after the next merge window closes.

While this restructuring allows for CODEC-less systems, it does not allow
for DAI-less systems yet. At least if you want to have a PCM device. To
properly support DAI-less systems 3 major pieces are missing:
* Currently the DAIs are entry and exit points of the PCM streams into the
DAPM graph. This needs to be reworked so that there is a native
representation of the PCM device in the DAPM graph which is used as the
entry and exit point instead.
* Support for creating a PCM device without specifying a DAI link. Right now
the only way in ASoC to create a PCM device is by having a DAI link. For
systems without DAIs and DAI links we need an alternative. Preferably the
driver for the on-chip CODEC should be able to create the PCM device itself
since it is basically embedded in its hardware.
* Proper devicetree bindings for this kind of devices

- Lars
Mark Brown
2014-07-28 11:20:55 UTC
Permalink
Post by Lars-Peter Clausen
Cc ASoC maintainers.
Jon, you should really know to CC maintainers.
Post by Lars-Peter Clausen
Post by j***@gmail.com
So how should this be implemented? You want to use simple-audio-card
when the MAX9768 is present.
You do - why? It's not immediately obvious to me that this fits well,
there's a good reason why lots of the functionality there is done as a
library...
Post by Lars-Peter Clausen
While this restructuring allows for CODEC-less systems, it does not allow
for DAI-less systems yet. At least if you want to have a PCM device. To
To be honest I don't see a great need to remove the requirement for a
DAI - even with the CODEC baked into the SoC there will often be some
form of IP separation and the stubbing isn't really the blocker to
supporting anything.
Post by Lars-Peter Clausen
* Support for creating a PCM device without specifying a DAI link. Right now
the only way in ASoC to create a PCM device is by having a DAI link. For
systems without DAIs and DAI links we need an alternative. Preferably the
driver for the on-chip CODEC should be able to create the PCM device itself
since it is basically embedded in its hardware.
Another and probably simpler way of approaching this is to allow more
than one thing in the card to provide DAI links. That meshes better
with DPCM as it stands and sidesteps the need to deal with carrying
digital stream configuration information through DAPM which is where you
end up otherwise since you really want DPCM systems to be able to behave
in a similar way.

A good proportion of these systems do actually seem to have physical I2S
interfaces as well to allow people to change up to a better CODEC if
they want so might actually want to be DPCM systems really.
Post by Lars-Peter Clausen
* Proper devicetree bindings for this kind of devices
What bindings would we have? It should be transparent to device tree
since shouldn't be representing the internals of devices in the device
tree, that's redundant and adds to complication. For device tree we
just want the external connection points of each device to be visible
and that's already handled.

What we do want is better support for building the card up from multiple
sources of data so that all the in-SoC stuff can be done by the drivers
for the components in the SoC instead of requring bits of it to be in
the machine driver as we do curently with DPCM.
j***@gmail.com
2014-07-28 12:54:13 UTC
Permalink
Post by Mark Brown
Post by Lars-Peter Clausen
Cc ASoC maintainers.
Jon, you should really know to CC maintainers.
Are the all CC'd now? I thought the ALSA list was sufficient.

So how do I set this hardware up?

on-chip codec - it is ADC/DAC with FIFIO directly attached. There is
no separate bus. on-chip codec supports things like mic1, mic2, line
in, line out, hp out. Most boards populate only a subset of the jacks.
Right now the device driver makes a dummy codec and internally creates
a card and links everything together.
http://git.elopez.com.ar/linux/src/abc050fbbaa5302b76ac585954cd207961fc9159/sound/soc/sunxi/sunxi-codec.c?at=sunxi-codec

Then someone came along and wanted to add a MAX9768. We're stuck
because the way the driver is built it doesn't support the external
MAX9768 codec driver. MAX9768 is just an amp with I2C control of
volume.

So how should the device tree look for no external amp? Right now
there is just a device node and the driver makes a card/dummy-codec
internally.

How should the device tree look when there is an external amp? Maybe
this amp should just be a chip of the device node?

How should the various jack populations be handled in the device tree?
--
Jon Smirl
***@gmail.com
j***@gmail.com
2014-07-28 13:49:27 UTC
Permalink
Post by j***@gmail.com
Post by Mark Brown
Post by Lars-Peter Clausen
Cc ASoC maintainers.
Jon, you should really know to CC maintainers.
Are the all CC'd now? I thought the ALSA list was sufficient.
So how do I set this hardware up?
on-chip codec - it is ADC/DAC with FIFIO directly attached. There is
no separate bus. on-chip codec supports things like mic1, mic2, line
in, line out, hp out. Most boards populate only a subset of the jacks.
Right now the device driver makes a dummy codec and internally creates
a card and links everything together.
http://git.elopez.com.ar/linux/src/abc050fbbaa5302b76ac585954cd207961fc9159/sound/soc/sunxi/sunxi-codec.c?at=sunxi-codec
Then someone came along and wanted to add a MAX9768. We're stuck
because the way the driver is built it doesn't support the external
MAX9768 codec driver. MAX9768 is just an amp with I2C control of
volume.
So how should the device tree look for no external amp? Right now
there is just a device node and the driver makes a card/dummy-codec
internally.
How should the device tree look when there is an external amp? Maybe
this amp should just be a chip of the device node?
Maybe something like this.....

i2c1: ***@01c2b000 {
pinctrl-names = "default";
pinctrl-0 = <&i2c1_pins_a>;
status = "okay";

max9768: ***@36 {
compatible = "max,9768";
reg = <0x36>;
};
};

codec: ***@01c22c00 {
compatible = "allwinner,sun7i-a20-codec";
reg = <0x01c22c00 0x40>;
interrupts = <0 30 4>;
clocks = <&pll2 0>, <&apb0_gates 0>, <&codec_clk>;
clock-names = "pll", "apb", "codec";
dmas = <&dma 0 19>, <&dma 0 19>;
dma-names = "rx", "tx";
widgets = "Mic1 Jack", "Headphone Jack";
external-amp = <&max9768>
status = "okay";
};

If external amp is missing I just bind to my internal dummy-codec.
Post by j***@gmail.com
How should the various jack populations be handled in the device tree?
--
Jon Smirl
--
Jon Smirl
***@gmail.com
Mark Brown
2014-07-28 16:27:15 UTC
Permalink
Post by j***@gmail.com
compatible = "allwinner,sun7i-a20-codec";
reg = <0x01c22c00 0x40>;
interrupts = <0 30 4>;
clocks = <&pll2 0>, <&apb0_gates 0>, <&codec_clk>;
clock-names = "pll", "apb", "codec";
dmas = <&dma 0 19>, <&dma 0 19>;
dma-names = "rx", "tx";
widgets = "Mic1 Jack", "Headphone Jack";
external-amp = <&max9768>
status = "okay";
};
If external amp is missing I just bind to my internal dummy-codec.
No, the CODEC that's in the device should be there all the time - it's
just the same as connecting an external amp to any other device,
describe the hardware in the SoC the same way all the time and then
connect any attached devices to it.
j***@gmail.com
2014-07-28 16:33:57 UTC
Permalink
Post by Mark Brown
Post by j***@gmail.com
compatible = "allwinner,sun7i-a20-codec";
reg = <0x01c22c00 0x40>;
interrupts = <0 30 4>;
clocks = <&pll2 0>, <&apb0_gates 0>, <&codec_clk>;
clock-names = "pll", "apb", "codec";
dmas = <&dma 0 19>, <&dma 0 19>;
dma-names = "rx", "tx";
widgets = "Mic1 Jack", "Headphone Jack";
external-amp = <&max9768>
status = "okay";
};
If external amp is missing I just bind to my internal dummy-codec.
No, the CODEC that's in the device should be there all the time - it's
just the same as connecting an external amp to any other device,
describe the hardware in the SoC the same way all the time and then
connect any attached devices to it.
Allwinner has named their on-chip audio interface 'codec'. This codec
just has two FIFOs hooked to the DAC/ADC. I coded everything in the
CPU-DAI and left the CODEC-DAI empty.

So what do you want the device tree to look like?
Example with no external amp.
Example with external amp.
--
Jon Smirl
***@gmail.com
Mark Brown
2014-07-28 16:36:45 UTC
Permalink
Post by j***@gmail.com
So what do you want the device tree to look like?
Example with no external amp.
Example with external amp.
To repeat what I said in a previous mail:

| Just the same as any other card - allow a phandle to be provided to the
| amplifier.

| Assuming "jack populations" are DAPM links just do it the same way as
| anything else and use snd_soc_of_parse_audio_routing().
j***@gmail.com
2014-07-28 16:47:09 UTC
Permalink
Post by Mark Brown
Post by j***@gmail.com
So what do you want the device tree to look like?
Example with no external amp.
Example with external amp.
I see the aux binding in soc-core.c
Where is an example of how to use it in a device tree?

None of these are used in a device tree that I can spot..
omap/rx51.c:static struct snd_soc_aux_dev rx51_aux_dev[] = {
omap/rx51.c: .aux_dev = rx51_aux_dev,
omap/rx51.c: .num_aux_devs = ARRAY_SIZE(rx51_aux_dev),
omap/rx51.c: rx51_aux_dev[0].codec_name = NULL;
omap/rx51.c: rx51_aux_dev[0].codec_of_node = dai_node;
samsung/speyside.c:static struct snd_soc_aux_dev speyside_aux_dev[] = {
samsung/speyside.c: .aux_dev = speyside_aux_dev,
samsung/speyside.c: .num_aux_devs = ARRAY_SIZE(speyside_aux_dev),
samsung/neo1973_wm8753.c:static struct snd_soc_aux_dev neo1973_aux_devs[] = {
samsung/neo1973_wm8753.c: .aux_dev = neo1973_aux_devs,
samsung/neo1973_wm8753.c: .num_aux_devs = ARRAY_SIZE(neo1973_aux_devs),
samsung/neo1973_wm8753.c: neo1973.num_aux_devs = 1;
Post by Mark Brown
| Just the same as any other card - allow a phandle to be provided to the
| amplifier.
| Assuming "jack populations" are DAPM links just do it the same way as
| anything else and use snd_soc_of_parse_audio_routing().
--
Jon Smirl
***@gmail.com
Lars-Peter Clausen
2014-07-28 16:49:16 UTC
Permalink
Post by j***@gmail.com
Post by j***@gmail.com
So what do you want the device tree to look like?
Example with no external amp.
Example with external amp.
I see the aux binding in soc-core.c
Where is an example of how to use it in a device tree?
https://lkml.org/lkml/2014/4/28/318

Does pretty much them same though to what you proposed.
Mark Brown
2014-07-28 16:56:14 UTC
Permalink
Post by Lars-Peter Clausen
Post by j***@gmail.com
Where is an example of how to use it in a device tree?
https://lkml.org/lkml/2014/4/28/318
Does pretty much them same though to what you proposed.
Right, the bit I was pointing to as problematic was the comment about
removing the description of the internal CODEC from the card if there
was an external component connected to it.
j***@gmail.com
2014-07-28 16:56:27 UTC
Permalink
Post by Lars-Peter Clausen
Post by j***@gmail.com
Post by j***@gmail.com
So what do you want the device tree to look like?
Example with no external amp.
Example with external amp.
I see the aux binding in soc-core.c
Where is an example of how to use it in a device tree?
https://lkml.org/lkml/2014/4/28/318
Does pretty much them same though to what you proposed.
So devicetree...
external-amp = phandle;

then internally I'll hook it up to the aux_dev instead of replacing my
codec. And yes, codec is not completely empty it has widgets for the
possible output pins.
--
Jon Smirl
***@gmail.com
Mark Brown
2014-07-28 18:28:28 UTC
Permalink
Post by j***@gmail.com
So devicetree...
external-amp = phandle;
then internally I'll hook it up to the aux_dev instead of replacing my
codec. And yes, codec is not completely empty it has widgets for the
possible output pins.
Right, and also allow the user to specify some DAPM links to connect the
amplifier to the CODEC otherwise it'll never get powered on.

Mark Brown
2014-07-28 16:18:23 UTC
Permalink
Post by j***@gmail.com
Post by Mark Brown
Post by Lars-Peter Clausen
Cc ASoC maintainers.
Jon, you should really know to CC maintainers.
Are the all CC'd now? I thought the ALSA list was sufficient.
No, you should always CC maintainers - never assume anything sent only
to a mailing list is going to be seen or read, certainly not with any
degree of promptness.
Post by j***@gmail.com
on-chip codec - it is ADC/DAC with FIFIO directly attached. There is
no separate bus. on-chip codec supports things like mic1, mic2, line
in, line out, hp out. Most boards populate only a subset of the jacks.
Right now the device driver makes a dummy codec and internally creates
a card and links everything together.
http://git.elopez.com.ar/linux/src/abc050fbbaa5302b76ac585954cd207961fc9159/sound/soc/sunxi/sunxi-codec.c?at=sunxi-codec
Then someone came along and wanted to add a MAX9768. We're stuck
because the way the driver is built it doesn't support the external
MAX9768 codec driver. MAX9768 is just an amp with I2C control of
volume.
This doesn't seem hard - just extend the binding for the device/card to
allow auxiliary devices to be specified (the matching code supports
that).
Post by j***@gmail.com
So how should the device tree look for no external amp? Right now
there is just a device node and the driver makes a card/dummy-codec
internally.
Your CODEC shouldn't be a completely dummy one, at a minimum it has some
external pins which need to be described and documented.
Post by j***@gmail.com
How should the device tree look when there is an external amp? Maybe
this amp should just be a chip of the device node?
Just the same as any other card - allow a phandle to be provided to the
amplifier.
Post by j***@gmail.com
How should the various jack populations be handled in the device tree?
Assuming "jack populations" are DAPM links just do it the same way as
anything else and use snd_soc_of_parse_audio_routing().
Loading...