[alsa-devel] asoc SND_SOC_DAPM_AIF_IN question
Hi,
In the codec driver I am writing I added 2 paths in map, one for Headset and second for Speaker. Both of these paths have common PCM port enable button so I added that using SND_SOC_DAPM_AIF_IN
So my codec map looks like: /*headset map*/ { "HSDAC Left", NULL, "PCM_In"}, { "HSDAC Right", NULL, "PCM_In"}, { "PCM_In", NULL, "Headset Rail"}, { "Headset Rail", NULL, "Audio Rail"},
/*speaker map*/ { "IHFDAC Left", NULL, "PCM_In"}, { "IHFDAC Right", NULL, "PCM_In"}, { "PCM_In", NULL, "Speaker Rail"}, { "Speaker Rail", NULL, "Audio Rail"},
The debugfs tell me this seems right [root@localhost dapm]# cat PCM_In PCM_In: Off in 0 out 5 - R636(0x27c) bit 0 stream HeadSet Speaker inactive in static Speaker Rail in static Headset Rail out static IHFDAC Right out static IHFDAC Left out static HSDAC Right out static HSDAC Left
But when the stream is started now all the widgets get powered on. The debugfs entry says [root@localhost dapm]# cat PCM_In PCM_In: On in 1 out 5 - R636(0x27c) bit 0 stream HeadSet Speaker active in static Speaker Rail in static Headset Rail out static IHFDAC Right out static IHFDAC Left out static HSDAC Right out static HSDAC Left
How is this detecting input as 1 (is this due to AIF_IN and thus turning on all the widgets in map? (turns on IHFDAC for HeadSet stream as well :(
What could I be doing wrong here? I want to add this PCM button for all streams (4 eventually) and this be enabled whenever anyone of them is started.
~Vinod
On Wed, Dec 22, 2010 at 10:39:55PM +0530, Koul, Vinod wrote:
So my codec map looks like: /*headset map*/ { "HSDAC Left", NULL, "PCM_In"}, { "HSDAC Right", NULL, "PCM_In"}, { "PCM_In", NULL, "Headset Rail"}, { "Headset Rail", NULL, "Audio Rail"},
/*speaker map*/ { "IHFDAC Left", NULL, "PCM_In"}, { "IHFDAC Right", NULL, "PCM_In"}, { "PCM_In", NULL, "Speaker Rail"}, { "Speaker Rail", NULL, "Audio Rail"},
But when the stream is started now all the widgets get powered on. The debugfs entry says
You have unconditionally connected both speaker and headphone widgets to the same input so when that input becomes active paths are completed to both outputs and both outpus are enabled.
These "Rail" widgets look quite unusual - what are they?
What could I be doing wrong here? I want to add this PCM button for all streams (4 eventually) and this be enabled whenever anyone of them is started.
What is a "PCM button" and what do you mean by starting a "stream"? Normally a stream would be a path between the CPU and the CODEC.
The way this works is that as described in reply to your previous mail DAPM powers anything on which has a completed path from input to output. As mentioned then if you have no routing control in the device the machine driver will arrange to enable and disable input and output widgets on the edge of the CODEC, either automatically using jack detection or by offering SOC_DAPM_PIN_SWITCH() or similar controls to applications.
On Wed, Dec 22, 2010 at 11:25:29PM +0530, Mark Brown wrote:
On Wed, Dec 22, 2010 at 10:39:55PM +0530, Koul, Vinod wrote:
So my codec map looks like: /*headset map*/ { "HSDAC Left", NULL, "PCM_In"}, { "HSDAC Right", NULL, "PCM_In"}, { "PCM_In", NULL, "Headset Rail"}, { "Headset Rail", NULL, "Audio Rail"},
/*speaker map*/ { "IHFDAC Left", NULL, "PCM_In"}, { "IHFDAC Right", NULL, "PCM_In"}, { "PCM_In", NULL, "Speaker Rail"}, { "Speaker Rail", NULL, "Audio Rail"},
But when the stream is started now all the widgets get powered on. The debugfs entry says
You have unconditionally connected both speaker and headphone widgets to the same input so when that input becomes active paths are completed to both outputs and both outpus are enabled.
Okay, that makes sense.
These "Rail" widgets look quite unusual - what are they?
Audio Supply rails, I have one global audio rail which controls most of audio widgets and then separate rails for speakers and headset. For example I need to turn on Audio supply rail and then headset rail for headsets to work properly. So I described them as SND_SOC_DAPM_SUPPLY. Added events so that I power them on and power off when stream becomes active or inactive.
What could I be doing wrong here? I want to add this PCM button for all
streams
(4 eventually) and this be enabled whenever anyone of them is started.
What is a "PCM button" and what do you mean by starting a "stream"? Normally a stream would be a path between the CPU and the CODEC.
This is PCM interface enable between codec and cpu. So for PCM port to work between codec and cpu, we need to enable the PCM port, this one does that. This is going to be a global switch to be turned on for all streams (I have 4 playback and 1 capture, and can be simultaneous).
The way this works is that as described in reply to your previous mail DAPM powers anything on which has a completed path from input to output. As mentioned then if you have no routing control in the device the machine driver will arrange to enable and disable input and output widgets on the edge of the CODEC, either automatically using jack detection or by offering SOC_DAPM_PIN_SWITCH() or similar controls to applications.
So what I have is below picture in codec
PCM PORT -> HSDAC -> Earpiece/Headset* -> IHFDAC ->Speaker <- ADC <- MICs
(*this will be toggled by user using controls exposed by machine driver which will using SOC_DAPM_PIN_SWITCH as suggested by you)
Here I was trying 1) Putting the PCM_In Button as SND_SOC_DAPM_AIF_IN() 2) Add this to codec map for streams so that its enabled for all streams 3) Add supply rails before this so they are powered for this(which is working for me)
Now only problem for me is to how to add PCM button for all streams? I have few alternatives like doing this in supply events or in dai start function, but was hoping that since this can be represented as a widget it should be done thru the audio map
Any suggestions....
~Vinod
On Thu, Dec 23, 2010 at 08:36:07AM +0530, Koul, Vinod wrote:
On Wed, Dec 22, 2010 at 11:25:29PM +0530, Mark Brown wrote:
These "Rail" widgets look quite unusual - what are they?
Audio Supply rails, I have one global audio rail which controls most of audio widgets and then separate rails for speakers and headset. For example I need to turn on Audio supply rail and then headset rail for headsets to work properly. So I described them as SND_SOC_DAPM_SUPPLY. Added events so that I power them on and power off when stream becomes active or inactive.
"Audio Supply" sounds like the main analogue bias for the CODEC - that would normally be managed by set_bias_level() rather than by having it supply every single widget in the CODEC map.
What is a "PCM button" and what do you mean by starting a "stream"? Normally a stream would be a path between the CPU and the CODEC.
This is PCM interface enable between codec and cpu. So for PCM port to work between codec and cpu, we need to enable the PCM port, this one does that. This is going to be a global switch to be turned on for all streams (I have 4 playback and 1 capture, and can be simultaneous).
If you have multiple links between the CPU and the CODEC with a single power bit to control them all I'd suggest defining several AIF widgets, each with no power management, then making the actual power controlled by a supply widget. That way the power will be enabled as required but you won't have tied all the data streams together in the DAPM map.
Here I was trying
- Putting the PCM_In Button as SND_SOC_DAPM_AIF_IN()
I'm still not sure what you mean by "Button"? I'm guessing it's a register control for power.
"Audio Supply" sounds like the main analogue bias for the CODEC - that would normally be managed by set_bias_level() rather than by having it supply every single widget in the CODEC map.
Yes that would make sense. But only for Audio rail which is global codec rail. What do you recommend for headset and speaker rails? They would be required only for headset and speaker DAI not rest.
If you have multiple links between the CPU and the CODEC with a single power bit to control them all I'd suggest defining several AIF widgets, each with no power management, then making the actual power controlled by a supply widget. That way the power will be enabled as required but you won't have tied all the data streams together in the DAPM map.
Okay so then why should I do with several AIF widgets, wont doing that in DAI startup be a better idea?
Here I was trying
- Putting the PCM_In Button as SND_SOC_DAPM_AIF_IN()
I'm still not sure what you mean by "Button"? I'm guessing it's a register control for power.
Yes :)
~Vinod
On Thu, Dec 23, 2010 at 06:31:08PM +0530, Koul, Vinod wrote:
"Audio Supply" sounds like the main analogue bias for the CODEC - that would normally be managed by set_bias_level() rather than by having it supply every single widget in the CODEC map.
Yes that would make sense. But only for Audio rail which is global codec rail. What do you recommend for headset and speaker rails? They would be required only for headset and speaker DAI not rest.
Supplies for them seem sensible.
If you have multiple links between the CPU and the CODEC with a single power bit to control them all I'd suggest defining several AIF widgets, each with no power management, then making the actual power controlled by a supply widget. That way the power will be enabled as required but you won't have tied all the data streams together in the DAPM map.
Okay so then why should I do with several AIF widgets, wont doing that in DAI startup be a better idea?
Doing things via data rather than with explicit code tends to be lower maintainance; there's less potential for things to go wrong and it's usually less work to keep up to date with API changes.
participants (2)
-
Koul, Vinod
-
Mark Brown