alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
* ASoC and a codec that can't be controlled
@ 2007-05-22 15:47 Timur Tabi
  2007-05-23 15:37 ` Liam Girdwood
  0 siblings, 1 reply; 22+ messages in thread
From: Timur Tabi @ 2007-05-22 15:47 UTC (permalink / raw)
  To: alsa-devel

I'm working on some ASoC drivers for a new board, and we're using a CS4270.  The CS4270 is 
interesting in that if it is connected in stand-alone mode, there is no way to configure 
it.  The board wirings determine all the parameters.

Therefore, my CS4270 codec driver will probably be very skimpy.

My question is: does this mean that my cs4270.c file will *never* call these functions:

snd_ctl_add
snd_soc_cnew
snd_soc_dapm_new_control
snd_soc_dapm_connect_input
snd_soc_dapm_new_widgets

These are the functions used to add new controls and widgets.

So how does ALSA know that it needs to call my I2S driver *instead* of my codec driver to 
do stuff like change volume?

-- 
Timur Tabi
Linux Kernel Developer @ Freescale

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: ASoC and a codec that can't be controlled
  2007-05-22 15:47 ASoC and a codec that can't be controlled Timur Tabi
@ 2007-05-23 15:37 ` Liam Girdwood
  2007-05-25 20:17   ` Timur Tabi
  0 siblings, 1 reply; 22+ messages in thread
From: Liam Girdwood @ 2007-05-23 15:37 UTC (permalink / raw)
  To: Timur Tabi; +Cc: alsa-devel

On Tue, 2007-05-22 at 10:47 -0500, Timur Tabi wrote:
> I'm working on some ASoC drivers for a new board, and we're using a CS4270.  The CS4270 is 
> interesting in that if it is connected in stand-alone mode, there is no way to configure 
> it.  The board wirings determine all the parameters.
> 
> Therefore, my CS4270 codec driver will probably be very skimpy.
> 
> My question is: does this mean that my cs4270.c file will *never* call these functions:
> 
> snd_ctl_add
> snd_soc_cnew

These functions are only required in the codec driver to change volume,
mixer settings etc. If your codec has no volume or mixers then you don't
need them.


> snd_soc_dapm_new_control
> snd_soc_dapm_connect_input
> snd_soc_dapm_new_widgets

These are used for setting up the dynamic audio power management and
won't be needed in stand alone mode.

> 
> These are the functions used to add new controls and widgets.
> 
> So how does ALSA know that it needs to call my I2S driver *instead* of my codec driver to 
> do stuff like change volume?

You probably want to create a volume kcontrol in your I2S driver. I
assume your I2S controller can digitally adjust the volume by altering
the PCM stream ? The kcontrols can be added in your I2S driver probe
function.


Liam

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: ASoC and a codec that can't be controlled
  2007-05-23 15:37 ` Liam Girdwood
@ 2007-05-25 20:17   ` Timur Tabi
  2007-05-28 12:10     ` Liam Girdwood
  0 siblings, 1 reply; 22+ messages in thread
From: Timur Tabi @ 2007-05-25 20:17 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: alsa-devel

Liam Girdwood wrote:

> These are used for setting up the dynamic audio power management and
> won't be needed in stand alone mode.

So if I don't care about power management, can I completely ignore anything with "dapm" in it?

Also, do I need a codec driver at all, even if I can't control the codec?  That is, can I 
do stuff like this:

static struct snd_soc_device mysoc_snd_devdata = {
	.machine = &snd_soc_machine_mysoc,
	.platform = &mysoc_soc_platform,
};

static struct snd_soc_dai_link mpc8610hpcd_dai = {
	.name = "CS4270",
	.stream_name = "CS4270",
	.cpu_dai = &mysoc_i2s_dai,
	.init = mpc8610hpcd_machine_init,
	.ops = &mpc8610hpcd_ops,
};

?

-- 
Timur Tabi
Linux Kernel Developer @ Freescale

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: ASoC and a codec that can't be controlled
  2007-05-25 20:17   ` Timur Tabi
@ 2007-05-28 12:10     ` Liam Girdwood
  2007-05-29  0:18       ` Timur Tabi
                         ` (3 more replies)
  0 siblings, 4 replies; 22+ messages in thread
From: Liam Girdwood @ 2007-05-28 12:10 UTC (permalink / raw)
  To: Timur Tabi; +Cc: alsa-devel

On Fri, 2007-05-25 at 15:17 -0500, Timur Tabi wrote:
> Liam Girdwood wrote:
> 
> > These are used for setting up the dynamic audio power management and
> > won't be needed in stand alone mode.
> 
> So if I don't care about power management, can I completely ignore anything with "dapm" in it?

Yes.

> 
> Also, do I need a codec driver at all, even if I can't control the codec?  That is, can I 
> do stuff like this:
> 
> static struct snd_soc_device mysoc_snd_devdata = {
> 	.machine = &snd_soc_machine_mysoc,
> 	.platform = &mysoc_soc_platform,
> };
> 
> static struct snd_soc_dai_link mpc8610hpcd_dai = {
> 	.name = "CS4270",
> 	.stream_name = "CS4270",
> 	.cpu_dai = &mysoc_i2s_dai,
> 	.init = mpc8610hpcd_machine_init,
> 	.ops = &mpc8610hpcd_ops,
> };

Yes, although my feeling is that a codec "driver" would still be needed
to define the capabilities of your codec within the audio subsystem.

e.g. supported sample rates, interface formats, etc

