[alsa-devel] ASoC - Support for multiple components
Currently ASoC is designed around a single CODEC and a single platform DMA engine in every sound card instance. This is fine for most embedded devices but current smart phone and STB designs are starting to outgrow this architecture.
I'm currently working on adding ASoC support for multiple different CODECs and Platforms (DMA, Audio Engines) into a single sound card instance. This work will allow ASoC to support N CODECs and N platforms per sound card instance and also allow better integration of audio components from GSM MODEMs, BT, FM transceivers and PCM DSPs.
I've now split each ASoC component (i.e. DMA, CODEC, DAI) into driver and device structures. This now means each ASoC component is a regular kernel device and can have private device data and platform_data. It should also provide better support for open firmware and flattened device tree.
I've CC'ed folks on this mail who have either contributed or maintain ASoC architecture code. Please have a look at your architecture and test if you can. I only have access to OMAP and pxa3xx hardware and as such have only tested the changes on these two architectures only. I'd appreciated anyone else testing on the other architectures too.
The changes are all purely mechanical to component registration and component private data only. However, some architectures (txx9, imx, s3c) required some extra effort to use the device model as they had (to varying degrees) coupled their DMA and DAI code more tightly. The fsl platform also required extra work around the open firmware interface. Grant/Timur do we still need soc-of-simple now that all components are regular devices ?
The code is in my topic/multi-component branch here :-
git://git.kernel.org/pub/scm/linux/kernel/git/lrg/asoc-2.6.git
It's currently a patch for each component for easier review atm but will be rebased into a single commit when it's ready for upstream so it won't break bisect.
If the testing can be done quickly then we can go for 2-6.35 otherwise we are looking at 2.6.36.
Thanks
Liam
Liam Girdwood wrote:
Currently ASoC is designed around a single CODEC and a single platform DMA engine in every sound card instance. This is fine for most embedded devices but current smart phone and STB designs are starting to outgrow this architecture.
I'm currently working on adding ASoC support for multiple different CODECs and Platforms (DMA, Audio Engines) into a single sound card instance. This work will allow ASoC to support N CODECs and N platforms per sound card instance and also allow better integration of audio components from GSM MODEMs, BT, FM transceivers and PCM DSPs.
Yea!
I've now split each ASoC component (i.e. DMA, CODEC, DAI) into driver and device structures. This now means each ASoC component is a regular kernel device and can have private device data and platform_data. It should also provide better support for open firmware and flattened device tree.
Yea!
I've CC'ed folks on this mail who have either contributed or maintain ASoC architecture code. Please have a look at your architecture and test if you can. I only have access to OMAP and pxa3xx hardware and as such have only tested the changes on these two architectures only. I'd appreciated anyone else testing on the other architectures too.
I'll take a look at it this week or next.
The changes are all purely mechanical to component registration and component private data only. However, some architectures (txx9, imx, s3c) required some extra effort to use the device model as they had (to varying degrees) coupled their DMA and DAI code more tightly. The fsl platform also required extra work around the open firmware interface. Grant/Timur do we still need soc-of-simple now that all components are regular devices ?
I've never looked at soc-of-simple before, so I can't say. Obviously, I've never needed it, and I never planned to use it.
The code is in my topic/multi-component branch here :-
git://git.kernel.org/pub/scm/linux/kernel/git/lrg/asoc-2.6.git
It's currently a patch for each component for easier review atm but will be rebased into a single commit when it's ready for upstream so it won't break bisect.
If the testing can be done quickly then we can go for 2-6.35 otherwise we are looking at 2.6.36.
Ok.
On Mon, Apr 19, 2010 at 8:09 AM, Liam Girdwood lrg@slimlogic.co.uk wrote:
Currently ASoC is designed around a single CODEC and a single platform DMA engine in every sound card instance. This is fine for most embedded devices but current smart phone and STB designs are starting to outgrow this architecture.
I'm currently working on adding ASoC support for multiple different CODECs and Platforms (DMA, Audio Engines) into a single sound card instance. This work will allow ASoC to support N CODECs and N platforms per sound card instance and also allow better integration of audio components from GSM MODEMs, BT, FM transceivers and PCM DSPs.
I've now split each ASoC component (i.e. DMA, CODEC, DAI) into driver and device structures. This now means each ASoC component is a regular kernel device and can have private device data and platform_data. It should also provide better support for open firmware and flattened device tree.
I've CC'ed folks on this mail who have either contributed or maintain ASoC architecture code. Please have a look at your architecture and test if you can. I only have access to OMAP and pxa3xx hardware and as such have only tested the changes on these two architectures only. I'd appreciated anyone else testing on the other architectures too.
The changes are all purely mechanical to component registration and component private data only. However, some architectures (txx9, imx, s3c) required some extra effort to use the device model as they had (to varying degrees) coupled their DMA and DAI code more tightly. The fsl platform also required extra work around the open firmware interface. Grant/Timur do we still need soc-of-simple now that all components are regular devices ?
The code is in my topic/multi-component branch here :-
git://git.kernel.org/pub/scm/linux/kernel/git/lrg/asoc-2.6.git
Hi Liam,
This is definitely a step in the right direction. All of the OF ASoC stuff is definitely a hack to work around the lack of separate devices & drivers in the ASoC subsystem. I'll take a look through, but some more information would help a lot. Can you write a description of the device model that you're using for the ASoC linkage? Here are some of the questions I have:
- What bus type is used for codec and platform (dai) device registrations? (okay, 'platform' is really confusing here because of the dual meaning with Linux driver core. I'm going to use 'dai' in this email instead from now on. It might not be the best term, but it at least it isn't ambiguous.) - What does the device hierarchy look like (what is the parent device for each of the codec and devices)? - Related to that, how are things like i2c codecs handled? By rights, there will be an i2c device registered under the i2c bus device for the control interface. How will this relate to the ASoC model? - None of the drivers appear to include struct device_driver; which tells me that they don't use the driver core binding model. How do drivers get bound to devices? Why does the ASoC code create an driver interface instead of using the core code (what does the core code not provide)? - What code is responsible for performing the codec and dai driver registrations?
Thanks, g.
Hi Grant,
On Mon, 2010-04-19 at 09:15 -0600, Grant Likely wrote:
On Mon, Apr 19, 2010 at 8:09 AM, Liam Girdwood lrg@slimlogic.co.uk wrote:
Currently ASoC is designed around a single CODEC and a single platform DMA engine in every sound card instance. This is fine for most embedded devices but current smart phone and STB designs are starting to outgrow this architecture.
I'm currently working on adding ASoC support for multiple different CODECs and Platforms (DMA, Audio Engines) into a single sound card instance. This work will allow ASoC to support N CODECs and N platforms per sound card instance and also allow better integration of audio components from GSM MODEMs, BT, FM transceivers and PCM DSPs.
I've now split each ASoC component (i.e. DMA, CODEC, DAI) into driver and device structures. This now means each ASoC component is a regular kernel device and can have private device data and platform_data. It should also provide better support for open firmware and flattened device tree.
I've CC'ed folks on this mail who have either contributed or maintain ASoC architecture code. Please have a look at your architecture and test if you can. I only have access to OMAP and pxa3xx hardware and as such have only tested the changes on these two architectures only. I'd appreciated anyone else testing on the other architectures too.
The changes are all purely mechanical to component registration and component private data only. However, some architectures (txx9, imx, s3c) required some extra effort to use the device model as they had (to varying degrees) coupled their DMA and DAI code more tightly. The fsl platform also required extra work around the open firmware interface. Grant/Timur do we still need soc-of-simple now that all components are regular devices ?
The code is in my topic/multi-component branch here :-
git://git.kernel.org/pub/scm/linux/kernel/git/lrg/asoc-2.6.git
Hi Liam,
This is definitely a step in the right direction. All of the OF ASoC stuff is definitely a hack to work around the lack of separate devices & drivers in the ASoC subsystem. I'll take a look through, but some more information would help a lot. Can you write a description of the device model that you're using for the ASoC linkage? Here are some of the questions I have:
- What bus type is used for codec and platform (dai) device
registrations? (okay, 'platform' is really confusing here because of the dual meaning with Linux driver core. I'm going to use 'dai' in this email instead from now on. It might not be the best term, but it at least it isn't ambiguous.)
The ASoC 'bus' type hasn't changed with this patch. The fabric/machine driver still describes how the audio card is configured.
- What does the device hierarchy look like (what is the parent device
for each of the codec and devices)?
- Related to that, how are things like i2c codecs handled? By rights,
there will be an i2c device registered under the i2c bus device for the control interface. How will this relate to the ASoC model?
I2C/SPI codecs can now register with the driver core as I2C/SPI drivers. e.g. the I2C/SPI device probe registers the ASoC device :-
struct snd_soc_codec_driver soc_codec_dev_wm8731 = { .name = "WM8731", .probe = wm8731_probe, .remove = wm8731_remove, .suspend = wm8731_suspend, .resume = wm8731_resume, .owner = THIS_MODULE, .set_bias_level = wm8731_set_bias_level, .reg_cache_size = sizeof(wm8731_reg), .reg_cache_default = wm8731_reg, }; EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731);
#if defined(CONFIG_SPI_MASTER) static int __devinit wm8731_spi_probe(struct spi_device *spi) { struct wm8731_priv *wm8731; int ret;
wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); if (wm8731 == NULL) return -ENOMEM;
wm8731->control_data = spi; wm8731->control_type = SND_SOC_SPI; spi_set_drvdata(spi, wm8731);
ret = snd_soc_register_codec(&spi->dev, spi->chip_select, &soc_codec_dev_wm8731, &wm8731_dai, 1); if (ret < 0) kfree(wm8731); return ret; }
static int __devexit wm8731_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev, spi->chip_select); kfree(spi_get_drvdata(spi)); return 0; }
static struct spi_driver wm8731_spi_driver = { .driver = { .name = "wm8731", .bus = &spi_bus_type, .owner = THIS_MODULE, }, .probe = wm8731_spi_probe, .remove = __devexit_p(wm8731_spi_remove), }; #endif /* CONFIG_SPI_MASTER */
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) static __devinit int wm8731_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct wm8731_priv *wm8731; int ret;
wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); if (wm8731 == NULL) return -ENOMEM;
i2c_set_clientdata(i2c, wm8731); wm8731->control_data = i2c; wm8731->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c->dev, i2c->addr, &soc_codec_dev_wm8731, &wm8731_dai, 1); if (ret < 0) kfree(wm8731); return ret; }
static __devexit int wm8731_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev, client->addr); kfree(i2c_get_clientdata(client)); return 0; }
static const struct i2c_device_id wm8731_i2c_id[] = { { "wm8731", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id);
static struct i2c_driver wm8731_i2c_driver = { .driver = { .name = "WM8731 I2C Codec", .owner = THIS_MODULE, }, .probe = wm8731_i2c_probe, .remove = __devexit_p(wm8731_i2c_remove), .id_table = wm8731_i2c_id, }; #endif
static int __init wm8731_modinit(void) { int ret = 0; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) ret = i2c_add_driver(&wm8731_i2c_driver); if (ret != 0) { printk(KERN_ERR "Failed to register WM8731 I2C driver: %d\n", ret); } #endif #if defined(CONFIG_SPI_MASTER) ret = spi_register_driver(&wm8731_spi_driver); if (ret != 0) { printk(KERN_ERR "Failed to register WM8731 SPI driver: %d\n", ret); } #endif return ret; } module_init(wm8731_modinit);
static void __exit wm8731_exit(void) { #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) i2c_del_driver(&wm8731_i2c_driver); #endif #if defined(CONFIG_SPI_MASTER) spi_unregister_driver(&wm8731_spi_driver); #endif } module_exit(wm8731_exit);
So the arch/board driver would register an I2C/SPI device for the codec (with any platform data) and initiate the I2C/SPI codec probe(). This in turn registers the ASoC component device with the ASoC core so it can be asoc_probed() when it's sibling component devices are registered (the last part is pretty much the same as the current version). The only difference now is that our component is a core device and passes in it's device upon ASoC component registration.
- None of the drivers appear to include struct device_driver; which
tells me that they don't use the driver core binding model. How do drivers get bound to devices? Why does the ASoC code create an driver interface instead of using the core code (what does the core code not provide)?
ASoC doesn't fully use the driver model for components in this changeset (or at all) due to the complex relationships between the individual components for probing() and for control of PM operations (i.e. we cant have pops and clicks at suspend).
This is not to say ASoC wont use the full driver model for components in the future. This work is an important step on the way to achieving this aim.
- What code is responsible for performing the codec and dai driver
registrations?
Please see above WM8713 codec driver code snippet for full use.
int snd_soc_register_codec(struct device *dev, int id, struct snd_soc_codec_driver *codec_drv, struct snd_soc_dai_driver *dai_drv, int num_dai); void snd_soc_unregister_codec(struct device *dev, int id);
Registers and unregisters our codec and DAI devices. It also registers the codec and DAI ASoC 'driver' too.
Liam
On Mon, Apr 19, 2010 at 05:25:14PM +0100, Liam Girdwood wrote:
On Mon, 2010-04-19 at 09:15 -0600, Grant Likely wrote:
- Related to that, how are things like i2c codecs handled? By rights,
there will be an i2c device registered under the i2c bus device for the control interface. How will this relate to the ASoC model?
I2C/SPI codecs can now register with the driver core as I2C/SPI drivers. e.g. the I2C/SPI device probe registers the ASoC device :-
This is very similar to the current code structurally, from the driver point of view the main change here is that it's now become mandatory to use device model style stuff. This means that there's not much to be scared about if your drivers are using that already, though soc_of_simple never got converted.
- None of the drivers appear to include struct device_driver; which
tells me that they don't use the driver core binding model. How do drivers get bound to devices? Why does the ASoC code create an driver interface instead of using the core code (what does the core code not provide)?
ASoC doesn't fully use the driver model for components in this changeset (or at all) due to the complex relationships between the individual components for probing() and for control of PM operations (i.e. we cant have pops and clicks at suspend).
This is not to say ASoC wont use the full driver model for components in the future. This work is an important step on the way to achieving this aim.
The ordering requirements here mean this is a *very* open question. Linus just nacked a bunch of stuff for 2.6.34 which would have added some ability to waiting for components to probe stuff that things like ASoC would need to use the driver core fully. At the minute subsystems like ASoC which are built up of components that don't have much to do with each other have to do something like ASoC is doing and waiting for all the components to come online before bringing the subsystem level devices up.
Again, this isn't much change from a driver point of view from the situation in 2.6.34, it's more moving forward to making it mandatory and taking advantage of the features that can be brought than anything else.
On Tue, 2010-04-20 at 02:14 +0900, Mark Brown wrote:
On Mon, Apr 19, 2010 at 05:25:14PM +0100, Liam Girdwood wrote:
ASoC doesn't fully use the driver model for components in this changeset (or at all) due to the complex relationships between the individual components for probing() and for control of PM operations (i.e. we cant have pops and clicks at suspend).
This is not to say ASoC wont use the full driver model for components in the future. This work is an important step on the way to achieving this aim.
The ordering requirements here mean this is a *very* open question. Linus just nacked a bunch of stuff for 2.6.34 which would have added some ability to waiting for components to probe stuff that things like ASoC would need to use the driver core fully. At the minute subsystems like ASoC which are built up of components that don't have much to do with each other have to do something like ASoC is doing and waiting for all the components to come online before bringing the subsystem level devices up.
Heh - I wasn't volunteering to make the changes in driver core to support this myself, but was planning to wait for someone else to do something acceptable for Linus here ;)
Liam
On Mon, Apr 19, 2010 at 09:15:49AM -0600, Grant Likely wrote:
This is definitely a step in the right direction. All of the OF ASoC stuff is definitely a hack to work around the lack of separate devices & drivers in the ASoC subsystem. I'll take a look through, but some
Note that as I've mentioned to you before it's been possible to do device model registration of ASoC drivers for about a year now - Timur's drivers show an example of doing that with OpenFirmware. The changes Liam has done are more working towards taking advantage of this to add new features.
Hi,
On Monday 19 April 2010 17:09:04 ext Liam Girdwood wrote:
Currently ASoC is designed around a single CODEC and a single platform DMA engine in every sound card instance. This is fine for most embedded devices but current smart phone and STB designs are starting to outgrow this architecture.
I'm currently working on adding ASoC support for multiple different CODECs and Platforms (DMA, Audio Engines) into a single sound card instance. This work will allow ASoC to support N CODECs and N platforms per sound card instance and also allow better integration of audio components from GSM MODEMs, BT, FM transceivers and PCM DSPs.
I've now split each ASoC component (i.e. DMA, CODEC, DAI) into driver and device structures. This now means each ASoC component is a regular kernel device and can have private device data and platform_data. It should also provide better support for open firmware and flattened device tree.
Really nice!
I've CC'ed folks on this mail who have either contributed or maintain ASoC architecture code. Please have a look at your architecture and test if you can. I only have access to OMAP and pxa3xx hardware and as such have only tested the changes on these two architectures only. I'd appreciated anyone else testing on the other architectures too.
Just a side note: you missed the OMAP PCM/McBSP folks from the CC: Jarkko, and me ;) I'll add Jarkko to the cc...
The changes are all purely mechanical to component registration and component private data only. However, some architectures (txx9, imx, s3c) required some extra effort to use the device model as they had (to varying degrees) coupled their DMA and DAI code more tightly. The fsl platform also required extra work around the open firmware interface. Grant/Timur do we still need soc-of-simple now that all components are regular devices ?
I have one question: How the overlapping kcontrol names are going to handled (plain kcontrol and DAPM widget names)? What will happen if let say you have wm8711 _and_ wm8731 in the same card? Both have: "Master Playback Volume", "Master Playback ZC Switch" in snd_kcontrol_new, and also LOUT, ROUT, LHPOUT, RHPOUT, and SND_SOC_DAPM_MIXER("Output Mixer",..) in snd_soc_dapm_widget.
How the user will see these in one card?
The code is in my topic/multi-component branch here :-
git://git.kernel.org/pub/scm/linux/kernel/git/lrg/asoc-2.6.git
It's currently a patch for each component for easier review atm but will be rebased into a single commit when it's ready for upstream so it won't break bisect.
If the testing can be done quickly then we can go for 2-6.35 otherwise we are looking at 2.6.36.
Thanks
Liam
On Tue, 2010-04-20 at 10:17 +0300, Peter Ujfalusi wrote:
I've CC'ed folks on this mail who have either contributed or maintain ASoC architecture code. Please have a look at your architecture and test if you can. I only have access to OMAP and pxa3xx hardware and as such have only tested the changes on these two architectures only. I'd appreciated anyone else testing on the other architectures too.
Just a side note: you missed the OMAP PCM/McBSP folks from the CC: Jarkko, and me ;) I'll add Jarkko to the cc...
Oops, sorry about that.
The changes are all purely mechanical to component registration and component private data only. However, some architectures (txx9, imx, s3c) required some extra effort to use the device model as they had (to varying degrees) coupled their DMA and DAI code more tightly. The fsl platform also required extra work around the open firmware interface. Grant/Timur do we still need soc-of-simple now that all components are regular devices ?
I have one question: How the overlapping kcontrol names are going to handled (plain kcontrol and DAPM widget names)? What will happen if let say you have wm8711 _and_ wm8731 in the same card? Both have: "Master Playback Volume", "Master Playback ZC Switch" in snd_kcontrol_new, and also LOUT, ROUT, LHPOUT, RHPOUT, and SND_SOC_DAPM_MIXER("Output Mixer",..) in snd_soc_dapm_widget.
How the user will see these in one card?
A subsequent patch will add an ID qualifier to kcontrol names and DAPM widget names. So we can have things like "Master Playback Volume.0" and "Master Playback Volume.1" to differentiate the two separate controls.
Liam
On Tuesday 20 April 2010 13:46:07 ext Liam Girdwood wrote:
I have one question: How the overlapping kcontrol names are going to handled (plain kcontrol and DAPM widget names)? What will happen if let say you have wm8711 _and_ wm8731 in the same card? Both have: "Master Playback Volume", "Master Playback ZC Switch" in snd_kcontrol_new, and also LOUT, ROUT, LHPOUT, RHPOUT, and SND_SOC_DAPM_MIXER("Output Mixer",..) in snd_soc_dapm_widget.
How the user will see these in one card?
A subsequent patch will add an ID qualifier to kcontrol names and DAPM widget names. So we can have things like "Master Playback Volume.0" and "Master Playback Volume.1" to differentiate the two separate controls.
I see. How these IDs will be added? Will does are given by the core automatically based on device load order, or will the machine driver have the ability to specify the ID for a codec?
Another question: how the PCM interfaces will be seen when we have multiple codec/dai in a card? I suppose we will have multiple PCMs in a card, when we have multiple codec (multiple dai pairs)..?
Liam
On Wed, 2010-04-21 at 08:53 +0300, Peter Ujfalusi wrote:
On Tuesday 20 April 2010 13:46:07 ext Liam Girdwood wrote:
I have one question: How the overlapping kcontrol names are going to handled (plain kcontrol and DAPM widget names)? What will happen if let say you have wm8711 _and_ wm8731 in the same card? Both have: "Master Playback Volume", "Master Playback ZC Switch" in snd_kcontrol_new, and also LOUT, ROUT, LHPOUT, RHPOUT, and SND_SOC_DAPM_MIXER("Output Mixer",..) in snd_soc_dapm_widget.
How the user will see these in one card?
A subsequent patch will add an ID qualifier to kcontrol names and DAPM widget names. So we can have things like "Master Playback Volume.0" and "Master Playback Volume.1" to differentiate the two separate controls.
I see. How these IDs will be added? Will does are given by the core automatically based on device load order, or will the machine driver have the ability to specify the ID for a codec?
The machine driver will be able to specify the ID.
Another question: how the PCM interfaces will be seen when we have multiple codec/dai in a card? I suppose we will have multiple PCMs in a card, when we have multiple codec (multiple dai pairs)..?
Yes, that's correct. We already support many cards with multiple PCMs atm. e.g. some WM9713 based cards already support 3 PCMs - 1 HiFi, 1 voice and 1 System.
Liam
On Wed, Apr 21, 2010 at 08:18:46AM +0100, Liam Girdwood wrote:
On Wed, 2010-04-21 at 08:53 +0300, Peter Ujfalusi wrote:
I see. How these IDs will be added? Will does are given by the core automatically based on device load order, or will the machine driver have the ability to specify the ID for a codec?
The machine driver will be able to specify the ID.
I guess for the default we could do something like sort by the dev_name() of the CODEC or something.
Another question: how the PCM interfaces will be seen when we have multiple codec/dai in a card? I suppose we will have multiple PCMs in a card, when we have multiple codec (multiple dai pairs)..?
Yes, that's correct. We already support many cards with multiple PCMs atm. e.g. some WM9713 based cards already support 3 PCMs - 1 HiFi, 1 voice and 1 System.
Pandora is another example in mainline.
On Tue, Apr 20, 2010 at 11:46:07AM +0100, Liam Girdwood wrote:
On Tue, 2010-04-20 at 10:17 +0300, Peter Ujfalusi wrote:
How the user will see these in one card?
A subsequent patch will add an ID qualifier to kcontrol names and DAPM widget names. So we can have things like "Master Playback Volume.0" and "Master Playback Volume.1" to differentiate the two separate controls.
It occurs to me that we probably want something a bit more flexible here than just a numeric ID - most of the use cases for having more than one of the same device are for things like 5.1 or dual speaker amps for stereo where it'd be much more convenient to have the machine driver be able to add text based prefixes to the control names (eg, "Left" and "Right").
On Mon, 2010-04-26 at 11:49 +0100, Mark Brown wrote:
On Tue, Apr 20, 2010 at 11:46:07AM +0100, Liam Girdwood wrote:
On Tue, 2010-04-20 at 10:17 +0300, Peter Ujfalusi wrote:
How the user will see these in one card?
A subsequent patch will add an ID qualifier to kcontrol names and DAPM widget names. So we can have things like "Master Playback Volume.0" and "Master Playback Volume.1" to differentiate the two separate controls.
It occurs to me that we probably want something a bit more flexible here than just a numeric ID - most of the use cases for having more than one of the same device are for things like 5.1 or dual speaker amps for stereo where it'd be much more convenient to have the machine driver be able to add text based prefixes to the control names (eg, "Left" and "Right").
So I think here we can have an optional 'identifier' that could be used to describe the intended use case better (like the "Left" and "Right" above). If the string ID is not supplied we can revert back to the number or nothing at all i.e. if the system is a simple single codec design.
Liam
On Mon, Apr 26, 2010 at 12:17:27PM +0100, Liam Girdwood wrote:
So I think here we can have an optional 'identifier' that could be used to describe the intended use case better (like the "Left" and "Right" above). If the string ID is not supplied we can revert back to the number or nothing at all i.e. if the system is a simple single codec design.
Yes, that was pretty much what I was thinking. Or use the deV_name() instead of the number, I guess.
On Mon, Apr 26, 2010 at 5:49 AM, Mark Brown broonie@opensource.wolfsonmicro.com wrote:
It occurs to me that we probably want something a bit more flexible here than just a numeric ID - most of the use cases for having more than one of the same device are for things like 5.1 or dual speaker amps for stereo where it'd be much more convenient to have the machine driver be able to add text based prefixes to the control names (eg, "Left" and "Right").
How about instead of a string + id, we just have a string, and then define a convention for various devices. For instance, the codec could be "name@bus-addr", so my cs4270 driver would register something like "cs4270@0-004f".
On Mon, Apr 26, 2010 at 07:05:41AM -0500, Timur Tabi wrote:
On Mon, Apr 26, 2010 at 5:49 AM, Mark Brown
It occurs to me that we probably want something a bit more flexible here than just a numeric ID - most of the use cases for having more than one of the same device are for things like 5.1 or dual speaker amps for stereo where it'd be much more convenient to have the machine driver be able to add text based prefixes to the control names (eg, "Left" and "Right").
How about instead of a string + id, we just have a string, and then define a convention for various devices. For instance, the codec could be "name@bus-addr", so my cs4270 driver would register something like "cs4270@0-004f".
Well, we already have a struct device for the actual chip so we can just dev_name() away. The problem is presenting the results to userspace in a useful fashion.
On Mon, Apr 19, 2010 at 9:09 AM, Liam Girdwood lrg@slimlogic.co.uk wrote:
I've CC'ed folks on this mail who have either contributed or maintain ASoC architecture code. Please have a look at your architecture and test if you can. I only have access to OMAP and pxa3xx hardware and as such have only tested the changes on these two architectures only. I'd appreciated anyone else testing on the other architectures too.
A few things:
First, you probably need to add this:
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 38d94d7..c2df201 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1364,8 +1364,10 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) soc_bind_dai_link(card, i);
/* bind completed ? */ - if (card->num_rtd != card->num_links) + if (card->num_rtd != card->num_links) { + mutex_unlock(&card->mutex); return; + }
/* card bind complete so register a sound card */ ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, @@ -1373,6 +1375,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) if (ret < 0) { printk(KERN_ERR "asoc: can't create sound card for card %s\n", card->name); + mutex_unlock(&card->mutex); return; } card->snd_card->dev = card->dev;
Secondly, I'm seeing this when I turn on debugging:
Cirrus Logic CS4270 ALSA SoC Codec Driver cs4270 0-004f: found device at i2c address 4F cs4270 0-004f: hardware revision 3 cs4270 0-004f: codec register CS4270 79 cs4270 0-004f: dai register cs4270 0 Registered DAI 'cs4270.0' Registered codec 'CS4270.79' ...
soc-audio soc-audio: CODEC CS4270 not registered
Does this mean that my fabric driver should be looking for "CS4270.79" instead of just "CS4270"?
On Wed, Apr 21, 2010 at 4:07 PM, Timur Tabi timur@freescale.com wrote:
Cirrus Logic CS4270 ALSA SoC Codec Driver cs4270 0-004f: found device at i2c address 4F cs4270 0-004f: hardware revision 3 cs4270 0-004f: codec register CS4270 79 cs4270 0-004f: dai register cs4270 0 Registered DAI 'cs4270.0' Registered codec 'CS4270.79' ...
soc-audio soc-audio: CODEC CS4270 not registered
Does this mean that my fabric driver should be looking for "CS4270.79" instead of just "CS4270"?
Ok, I figured out the solution. I need to add this to mpc8610_hpcd_probe():
+ iprop = of_get_property(codec_np, "reg", NULL); + if (!iprop) { + dev_err(&ofdev->dev, "codec node is missing 'reg' property\n"); + goto error; + } + machine_data->dai.codec_id = *iprop;
So I have another question. Currently, I need to do this:
machine_data->dai.codec_dai_drv = &cs4270_dai; /* The codec_dai we want */
In other words, I still need to have a global variable in my codec driver called "cs4270_dai" that the fabric driver has to access. This is a real problem because it means that my fabric driver has to be hard-coded with the information on the codec that's attached to the SSI. However, I already have that information in the device tree, I can extract all the information I need from the device tree. If I can get rid of the assignment of "cs4270_dai", I can make my machine driver completely codec-independent.
On Wed, 2010-04-21 at 17:13 -0500, Timur Tabi wrote:
On Wed, Apr 21, 2010 at 4:07 PM, Timur Tabi timur@freescale.com wrote:
Cirrus Logic CS4270 ALSA SoC Codec Driver cs4270 0-004f: found device at i2c address 4F cs4270 0-004f: hardware revision 3 cs4270 0-004f: codec register CS4270 79 cs4270 0-004f: dai register cs4270 0 Registered DAI 'cs4270.0' Registered codec 'CS4270.79' ...
soc-audio soc-audio: CODEC CS4270 not registered
Does this mean that my fabric driver should be looking for "CS4270.79" instead of just "CS4270"?
I've appended a component ID to each instantiated ASoC component to distinguish similar/same component types from each other. e.g. consider a board with two CS4270 codecs. The component ID used here is unique to the device and is either the platform_device ID, I2C address or SPI chip select. Although, it doesn't really matter what the ID source is as long as it's unique to that device.
Ok, I figured out the solution. I need to add this to mpc8610_hpcd_probe():
iprop = of_get_property(codec_np, "reg", NULL);
if (!iprop) {
dev_err(&ofdev->dev, "codec node is missing 'reg' property\n");
goto error;
}
machine_data->dai.codec_id = *iprop;
Applied.
So I have another question. Currently, I need to do this:
machine_data->dai.codec_dai_drv = &cs4270_dai; /* The codec_dai we want */
In other words, I still need to have a global variable in my codec driver called "cs4270_dai" that the fabric driver has to access. This is a real problem because it means that my fabric driver has to be hard-coded with the information on the codec that's attached to the SSI. However, I already have that information in the device tree, I can extract all the information I need from the device tree. If I can get rid of the assignment of "cs4270_dai", I can make my machine driver completely codec-independent.
The use of ID here is to deprecate the passing in of the 'driver' struct so it can be removed in a subsequent patch. I'm trying to make the changes as small as possible here, but let me see how much difference changing this now will make to the current patch size.
Liam
Liam Girdwood wrote:
The use of ID here is to deprecate the passing in of the 'driver' struct so it can be removed in a subsequent patch. I'm trying to make the changes as small as possible here, but let me see how much difference changing this now will make to the current patch size.
I'd be okay if you did this work later, if it turns out to be too onerous.
On Wed, 2010-04-21 at 16:07 -0500, Timur Tabi wrote:
On Mon, Apr 19, 2010 at 9:09 AM, Liam Girdwood lrg@slimlogic.co.uk wrote:
I've CC'ed folks on this mail who have either contributed or maintain ASoC architecture code. Please have a look at your architecture and test if you can. I only have access to OMAP and pxa3xx hardware and as such have only tested the changes on these two architectures only. I'd appreciated anyone else testing on the other architectures too.
A few things:
First, you probably need to add this:
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 38d94d7..c2df201 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1364,8 +1364,10 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) soc_bind_dai_link(card, i);
/* bind completed ? */
if (card->num_rtd != card->num_links)
if (card->num_rtd != card->num_links) {
mutex_unlock(&card->mutex); return;
} /* card bind complete so register a sound card */ ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
@@ -1373,6 +1375,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) if (ret < 0) { printk(KERN_ERR "asoc: can't create sound card for card %s\n", card->name);
mutex_unlock(&card->mutex); return; } card->snd_card->dev = card->dev;
Thanks, applied. I guess this got lost in a rebase.
Liam
participants (5)
-
Grant Likely
-
Liam Girdwood
-
Mark Brown
-
Peter Ujfalusi
-
Timur Tabi