[alsa-devel] ASoC: Device tree binding to dummy codec
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.
Cc ASoC maintainers.
On 07/26/2014 05:18 PM, jonsmirl@gmail.com wrote:
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
On Mon, Jul 28, 2014 at 08:24:39AM +0200, Lars-Peter Clausen wrote:
Cc ASoC maintainers.
Jon, you should really know to CC maintainers.
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...
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:
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.
- 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.
- 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.
On Mon, Jul 28, 2014 at 7:20 AM, Mark Brown broonie@kernel.org wrote:
On Mon, Jul 28, 2014 at 08:24:39AM +0200, Lars-Peter Clausen wrote:
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/...
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?
On Mon, Jul 28, 2014 at 8:54 AM, jonsmirl@gmail.com jonsmirl@gmail.com wrote:
On Mon, Jul 28, 2014 at 7:20 AM, Mark Brown broonie@kernel.org wrote:
On Mon, Jul 28, 2014 at 08:24:39AM +0200, Lars-Peter Clausen wrote:
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/...
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: i2c@01c2b000 { pinctrl-names = "default"; pinctrl-0 = <&i2c1_pins_a>; status = "okay";
max9768: max9768@36 { compatible = "max,9768"; reg = <0x36>; }; };
codec: 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.
How should the various jack populations be handled in the device tree?
-- Jon Smirl jonsmirl@gmail.com
On Mon, Jul 28, 2014 at 09:49:27AM -0400, jonsmirl@gmail.com wrote:
codec: 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.
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.
On Mon, Jul 28, 2014 at 12:27 PM, Mark Brown broonie@kernel.org wrote:
On Mon, Jul 28, 2014 at 09:49:27AM -0400, jonsmirl@gmail.com wrote:
codec: 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.
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.
On Mon, Jul 28, 2014 at 12:33:57PM -0400, jonsmirl@gmail.com wrote:
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().
On Mon, Jul 28, 2014 at 12:36 PM, Mark Brown broonie@kernel.org wrote:
On Mon, Jul 28, 2014 at 12:33:57PM -0400, jonsmirl@gmail.com wrote:
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:
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;
| 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().
On 07/28/2014 06:47 PM, jonsmirl@gmail.com wrote:
On Mon, Jul 28, 2014 at 12:36 PM, Mark Brown broonie@kernel.org wrote:
On Mon, Jul 28, 2014 at 12:33:57PM -0400, jonsmirl@gmail.com wrote:
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:
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.
On Mon, Jul 28, 2014 at 06:49:16PM +0200, Lars-Peter Clausen wrote:
On 07/28/2014 06:47 PM, jonsmirl@gmail.com wrote:
Where is an example of how to use it in a device tree?
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.
On Mon, Jul 28, 2014 at 12:49 PM, Lars-Peter Clausen lars@metafoo.de wrote:
On 07/28/2014 06:47 PM, jonsmirl@gmail.com wrote:
On Mon, Jul 28, 2014 at 12:36 PM, Mark Brown broonie@kernel.org wrote:
On Mon, Jul 28, 2014 at 12:33:57PM -0400, jonsmirl@gmail.com wrote:
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:
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.
On Mon, Jul 28, 2014 at 12:56:27PM -0400, jonsmirl@gmail.com wrote:
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.
On Mon, Jul 28, 2014 at 08:54:13AM -0400, jonsmirl@gmail.com wrote:
On Mon, Jul 28, 2014 at 7:20 AM, Mark Brown broonie@kernel.org wrote:
On Mon, Jul 28, 2014 at 08:24:39AM +0200, Lars-Peter Clausen wrote:
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.
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/...
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).
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.
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.
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().
participants (3)
-
jonsmirl@gmail.com
-
Lars-Peter Clausen
-
Mark Brown