Liam

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: ASoC and a codec that can't be controlled
  2007-05-28 12:10     ` Liam Girdwood
@ 2007-05-29  0:18       ` Timur Tabi
  2007-05-29  8:53         ` Liam Girdwood
  2007-05-29 18:47       ` Timur Tabi
                         ` (2 subsequent siblings)
  3 siblings, 1 reply; 22+ messages in thread
From: Timur Tabi @ 2007-05-29  0:18 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: alsa-devel

Liam Girdwood wrote:

> Yes, although my feeling is that a codec "driver" would still be needed
> to define the capabilities of your codec within the audio subsystem.
> 
> e.g. supported sample rates, interface formats, etc

I'm curious - why would the codec driver dictate all that?  On my board, the sample rates are determined by the I2S controller, not the codec, because in order to change the sample rate, I program new divisors into the I2S controller's registers.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: ASoC and a codec that can't be controlled
  2007-05-29  0:18       ` Timur Tabi
@ 2007-05-29  8:53         ` Liam Girdwood
  2007-05-29 18:10           ` Timur Tabi
  0 siblings, 1 reply; 22+ messages in thread
From: Liam Girdwood @ 2007-05-29  8:53 UTC (permalink / raw)
  To: Timur Tabi; +Cc: alsa-devel

On Mon, 2007-05-28 at 19:18 -0500, Timur Tabi wrote:
> Liam Girdwood wrote:
> 
> > Yes, although my feeling is that a codec "driver" would still be needed
> > to define the capabilities of your codec within the audio subsystem.
> > 
> > e.g. supported sample rates, interface formats, etc
> 
> I'm curious - why would the codec driver dictate all that?  On my board, the sample rates are determined by the I2S controller, not the codec, because in order to change the sample rate, I program new divisors into the I2S controller's registers.


Some codecs can only support a small range of sample rates e.g. 8k &
48k, whilst your controller may support more. This just makes sure the
audio is set a rate the codec can handle, otherwise audio quality will
probably suffer.

Liam

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: ASoC and a codec that can't be controlled
  2007-05-29  8:53         ` Liam Girdwood
@ 2007-05-29 18:10           ` Timur Tabi
  2007-05-30 12:28             ` Liam Girdwood
  0 siblings, 1 reply; 22+ messages in thread
From: Timur Tabi @ 2007-05-29 18:10 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: alsa-devel

Liam Girdwood wrote:

> Some codecs can only support a small range of sample rates e.g. 8k &
> 48k, whilst your controller may support more. This just makes sure the
> audio is set a rate the codec can handle, otherwise audio quality will
> probably suffer.

What about boards where the codec does *not* dictate the available sample rates?  That is, 
what if the SOC can't generate the frequencies necessary to drive the codec at all the 
rates it supports?  The codec driver would then need to be told by the machine driver 
which sample rates are going to be used.  When the codec driver is initialized, it needs 
to set the snd_soc_codec.dai field to point to the codec's DAI, and that structure 
contains the list of supported sample rates.

I guess in the PowerPC world, the codec driver can query the codec node in the device 
tree, but ideally there would need to be some standard interface.

-- 
Timur Tabi
Linux Kernel Developer @ Freescale

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: ASoC and a codec that can't be controlled
  2007-05-28 12:10     ` Liam Girdwood
  2007-05-29  0:18       ` Timur Tabi
@ 2007-05-29 18:47       ` Timur Tabi
  2007-05-30 12:20         ` Liam Girdwood
  2007-05-29 19:02       ` Timur Tabi
  2007-05-29 23:05       ` Timur Tabi
  3 siblings, 1 reply; 22+ messages in thread
From: Timur Tabi @ 2007-05-29 18:47 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: alsa-devel

Liam Girdwood wrote:
> On Fri, 2007-05-25 at 15:17 -0500, Timur Tabi wrote:
>> Liam Girdwood wrote:
>>
>>> These are used for setting up the dynamic audio power management and
>>> won't be needed in stand alone mode.
>> So if I don't care about power management, can I completely ignore anything with "dapm" in it?
> 
> Yes.
> 
>> Also, do I need a codec driver at all, even if I can't control the codec?  That is, can I 
>> do stuff like this:
>>
>> static struct snd_soc_device mysoc_snd_devdata = {
>> 	.machine = &snd_soc_machine_mysoc,
>> 	.platform = &mysoc_soc_platform,
>> };
>>
>> static struct snd_soc_dai_link mpc8610hpcd_dai = {
>> 	.name = "CS4270",
>> 	.stream_name = "CS4270",
>> 	.cpu_dai = &mysoc_i2s_dai,
>> 	.init = mpc8610hpcd_machine_init,
>> 	.ops = &mpc8610hpcd_ops,
>> };
> 
> Yes, although my feeling is that a codec "driver" would still be needed
> to define the capabilities of your codec within the audio subsystem.

Another question:

Why do I need to specify the codec DAI in two different structures?

eti_b1_wm8731.c:

static struct snd_soc_dai_link eti_b1_dai = {
	.name = "WM8731",
	.stream_name = "WM8731",
	.cpu_dai = &at91_i2s_dai[1],
	.codec_dai = &wm8731_dai,	<----
	.init = eti_b1_wm8731_init,
	.ops = &eti_b1_ops,
};

wm8731.c:

static int wm8731_init(struct snd_soc_device *socdev)
{
	struct snd_soc_codec *codec = socdev->codec;
...
	int reg, ret = 0;

	codec->dai = &wm8731_dai;	<-----

-- 
Timur Tabi
Linux Kernel Developer @ Freescale

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: ASoC and a codec that can't be controlled
  2007-05-28 12:10     ` Liam Girdwood
  2007-05-29  0:18       ` Timur Tabi
  2007-05-29 18:47       ` Timur Tabi
