Message ID | 1404200881-32253-7-git-send-email-bcousson@baylibre.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 07/01/2014 09:47 AM, Benoit Cousson wrote: [...] for (i = 0; i < rtd->num_codecs; i++) { > + struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; > + /* check client and interface hw capabilities */ > + snprintf(new_name, sizeof(new_name), "%s %s-%d", > + rtd->dai_link->stream_name, codec_dai->name, num); We may need to rethink how to do the naming for multiple CODEC DAI links here. This implementation will just keep overwriting new_name with each loop iteration and end up using the last one. Vinod may have some insights.
On Tue, Jul 01, 2014 at 03:49:51PM +0200, Lars-Peter Clausen wrote: > On 07/01/2014 09:47 AM, Benoit Cousson wrote: And you should have cced me on this patch > [...] > for (i = 0; i < rtd->num_codecs; i++) { > >+ struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; > >+ /* check client and interface hw capabilities */ > >+ snprintf(new_name, sizeof(new_name), "%s %s-%d", > >+ rtd->dai_link->stream_name, codec_dai->name, num); > > We may need to rethink how to do the naming for multiple CODEC DAI > links here. This implementation will just keep overwriting new_name > with each loop iteration and end up using the last one. Vinod may > have some insights. I am intrugued on how we do this for pcms with multi-codec support. Looking at the patch series I dont think the soc_pcm_new() has been updated (please point out if i missed, it is late in night) Shouldnt this be updated for pcm too? I would suggest makes sense is to keep appending the codec name for the dai-link. But yes keep a check on the size. Unless we have better ideas.
On Tue, Jul 01, 2014 at 09:47:59AM +0200, Benoit Cousson wrote: > Add multicodec support in soc-compress.c > > @@ -294,13 +299,19 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd) > goto out; > } > > - switch (cmd) { > - case SNDRV_PCM_TRIGGER_START: > - snd_soc_dai_digital_mute(codec_dai, 0, cstream->direction); > - break; > - case SNDRV_PCM_TRIGGER_STOP: > - snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction); > - break; > + for (i = 0; i < rtd->num_codecs; i++) { > + struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; > + > + switch (cmd) { > + case SNDRV_PCM_TRIGGER_START: > + snd_soc_dai_digital_mute(codec_dai, 0, > + cstream->direction); > + break; > + case SNDRV_PCM_TRIGGER_STOP: > + snd_soc_dai_digital_mute(codec_dai, 1, > + cstream->direction); Wouldnt it make sense to fix snd_soc_dai_digital_mute() for multi-codecs. Did you do same thing for pcm? > + break; > + } > } > > out: > @@ -622,23 +633,33 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) > { > struct snd_soc_codec *codec = rtd->codec; > struct snd_soc_platform *platform = rtd->platform; > - struct snd_soc_dai *codec_dai = rtd->codec_dai; > struct snd_soc_dai *cpu_dai = rtd->cpu_dai; > struct snd_compr *compr; > struct snd_pcm *be_pcm; > char new_name[64]; > - int ret = 0, direction = 0; > - > - /* check client and interface hw capabilities */ > - snprintf(new_name, sizeof(new_name), "%s %s-%d", > - rtd->dai_link->stream_name, codec_dai->name, num); > - > - if (codec_dai->driver->playback.channels_min) > - direction = SND_COMPRESS_PLAYBACK; > - else if (codec_dai->driver->capture.channels_min) > - direction = SND_COMPRESS_CAPTURE; > - else > - return -EINVAL; > + int i, ret = 0, direction = -1; > + > + for (i = 0; i < rtd->num_codecs; i++) { > + struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; > + /* check client and interface hw capabilities */ > + snprintf(new_name, sizeof(new_name), "%s %s-%d", > + rtd->dai_link->stream_name, codec_dai->name, num); > + > + if (direction < 0) { > + if (codec_dai->driver->playback.channels_min) > + direction = SND_COMPRESS_PLAYBACK; > + else if (codec_dai->driver->capture.channels_min) > + direction = SND_COMPRESS_CAPTURE; direction wont change with multiple codecs, so this loop makes no sense here. For simplcity perhaps we can use cpu_dai? > + else > + return -EINVAL; > + } else { when will this get executed? You have initialized direction to -1 and if case is always true. I think compiler will simply remove the below sinppet. > + if ((codec_dai->driver->playback.channels_min && > + direction != SND_COMPRESS_PLAYBACK) || > + (codec_dai->driver->capture.channels_min && > + direction != SND_COMPRESS_CAPTURE)) and what exactly are we trying to check here? > + return -EINVAL; > + } > + } > > compr = kzalloc(sizeof(*compr), GFP_KERNEL); > if (compr == NULL) { > @@ -692,8 +713,11 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) > rtd->compr = compr; > compr->private_data = rtd; > > - printk(KERN_INFO "compress asoc: %s <-> %s mapping ok\n", codec_dai->name, > - cpu_dai->name); > + for (i = 0; i < rtd->num_codecs; i++) { > + struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; > + printk(KERN_INFO "compress asoc: %s <-> %s mapping ok\n", > + codec_dai->name, cpu_dai->name); wrong again. You are not creating multiple links with multi-codec. Link is still single.
On 07/01/2014 06:25 PM, Vinod Koul wrote: > On Tue, Jul 01, 2014 at 03:49:51PM +0200, Lars-Peter Clausen wrote: >> On 07/01/2014 09:47 AM, Benoit Cousson wrote: > And you should have cced me on this patch > >> [...] >> for (i = 0; i < rtd->num_codecs; i++) { >>> + struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; >>> + /* check client and interface hw capabilities */ >>> + snprintf(new_name, sizeof(new_name), "%s %s-%d", >>> + rtd->dai_link->stream_name, codec_dai->name, num); >> >> We may need to rethink how to do the naming for multiple CODEC DAI >> links here. This implementation will just keep overwriting new_name >> with each loop iteration and end up using the last one. Vinod may >> have some insights. > > I am intrugued on how we do this for pcms with multi-codec support. > > Looking at the patch series I dont think the soc_pcm_new() has been updated > (please point out if i missed, it is late in night) > Shouldnt this be updated for pcm too? > > I would suggest makes sense is to keep appending the codec name for the > dai-link. But yes keep a check on the size. Unless we have better ideas. > This is what the patch series does for normal PCMs snprintf(new_name, sizeof(new_name), "%s %s-%d", - rtd->dai_link->stream_name, codec_dai->name, num); + rtd->dai_link->stream_name, + (rtd->num_codecs > 1) ? + "multicodec" : rtd->codec_dai->name, num);
On Tue, Jul 01, 2014 at 06:42:12PM +0200, Lars-Peter Clausen wrote: > On 07/01/2014 06:25 PM, Vinod Koul wrote: > >On Tue, Jul 01, 2014 at 03:49:51PM +0200, Lars-Peter Clausen wrote: > >>On 07/01/2014 09:47 AM, Benoit Cousson wrote: > >And you should have cced me on this patch > > > >>[...] > >>for (i = 0; i < rtd->num_codecs; i++) { > >>>+ struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; > >>>+ /* check client and interface hw capabilities */ > >>>+ snprintf(new_name, sizeof(new_name), "%s %s-%d", > >>>+ rtd->dai_link->stream_name, codec_dai->name, num); > >> > >>We may need to rethink how to do the naming for multiple CODEC DAI > >>links here. This implementation will just keep overwriting new_name > >>with each loop iteration and end up using the last one. Vinod may > >>have some insights. > > > >I am intrugued on how we do this for pcms with multi-codec support. > > > >Looking at the patch series I dont think the soc_pcm_new() has been updated > >(please point out if i missed, it is late in night) > >Shouldnt this be updated for pcm too? > > > >I would suggest makes sense is to keep appending the codec name for the > >dai-link. But yes keep a check on the size. Unless we have better ideas. > > > > This is what the patch series does for normal PCMs > > snprintf(new_name, sizeof(new_name), "%s %s-%d", > - rtd->dai_link->stream_name, codec_dai->name, num); > + rtd->dai_link->stream_name, > + (rtd->num_codecs > 1) ? > + "multicodec" : rtd->codec_dai->name, num); Sounds good to me!
On 01/07/2014 18:25, Vinod Koul wrote: > On Tue, Jul 01, 2014 at 03:49:51PM +0200, Lars-Peter Clausen wrote: >> On 07/01/2014 09:47 AM, Benoit Cousson wrote: > And you should have cced me on this patch Sorry, my mistake. I'll add you for the next release. Regards, Benoit > >> [...] >> for (i = 0; i < rtd->num_codecs; i++) { >>> + struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; >>> + /* check client and interface hw capabilities */ >>> + snprintf(new_name, sizeof(new_name), "%s %s-%d", >>> + rtd->dai_link->stream_name, codec_dai->name, num); >> >> We may need to rethink how to do the naming for multiple CODEC DAI >> links here. This implementation will just keep overwriting new_name >> with each loop iteration and end up using the last one. Vinod may >> have some insights. > > I am intrugued on how we do this for pcms with multi-codec support. > > Looking at the patch series I dont think the soc_pcm_new() has been updated > (please point out if i missed, it is late in night) > Shouldnt this be updated for pcm too? > > I would suggest makes sense is to keep appending the codec name for the > dai-link. But yes keep a check on the size. Unless we have better ideas. >
On Tue, Jul 01, 2014 at 10:11:34PM +0530, Vinod Koul wrote: > On Tue, Jul 01, 2014 at 09:47:59AM +0200, Benoit Cousson wrote: > > + for (i = 0; i < rtd->num_codecs; i++) { > > + struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; > > + > > + switch (cmd) { > > + case SNDRV_PCM_TRIGGER_START: > > + snd_soc_dai_digital_mute(codec_dai, 0, > > + cstream->direction); > > + break; > > + case SNDRV_PCM_TRIGGER_STOP: > > + snd_soc_dai_digital_mute(codec_dai, 1, > > + cstream->direction); > Wouldnt it make sense to fix snd_soc_dai_digital_mute() for multi-codecs. Did > you do same thing for pcm? Yes, the other callers also iterate through all the CODECs. It might be sensible to have a wrapper which does the iteration but I do think it's reasonable for _dai_digital_mute() to just operate on one DAI.
On 01/07/2014 18:41, Vinod Koul wrote: > On Tue, Jul 01, 2014 at 09:47:59AM +0200, Benoit Cousson wrote: >> Add multicodec support in soc-compress.c >> >> @@ -294,13 +299,19 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd) >> goto out; >> } >> >> - switch (cmd) { >> - case SNDRV_PCM_TRIGGER_START: >> - snd_soc_dai_digital_mute(codec_dai, 0, cstream->direction); >> - break; >> - case SNDRV_PCM_TRIGGER_STOP: >> - snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction); >> - break; >> + for (i = 0; i < rtd->num_codecs; i++) { >> + struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; >> + >> + switch (cmd) { >> + case SNDRV_PCM_TRIGGER_START: >> + snd_soc_dai_digital_mute(codec_dai, 0, >> + cstream->direction); >> + break; >> + case SNDRV_PCM_TRIGGER_STOP: >> + snd_soc_dai_digital_mute(codec_dai, 1, >> + cstream->direction); > Wouldnt it make sense to fix snd_soc_dai_digital_mute() for multi-codecs. Did > you do same thing for pcm? What do you mean by fix for multi-codecs? > >> + break; >> + } >> } >> >> out: >> @@ -622,23 +633,33 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) >> { >> struct snd_soc_codec *codec = rtd->codec; >> struct snd_soc_platform *platform = rtd->platform; >> - struct snd_soc_dai *codec_dai = rtd->codec_dai; >> struct snd_soc_dai *cpu_dai = rtd->cpu_dai; >> struct snd_compr *compr; >> struct snd_pcm *be_pcm; >> char new_name[64]; >> - int ret = 0, direction = 0; >> - >> - /* check client and interface hw capabilities */ >> - snprintf(new_name, sizeof(new_name), "%s %s-%d", >> - rtd->dai_link->stream_name, codec_dai->name, num); >> - >> - if (codec_dai->driver->playback.channels_min) >> - direction = SND_COMPRESS_PLAYBACK; >> - else if (codec_dai->driver->capture.channels_min) >> - direction = SND_COMPRESS_CAPTURE; >> - else >> - return -EINVAL; >> + int i, ret = 0, direction = -1; >> + >> + for (i = 0; i < rtd->num_codecs; i++) { >> + struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; >> + /* check client and interface hw capabilities */ >> + snprintf(new_name, sizeof(new_name), "%s %s-%d", >> + rtd->dai_link->stream_name, codec_dai->name, num); >> + >> + if (direction < 0) { >> + if (codec_dai->driver->playback.channels_min) >> + direction = SND_COMPRESS_PLAYBACK; >> + else if (codec_dai->driver->capture.channels_min) >> + direction = SND_COMPRESS_CAPTURE; > direction wont change with multiple codecs, so this loop makes no sense here. > For simplcity perhaps we can use cpu_dai? >> + else >> + return -EINVAL; >> + } else { > when will this get executed? You have initialized direction to -1 and if case is > always true. I think compiler will simply remove the below sinppet. direction is set to -1, then the first iteration will set it to the direction of the first codec_dai. The other iteration are just checking that there are all in the same direction and will fail otherwise. >> + if ((codec_dai->driver->playback.channels_min && >> + direction != SND_COMPRESS_PLAYBACK) || >> + (codec_dai->driver->capture.channels_min && >> + direction != SND_COMPRESS_CAPTURE)) > and what exactly are we trying to check here? That every codec_dai are in the same direction. If you think this is pointless since every DAI are always in the same direction, we can just remove it. >> + return -EINVAL; >> + } >> + } >> >> compr = kzalloc(sizeof(*compr), GFP_KERNEL); >> if (compr == NULL) { >> @@ -692,8 +713,11 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) >> rtd->compr = compr; >> compr->private_data = rtd; >> >> - printk(KERN_INFO "compress asoc: %s <-> %s mapping ok\n", codec_dai->name, >> - cpu_dai->name); >> + for (i = 0; i < rtd->num_codecs; i++) { >> + struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; >> + printk(KERN_INFO "compress asoc: %s <-> %s mapping ok\n", >> + codec_dai->name, cpu_dai->name); > wrong again. You are not creating multiple links with multi-codec. Link is still > single. Yeah, I know, the idea was to print that we have multiple codec. I'll use the same "multicodec" info like we did for PCM. Thanks for the feedback, Benoit
On Tue, Jul 01, 2014 at 06:41:17PM +0100, Mark Brown wrote: > On Tue, Jul 01, 2014 at 10:11:34PM +0530, Vinod Koul wrote: > > On Tue, Jul 01, 2014 at 09:47:59AM +0200, Benoit Cousson wrote: > > > > + for (i = 0; i < rtd->num_codecs; i++) { > > > + struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; > > > + > > > + switch (cmd) { > > > + case SNDRV_PCM_TRIGGER_START: > > > + snd_soc_dai_digital_mute(codec_dai, 0, > > > + cstream->direction); > > > + break; > > > + case SNDRV_PCM_TRIGGER_STOP: > > > + snd_soc_dai_digital_mute(codec_dai, 1, > > > + cstream->direction); > > > Wouldnt it make sense to fix snd_soc_dai_digital_mute() for multi-codecs. Did > > you do same thing for pcm? > > Yes, the other callers also iterate through all the CODECs. It might be > sensible to have a wrapper which does the iteration but I do think it's > reasonable for _dai_digital_mute() to just operate on one DAI. Yes that sounds okay as well
On Wed, Jul 02, 2014 at 02:53:50PM +0200, Benoit Cousson wrote: > >>@@ -622,23 +633,33 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) > >> { > >> struct snd_soc_codec *codec = rtd->codec; > >> struct snd_soc_platform *platform = rtd->platform; > >>- struct snd_soc_dai *codec_dai = rtd->codec_dai; > >> struct snd_soc_dai *cpu_dai = rtd->cpu_dai; > >> struct snd_compr *compr; > >> struct snd_pcm *be_pcm; > >> char new_name[64]; > >>- int ret = 0, direction = 0; > >>- > >>- /* check client and interface hw capabilities */ > >>- snprintf(new_name, sizeof(new_name), "%s %s-%d", > >>- rtd->dai_link->stream_name, codec_dai->name, num); > >>- > >>- if (codec_dai->driver->playback.channels_min) > >>- direction = SND_COMPRESS_PLAYBACK; > >>- else if (codec_dai->driver->capture.channels_min) > >>- direction = SND_COMPRESS_CAPTURE; > >>- else > >>- return -EINVAL; > >>+ int i, ret = 0, direction = -1; > >>+ > >>+ for (i = 0; i < rtd->num_codecs; i++) { > >>+ struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; > >>+ /* check client and interface hw capabilities */ > >>+ snprintf(new_name, sizeof(new_name), "%s %s-%d", > >>+ rtd->dai_link->stream_name, codec_dai->name, num); > >>+ > >>+ if (direction < 0) { > >>+ if (codec_dai->driver->playback.channels_min) > >>+ direction = SND_COMPRESS_PLAYBACK; > >>+ else if (codec_dai->driver->capture.channels_min) > >>+ direction = SND_COMPRESS_CAPTURE; > >direction wont change with multiple codecs, so this loop makes no sense here. > >For simplcity perhaps we can use cpu_dai? > >>+ else > >>+ return -EINVAL; > >>+ } else { > >when will this get executed? You have initialized direction to -1 and if case is > >always true. I think compiler will simply remove the below sinppet. > > direction is set to -1, then the first iteration will set it to the > direction of the first codec_dai. The other iteration are just > checking that there are all in the same direction and will fail > otherwise. > > >>+ if ((codec_dai->driver->playback.channels_min && > >>+ direction != SND_COMPRESS_PLAYBACK) || > >>+ (codec_dai->driver->capture.channels_min && > >>+ direction != SND_COMPRESS_CAPTURE)) > >and what exactly are we trying to check here? > > That every codec_dai are in the same direction. > > If you think this is pointless since every DAI are always in the > same direction, we can just remove it. I think that will simplify it. we certainly dont expect different direction, right?
On 03/07/2014 08:41, Vinod Koul wrote: > On Wed, Jul 02, 2014 at 02:53:50PM +0200, Benoit Cousson wrote: >>>> @@ -622,23 +633,33 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) >>>> { >>>> struct snd_soc_codec *codec = rtd->codec; >>>> struct snd_soc_platform *platform = rtd->platform; >>>> - struct snd_soc_dai *codec_dai = rtd->codec_dai; >>>> struct snd_soc_dai *cpu_dai = rtd->cpu_dai; >>>> struct snd_compr *compr; >>>> struct snd_pcm *be_pcm; >>>> char new_name[64]; >>>> - int ret = 0, direction = 0; >>>> - >>>> - /* check client and interface hw capabilities */ >>>> - snprintf(new_name, sizeof(new_name), "%s %s-%d", >>>> - rtd->dai_link->stream_name, codec_dai->name, num); >>>> - >>>> - if (codec_dai->driver->playback.channels_min) >>>> - direction = SND_COMPRESS_PLAYBACK; >>>> - else if (codec_dai->driver->capture.channels_min) >>>> - direction = SND_COMPRESS_CAPTURE; >>>> - else >>>> - return -EINVAL; >>>> + int i, ret = 0, direction = -1; >>>> + >>>> + for (i = 0; i < rtd->num_codecs; i++) { >>>> + struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; >>>> + /* check client and interface hw capabilities */ >>>> + snprintf(new_name, sizeof(new_name), "%s %s-%d", >>>> + rtd->dai_link->stream_name, codec_dai->name, num); >>>> + >>>> + if (direction < 0) { >>>> + if (codec_dai->driver->playback.channels_min) >>>> + direction = SND_COMPRESS_PLAYBACK; >>>> + else if (codec_dai->driver->capture.channels_min) >>>> + direction = SND_COMPRESS_CAPTURE; >>> direction wont change with multiple codecs, so this loop makes no sense here. >>> For simplcity perhaps we can use cpu_dai? >>>> + else >>>> + return -EINVAL; >>>> + } else { >>> when will this get executed? You have initialized direction to -1 and if case is >>> always true. I think compiler will simply remove the below sinppet. >> >> direction is set to -1, then the first iteration will set it to the >> direction of the first codec_dai. The other iteration are just >> checking that there are all in the same direction and will fail >> otherwise. >> >>>> + if ((codec_dai->driver->playback.channels_min && >>>> + direction != SND_COMPRESS_PLAYBACK) || >>>> + (codec_dai->driver->capture.channels_min && >>>> + direction != SND_COMPRESS_CAPTURE)) >>> and what exactly are we trying to check here? >> >> That every codec_dai are in the same direction. >> >> If you think this is pointless since every DAI are always in the >> same direction, we can just remove it. > I think that will simplify it. we certainly dont expect different direction, > right? Lars, Mark Any thought on that? Does that sound reasonable to you to use only the first codec_dai to figure out the direction? Thanks, Benoit
On Thu, Jul 03, 2014 at 01:09:28PM +0200, Benoit Cousson wrote: > On 03/07/2014 08:41, Vinod Koul wrote: > >I think that will simplify it. we certainly dont expect different direction, > >right? > Any thought on that? Does that sound reasonable to you to use only the first > codec_dai to figure out the direction? Yes, it seems sensible enough to me.
On 07/03/2014 01:09 PM, Benoit Cousson wrote: > On 03/07/2014 08:41, Vinod Koul wrote: >> On Wed, Jul 02, 2014 at 02:53:50PM +0200, Benoit Cousson wrote: >>>>> @@ -622,23 +633,33 @@ int soc_new_compress(struct snd_soc_pcm_runtime >>>>> *rtd, int num) >>>>> { >>>>> struct snd_soc_codec *codec = rtd->codec; >>>>> struct snd_soc_platform *platform = rtd->platform; >>>>> - struct snd_soc_dai *codec_dai = rtd->codec_dai; >>>>> struct snd_soc_dai *cpu_dai = rtd->cpu_dai; >>>>> struct snd_compr *compr; >>>>> struct snd_pcm *be_pcm; >>>>> char new_name[64]; >>>>> - int ret = 0, direction = 0; >>>>> - >>>>> - /* check client and interface hw capabilities */ >>>>> - snprintf(new_name, sizeof(new_name), "%s %s-%d", >>>>> - rtd->dai_link->stream_name, codec_dai->name, num); >>>>> - >>>>> - if (codec_dai->driver->playback.channels_min) >>>>> - direction = SND_COMPRESS_PLAYBACK; >>>>> - else if (codec_dai->driver->capture.channels_min) >>>>> - direction = SND_COMPRESS_CAPTURE; >>>>> - else >>>>> - return -EINVAL; >>>>> + int i, ret = 0, direction = -1; >>>>> + >>>>> + for (i = 0; i < rtd->num_codecs; i++) { >>>>> + struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; >>>>> + /* check client and interface hw capabilities */ >>>>> + snprintf(new_name, sizeof(new_name), "%s %s-%d", >>>>> + rtd->dai_link->stream_name, codec_dai->name, num); >>>>> + >>>>> + if (direction < 0) { >>>>> + if (codec_dai->driver->playback.channels_min) >>>>> + direction = SND_COMPRESS_PLAYBACK; >>>>> + else if (codec_dai->driver->capture.channels_min) >>>>> + direction = SND_COMPRESS_CAPTURE; >>>> direction wont change with multiple codecs, so this loop makes no sense >>>> here. >>>> For simplcity perhaps we can use cpu_dai? >>>>> + else >>>>> + return -EINVAL; >>>>> + } else { >>>> when will this get executed? You have initialized direction to -1 and if >>>> case is >>>> always true. I think compiler will simply remove the below sinppet. >>> >>> direction is set to -1, then the first iteration will set it to the >>> direction of the first codec_dai. The other iteration are just >>> checking that there are all in the same direction and will fail >>> otherwise. >>> >>>>> + if ((codec_dai->driver->playback.channels_min && >>>>> + direction != SND_COMPRESS_PLAYBACK) || >>>>> + (codec_dai->driver->capture.channels_min && >>>>> + direction != SND_COMPRESS_CAPTURE)) >>>> and what exactly are we trying to check here? >>> >>> That every codec_dai are in the same direction. >>> >>> If you think this is pointless since every DAI are always in the >>> same direction, we can just remove it. >> I think that will simplify it. we certainly dont expect different direction, >> right? > > Lars, Mark > Any thought on that? Does that sound reasonable to you to use only the first > codec_dai to figure out the direction? > I guess it is ok. But I'm wondering if the direction shouldn't depend on the CPU dai rather than the CODEC dai? E.g. it is possible to have a CODEC with both playback and capture support in two dai_links, one for capture, one for playback. The check above would create a SND_COMPRESS_PLAYBACK stream in both cases. Even if the CPU dai only supported capture in one of the cases. - Lars
On 03/07/2014 13:20, Lars-Peter Clausen wrote: > On 07/03/2014 01:09 PM, Benoit Cousson wrote: >> On 03/07/2014 08:41, Vinod Koul wrote: >>> On Wed, Jul 02, 2014 at 02:53:50PM +0200, Benoit Cousson wrote: >>>>>> @@ -622,23 +633,33 @@ int soc_new_compress(struct snd_soc_pcm_runtime >>>>>> *rtd, int num) >>>>>> { >>>>>> struct snd_soc_codec *codec = rtd->codec; >>>>>> struct snd_soc_platform *platform = rtd->platform; >>>>>> - struct snd_soc_dai *codec_dai = rtd->codec_dai; >>>>>> struct snd_soc_dai *cpu_dai = rtd->cpu_dai; >>>>>> struct snd_compr *compr; >>>>>> struct snd_pcm *be_pcm; >>>>>> char new_name[64]; >>>>>> - int ret = 0, direction = 0; >>>>>> - >>>>>> - /* check client and interface hw capabilities */ >>>>>> - snprintf(new_name, sizeof(new_name), "%s %s-%d", >>>>>> - rtd->dai_link->stream_name, codec_dai->name, num); >>>>>> - >>>>>> - if (codec_dai->driver->playback.channels_min) >>>>>> - direction = SND_COMPRESS_PLAYBACK; >>>>>> - else if (codec_dai->driver->capture.channels_min) >>>>>> - direction = SND_COMPRESS_CAPTURE; >>>>>> - else >>>>>> - return -EINVAL; >>>>>> + int i, ret = 0, direction = -1; >>>>>> + >>>>>> + for (i = 0; i < rtd->num_codecs; i++) { >>>>>> + struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; >>>>>> + /* check client and interface hw capabilities */ >>>>>> + snprintf(new_name, sizeof(new_name), "%s %s-%d", >>>>>> + rtd->dai_link->stream_name, codec_dai->name, num); >>>>>> + >>>>>> + if (direction < 0) { >>>>>> + if (codec_dai->driver->playback.channels_min) >>>>>> + direction = SND_COMPRESS_PLAYBACK; >>>>>> + else if (codec_dai->driver->capture.channels_min) >>>>>> + direction = SND_COMPRESS_CAPTURE; >>>>> direction wont change with multiple codecs, so this loop makes no >>>>> sense >>>>> here. >>>>> For simplcity perhaps we can use cpu_dai? >>>>>> + else >>>>>> + return -EINVAL; >>>>>> + } else { >>>>> when will this get executed? You have initialized direction to -1 >>>>> and if >>>>> case is >>>>> always true. I think compiler will simply remove the below sinppet. >>>> >>>> direction is set to -1, then the first iteration will set it to the >>>> direction of the first codec_dai. The other iteration are just >>>> checking that there are all in the same direction and will fail >>>> otherwise. >>>> >>>>>> + if ((codec_dai->driver->playback.channels_min && >>>>>> + direction != SND_COMPRESS_PLAYBACK) || >>>>>> + (codec_dai->driver->capture.channels_min && >>>>>> + direction != SND_COMPRESS_CAPTURE)) >>>>> and what exactly are we trying to check here? >>>> >>>> That every codec_dai are in the same direction. >>>> >>>> If you think this is pointless since every DAI are always in the >>>> same direction, we can just remove it. >>> I think that will simplify it. we certainly dont expect different >>> direction, >>> right? >> >> Lars, Mark >> Any thought on that? Does that sound reasonable to you to use only the >> first >> codec_dai to figure out the direction? >> > > I guess it is ok. But I'm wondering if the direction shouldn't depend on > the CPU dai rather than the CODEC dai? E.g. it is possible to have a > CODEC with both playback and capture support in two dai_links, one for > capture, one for playback. The check above would create a > SND_COMPRESS_PLAYBACK stream in both cases. Even if the CPU dai only > supported capture in one of the cases. OK, I'll use the cpu_dai then. Thanks, Benoit
On 07/03/2014 01:39 PM, Benoit Cousson wrote: > On 03/07/2014 13:20, Lars-Peter Clausen wrote: >> On 07/03/2014 01:09 PM, Benoit Cousson wrote: >>> On 03/07/2014 08:41, Vinod Koul wrote: >>>> On Wed, Jul 02, 2014 at 02:53:50PM +0200, Benoit Cousson wrote: >>>>>>> @@ -622,23 +633,33 @@ int soc_new_compress(struct snd_soc_pcm_runtime >>>>>>> *rtd, int num) >>>>>>> { >>>>>>> struct snd_soc_codec *codec = rtd->codec; >>>>>>> struct snd_soc_platform *platform = rtd->platform; >>>>>>> - struct snd_soc_dai *codec_dai = rtd->codec_dai; >>>>>>> struct snd_soc_dai *cpu_dai = rtd->cpu_dai; >>>>>>> struct snd_compr *compr; >>>>>>> struct snd_pcm *be_pcm; >>>>>>> char new_name[64]; >>>>>>> - int ret = 0, direction = 0; >>>>>>> - >>>>>>> - /* check client and interface hw capabilities */ >>>>>>> - snprintf(new_name, sizeof(new_name), "%s %s-%d", >>>>>>> - rtd->dai_link->stream_name, codec_dai->name, num); >>>>>>> - >>>>>>> - if (codec_dai->driver->playback.channels_min) >>>>>>> - direction = SND_COMPRESS_PLAYBACK; >>>>>>> - else if (codec_dai->driver->capture.channels_min) >>>>>>> - direction = SND_COMPRESS_CAPTURE; >>>>>>> - else >>>>>>> - return -EINVAL; >>>>>>> + int i, ret = 0, direction = -1; >>>>>>> + >>>>>>> + for (i = 0; i < rtd->num_codecs; i++) { >>>>>>> + struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; >>>>>>> + /* check client and interface hw capabilities */ >>>>>>> + snprintf(new_name, sizeof(new_name), "%s %s-%d", >>>>>>> + rtd->dai_link->stream_name, codec_dai->name, num); >>>>>>> + >>>>>>> + if (direction < 0) { >>>>>>> + if (codec_dai->driver->playback.channels_min) >>>>>>> + direction = SND_COMPRESS_PLAYBACK; >>>>>>> + else if (codec_dai->driver->capture.channels_min) >>>>>>> + direction = SND_COMPRESS_CAPTURE; >>>>>> direction wont change with multiple codecs, so this loop makes no >>>>>> sense >>>>>> here. >>>>>> For simplcity perhaps we can use cpu_dai? >>>>>>> + else >>>>>>> + return -EINVAL; >>>>>>> + } else { >>>>>> when will this get executed? You have initialized direction to -1 >>>>>> and if >>>>>> case is >>>>>> always true. I think compiler will simply remove the below sinppet. >>>>> >>>>> direction is set to -1, then the first iteration will set it to the >>>>> direction of the first codec_dai. The other iteration are just >>>>> checking that there are all in the same direction and will fail >>>>> otherwise. >>>>> >>>>>>> + if ((codec_dai->driver->playback.channels_min && >>>>>>> + direction != SND_COMPRESS_PLAYBACK) || >>>>>>> + (codec_dai->driver->capture.channels_min && >>>>>>> + direction != SND_COMPRESS_CAPTURE)) >>>>>> and what exactly are we trying to check here? >>>>> >>>>> That every codec_dai are in the same direction. >>>>> >>>>> If you think this is pointless since every DAI are always in the >>>>> same direction, we can just remove it. >>>> I think that will simplify it. we certainly dont expect different >>>> direction, >>>> right? >>> >>> Lars, Mark >>> Any thought on that? Does that sound reasonable to you to use only the >>> first >>> codec_dai to figure out the direction? >>> >> >> I guess it is ok. But I'm wondering if the direction shouldn't depend on >> the CPU dai rather than the CODEC dai? E.g. it is possible to have a >> CODEC with both playback and capture support in two dai_links, one for >> capture, one for playback. The check above would create a >> SND_COMPRESS_PLAYBACK stream in both cases. Even if the CPU dai only >> supported capture in one of the cases. > > OK, I'll use the cpu_dai then. Lets wait for Vinod's feedback on this first. He knows this code best and what the intentions are. - Lars
On 03/07/2014 13:43, Lars-Peter Clausen wrote: > On 07/03/2014 01:39 PM, Benoit Cousson wrote: >> On 03/07/2014 13:20, Lars-Peter Clausen wrote: >>> On 07/03/2014 01:09 PM, Benoit Cousson wrote: >>>> On 03/07/2014 08:41, Vinod Koul wrote: >>>>> On Wed, Jul 02, 2014 at 02:53:50PM +0200, Benoit Cousson wrote: >>>>>>>> @@ -622,23 +633,33 @@ int soc_new_compress(struct >>>>>>>> snd_soc_pcm_runtime >>>>>>>> *rtd, int num) >>>>>>>> { >>>>>>>> struct snd_soc_codec *codec = rtd->codec; >>>>>>>> struct snd_soc_platform *platform = rtd->platform; >>>>>>>> - struct snd_soc_dai *codec_dai = rtd->codec_dai; >>>>>>>> struct snd_soc_dai *cpu_dai = rtd->cpu_dai; >>>>>>>> struct snd_compr *compr; >>>>>>>> struct snd_pcm *be_pcm; >>>>>>>> char new_name[64]; >>>>>>>> - int ret = 0, direction = 0; >>>>>>>> - >>>>>>>> - /* check client and interface hw capabilities */ >>>>>>>> - snprintf(new_name, sizeof(new_name), "%s %s-%d", >>>>>>>> - rtd->dai_link->stream_name, codec_dai->name, num); >>>>>>>> - >>>>>>>> - if (codec_dai->driver->playback.channels_min) >>>>>>>> - direction = SND_COMPRESS_PLAYBACK; >>>>>>>> - else if (codec_dai->driver->capture.channels_min) >>>>>>>> - direction = SND_COMPRESS_CAPTURE; >>>>>>>> - else >>>>>>>> - return -EINVAL; >>>>>>>> + int i, ret = 0, direction = -1; >>>>>>>> + >>>>>>>> + for (i = 0; i < rtd->num_codecs; i++) { >>>>>>>> + struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; >>>>>>>> + /* check client and interface hw capabilities */ >>>>>>>> + snprintf(new_name, sizeof(new_name), "%s %s-%d", >>>>>>>> + rtd->dai_link->stream_name, codec_dai->name, num); >>>>>>>> + >>>>>>>> + if (direction < 0) { >>>>>>>> + if (codec_dai->driver->playback.channels_min) >>>>>>>> + direction = SND_COMPRESS_PLAYBACK; >>>>>>>> + else if (codec_dai->driver->capture.channels_min) >>>>>>>> + direction = SND_COMPRESS_CAPTURE; >>>>>>> direction wont change with multiple codecs, so this loop makes no >>>>>>> sense >>>>>>> here. >>>>>>> For simplcity perhaps we can use cpu_dai? >>>>>>>> + else >>>>>>>> + return -EINVAL; >>>>>>>> + } else { >>>>>>> when will this get executed? You have initialized direction to -1 >>>>>>> and if >>>>>>> case is >>>>>>> always true. I think compiler will simply remove the below sinppet. >>>>>> >>>>>> direction is set to -1, then the first iteration will set it to the >>>>>> direction of the first codec_dai. The other iteration are just >>>>>> checking that there are all in the same direction and will fail >>>>>> otherwise. >>>>>> >>>>>>>> + if ((codec_dai->driver->playback.channels_min && >>>>>>>> + direction != SND_COMPRESS_PLAYBACK) || >>>>>>>> + (codec_dai->driver->capture.channels_min && >>>>>>>> + direction != SND_COMPRESS_CAPTURE)) >>>>>>> and what exactly are we trying to check here? >>>>>> >>>>>> That every codec_dai are in the same direction. >>>>>> >>>>>> If you think this is pointless since every DAI are always in the >>>>>> same direction, we can just remove it. >>>>> I think that will simplify it. we certainly dont expect different >>>>> direction, >>>>> right? >>>> >>>> Lars, Mark >>>> Any thought on that? Does that sound reasonable to you to use only the >>>> first >>>> codec_dai to figure out the direction? >>>> >>> >>> I guess it is ok. But I'm wondering if the direction shouldn't depend on >>> the CPU dai rather than the CODEC dai? E.g. it is possible to have a >>> CODEC with both playback and capture support in two dai_links, one for >>> capture, one for playback. The check above would create a >>> SND_COMPRESS_PLAYBACK stream in both cases. Even if the CPU dai only >>> supported capture in one of the cases. >> >> OK, I'll use the cpu_dai then. > > Lets wait for Vinod's feedback on this first. He knows this code best > and what the intentions are. Sure, but he was the first one to propose using that :-) >>>>>>> direction wont change with multiple codecs, so this loop makes no >>>>>>> sense >>>>>>> here. >>>>>>> For simplcity perhaps we can use cpu_dai? Regards, Benoit
On Thu, Jul 03, 2014 at 01:46:23PM +0200, Benoit Cousson wrote: > On 03/07/2014 13:43, Lars-Peter Clausen wrote: > > On 07/03/2014 01:39 PM, Benoit Cousson wrote: > >> On 03/07/2014 13:20, Lars-Peter Clausen wrote: > >>> On 07/03/2014 01:09 PM, Benoit Cousson wrote: > >>>> On 03/07/2014 08:41, Vinod Koul wrote: > >>>>> On Wed, Jul 02, 2014 at 02:53:50PM +0200, Benoit Cousson wrote: > >>>>>>>> @@ -622,23 +633,33 @@ int soc_new_compress(struct > >>>>>>>> snd_soc_pcm_runtime > >>>>>>>> *rtd, int num) > >>>>>>>> { > >>>>>>>> struct snd_soc_codec *codec = rtd->codec; > >>>>>>>> struct snd_soc_platform *platform = rtd->platform; > >>>>>>>> - struct snd_soc_dai *codec_dai = rtd->codec_dai; > >>>>>>>> struct snd_soc_dai *cpu_dai = rtd->cpu_dai; > >>>>>>>> struct snd_compr *compr; > >>>>>>>> struct snd_pcm *be_pcm; > >>>>>>>> char new_name[64]; > >>>>>>>> - int ret = 0, direction = 0; > >>>>>>>> - > >>>>>>>> - /* check client and interface hw capabilities */ > >>>>>>>> - snprintf(new_name, sizeof(new_name), "%s %s-%d", > >>>>>>>> - rtd->dai_link->stream_name, codec_dai->name, num); > >>>>>>>> - > >>>>>>>> - if (codec_dai->driver->playback.channels_min) > >>>>>>>> - direction = SND_COMPRESS_PLAYBACK; > >>>>>>>> - else if (codec_dai->driver->capture.channels_min) > >>>>>>>> - direction = SND_COMPRESS_CAPTURE; > >>>>>>>> - else > >>>>>>>> - return -EINVAL; > >>>>>>>> + int i, ret = 0, direction = -1; > >>>>>>>> + > >>>>>>>> + for (i = 0; i < rtd->num_codecs; i++) { > >>>>>>>> + struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; > >>>>>>>> + /* check client and interface hw capabilities */ > >>>>>>>> + snprintf(new_name, sizeof(new_name), "%s %s-%d", > >>>>>>>> + rtd->dai_link->stream_name, codec_dai->name, num); > >>>>>>>> + > >>>>>>>> + if (direction < 0) { > >>>>>>>> + if (codec_dai->driver->playback.channels_min) > >>>>>>>> + direction = SND_COMPRESS_PLAYBACK; > >>>>>>>> + else if (codec_dai->driver->capture.channels_min) > >>>>>>>> + direction = SND_COMPRESS_CAPTURE; > >>>>>>> direction wont change with multiple codecs, so this loop makes no > >>>>>>> sense > >>>>>>> here. > >>>>>>> For simplcity perhaps we can use cpu_dai? > >>>>>>>> + else > >>>>>>>> + return -EINVAL; > >>>>>>>> + } else { > >>>>>>> when will this get executed? You have initialized direction to -1 > >>>>>>> and if > >>>>>>> case is > >>>>>>> always true. I think compiler will simply remove the below sinppet. > >>>>>> > >>>>>> direction is set to -1, then the first iteration will set it to the > >>>>>> direction of the first codec_dai. The other iteration are just > >>>>>> checking that there are all in the same direction and will fail > >>>>>> otherwise. > >>>>>> > >>>>>>>> + if ((codec_dai->driver->playback.channels_min && > >>>>>>>> + direction != SND_COMPRESS_PLAYBACK) || > >>>>>>>> + (codec_dai->driver->capture.channels_min && > >>>>>>>> + direction != SND_COMPRESS_CAPTURE)) > >>>>>>> and what exactly are we trying to check here? > >>>>>> > >>>>>> That every codec_dai are in the same direction. > >>>>>> > >>>>>> If you think this is pointless since every DAI are always in the > >>>>>> same direction, we can just remove it. > >>>>> I think that will simplify it. we certainly dont expect different > >>>>> direction, > >>>>> right? > >>>> > >>>> Lars, Mark > >>>> Any thought on that? Does that sound reasonable to you to use only the > >>>> first > >>>> codec_dai to figure out the direction? > >>>> > >>> > >>> I guess it is ok. But I'm wondering if the direction shouldn't depend on > >>> the CPU dai rather than the CODEC dai? E.g. it is possible to have a > >>> CODEC with both playback and capture support in two dai_links, one for > >>> capture, one for playback. The check above would create a > >>> SND_COMPRESS_PLAYBACK stream in both cases. Even if the CPU dai only > >>> supported capture in one of the cases. > >> > >> OK, I'll use the cpu_dai then. > > > > Lets wait for Vinod's feedback on this first. He knows this code best > > and what the intentions are. > > Sure, but he was the first one to propose using that :-) cpu_dai should be okay :) BUT Now thinking over this again, does this make sense do do with multiple codecs?? For folks haveing decoders in DSP inside SoC, the compressed device will be actually a FE. The BE will be PCM to which codec would be linked. The folks supporting decoders inside codec like WM wont ever need this. Mark, do you agree to this? So re-thinking again on why we need this??
On Thu, Jul 03, 2014 at 05:36:13PM +0530, Vinod Koul wrote: > On Thu, Jul 03, 2014 at 01:46:23PM +0200, Benoit Cousson wrote: > > On 03/07/2014 13:43, Lars-Peter Clausen wrote: > > > On 07/03/2014 01:39 PM, Benoit Cousson wrote: > > >> On 03/07/2014 13:20, Lars-Peter Clausen wrote: > > >>> On 07/03/2014 01:09 PM, Benoit Cousson wrote: > > >>>> On 03/07/2014 08:41, Vinod Koul wrote: > > >>>>> On Wed, Jul 02, 2014 at 02:53:50PM +0200, Benoit Cousson wrote: People, please delete irrelevant context from your e-mails - it makes it easier to find the new content. > BUT Now thinking over this again, does this make sense do do with multiple > codecs?? > For folks haveing decoders in DSP inside SoC, the compressed device will be > actually a FE. The BE will be PCM to which codec would be linked. The folks > supporting decoders inside codec like WM wont ever need this. > Mark, do you agree to this? > So re-thinking again on why we need this?? The use case tends to be for applications that have one device per physical output. This isn't normally mobile, it's normally high performance audio applications where people are doing things to try to electrically isolate the analogue outputs or dealing with high power so need to keep speaker outputs physically separate. I can imagine set top box type applications (which do use offloaded media decode) doing this.
On Thu, Jul 03, 2014 at 01:18:46PM +0100, Mark Brown wrote: > > BUT Now thinking over this again, does this make sense do do with multiple > > codecs?? > > > For folks haveing decoders in DSP inside SoC, the compressed device will be > > actually a FE. The BE will be PCM to which codec would be linked. The folks > > supporting decoders inside codec like WM wont ever need this. > > > Mark, do you agree to this? > > > So re-thinking again on why we need this?? > > The use case tends to be for applications that have one device per > physical output. This isn't normally mobile, it's normally high > performance audio applications where people are doing things to try to > electrically isolate the analogue outputs or dealing with high power so > need to keep speaker outputs physically separate. I can imagine set top > box type applications (which do use offloaded media decode) doing this. Not sure if I follow you, I have no idea of how these systems work. But if sound card has compressed device it would need to represent using DPCM as we don't know the decoder PCM output. The multiple codecs would then connect to the PCM BE. So on Compressed FE, we wont have multiple codecs. For codecs, the compressed audio will go to one codec, multiple ones wont make sense. So how can we have a situation where we have compressed device linked to multiple codecs?
On 07/03/2014 06:15 PM, Vinod Koul wrote: > On Thu, Jul 03, 2014 at 01:18:46PM +0100, Mark Brown wrote: >>> BUT Now thinking over this again, does this make sense do do with multiple >>> codecs?? >> >>> For folks haveing decoders in DSP inside SoC, the compressed device will be >>> actually a FE. The BE will be PCM to which codec would be linked. The folks >>> supporting decoders inside codec like WM wont ever need this. >> >>> Mark, do you agree to this? >> >>> So re-thinking again on why we need this?? >> >> The use case tends to be for applications that have one device per >> physical output. This isn't normally mobile, it's normally high >> performance audio applications where people are doing things to try to >> electrically isolate the analogue outputs or dealing with high power so >> need to keep speaker outputs physically separate. I can imagine set top >> box type applications (which do use offloaded media decode) doing this. > > Not sure if I follow you, I have no idea of how these systems work. > > But if sound card has compressed device it would need to represent using DPCM as > we don't know the decoder PCM output. The multiple codecs would then connect to > the PCM BE. > So on Compressed FE, we wont have multiple codecs. > > For codecs, the compressed audio will go to one codec, multiple ones wont make > sense. > > So how can we have a situation where we have compressed device linked to > multiple codecs? > If the assumption is that a DAI link that has a compressed DAI on the CPU side is never connected to a 'real' CODEC (or multiple CODECS) on the CODEC side. I think we can just leave soc-compress.c alone and just add a sanity check to make sure that num_codecs is always 1. - Lars
On Thu, Jul 03, 2014 at 09:45:17PM +0530, Vinod Koul wrote: > On Thu, Jul 03, 2014 at 01:18:46PM +0100, Mark Brown wrote: > > The use case tends to be for applications that have one device per > > physical output. This isn't normally mobile, it's normally high > > performance audio applications where people are doing things to try to > > electrically isolate the analogue outputs or dealing with high power so > > need to keep speaker outputs physically separate. I can imagine set top > > box type applications (which do use offloaded media decode) doing this. > Not sure if I follow you, I have no idea of how these systems work. They're having the SoC play stereo (or whatever) data and then having multiple CODECs on the bus, each parsing some subset of the channels (typically one channel per CODEC). > So how can we have a situation where we have compressed device linked to > multiple codecs? If it's intended to be DPCM only (which it iss now I think about it) it sounds like you can't have it linked to *any* real CODECS, at least not directly!
>>> The use case tends to be for applications that have one device per >>> physical output. This isn't normally mobile, it's normally high >>> performance audio applications where people are doing things to try to >>> electrically isolate the analogue outputs or dealing with high power so >>> need to keep speaker outputs physically separate. I can imagine set top >>> box type applications (which do use offloaded media decode) doing this. > >> Not sure if I follow you, I have no idea of how these systems work. > > They're having the SoC play stereo (or whatever) data and then having > multiple CODECs on the bus, each parsing some subset of the channels > (typically one channel per CODEC). This sort of stream aggregation/split is a very valid use case that's coming to mobiles in the very near future with new interfaces being standardized. > >> So how can we have a situation where we have compressed device linked to >> multiple codecs? > > If it's intended to be DPCM only (which it iss now I think about it) it > sounds like you can't have it linked to *any* real CODECS, at least not > directly! there are very few references to codec_dais in soc-compress and some are in sections copy/pasted from soc-pcm, which makes me wonder as well if they needed to be there in the first place. -Pierre
On 03/07/2014 20:23, Lars-Peter Clausen wrote: [...] > If the assumption is that a DAI link that has a compressed DAI on the > CPU side is never connected to a 'real' CODEC (or multiple CODECS) on > the CODEC side. I think we can just leave soc-compress.c alone and just > add a sanity check to make sure that num_codecs is always 1. OK, I'll repost the series without any change on soc-compress.c beside a test. Thanks, Benoit
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index f96fb96..cd65b12 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -155,14 +155,17 @@ static void close_delayed_work(struct work_struct *work) { struct snd_soc_pcm_runtime *rtd = container_of(work, struct snd_soc_pcm_runtime, delayed_work.work); - struct snd_soc_dai *codec_dai = rtd->codec_dai; + int i; mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); - dev_dbg(rtd->dev, "ASoC: pop wq checking: %s status: %s waiting: %s\n", - codec_dai->driver->playback.stream_name, - codec_dai->playback_active ? "active" : "inactive", - rtd->pop_wait ? "yes" : "no"); + for (i = 0; i < rtd->num_codecs; i++) { + struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; + dev_dbg(rtd->dev, "ASoC: pop wq checking: %s status: %s waiting: %s\n", + codec_dai->driver->playback.stream_name, + codec_dai->playback_active ? "active" : "inactive", + rtd->pop_wait ? "yes" : "no"); + } /* are we waiting on this codec DAI stream */ if (rtd->pop_wait == 1) { @@ -179,8 +182,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream) struct snd_soc_pcm_runtime *rtd = cstream->private_data; struct snd_soc_platform *platform = rtd->platform; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - int stream; + int stream, i; mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); @@ -191,14 +193,18 @@ static int soc_compr_free(struct snd_compr_stream *cstream) snd_soc_runtime_deactivate(rtd, stream); - snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction); + for (i = 0; i < rtd->num_codecs; i++) { + struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; + + snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction); + + if (!codec_dai->active) + codec_dai->rate = 0; + } if (!cpu_dai->active) cpu_dai->rate = 0; - if (!codec_dai->active) - codec_dai->rate = 0; - if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->shutdown) rtd->dai_link->compr_ops->shutdown(cstream); @@ -283,8 +289,7 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd) struct snd_soc_pcm_runtime *rtd = cstream->private_data; struct snd_soc_platform *platform = rtd->platform; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - int ret = 0; + int i, ret = 0; mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); @@ -294,13 +299,19 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd) goto out; } - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - snd_soc_dai_digital_mute(codec_dai, 0, cstream->direction); - break; - case SNDRV_PCM_TRIGGER_STOP: - snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction); - break; + for (i = 0; i < rtd->num_codecs; i++) { + struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + snd_soc_dai_digital_mute(codec_dai, 0, + cstream->direction); + break; + case SNDRV_PCM_TRIGGER_STOP: + snd_soc_dai_digital_mute(codec_dai, 1, + cstream->direction); + break; + } } out: @@ -622,23 +633,33 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_platform *platform = rtd->platform; - struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_compr *compr; struct snd_pcm *be_pcm; char new_name[64]; - int ret = 0, direction = 0; - - /* check client and interface hw capabilities */ - snprintf(new_name, sizeof(new_name), "%s %s-%d", - rtd->dai_link->stream_name, codec_dai->name, num); - - if (codec_dai->driver->playback.channels_min) - direction = SND_COMPRESS_PLAYBACK; - else if (codec_dai->driver->capture.channels_min) - direction = SND_COMPRESS_CAPTURE; - else - return -EINVAL; + int i, ret = 0, direction = -1; + + for (i = 0; i < rtd->num_codecs; i++) { + struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; + /* check client and interface hw capabilities */ + snprintf(new_name, sizeof(new_name), "%s %s-%d", + rtd->dai_link->stream_name, codec_dai->name, num); + + if (direction < 0) { + if (codec_dai->driver->playback.channels_min) + direction = SND_COMPRESS_PLAYBACK; + else if (codec_dai->driver->capture.channels_min) + direction = SND_COMPRESS_CAPTURE; + else + return -EINVAL; + } else { + if ((codec_dai->driver->playback.channels_min && + direction != SND_COMPRESS_PLAYBACK) || + (codec_dai->driver->capture.channels_min && + direction != SND_COMPRESS_CAPTURE)) + return -EINVAL; + } + } compr = kzalloc(sizeof(*compr), GFP_KERNEL); if (compr == NULL) { @@ -692,8 +713,11 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) rtd->compr = compr; compr->private_data = rtd; - printk(KERN_INFO "compress asoc: %s <-> %s mapping ok\n", codec_dai->name, - cpu_dai->name); + for (i = 0; i < rtd->num_codecs; i++) { + struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; + printk(KERN_INFO "compress asoc: %s <-> %s mapping ok\n", + codec_dai->name, cpu_dai->name); + } return ret; compr_err:
Add multicodec support in soc-compress.c Signed-off-by: Benoit Cousson <bcousson@baylibre.com> Cc: Misael Lopez Cruz <misael.lopez@ti.com> --- sound/soc/soc-compress.c | 94 ++++++++++++++++++++++++++++++------------------ 1 file changed, 59 insertions(+), 35 deletions(-)