diff mbox

ASoC: tlv320aic31xx: Fix master mode clock I2S bus clocks

Message ID 20180212140646.3268-1-peter.ujfalusi@ti.com (mailing list archive)
State New, archived
Headers show

Commit Message

Peter Ujfalusi Feb. 12, 2018, 2:06 p.m. UTC
In the reset state of the codec we do not have complete playback or capture
routes.

The audio playback/capture will not work due to missing clock signals on
the I2S bus if PLL, MDAC/NDAC/DAC MADC/NADC/ADC is powered down.

To make sure that even if all output/input is disconnected the codec is
generating clocks, we need to have valid DAPM route in every case to power
up the must needed parts of the codec.

I have verified that switching DAC (during playback) or ADC (during
capture) will stop the I2S clocks, so the only solution is to connect the
'Off' routes as well to output/input.

Tested on am43x-epos-evm with aic3111 codec in master mode.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 sound/soc/codecs/tlv320aic31xx.c | 9 +++++++++
 1 file changed, 9 insertions(+)

Comments

Peter Ujfalusi Feb. 12, 2018, 2:09 p.m. UTC | #1
Oops,

the subject got a bit out of hand after rephrasing... I'll fix that up
for v2.

- Péter

On 2018-02-12 16:06, Peter Ujfalusi wrote:
> In the reset state of the codec we do not have complete playback or capture
> routes.
> 
> The audio playback/capture will not work due to missing clock signals on
> the I2S bus if PLL, MDAC/NDAC/DAC MADC/NADC/ADC is powered down.
> 
> To make sure that even if all output/input is disconnected the codec is
> generating clocks, we need to have valid DAPM route in every case to power
> up the must needed parts of the codec.
> 
> I have verified that switching DAC (during playback) or ADC (during
> capture) will stop the I2S clocks, so the only solution is to connect the
> 'Off' routes as well to output/input.
> 
> Tested on am43x-epos-evm with aic3111 codec in master mode.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> ---
>  sound/soc/codecs/tlv320aic31xx.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c
> index 858cb8be445f..d42a23eb916e 100644
> --- a/sound/soc/codecs/tlv320aic31xx.c
> +++ b/sound/soc/codecs/tlv320aic31xx.c
> @@ -586,9 +586,11 @@ common31xx_audio_map[] = {
>  	{"DAC Left Input", "Left Data", "DAC IN"},
>  	{"DAC Left Input", "Right Data", "DAC IN"},
>  	{"DAC Left Input", "Mono", "DAC IN"},
> +	{"DAC Left Input", "Off", "DAC IN"},
>  	{"DAC Right Input", "Left Data", "DAC IN"},
>  	{"DAC Right Input", "Right Data", "DAC IN"},
>  	{"DAC Right Input", "Mono", "DAC IN"},
> +	{"DAC Right Input", "Off", "DAC IN"},
>  	{"DAC Left", NULL, "DAC Left Input"},
>  	{"DAC Right", NULL, "DAC Right Input"},
>  
> @@ -601,6 +603,9 @@ common31xx_audio_map[] = {
>  	{"HP Right", "Switch", "Output Right"},
>  	{"HPR Driver", NULL, "HP Right"},
>  	{"HPR", NULL, "HPR Driver"},
> +
> +	{"HPL", NULL, "DAC Left"},
> +	{"HPR", NULL, "DAC Right"},
>  };
>  
>  static const struct snd_soc_dapm_route
> @@ -621,16 +626,20 @@ aic31xx_audio_map[] = {
>  	{"MIC1LP P-Terminal", "FFR 10 Ohm", "MIC1LP"},
>  	{"MIC1LP P-Terminal", "FFR 20 Ohm", "MIC1LP"},
>  	{"MIC1LP P-Terminal", "FFR 40 Ohm", "MIC1LP"},
> +	{"MIC1LP P-Terminal", "Off", "MIC1LP"},
>  	{"MIC1RP P-Terminal", "FFR 10 Ohm", "MIC1RP"},
>  	{"MIC1RP P-Terminal", "FFR 20 Ohm", "MIC1RP"},
>  	{"MIC1RP P-Terminal", "FFR 40 Ohm", "MIC1RP"},
> +	{"MIC1RP P-Terminal", "Off", "MIC1RP"},
>  	{"MIC1LM P-Terminal", "FFR 10 Ohm", "MIC1LM"},
>  	{"MIC1LM P-Terminal", "FFR 20 Ohm", "MIC1LM"},
>  	{"MIC1LM P-Terminal", "FFR 40 Ohm", "MIC1LM"},
> +	{"MIC1LM P-Terminal", "Off", "MIC1LM"},
>  
>  	{"MIC1LM M-Terminal", "FFR 10 Ohm", "MIC1LM"},
>  	{"MIC1LM M-Terminal", "FFR 20 Ohm", "MIC1LM"},
>  	{"MIC1LM M-Terminal", "FFR 40 Ohm", "MIC1LM"},
> +	{"MIC1LM M-Terminal", "Off", "MIC1LM"},
>  
>  	{"MIC_GAIN_CTL", NULL, "MIC1LP P-Terminal"},
>  	{"MIC_GAIN_CTL", NULL, "MIC1RP P-Terminal"},
> 

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
Andrew Davis Feb. 12, 2018, 2:17 p.m. UTC | #2
On 02/12/2018 08:06 AM, Peter Ujfalusi wrote:
> In the reset state of the codec we do not have complete playback or capture
> routes.
> 
> The audio playback/capture will not work due to missing clock signals on
> the I2S bus if PLL, MDAC/NDAC/DAC MADC/NADC/ADC is powered down.
> 
> To make sure that even if all output/input is disconnected the codec is
> generating clocks, we need to have valid DAPM route in every case to power
> up the must needed parts of the codec.
> 

If all output/input is disconnected why do we need the I2C clocks?

Or do you mean if only one is disconnected the PLL goes down? If that is
the case then it would be better to fix the DAPM route so both paths
correctly lead back to the PLL.

> I have verified that switching DAC (during playback) or ADC (during
> capture) will stop the I2S clocks, so the only solution is to connect the
> 'Off' routes as well to output/input.
> 
> Tested on am43x-epos-evm with aic3111 codec in master mode.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> ---
>  sound/soc/codecs/tlv320aic31xx.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c
> index 858cb8be445f..d42a23eb916e 100644
> --- a/sound/soc/codecs/tlv320aic31xx.c
> +++ b/sound/soc/codecs/tlv320aic31xx.c
> @@ -586,9 +586,11 @@ common31xx_audio_map[] = {
>  	{"DAC Left Input", "Left Data", "DAC IN"},
>  	{"DAC Left Input", "Right Data", "DAC IN"},
>  	{"DAC Left Input", "Mono", "DAC IN"},
> +	{"DAC Left Input", "Off", "DAC IN"},
>  	{"DAC Right Input", "Left Data", "DAC IN"},
>  	{"DAC Right Input", "Right Data", "DAC IN"},
>  	{"DAC Right Input", "Mono", "DAC IN"},
> +	{"DAC Right Input", "Off", "DAC IN"},
>  	{"DAC Left", NULL, "DAC Left Input"},
>  	{"DAC Right", NULL, "DAC Right Input"},
>  
> @@ -601,6 +603,9 @@ common31xx_audio_map[] = {
>  	{"HP Right", "Switch", "Output Right"},
>  	{"HPR Driver", NULL, "HP Right"},
>  	{"HPR", NULL, "HPR Driver"},
> +
> +	{"HPL", NULL, "DAC Left"},
> +	{"HPR", NULL, "DAC Right"},
>  };
>  
>  static const struct snd_soc_dapm_route
> @@ -621,16 +626,20 @@ aic31xx_audio_map[] = {
>  	{"MIC1LP P-Terminal", "FFR 10 Ohm", "MIC1LP"},
>  	{"MIC1LP P-Terminal", "FFR 20 Ohm", "MIC1LP"},
>  	{"MIC1LP P-Terminal", "FFR 40 Ohm", "MIC1LP"},
> +	{"MIC1LP P-Terminal", "Off", "MIC1LP"},
>  	{"MIC1RP P-Terminal", "FFR 10 Ohm", "MIC1RP"},
>  	{"MIC1RP P-Terminal", "FFR 20 Ohm", "MIC1RP"},
>  	{"MIC1RP P-Terminal", "FFR 40 Ohm", "MIC1RP"},
> +	{"MIC1RP P-Terminal", "Off", "MIC1RP"},
>  	{"MIC1LM P-Terminal", "FFR 10 Ohm", "MIC1LM"},
>  	{"MIC1LM P-Terminal", "FFR 20 Ohm", "MIC1LM"},
>  	{"MIC1LM P-Terminal", "FFR 40 Ohm", "MIC1LM"},
> +	{"MIC1LM P-Terminal", "Off", "MIC1LM"},
>  
>  	{"MIC1LM M-Terminal", "FFR 10 Ohm", "MIC1LM"},
>  	{"MIC1LM M-Terminal", "FFR 20 Ohm", "MIC1LM"},
>  	{"MIC1LM M-Terminal", "FFR 40 Ohm", "MIC1LM"},
> +	{"MIC1LM M-Terminal", "Off", "MIC1LM"},
>  
>  	{"MIC_GAIN_CTL", NULL, "MIC1LP P-Terminal"},
>  	{"MIC_GAIN_CTL", NULL, "MIC1RP P-Terminal"},
>
Peter Ujfalusi Feb. 12, 2018, 3:05 p.m. UTC | #3
On 2018-02-12 16:17, Andrew F. Davis wrote:
> On 02/12/2018 08:06 AM, Peter Ujfalusi wrote:
>> In the reset state of the codec we do not have complete playback or capture
>> routes.
>>
>> The audio playback/capture will not work due to missing clock signals on
>> the I2S bus if PLL, MDAC/NDAC/DAC MADC/NADC/ADC is powered down.
>>
>> To make sure that even if all output/input is disconnected the codec is
>> generating clocks, we need to have valid DAPM route in every case to power
>> up the must needed parts of the codec.
>>
> 
> If all output/input is disconnected why do we need the I2C clocks?

we need I2S clocks when user is running audio, otherwise it will time
out with error.

> Or do you mean if only one is disconnected the PLL goes down?

If both is down (DACs in case of playback, ADC in case of capture)

> If that is
> the case then it would be better to fix the DAPM route so both paths
> correctly lead back to the PLL.

This is what the patch is doing, it makes sure that DAC/ADC is powered
and all the other things we need for clock generation.

> 
>> I have verified that switching DAC (during playback) or ADC (during
>> capture) will stop the I2S clocks, so the only solution is to connect the
>> 'Off' routes as well to output/input.
>>
>> Tested on am43x-epos-evm with aic3111 codec in master mode.
>>
>> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
>> ---
>>  sound/soc/codecs/tlv320aic31xx.c | 9 +++++++++
>>  1 file changed, 9 insertions(+)
>>
>> diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c
>> index 858cb8be445f..d42a23eb916e 100644
>> --- a/sound/soc/codecs/tlv320aic31xx.c
>> +++ b/sound/soc/codecs/tlv320aic31xx.c
>> @@ -586,9 +586,11 @@ common31xx_audio_map[] = {
>>  	{"DAC Left Input", "Left Data", "DAC IN"},
>>  	{"DAC Left Input", "Right Data", "DAC IN"},
>>  	{"DAC Left Input", "Mono", "DAC IN"},
>> +	{"DAC Left Input", "Off", "DAC IN"},
>>  	{"DAC Right Input", "Left Data", "DAC IN"},
>>  	{"DAC Right Input", "Right Data", "DAC IN"},
>>  	{"DAC Right Input", "Mono", "DAC IN"},
>> +	{"DAC Right Input", "Off", "DAC IN"},
>>  	{"DAC Left", NULL, "DAC Left Input"},
>>  	{"DAC Right", NULL, "DAC Right Input"},
>>  
>> @@ -601,6 +603,9 @@ common31xx_audio_map[] = {
>>  	{"HP Right", "Switch", "Output Right"},
>>  	{"HPR Driver", NULL, "HP Right"},
>>  	{"HPR", NULL, "HPR Driver"},
>> +
>> +	{"HPL", NULL, "DAC Left"},
>> +	{"HPR", NULL, "DAC Right"},
>>  };
>>  
>>  static const struct snd_soc_dapm_route
>> @@ -621,16 +626,20 @@ aic31xx_audio_map[] = {
>>  	{"MIC1LP P-Terminal", "FFR 10 Ohm", "MIC1LP"},
>>  	{"MIC1LP P-Terminal", "FFR 20 Ohm", "MIC1LP"},
>>  	{"MIC1LP P-Terminal", "FFR 40 Ohm", "MIC1LP"},
>> +	{"MIC1LP P-Terminal", "Off", "MIC1LP"},
>>  	{"MIC1RP P-Terminal", "FFR 10 Ohm", "MIC1RP"},
>>  	{"MIC1RP P-Terminal", "FFR 20 Ohm", "MIC1RP"},
>>  	{"MIC1RP P-Terminal", "FFR 40 Ohm", "MIC1RP"},
>> +	{"MIC1RP P-Terminal", "Off", "MIC1RP"},
>>  	{"MIC1LM P-Terminal", "FFR 10 Ohm", "MIC1LM"},
>>  	{"MIC1LM P-Terminal", "FFR 20 Ohm", "MIC1LM"},
>>  	{"MIC1LM P-Terminal", "FFR 40 Ohm", "MIC1LM"},
>> +	{"MIC1LM P-Terminal", "Off", "MIC1LM"},
>>  
>>  	{"MIC1LM M-Terminal", "FFR 10 Ohm", "MIC1LM"},
>>  	{"MIC1LM M-Terminal", "FFR 20 Ohm", "MIC1LM"},
>>  	{"MIC1LM M-Terminal", "FFR 40 Ohm", "MIC1LM"},
>> +	{"MIC1LM M-Terminal", "Off", "MIC1LM"},
>>  
>>  	{"MIC_GAIN_CTL", NULL, "MIC1LP P-Terminal"},
>>  	{"MIC_GAIN_CTL", NULL, "MIC1RP P-Terminal"},
>>

- Péter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
Andrew Davis Feb. 12, 2018, 5:27 p.m. UTC | #4
On 02/12/2018 09:05 AM, Peter Ujfalusi wrote:
> 
> 
> On 2018-02-12 16:17, Andrew F. Davis wrote:
>> On 02/12/2018 08:06 AM, Peter Ujfalusi wrote:
>>> In the reset state of the codec we do not have complete playback or capture
>>> routes.
>>>
>>> The audio playback/capture will not work due to missing clock signals on
>>> the I2S bus if PLL, MDAC/NDAC/DAC MADC/NADC/ADC is powered down.
>>>
>>> To make sure that even if all output/input is disconnected the codec is
>>> generating clocks, we need to have valid DAPM route in every case to power
>>> up the must needed parts of the codec.
>>>
>>
>> If all output/input is disconnected why do we need the I2C clocks?
> 
> we need I2S clocks when user is running audio, otherwise it will time
> out with error.
> 

You mean in the case were they have the device set to route the I2S
stream to a dead end inside the CODEC (DAC IN -> OFF), but still want to
push data down the I2S line?

Is there no way to communicate the device is muted back to the I2S data
master to not try to push data?

>> Or do you mean if only one is disconnected the PLL goes down?
> 
> If both is down (DACs in case of playback, ADC in case of capture)
> 
>> If that is
>> the case then it would be better to fix the DAPM route so both paths
>> correctly lead back to the PLL.
> 
> This is what the patch is doing, it makes sure that DAC/ADC is powered
> and all the other things we need for clock generation.
> 

I don't see that, to me it looks like a workaround to force the whole
DAC/ADC PLL clock chain active even when there is no route to the DAC
(or from ADC) because we need a PLL derived clock to run the I2S clocks.

I understand the need: when acting as the clock master the CODEC should
always provide a clock (right?), even when the CODEC is muted (or the
I2S signal has no route to the DAC).

But what this patch does is to leave the DAC clocks always on, even in
clock slave mode, where there is no need to have the PLL or DAC clocks
on. Is there really no other way to force the PLL always on when in
clock master mode only?

>>
>>> I have verified that switching DAC (during playback) or ADC (during
>>> capture) will stop the I2S clocks, so the only solution is to connect the
>>> 'Off' routes as well to output/input.
>>>
>>> Tested on am43x-epos-evm with aic3111 codec in master mode.
>>>
>>> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
>>> ---
>>>  sound/soc/codecs/tlv320aic31xx.c | 9 +++++++++
>>>  1 file changed, 9 insertions(+)
>>>
>>> diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c
>>> index 858cb8be445f..d42a23eb916e 100644
>>> --- a/sound/soc/codecs/tlv320aic31xx.c
>>> +++ b/sound/soc/codecs/tlv320aic31xx.c
>>> @@ -586,9 +586,11 @@ common31xx_audio_map[] = {
>>>  	{"DAC Left Input", "Left Data", "DAC IN"},
>>>  	{"DAC Left Input", "Right Data", "DAC IN"},
>>>  	{"DAC Left Input", "Mono", "DAC IN"},
>>> +	{"DAC Left Input", "Off", "DAC IN"},
>>>  	{"DAC Right Input", "Left Data", "DAC IN"},
>>>  	{"DAC Right Input", "Right Data", "DAC IN"},
>>>  	{"DAC Right Input", "Mono", "DAC IN"},
>>> +	{"DAC Right Input", "Off", "DAC IN"},
>>>  	{"DAC Left", NULL, "DAC Left Input"},
>>>  	{"DAC Right", NULL, "DAC Right Input"},
>>>  
>>> @@ -601,6 +603,9 @@ common31xx_audio_map[] = {
>>>  	{"HP Right", "Switch", "Output Right"},
>>>  	{"HPR Driver", NULL, "HP Right"},
>>>  	{"HPR", NULL, "HPR Driver"},
>>> +
>>> +	{"HPL", NULL, "DAC Left"},
>>> +	{"HPR", NULL, "DAC Right"},
>>>  };
>>>  
>>>  static const struct snd_soc_dapm_route
>>> @@ -621,16 +626,20 @@ aic31xx_audio_map[] = {
>>>  	{"MIC1LP P-Terminal", "FFR 10 Ohm", "MIC1LP"},
>>>  	{"MIC1LP P-Terminal", "FFR 20 Ohm", "MIC1LP"},
>>>  	{"MIC1LP P-Terminal", "FFR 40 Ohm", "MIC1LP"},
>>> +	{"MIC1LP P-Terminal", "Off", "MIC1LP"},
>>>  	{"MIC1RP P-Terminal", "FFR 10 Ohm", "MIC1RP"},
>>>  	{"MIC1RP P-Terminal", "FFR 20 Ohm", "MIC1RP"},
>>>  	{"MIC1RP P-Terminal", "FFR 40 Ohm", "MIC1RP"},
>>> +	{"MIC1RP P-Terminal", "Off", "MIC1RP"},
>>>  	{"MIC1LM P-Terminal", "FFR 10 Ohm", "MIC1LM"},
>>>  	{"MIC1LM P-Terminal", "FFR 20 Ohm", "MIC1LM"},
>>>  	{"MIC1LM P-Terminal", "FFR 40 Ohm", "MIC1LM"},
>>> +	{"MIC1LM P-Terminal", "Off", "MIC1LM"},
>>>  
>>>  	{"MIC1LM M-Terminal", "FFR 10 Ohm", "MIC1LM"},
>>>  	{"MIC1LM M-Terminal", "FFR 20 Ohm", "MIC1LM"},
>>>  	{"MIC1LM M-Terminal", "FFR 40 Ohm", "MIC1LM"},
>>> +	{"MIC1LM M-Terminal", "Off", "MIC1LM"},
>>>  
>>>  	{"MIC_GAIN_CTL", NULL, "MIC1LP P-Terminal"},
>>>  	{"MIC_GAIN_CTL", NULL, "MIC1RP P-Terminal"},
>>>
> 
> - Péter
> 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
>
Jyri Sarha Feb. 13, 2018, 9:22 a.m. UTC | #5
On 12/02/18 19:27, Andrew F. Davis wrote:
>>> If all output/input is disconnected why do we need the I2C clocks?
>> we need I2S clocks when user is running audio, otherwise it will time
>> out with error.
>>
> You mean in the case were they have the device set to route the I2S
> stream to a dead end inside the CODEC (DAC IN -> OFF), but still want to
> push data down the I2S line?
> 
> Is there no way to communicate the device is muted back to the I2S data
> master to not try to push data

The audio device should still keep the stream flowing and continue
draining (or pushing) the samples even if the path is muted. Doing that
properly in any other way than keeping the I2S clocked is quite complicated.

Best regards,
Jyri
Peter Ujfalusi Feb. 13, 2018, 11:19 a.m. UTC | #6
On 2018-02-12 19:27, Andrew F. Davis wrote:
> On 02/12/2018 09:05 AM, Peter Ujfalusi wrote:
>>
>>
>> On 2018-02-12 16:17, Andrew F. Davis wrote:
>>> On 02/12/2018 08:06 AM, Peter Ujfalusi wrote:
>>>> In the reset state of the codec we do not have complete playback or capture
>>>> routes.
>>>>
>>>> The audio playback/capture will not work due to missing clock signals on
>>>> the I2S bus if PLL, MDAC/NDAC/DAC MADC/NADC/ADC is powered down.
>>>>
>>>> To make sure that even if all output/input is disconnected the codec is
>>>> generating clocks, we need to have valid DAPM route in every case to power
>>>> up the must needed parts of the codec.
>>>>
>>>
>>> If all output/input is disconnected why do we need the I2C clocks?
>>
>> we need I2S clocks when user is running audio, otherwise it will time
>> out with error.
>>
> 
> You mean in the case were they have the device set to route the I2S
> stream to a dead end inside the CODEC (DAC IN -> OFF), but still want to
> push data down the I2S line?
> 
> Is there no way to communicate the device is muted back to the I2S data
> master to not try to push data?

Not sure I follow you...
If the codec is clock master on the I2S bus, it must provide the clocks
during audio playback/capture. If the codec is muted, it still needs to
provide the clocks as w/o the clocks the CPU will not shift out data,
DMA will stall and the audio will be aborted with timeout.

>>> Or do you mean if only one is disconnected the PLL goes down?
>>
>> If both is down (DACs in case of playback, ADC in case of capture)
>>
>>> If that is
>>> the case then it would be better to fix the DAPM route so both paths
>>> correctly lead back to the PLL.
>>
>> This is what the patch is doing, it makes sure that DAC/ADC is powered
>> and all the other things we need for clock generation.
>>
> 
> I don't see that, to me it looks like a workaround to force the whole
> DAC/ADC PLL clock chain active even when there is no route to the DAC
> (or from ADC) because we need a PLL derived clock to run the I2S clocks.

The DAC will be only powered up if there is a playback stream. Same for
the ADC, it is only going to be powered up if there is a capture stream.

> I understand the need: when acting as the clock master the CODEC should
> always provide a clock (right?), even when the CODEC is muted (or the
> I2S signal has no route to the DAC).

The codec must provide clocks whenever we have active stream. It has
nothing to do with mute. If it is master.
You see: when the codec is I2S slave, the CPU will be generating the I2S
clocks even if you 'mute' the codec, or even if you unsolder it from the
board.

> But what this patch does is to leave the DAC clocks always on, even in
> clock slave mode, where there is no need to have the PLL or DAC clocks
> on. Is there really no other way to force the PLL always on when in
> clock master mode only?

We can not use DAPM_SUPPLY alone to enable the PLL since we also need to
enable the DAC/ADC we need to power up the minimal set all the time if
the codec is master.

What I did for v2 is that I have separated the new DAPM routes and only
apply them if the codec is clock master.

Try the following on am43x-epos-evm (if you have access to it):
after boot set up the mixers for Speaker for example:
amixer sset 'DAC' 127
amixer sset 'Speaker Analog' 127
amixer sset 'Speaker Driver' 0 on
amixer sset 'Speaker Left' on
amixer sset 'Speaker Right' on
amixer sset 'Output Left From Left DAC' on
amixer sset 'Output Right From Right DAC' on

in one terminal (to see the hw/appl ptr :
watch cat  /proc/asound/card0/pcm0p/sub0/status

on another one (or /dev/zero):
aplay -Dplughw:0,0 -fdat /dev/urandom

You can see that the hw/appl ptr is moving and audio is playing, now on
a third terminal:
i2cget -f -y 0 0x18 0x3f
will return: 0xd4

Disable the DACs (will not affect DAPM):
i2cset -f -y 0 0x18 0x3f 0x14

and the DMA is going to stop (I2S clocks are no longer running)

i2cset -f -y 0 0x18 0x3f 0xd4

Will get the clocks running again.

> 
>>>
>>>> I have verified that switching DAC (during playback) or ADC (during
>>>> capture) will stop the I2S clocks, so the only solution is to connect the
>>>> 'Off' routes as well to output/input.
>>>>
>>>> Tested on am43x-epos-evm with aic3111 codec in master mode.
>>>>
>>>> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
>>>> ---
>>>>  sound/soc/codecs/tlv320aic31xx.c | 9 +++++++++
>>>>  1 file changed, 9 insertions(+)
>>>>
>>>> diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c
>>>> index 858cb8be445f..d42a23eb916e 100644
>>>> --- a/sound/soc/codecs/tlv320aic31xx.c
>>>> +++ b/sound/soc/codecs/tlv320aic31xx.c
>>>> @@ -586,9 +586,11 @@ common31xx_audio_map[] = {
>>>>  	{"DAC Left Input", "Left Data", "DAC IN"},
>>>>  	{"DAC Left Input", "Right Data", "DAC IN"},
>>>>  	{"DAC Left Input", "Mono", "DAC IN"},
>>>> +	{"DAC Left Input", "Off", "DAC IN"},
>>>>  	{"DAC Right Input", "Left Data", "DAC IN"},
>>>>  	{"DAC Right Input", "Right Data", "DAC IN"},
>>>>  	{"DAC Right Input", "Mono", "DAC IN"},
>>>> +	{"DAC Right Input", "Off", "DAC IN"},
>>>>  	{"DAC Left", NULL, "DAC Left Input"},
>>>>  	{"DAC Right", NULL, "DAC Right Input"},
>>>>  
>>>> @@ -601,6 +603,9 @@ common31xx_audio_map[] = {
>>>>  	{"HP Right", "Switch", "Output Right"},
>>>>  	{"HPR Driver", NULL, "HP Right"},
>>>>  	{"HPR", NULL, "HPR Driver"},
>>>> +
>>>> +	{"HPL", NULL, "DAC Left"},
>>>> +	{"HPR", NULL, "DAC Right"},
>>>>  };
>>>>  
>>>>  static const struct snd_soc_dapm_route
>>>> @@ -621,16 +626,20 @@ aic31xx_audio_map[] = {
>>>>  	{"MIC1LP P-Terminal", "FFR 10 Ohm", "MIC1LP"},
>>>>  	{"MIC1LP P-Terminal", "FFR 20 Ohm", "MIC1LP"},
>>>>  	{"MIC1LP P-Terminal", "FFR 40 Ohm", "MIC1LP"},
>>>> +	{"MIC1LP P-Terminal", "Off", "MIC1LP"},
>>>>  	{"MIC1RP P-Terminal", "FFR 10 Ohm", "MIC1RP"},
>>>>  	{"MIC1RP P-Terminal", "FFR 20 Ohm", "MIC1RP"},
>>>>  	{"MIC1RP P-Terminal", "FFR 40 Ohm", "MIC1RP"},
>>>> +	{"MIC1RP P-Terminal", "Off", "MIC1RP"},
>>>>  	{"MIC1LM P-Terminal", "FFR 10 Ohm", "MIC1LM"},
>>>>  	{"MIC1LM P-Terminal", "FFR 20 Ohm", "MIC1LM"},
>>>>  	{"MIC1LM P-Terminal", "FFR 40 Ohm", "MIC1LM"},
>>>> +	{"MIC1LM P-Terminal", "Off", "MIC1LM"},
>>>>  
>>>>  	{"MIC1LM M-Terminal", "FFR 10 Ohm", "MIC1LM"},
>>>>  	{"MIC1LM M-Terminal", "FFR 20 Ohm", "MIC1LM"},
>>>>  	{"MIC1LM M-Terminal", "FFR 40 Ohm", "MIC1LM"},
>>>> +	{"MIC1LM M-Terminal", "Off", "MIC1LM"},
>>>>  
>>>>  	{"MIC_GAIN_CTL", NULL, "MIC1LP P-Terminal"},
>>>>  	{"MIC_GAIN_CTL", NULL, "MIC1RP P-Terminal"},
>>>>
>>
>> - Péter
>>
>> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
>> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
>>

- Péter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
Mark Brown Feb. 13, 2018, 12:23 p.m. UTC | #7
On Tue, Feb 13, 2018 at 01:19:05PM +0200, Peter Ujfalusi wrote:
> On 2018-02-12 19:27, Andrew F. Davis wrote:

> > Is there no way to communicate the device is muted back to the I2S data
> > master to not try to push data?

> Not sure I follow you...
> If the codec is clock master on the I2S bus, it must provide the clocks
> during audio playback/capture. If the codec is muted, it still needs to
> provide the clocks as w/o the clocks the CPU will not shift out data,
> DMA will stall and the audio will be aborted with timeout.

Right, and if userspace finds that audio is paused instead of muted that
will really confuse it - A/V sync will be broken, sync with song
progress will be broken...
diff mbox

Patch

diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c
index 858cb8be445f..d42a23eb916e 100644
--- a/sound/soc/codecs/tlv320aic31xx.c
+++ b/sound/soc/codecs/tlv320aic31xx.c
@@ -586,9 +586,11 @@  common31xx_audio_map[] = {
 	{"DAC Left Input", "Left Data", "DAC IN"},
 	{"DAC Left Input", "Right Data", "DAC IN"},
 	{"DAC Left Input", "Mono", "DAC IN"},
+	{"DAC Left Input", "Off", "DAC IN"},
 	{"DAC Right Input", "Left Data", "DAC IN"},
 	{"DAC Right Input", "Right Data", "DAC IN"},
 	{"DAC Right Input", "Mono", "DAC IN"},
+	{"DAC Right Input", "Off", "DAC IN"},
 	{"DAC Left", NULL, "DAC Left Input"},
 	{"DAC Right", NULL, "DAC Right Input"},
 
@@ -601,6 +603,9 @@  common31xx_audio_map[] = {
 	{"HP Right", "Switch", "Output Right"},
 	{"HPR Driver", NULL, "HP Right"},
 	{"HPR", NULL, "HPR Driver"},
+
+	{"HPL", NULL, "DAC Left"},
+	{"HPR", NULL, "DAC Right"},
 };
 
 static const struct snd_soc_dapm_route
@@ -621,16 +626,20 @@  aic31xx_audio_map[] = {
 	{"MIC1LP P-Terminal", "FFR 10 Ohm", "MIC1LP"},
 	{"MIC1LP P-Terminal", "FFR 20 Ohm", "MIC1LP"},
 	{"MIC1LP P-Terminal", "FFR 40 Ohm", "MIC1LP"},
+	{"MIC1LP P-Terminal", "Off", "MIC1LP"},
 	{"MIC1RP P-Terminal", "FFR 10 Ohm", "MIC1RP"},
 	{"MIC1RP P-Terminal", "FFR 20 Ohm", "MIC1RP"},
 	{"MIC1RP P-Terminal", "FFR 40 Ohm", "MIC1RP"},
+	{"MIC1RP P-Terminal", "Off", "MIC1RP"},
 	{"MIC1LM P-Terminal", "FFR 10 Ohm", "MIC1LM"},
 	{"MIC1LM P-Terminal", "FFR 20 Ohm", "MIC1LM"},
 	{"MIC1LM P-Terminal", "FFR 40 Ohm", "MIC1LM"},
+	{"MIC1LM P-Terminal", "Off", "MIC1LM"},
 
 	{"MIC1LM M-Terminal", "FFR 10 Ohm", "MIC1LM"},
 	{"MIC1LM M-Terminal", "FFR 20 Ohm", "MIC1LM"},
 	{"MIC1LM M-Terminal", "FFR 40 Ohm", "MIC1LM"},
+	{"MIC1LM M-Terminal", "Off", "MIC1LM"},
 
 	{"MIC_GAIN_CTL", NULL, "MIC1LP P-Terminal"},
 	{"MIC_GAIN_CTL", NULL, "MIC1RP P-Terminal"},