@ 2007-05-29 19:02       ` Timur Tabi
       [not found]         ` <1180529741.29590.54.camel@a10072.wolfsonmicro.main>
  2007-05-29 23:05       ` Timur Tabi
  3 siblings, 1 reply; 22+ messages in thread
From: Timur Tabi @ 2007-05-29 19:02 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: alsa-devel

Liam Girdwood wrote:

> Yes, although my feeling is that a codec "driver" would still be needed
> to define the capabilities of your codec within the audio subsystem.

Another question:

Why is it the codec driver that calls snd_soc_new_pcms()?  Shouldn't the PCM driver be 
doing that?

Looking in snd_soc_new_pcms() itself, I see this:

	codec->card = snd_card_new(idx, xid, codec->owner, 0);

Here we create a new "sound card", and we assign it to the

I guess I just don't understand why the codec driver is acting like the "master" driver of 
ASOC.  IMHO, the codec driver should be doing two things:

1) Specifying the capabilities of the codec hardware itself, without any assumption that 
these capabilities dictate the capabilities of the system as a whole (e.g. the codec 
shouldn't assume that the system supports every sampling rate that the codec does).
2) Providing APIs for controlling the codec.

ASOC and the machine driver should then work in tandem to decide which driver will do what 
and which capabilities are *actually* supported.  *Something* needs to look at the entire 
system and say to each device, "Well, yes, I know about this little feature of yours, but 
we're just not going to support that today."

-- 
Timur Tabi
Linux Kernel Developer @ Freescale

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: ASoC and a codec that can't be controlled
  2007-05-28 12:10     ` Liam Girdwood
                         ` (2 preceding siblings ...)
  2007-05-29 19:02       ` Timur Tabi
@ 2007-05-29 23:05       ` Timur Tabi
  2007-05-30 13:06         ` Liam Girdwood
  3 siblings, 1 reply; 22+ messages in thread
From: Timur Tabi @ 2007-05-29 23:05 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: alsa-devel

Liam Girdwood wrote:

> Yes, although my feeling is that a codec "driver" would still be needed
> to define the capabilities of your codec within the audio subsystem.

Ok, I just noticed this:

at91-i2s.c:

#define AT91_I2S_RATES (SNDRV_PCM_RATE_8000  | SNDRV_PCM_RATE_11025 |\
			SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
			SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
			SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
			SNDRV_PCM_RATE_96000)

struct snd_soc_cpu_dai at91_i2s_dai[NUM_SSC_DEVICES] = {
	{	.name = "at91_ssc0/i2s",
		.id = 0,
		.type = SND_SOC_DAI_I2S,
		.suspend = at91_i2s_suspend,
		.resume = at91_i2s_resume,
		.playback = {
			.channels_min = 1,
			.channels_max = 2,
			.rates = AT91_I2S_RATES,
			.formats = SNDRV_PCM_FMTBIT_S16_LE,},
		.capture = {
			.channels_min = 1,
			.channels_max = 2,
			.rates = AT91_I2S_RATES,
			.formats = SNDRV_PCM_FMTBIT_S16_LE,},

wm8731.c:

#define WM8731_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
		SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
		SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
		SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
		SNDRV_PCM_RATE_96000)

#define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
	SNDRV_PCM_FMTBIT_S24_LE)

struct snd_soc_codec_dai wm8731_dai = {
	.name = "WM8731",
	.playback = {
		.stream_name = "Playback",
		.channels_min = 1,
		.channels_max = 2,
		.rates = WM8731_RATES,
		.formats = WM8731_FORMATS,},
	.capture = {
		.stream_name = "Capture",
		.channels_min = 1,
		.channels_max = 2,
		.rates = WM8731_RATES,
		.formats = WM8731_FORMATS,},

So does this mean that ALSA looks at the rate and format capabilities of the I2S interface 
and the codec, and then only chooses ones that both support?

Also, what does it mean for the codec to support little-endian?  On PowerPC, all registers 
are big-endian, so my version of at91-i2s.c has to have SNDRV_PCM_FMTBIT_S24_BE.

Your codec driver says it's little-endian.  But the I2S standard is serial, so endianness 
doesn't apply.  Yet if I say the codec is little-endian, but the I2S interface is 
big-endian, how can ALSA resolve that?

-- 
Timur Tabi
Linux Kernel Developer @ Freescale

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: ASoC and a codec that can't be controlled
  2007-05-29 18:47       ` Timur Tabi
@ 2007-05-30 12:20         ` Liam Girdwood
  0 siblings, 0 replies; 22+ messages in thread
From: Liam Girdwood @ 2007-05-30 12:20 UTC (permalink / raw)
  To: Timur Tabi; +Cc: alsa-devel

On Tue, 2007-05-29 at 13:47 -0500, Timur Tabi wrote:
> Liam Girdwood wrote:
> > On Fri, 2007-05-25 at 15:17 -0500, Timur Tabi wrote:
> >> Liam Girdwood wrote:
> >>
> >>> These are used for setting up the dynamic audio power management and
> >>> won't be needed in stand alone mode.
> >> So if I don't care about power management, can I completely ignore anything with "dapm" in it?
> > 
> > Yes.
> > 
> >> Also, do I need a codec driver at all, even if I can't control the codec?  That is, can I 
> >> do stuff like this:
> >>
> >> static struct snd_soc_device mysoc_snd_devdata = {
> >> 	.machine = &snd_soc_machine_mysoc,
> >> 	.platform = &mysoc_soc_platform,
> >> };
> >>
> >> static struct snd_soc_dai_link mpc8610hpcd_dai = {
> >> 	.name = "CS4270",
> >> 	.stream_name = "CS4270",
> >> 	.cpu_dai = &mysoc_i2s_dai,
> >> 	.init = mpc8610hpcd_machine_init,
> >> 	.ops = &mpc8610hpcd_ops,
> >> };
> > 
> > Yes, although my feeling is that a codec "driver" would still be needed
> > to define the capabilities of your codec within the audio subsystem.
> 
> Another question:
> 
> Why do I need to specify the codec DAI in two different structures?
> 
> eti_b1_wm8731.c:
> 
> static struct snd_soc_dai_link eti_b1_dai = {
> 	.name = "WM8731",
> 	.stream_name = "WM8731",
> 	.cpu_dai = &at91_i2s_dai[1],
> 	.codec_dai = &wm8731_dai,	<----
> 	.init = eti_b1_wm8731_init,
> 	.ops = &eti_b1_ops,
> };
> 
> wm8731.c:
> 
> static int wm8731_init(struct snd_soc_device *socdev)
> {
> 	struct snd_soc_codec *codec = socdev->codec;
> ...
> 	int reg, ret = 0;
> 
> 	codec->dai = &wm8731_dai;	<-----
> 

Looks like some naming confusion on my part here, so his probably needs
a little refactoring in the codec struct.  

The codec struct contains a pointer to _all_ the digital audio
interfaces it supports (e.g. some codecs support more than 1 DAI),
whilst the link struct contains a mapping between codec interface n and
SoC interface n. In this example the WM8731 only has 1 DAI, so it does
look like duplication.

I'll refactor this in a future patch.

Liam

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: ASoC and a codec that can't be controlled
  2007-05-29 18:10           ` Timur Tabi
@ 2007-05-30 12:28             ` Liam Girdwood
  0 siblings, 0 replies; 22+ messages in thread
From: Liam Girdwood @ 2007-05-30 12:28 UTC (permalink / raw)
  To: Timur Tabi; +Cc: alsa-devel

On Tue, 2007-05-29 at 13:10 -0500, Timur Tabi wrote:
> Liam Girdwood wrote:
> 
> > Some codecs can only support a small range of sample rates e.g. 8k &
> > 48k, whilst your controller may support more. This just makes sure the
> > audio is set a rate the codec can handle, otherwise audio quality will
> > probably suffer.
> 
> What about boards where the codec does *not* dictate the available sample rates?  That is, 
> what if the SOC can't generate the frequencies necessary to drive the codec at all the 
> rates it supports?  The codec driver would then need to be told by the machine driver 
> which sample rates are going to be used.  When the codec driver is initialized, it needs 
> to set the snd_soc_codec.dai field to point to the codec's DAI, and that structure 
> contains the list of supported sample rates.
> 

ASoC creates a bitmask of supported sample rates from the DMA, I2S
controller and codec and then AND's them together. It then checks the
requested rate, etc against this bitmask before proceeding. This way the
whole audio system dictates the supported rate and not any single
component.

Liam

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: ASoC and a codec that can't be controlled
  2007-05-29 23:05       ` Timur Tabi
@ 2007-05-30 13:06         ` Liam Girdwood
  2007-05-30 15:46           ` Timur Tabi
  0 siblings, 1 reply; 22+ messages in thread
From: Liam Girdwood @ 2007-05-30 13:06 UTC (permalink / raw)
  To: Timur Tabi; +Cc: alsa-devel

On Tue, 2007-05-29 at 18:05 -0500, Timur Tabi wrote:
> Liam Girdwood wrote:
> 
> > Yes, although my feeling is that a codec "driver" would still be needed
> > to define the capabilities of your codec within the audio subsystem.
> 
> Ok, I just noticed this:
> 
> at91-i2s.c:
> 
> #define AT91_I2S_RATES (SNDRV_PCM_RATE_8000  | SNDRV_PCM_RATE_11025 |\
> 			SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
> 			SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
> 			SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
> 			SNDRV_PCM_RATE_96000)
> 
> struct snd_soc_cpu_dai at91_i2s_dai[NUM_SSC_DEVICES] = {
> 	{	.name = "at91_ssc0/i2s",
> 		.id = 0,
> 		.type = SND_SOC_DAI_I2S,
> 		.suspend = at91_i2s_suspend,
> 		.resume = at91_i2s_resume,
> 		.playback = {
> 			.channels_min = 1,
> 			.channels_max = 2,
> 			.rates = AT91_I2S_RATES,
> 			.formats = SNDRV_PCM_FMTBIT_S16_LE,},
> 		.capture = {
> 			.channels_min = 1,
> 			.channels_max = 2,
> 			.rates = AT91_I2S_RATES,
> 			.formats = SNDRV_PCM_FMTBIT_S16_LE,},
> 
> wm8731.c:
> 
> #define WM8731_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
> 		SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
> 		SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
> 		SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
> 		SNDRV_PCM_RATE_96000)
> 
> #define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
> 	SNDRV_PCM_FMTBIT_S24_LE)
> 
> struct snd_soc_codec_dai wm8731_dai = {
> 	.name = "WM8731",
> 	.playback = {
> 		.stream_name = "Playback",
> 		.channels_min = 1,
> 		.channels_max = 2,
> 		.rates = WM8731_RATES,
> 		.formats = WM8731_FORMATS,},
> 	.capture = {
> 		.stream_name = "Capture",
> 		.channels_min = 1,
> 		.channels_max = 2,
> 		.rates = WM8731_RATES,
> 		.formats = WM8731_FORMATS,},
> 
> So does this mean that ALSA looks at the rate and format capabilities of the I2S interface 
> and the codec, and then only chooses ones that both support?
> 

Yes.

> Also, what does it mean for the codec to support little-endian?  On PowerPC, all registers 
> are big-endian, so my version of at91-i2s.c has to have SNDRV_PCM_FMTBIT_S24_BE.
> 
> Your codec driver says it's little-endian.  But the I2S standard is serial, so endianness 
> doesn't apply.  Yet if I say the codec is little-endian, but the I2S interface is 
> big-endian, how can ALSA resolve that?
> 

This was added as some controllers and codecs can shift out data in
different formats (e.g. LSB or MSB first). It's only really used atm for
data size (e.g. 16, 24 bits) as the endianess is currently not dealt
with correctly. I've logged bug :-

https://bugtrack.alsa-project.org/alsa-bug/view.php?id=3132

Fwiw, you should be ok in the mean time as most audio data is stored on
file in little endian format. Your media player should open such little
endian files as *_LE when it configures the ALSA pcm. This should work
if your I2S, DMA and codec are marked as supporting LE formats.

Liam

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: ASoC and a codec that can't be controlled
  2007-05-30 13:06         ` Liam Girdwood
@ 2007-05-30 15:46           ` Timur Tabi
  2007-05-31 17:32             ` Liam Girdwood
  0 siblings, 1 reply; 22+ messages in thread
From: Timur Tabi @ 2007-05-30 15:46 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: alsa-devel

Liam Girdwood wrote:

> Fwiw, you should be ok in the mean time as most audio data is stored on
> file in little endian format. Your media player should open such little
> endian files as *_LE when it configures the ALSA pcm. This should work
> if your I2S, DMA and codec are marked as supporting LE formats.

What about this snippet in asound.h:

#ifdef  __LITTLE_ENDIAN
#define SNDRV_LITTLE_ENDIAN
#else
#ifdef __BIG_ENDIAN
#define SNDRV_BIG_ENDIAN

...

#ifdef SNDRV_LITTLE_ENDIAN
#define	SNDRV_PCM_FORMAT_S16		SNDRV_PCM_FORMAT_S16_LE
#define	SNDRV_PCM_FORMAT_U16		SNDRV_PCM_FORMAT_U16_LE
#define	SNDRV_PCM_FORMAT_S24		SNDRV_PCM_FORMAT_S24_LE
...
#endif
#ifdef SNDRV_BIG_ENDIAN
#define	SNDRV_PCM_FORMAT_S16		SNDRV_PCM_FORMAT_S16_BE
#define	SNDRV_PCM_FORMAT_U16		SNDRV_PCM_FORMAT_U16_BE
#define	SNDRV_PCM_FORMAT_S24		SNDRV_PCM_FORMAT_S24_BE
...
#endif

I could then do this:

#define CS4270_FORMATS SNDRV_PCM_FMTBIT_S24

On big-endian platforms like mine, CS4270_FORMATS will be SNDRV_PCM_FORMAT_S24_BE and on 
little-endian platforms it will be SNDRV_PCM_FORMAT_S24_LE.  Assuming the I2S registers 
are the same endian as the platform, will this work?

If not, then what about this:

#define CS4270_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)

That would tell ALSA that the CS4270 supports both formats, which isn't technically true, 
but it wouldn't matter because the I2S interface is what determines the actual 
"endianness" of the serial data.

-- 
Timur Tabi
Linux Kernel Developer @ Freescale

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: ASoC and a codec that can't be controlled
       [not found]         ` <1180529741.29590.54.camel@a10072.wolfsonmicro.main>
@ 2007-05-30 18:10           ` Timur Tabi
  2007-05-31 17:19             ` Liam Girdwood
  0 siblings, 1 reply; 22+ messages in thread
From: Timur Tabi @ 2007-05-30 18:10 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: alsa-devel

Liam Girdwood wrote:

>> I guess I just don't understand why the codec driver is acting like the "master" driver of 
>> ASOC.  IMHO, the codec driver should be doing two things:
> 
> I guess this is due to an ordering issue we had during early
> development. We had to make sure that the I2C probe of the codec
> succeeded before registering the card, pcms, etc. Fwiw, I do intend to
> address this in future versions (I should probably add a road map to the
> wiki now).

In that case, I think we can solve this problem as well as the PowerPC device tree problem 
in one shot, because they're basically the same problem.

Anyway, let me see if I get this right:

1. The first function called is eti_b1_init().
2. eti_b1_init() calls platform_device_add() to add an soc-audio class device and register 
the eti_b1_snd_devdata structure.
3. The registration causes a number of things to happen, one of which is a call to 
soc_probe().
4. soc_probe() sees that the snd_soc_machine_eti_b1.probe is NULL, so that part is skipped.
3. soc_probe() sees that snd_soc_machine_eti_b1.dai_link->cpu_dai->probe is also NULL, so 
that part is skipped. (eti_b1_snd_devdata.machine == snd_soc_machine_eti_b1)
4. soc_probe() sees that soc_codec_dev_wm8731.probe is not NULL, so it calls wm8731_probe().
5. wm8731_probe() registers an I2C driver.
6. The I2C class driver calls wm8731_i2c_driver.attach_adapter, which is wm8731_i2c_attach().
7. wm8731_i2c_attach() calls i2c_probe(), which in turn calls wm8731_codec_probe()
8. wm8731_codec_probe() allocates a snd_soc_codec structure.
8. wm8731_codec_probe() calls wm8731_init().

This means that if there is no I2C support, wm8731_init() will never be called.

9. wm8731_init() initializes the snd_soc_codec structure.

Question: why doesn't wm8731_probe() initialize the non-I2C parts of the snd_soc_codec 
structure?  For example, snd_soc_codec.dai, snd_soc_codec.name, and snd_soc_codec.owner? 
That way, the snd_soc_codec structure will be properly initialized even when there's no I2C.

10. wm8731_init() calls snd_soc_new_pcms.
11. wm8731_init() exits, wm8731_codec_probe() exits, wm8731_i2c_attach() exits, and then 
wm8731_probe() exits.  Control returns to soc_probe().
12. soc_probe() notices that eti_b1_snd_devdata.platform.probe is NULL, so it skips that.

Question: why don't you define a function for at91_soc_platform.probe, and in that 
function you can call snd_soc_new_pcms()?  That way, you guarantee the codec driver's I2C 
interface is initialized before snd_soc_new_pcms() is called, and you avoid have PCM calls 
in the codec driver.

>> ASOC and the machine driver should then work in tandem to decide which driver will do what 
>> and which capabilities are *actually* supported.  *Something* needs to look at the entire 
>> system and say to each device, "Well, yes, I know about this little feature of yours, but 
>> we're just not going to support that today."
>>
> 
> The machine driver pretty much already does this. It can override valid
> hardware configurations and return -EINVAl if required. 

Do you have an example of that?  Would that be eti_b1_hw_params()?

-- 
Timur Tabi
Linux Kernel Developer @ Freescale

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: ASoC and a codec that can't be controlled
  2007-05-30 18:10           ` Timur Tabi
@ 2007-05-31 17:19             ` Liam Girdwood
  2007-05-31 19:49               ` Timur Tabi
  2007-06-01 21:34               ` Timur Tabi
  0 siblings, 2 replies; 22+ messages in thread
From: Liam Girdwood @ 2007-05-31 17:19 UTC (permalink / raw)
  To: Timur Tabi; +Cc: alsa-devel

On Wed, 2007-05-30 at 13:10 -0500, Timur Tabi wrote:
> Liam Girdwood wrote:
> 
> >> I guess I just don't understand why the codec driver is acting like the "master" driver of 
> >> ASOC.  IMHO, the codec driver should be doing two things:
> > 
> > I guess this is due to an ordering issue we had during early
> > development. We had to make sure that the I2C probe of the codec
> > succeeded before registering the card, pcms, etc. Fwiw, I do intend to
> > address this in future versions (I should probably add a road map to the
> > wiki now).
> 

Wiki roadmap now added.

https://bugtrack.alsa-project.org/wiki/wikka.php?wakka=ASoCRoadMap

> In that case, I think we can solve this problem as well as the PowerPC device tree problem 
> in one shot, because they're basically the same problem.
> 
> Anyway, let me see if I get this right:
> 
> 1. The first function called is eti_b1_init().
> 2. eti_b1_init() calls platform_device_add() to add an soc-audio class device and register 
> the eti_b1_snd_devdata structure.
> 3. The registration causes a number of things to happen, one of which is a call to 
> soc_probe().
> 4. soc_probe() sees that the snd_soc_machine_eti_b1.probe is NULL, so that part is skipped.
> 3. soc_probe() sees that snd_soc_machine_eti_b1.dai_link->cpu_dai->probe is also NULL, so 
> that part is skipped. (eti_b1_snd_devdata.machine == snd_soc_machine_eti_b1)
> 4. soc_probe() sees that soc_codec_dev_wm8731.probe is not NULL, so it calls wm8731_probe().
> 5. wm8731_probe() registers an I2C driver.
> 6. The I2C class driver calls wm8731_i2c_driver.attach_adapter, which is wm8731_i2c_attach().
> 7. wm8731_i2c_attach() calls i2c_probe(), which in turn calls wm8731_codec_probe()
> 8. wm8731_codec_probe() allocates a snd_soc_codec structure.
> 8. wm8731_codec_probe() calls wm8731_init().
> 
> This means that if there is no I2C support, wm8731_init() will never be called.
> 
> 9. wm8731_init() initializes the snd_soc_codec structure.
> 
> Question: why doesn't wm8731_probe() initialize the non-I2C parts of the snd_soc_codec 
> structure?  For example, snd_soc_codec.dai, snd_soc_codec.name, and snd_soc_codec.owner? 
> That way, the snd_soc_codec structure will be properly initialized even when there's no I2C.
> 

This codec only supports I2C, so it shouldn't matter too much. But it
would be better for codecs using other IO mechanisms.

> 10. wm8731_init() calls snd_soc_new_pcms.
> 11. wm8731_init() exits, wm8731_codec_probe() exits, wm8731_i2c_attach() exits, and then 
> wm8731_probe() exits.  Control returns to soc_probe().
> 12. soc_probe() notices that eti_b1_snd_devdata.platform.probe is NULL, so it skips that.
> 
> Question: why don't you define a function for at91_soc_platform.probe, and in that 
> function you can call snd_soc_new_pcms()?  That way, you guarantee the codec driver's I2C 
> interface is initialized before snd_soc_new_pcms() is called, and you avoid have PCM calls 
> in the codec driver.
> 

I think the best place to call snd_soc_new_pcms is in the machine
driver. This means we don't have to add any pcms that are not used. 

> >> ASOC and the machine driver should then work in tandem to decide which driver will do what 
> >> and which capabilities are *actually* supported.  *Something* needs to look at the entire 
> >> system and say to each device, "Well, yes, I know about this little feature of yours, but 
> >> we're just not going to support that today."
> >>
> > 
> > The machine driver pretty much already does this. It can override valid
> > hardware configurations and return -EINVAl if required. 
> 
> Do you have an example of that?  Would that be eti_b1_hw_params()?

Yes, the hw_params could return error on anything the machine didn't
like. e.g. this could be used to workaround quirks. 

Liam

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: ASoC and a codec that can't be controlled
  2007-05-30 15:46           ` Timur Tabi
@ 2007-05-31 17:32             ` Liam Girdwood
  2007-05-31 18:55               ` Timur Tabi
  0 siblings, 1 reply; 22+ messages in thread
From: Liam Girdwood @ 2007-05-31 17:32 UTC (permalink / raw)
  To: Timur Tabi; +Cc: alsa-devel

On Wed, 2007-05-30 at 10:46 -0500, Timur Tabi wrote:
> Liam Girdwood wrote:
> 
> > Fwiw, you should be ok in the mean time as most audio data is stored on
> > file in little endian format. Your media player should open such little
> > endian files as *_LE when it configures the ALSA pcm. This should work
> > if your I2S, DMA and codec are marked as supporting LE formats.
> 
> What about this snippet in asound.h:
> 
> #ifdef  __LITTLE_ENDIAN
> #define SNDRV_LITTLE_ENDIAN
> #else
> #ifdef __BIG_ENDIAN
> #define SNDRV_BIG_ENDIAN
> 
> ...
> 
> #ifdef SNDRV_LITTLE_ENDIAN
> #define	SNDRV_PCM_FORMAT_S16		SNDRV_PCM_FORMAT_S16_LE
> #define	SNDRV_PCM_FORMAT_U16		SNDRV_PCM_FORMAT_U16_LE
> #define	SNDRV_PCM_FORMAT_S24		SNDRV_PCM_FORMAT_S24_LE
> ...
> #endif
> #ifdef SNDRV_BIG_ENDIAN
> #define	SNDRV_PCM_FORMAT_S16		SNDRV_PCM_FORMAT_S16_BE
> #define	SNDRV_PCM_FORMAT_U16		SNDRV_PCM_FORMAT_U16_BE
> #define	SNDRV_PCM_FORMAT_S24		SNDRV_PCM_FORMAT_S24_BE
> ...
> #endif
> 
> I could then do this:
> 
> #define CS4270_FORMATS SNDRV_PCM_FMTBIT_S24

I'll fix this in the core so we don't need to do this. Please use _LE
atm.

> 
> On big-endian platforms like mine, CS4270_FORMATS will be SNDRV_PCM_FORMAT_S24_BE and on 
> little-endian platforms it will be SNDRV_PCM_FORMAT_S24_LE.  Assuming the I2S registers 
> are the same endian as the platform, will this work?
> 

I think this probably depends on how your audio FIFO's align the data
received from memory/DMA.  They should do any bit reordering based on
the audio format, and size etc set in the control register. (Although,
ymmv.)


> If not, then what about this:
> 
> #define CS4270_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)
> 
> That would tell ALSA that the CS4270 supports both formats, which isn't technically true, 
> but it wouldn't matter because the I2S interface is what determines the actual 
> "endianness" of the serial data.
> 

This looks fine as a workaround atm, I'll try and have a look at this
bug tomorrow so we don't need to do this.

Liam

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: ASoC and a codec that can't be controlled
  2007-05-31 17:32             ` Liam Girdwood
@ 2007-05-31 18:55               ` Timur Tabi
  0 siblings, 0 replies; 22+ messages in thread
From: Timur Tabi @ 2007-05-31 18:55 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: alsa-devel

Liam Girdwood wrote:

>> On big-endian platforms like mine, CS4270_FORMATS will be SNDRV_PCM_FORMAT_S24_BE and on 
>> little-endian platforms it will be SNDRV_PCM_FORMAT_S24_LE.  Assuming the I2S registers 
>> are the same endian as the platform, will this work?
>>
> 
> I think this probably depends on how your audio FIFO's align the data
> received from memory/DMA.  They should do any bit reordering based on
> the audio format, and size etc set in the control register. (Although,
> ymmv.)

Ok, I'm a little confused.  I was going to specify the SNDRV_PCM_FORMAT_S24_BE for my I2C 
device because the actual 32-bit memory-mapped registers are big-endian.  The structure 
definition even uses __be32 for each field.

My goal was to specify a single value (i.e. SNDRV_PCM_FORMAT_S24_BE) such that ALSA would 
give me a 32-bit quantity that exactly matches what my device expects.

I wish asound.h had more documentation.  I don't know what any of these macros *really* mean.

>> #define CS4270_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)
>>
>> That would tell ALSA that the CS4270 supports both formats, which isn't technically true, 
>> but it wouldn't matter because the I2S interface is what determines the actual 
>> "endianness" of the serial data.
> 
> This looks fine as a workaround atm, I'll try and have a look at this
> bug tomorrow so we don't need to do this.

Ok, I'll do this for now.



-- 
Timur Tabi
Linux Kernel Developer @ Freescale

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: ASoC and a codec that can't be controlled
  2007-05-31 17:19             ` Liam Girdwood
@ 2007-05-31 19:49               ` Timur Tabi
  2007-06-01 13:36                 ` Liam Girdwood
  2007-06-01 21:34               ` Timur Tabi
  1 sibling, 1 reply; 22+ messages in thread
From: Timur Tabi @ 2007-05-31 19:49 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: alsa-devel

Liam Girdwood wrote:

> I think the best place to call snd_soc_new_pcms is in the machine
> driver. This means we don't have to add any pcms that are not used. 

True, but the machine driver is probed before the codec driver is probed.  So if you 
really need the codec driver to initialize the I2C bus first, then you've got a problem. 
Re-arranging the order of probes in soc_probe() is not really a solution.

So on your baord, why does the I2C interface need to be running before anything else can 
be probed?

> Yes, the hw_params could return error on anything the machine didn't
> like. e.g. this could be used to workaround quirks. 

Would ALSA know to try something else, if a particular combination was rejected?



-- 
Timur Tabi
Linux Kernel Developer @ Freescale

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: ASoC and a codec that can't be controlled
  2007-05-31 19:49               ` Timur Tabi
@ 2007-06-01 13:36                 ` Liam Girdwood
  2007-06-01 13:45                   ` Timur Tabi
  0 siblings, 1 reply; 22+ messages in thread
From: Liam Girdwood @ 2007-06-01 13:36 UTC (permalink / raw)
  To: Timur Tabi; +Cc: alsa-devel

On Thu, 2007-05-31 at 14:49 -0500, Timur Tabi wrote:
> Liam Girdwood wrote:
> 
> > I think the best place to call snd_soc_new_pcms is in the machine
> > driver. This means we don't have to add any pcms that are not used. 
> 
> True, but the machine driver is probed before the codec driver is probed.  So if you 
> really need the codec driver to initialize the I2C bus first, then you've got a problem. 
> Re-arranging the order of probes in soc_probe() is not really a solution.
> 
> So on your baord, why does the I2C interface need to be running before anything else can 
> be probed?

Imho, there is little point in probing or allocating any more resources
until we know the I2C codec probe succeeds. We would just have to free
any resources allocated up to that point. 


> 
> > Yes, the hw_params could return error on anything the machine didn't
> > like. e.g. this could be used to workaround quirks. 
> 
> Would ALSA know to try something else, if a particular combination was rejected?
> 

This would be up to your user space application. In general all common
sample rates and formats are supported by most drivers e.g. 44.1k
stereo. If some combinations are rejected, it's most likely due to
hardware limitations.

Liam

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: ASoC and a codec that can't be controlled
  2007-06-01 13:36                 ` Liam Girdwood
@ 2007-06-01 13:45                   ` Timur Tabi
  0 siblings, 0 replies; 22+ messages in thread
From: Timur Tabi @ 2007-06-01 13:45 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: alsa-devel

Liam Girdwood wrote:

> Imho, there is little point in probing or allocating any more resources
> until we know the I2C codec probe succeeds. We would just have to free
> any resources allocated up to that point. 

True, but if the I2C probe fails, then I would think that the whole system is shot, so this sounds like a very unlikely situation.  If you changed the code to clean up after an I2C failure, you could make the whole thing more modular, including eliminating the call to snd_soc_new() in the codec driver.

Since ASoC divides everything into four more-or-less independent drivers, it makes sense that it should be able to handle a situation where one of those drivers just fails to load.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: ASoC and a codec that can't be controlled
  2007-05-31 17:19             ` Liam Girdwood
  2007-05-31 19:49               ` Timur Tabi
@ 2007-06-01 21:34               ` Timur Tabi
  1 sibling, 0 replies; 22+ messages in thread
From: Timur Tabi @ 2007-06-01 21:34 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: alsa-devel

Liam Girdwood wrote:

> I think the best place to call snd_soc_new_pcms is in the machine
> driver. This means we don't have to add any pcms that are not used. 

Are you talking about the snd_soc_dai_link.init() function?  If so, then  where do you 
call snd_soc_free_pcms()?  The snd_soc_dai_link structure has no "exit" function.

-- 
Timur Tabi
Linux Kernel Developer @ Freescale

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2007-06-01 21:34 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-05-22 15:47 ASoC and a codec that can't be controlled Timur Tabi
2007-05-23 15:37 ` Liam Girdwood
2007-05-25 20:17   ` Timur Tabi
2007-05-28 12:10     ` Liam Girdwood
2007-05-29  0:18       ` Timur Tabi
2007-05-29  8:53         ` Liam Girdwood
2007-05-29 18:10           ` Timur Tabi
2007-05-30 12:28             ` Liam Girdwood
2007-05-29 18:47       ` Timur Tabi
2007-05-30 12:20         ` Liam Girdwood
2007-05-29 19:02       ` Timur Tabi
     [not found]         ` <1180529741.29590.54.camel@a10072.wolfsonmicro.main>
2007-05-30 18:10           ` Timur Tabi
2007-05-31 17:19             ` Liam Girdwood
2007-05-31 19:49               ` Timur Tabi
2007-06-01 13:36                 ` Liam Girdwood
2007-06-01 13:45                   ` Timur Tabi
2007-06-01 21:34               ` Timur Tabi
2007-05-29 23:05       ` Timur Tabi
2007-05-30 13:06         ` Liam Girdwood
2007-05-30 15:46           ` Timur Tabi
2007-05-31 17:32             ` Liam Girdwood
2007-05-31 18:55               ` Timur Tabi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).