diff mbox

omap4-droid4: voice call support was Re: [PATCHv5,5/5] ARM: dts: omap4-droid4: add soundcard

Message ID 20180326141638.GB1450@amd (mailing list archive)
State New, archived
Headers show

Commit Message

Pavel Machek March 26, 2018, 2:16 p.m. UTC
Hi!

Do you have any ideas what needs to be done for voice calls support? I
can talk to the modem and start a call.

Then something like this (untested!) is certainly needed. Probably
more...

Thanks,
									Pavel

Comments

Sebastian Reichel March 26, 2018, 3:58 p.m. UTC | #1
Hi,

On Mon, Mar 26, 2018 at 04:16:38PM +0200, Pavel Machek wrote:
> Do you have any ideas what needs to be done for voice calls
> support?

Sure.

> I can talk to the modem and start a call.

Doing an AT query is the easy part :)

> Then something like this (untested!) is certainly needed.
> Probably more...

I intentionally left this part out. The CPCAP codec has two DAIs
and not 3+. The code you just added is a hack from Motorola. Their
driver is full of hacks and it's obvious its author(s) did not
fully understand the ASoC APIs.

My understanding is, that we only need to replace the audio-graph-card
driver to something more complex. The VOICE DAI needs to be configured
differently based on the use case:

call:
	* mode=i2s
	* freq=26000000
	* samprate=16000 or samprate=8000

bt voice:
	* mode="4 timeslots network"
	* freq=26000000
	* samprate=8000
	* CPCAP_BIT_MIC2_TIMESLOT1

bt call:
	* mode="4 timeslots network"
	* freq=19200000
	* samprate=8000
	* CPCAP_BIT_MIC2_TIMESLOT1

"audio-graph-card" is not capable of doing this. I was planning to
try "audio-graph-scu-card" in combination with adding codecs for the
modem and BT to DT. If that does not work we need a Droid 4 specific
soundcard driver.

Either way "audio-graph-card" is not the correct driver for D4. I
added it nevertheless, since it gets audio working for now and there
is no risk of DT breakage. Old *.dtb will continue to work with the
"audio-graph-card" even after we switch to something else.

-- Sebastian

> Thanks,
> 									Pavel
> 
> diff --git a/sound/soc/codecs/cpcap.c b/sound/soc/codecs/cpcap.c
> index aedb267..7646f68 100644
> --- a/sound/soc/codecs/cpcap.c
> +++ b/sound/soc/codecs/cpcap.c
> @@ -1280,6 +1280,60 @@ static int cpcap_voice_hw_params(struct snd_pcm_substream *substream,
>  	return 0;
>  }
>  
> +static int cpcap_incall_hw_params(struct snd_pcm_substream *substream,
> +				 struct snd_pcm_hw_params *params,
> +				 struct snd_soc_dai *dai)
> +{
> +	struct snd_soc_codec *codec = dai->codec;
> +	struct device *dev = codec->dev;
> +	struct cpcap_audio *cpcap = snd_soc_codec_get_drvdata(codec);
> +	static const u16 reg_cdi = CPCAP_REG_CDI;
> +	int rate = params_rate(params);
> +	int channels = params_channels(params);
> +	int direction = substream->stream;
> +	u16 val, mask;
> +	int err;
> +
> +	dev_dbg(dev, "Incall setup HW params: rate=%d, direction=%d, chan=%d",
> +		rate, direction, channels);
> +
> +	/* codec, 1 in original code is CPCAP_REG_CC
> +	   codec, 2 is CPCAP_REG_CDI
> +	   codec, 5 is CPCAP_REG_TXI */
> +
> +	if (/* cpcap->codec_strm_cnt == */ 1) {
> +		/*
> +		if (pdata->voice_type != VOICE_TYPE_QC)
> +			printk("FIXME: Only MDM6600 support is implemented here.\n");
> +		*/
> +
> +		err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, 0xffff, 0xAE02);
> +		if (err) printk("cpcap error %d\n", __LINE__);
> +
> +		err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CC, 0xffff, 0x6120);
> +		if (err) printk("cpcap error %d\n", __LINE__);
> +
> +		err = cpcap_set_samprate(cpcap, CPCAP_DAI_VOICE, rate);
> +		printk("Configured stream\n");
> +	}
> +
> +	/* (direction == SNDRV_PCM_STREAM_CAPTURE) ?? */
> +	if (substream->stream) { /* up link */
> +		unsigned int set =  CPCAP_BIT_AUDIHPF_1 | CPCAP_BIT_AUDIHPF_0;
> +		err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CC, set, set);
> +		if (err) printk("cpcap error %d\n", __LINE__);
> +
> +		set = CPCAP_BIT_MB_ON1L | CPCAP_BIT_MB_ON1R;
> +		err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI, set, set);
> +	} else { /* down link */
> +		unsigned int set =  CPCAP_BIT_AUDOHPF_1 | CPCAP_BIT_AUDOHPF_0;
> +		err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CC, set, set);
> +		if (err) printk("cpcap error %d\n", __LINE__);
> +	}
> +
> +	return err;
> +}
> +
>  static int cpcap_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
>  				      unsigned int freq, int dir)
>  {
> @@ -1394,6 +1448,14 @@ static const struct snd_soc_dai_ops cpcap_dai_voice_ops = {
>  	.digital_mute	= cpcap_voice_set_mute,
>  };
>  
> +static const struct snd_soc_dai_ops cpcap_dai_incall_ops = {
> +	/* FIXME */
> +	.hw_params	= cpcap_incall_hw_params,
> +	.set_sysclk	= cpcap_voice_set_dai_sysclk,
> +	.set_fmt	= cpcap_voice_set_dai_fmt,
> +	.digital_mute	= cpcap_voice_set_mute,
> +};
> +
>  static struct snd_soc_dai_driver cpcap_dai[] = {
>  {
>  	.id = 0,
> @@ -1426,6 +1488,26 @@ static struct snd_soc_dai_driver cpcap_dai[] = {
>  	},
>  	.ops = &cpcap_dai_voice_ops,
>  },
> +{
> +	.id = 2,
> +	.name = "cpcap in-call",
> +	.playback = {
> +		.stream_name = "InCall DL",
> +		.channels_min = 1,
> +		.channels_max = 2,
> +		.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
> +		.formats = SNDRV_PCM_FMTBIT_S16_LE,
> +	},
> +	.capture = {
> +		.stream_name = "Capture",
> +		.channels_min = 1,
> +		.channels_max = 2,
> +		.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
> +		.formats = SNDRV_PCM_FMTBIT_S16_LE,
> +	},
> +	.ops = &cpcap_dai_incall_ops,
> +},
> +/* FIXME: this misses bt-call, cpcap bt, BPvoice, FM */
>  };
>  
>  static int cpcap_dai_mux(struct cpcap_audio *cpcap, bool swap_dai_configuration)
> 
> 
> 
> 
> 
> 
> -- 
> (english) http://www.livejournal.com/~pavelmachek
> (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Pavel Machek March 26, 2018, 8:31 p.m. UTC | #2
Hi!

> On Mon, Mar 26, 2018 at 04:16:38PM +0200, Pavel Machek wrote:
> > Do you have any ideas what needs to be done for voice calls
> > support?
> 
> Sure.

:-).

> > I can talk to the modem and start a call.
> 
> Doing an AT query is the easy part :)

Well, yes. Doing it right (ofono, etc) is not that easy.

> > Then something like this (untested!) is certainly needed.
> > Probably more...
> 
> I intentionally left this part out. The CPCAP codec has two DAIs
> and not 3+. The code you just added is a hack from Motorola. Their
> driver is full of hacks and it's obvious its author(s) did not
> fully understand the ASoC APIs.

Ok.

> My understanding is, that we only need to replace the audio-graph-card
> driver to something more complex. The VOICE DAI needs to be configured
> differently based on the use case:
> 
> call:
> 	* mode=i2s
> 	* freq=26000000
> 	* samprate=16000 or samprate=8000

Ok, lets ignore bluetooth for now. There is "normal" mode, and then
there's "call" mode, right? Where's "normal" mode configured?

Could we simply always configure the VOICE DAI in the call mode? Yes,
it would limit samplerates to 8 or 16k, but .. that's not too
important limitation for voice codec...?

> "audio-graph-card" is not capable of doing this. I was planning to
> try "audio-graph-scu-card" in combination with adding codecs for the
> modem and BT to DT. If that does not work we need a Droid 4 specific
> soundcard driver.
> 
> Either way "audio-graph-card" is not the correct driver for D4. I
> added it nevertheless, since it gets audio working for now and there
> is no risk of DT breakage. Old *.dtb will continue to work with the
> "audio-graph-card" even after we switch to something else.

Well, you'll still cause regressions when you change the dts, as
people will have wrong .config for new dts.

Best regards,
									Pavel
Sebastian Reichel March 26, 2018, 11:10 p.m. UTC | #3
Hi,

On Mon, Mar 26, 2018 at 10:31:54PM +0200, Pavel Machek wrote:
> Hi!
> 
> > On Mon, Mar 26, 2018 at 04:16:38PM +0200, Pavel Machek wrote:
> > > Do you have any ideas what needs to be done for voice calls
> > > support?
> > 
> > Sure.
> 
> :-).
> 
> > > I can talk to the modem and start a call.
> > 
> > Doing an AT query is the easy part :)
> 
> Well, yes. Doing it right (ofono, etc) is not that easy.

I agree. That can be worked on independently.

> > > Then something like this (untested!) is certainly needed.
> > > Probably more...
> > 
> > I intentionally left this part out. The CPCAP codec has two DAIs
> > and not 3+. The code you just added is a hack from Motorola. Their
> > driver is full of hacks and it's obvious its author(s) did not
> > fully understand the ASoC APIs.
> 
> Ok.
> 
> > My understanding is, that we only need to replace the audio-graph-card
> > driver to something more complex. The VOICE DAI needs to be configured
> > differently based on the use case:
> > 
> > call:
> > 	* mode=i2s
> > 	* freq=26000000
> > 	* samprate=16000 or samprate=8000
> 
> Ok, lets ignore bluetooth for now. There is "normal" mode, and then
> there's "call" mode, right? Where's "normal" mode configured?

mcbsp3_port: port {
	cpu_dai3: endpoint {
		dai-format = "dsp_a";
		frame-master = <&cpcap_audio_codec1>;
		bitclock-master = <&cpcap_audio_codec1>;
		remote-endpoint = <&cpcap_audio_codec1>;
	};
};

> Could we simply always configure the VOICE DAI in the call mode? Yes,
> it would limit samplerates to 8 or 16k, but .. that's not too
> important limitation for voice codec...?

I think we could configure "normal" mode to use the same settings
as call mode. But ASoC will disable CPCAP, since there will be no
active user without ASoC knowing about the modem.

> > "audio-graph-card" is not capable of doing this. I was planning to
> > try "audio-graph-scu-card" in combination with adding codecs for the
> > modem and BT to DT. If that does not work we need a Droid 4 specific
> > soundcard driver.
> > 
> > Either way "audio-graph-card" is not the correct driver for D4. I
> > added it nevertheless, since it gets audio working for now and there
> > is no risk of DT breakage. Old *.dtb will continue to work with the
> > "audio-graph-card" even after we switch to something else.
> 
> Well, you'll still cause regressions when you change the dts, as
> people will have wrong .config for new dts.

That's correct, the .config needs to change. I think that's
ok, because the only alternative is having no audio support
at all until the soundcard driver is ready. This means, that
you also need to change .config once its ready (in case you
want to use it).

-- Sebastian
Mark Brown March 27, 2018, 12:14 p.m. UTC | #4
On Mon, Mar 26, 2018 at 05:58:28PM +0200, Sebastian Reichel wrote:

> My understanding is, that we only need to replace the audio-graph-card
> driver to something more complex. The VOICE DAI needs to be configured
> differently based on the use case:

No, this is exactly the sort of use case with multiple DAIs that the
graph card is intended to enable over the old simple-card.

> "audio-graph-card" is not capable of doing this. I was planning to
> try "audio-graph-scu-card" in combination with adding codecs for the
> modem and BT to DT. If that does not work we need a Droid 4 specific
> soundcard driver.

That's just the audio graph card with some hacks for working with a DPCM
based SoC driver set.
Pavel Machek March 27, 2018, 8:41 p.m. UTC | #5
Hi!

> > > My understanding is, that we only need to replace the audio-graph-card
> > > driver to something more complex. The VOICE DAI needs to be configured
> > > differently based on the use case:
> > > 
> > > call:
> > > 	* mode=i2s
> > > 	* freq=26000000
> > > 	* samprate=16000 or samprate=8000
> > 
> > Ok, lets ignore bluetooth for now. There is "normal" mode, and then
> > there's "call" mode, right? Where's "normal" mode configured?
> 
> mcbsp3_port: port {
> 	cpu_dai3: endpoint {
> 		dai-format = "dsp_a";
> 		frame-master = <&cpcap_audio_codec1>;
> 		bitclock-master = <&cpcap_audio_codec1>;
> 		remote-endpoint = <&cpcap_audio_codec1>;
> 	};
> };

Hmm. Can't tell mode and freq here easily. Does it default to i2s /
26000000?

> > Could we simply always configure the VOICE DAI in the call mode? Yes,
> > it would limit samplerates to 8 or 16k, but .. that's not too
> > important limitation for voice codec...?
> 
> I think we could configure "normal" mode to use the same settings
> as call mode. But ASoC will disable CPCAP, since there will be no
> active user without ASoC knowing about the modem.

Ok, but then we can just start playback/recording with the call, and
everything should work, no?

But Motorola code seems to do different magic according to modem type,
so things may not be as easy.

                if (pdata->voice_type == VOICE_TYPE_STE) {
                        /* STE_M570 */
                        ret = cpcap_audio_reg_write(codec, 2, 0xAE06);
                        if (rate == 16000)
				ret |= cpcap_audio_reg_write(codec, 1, 0x8720);
                        else
                                ret |= cpcap_audio_reg_write(codec, 1, 0x8120);
                } else if (pdata->voice_type == VOICE_TYPE_QC) {
                        /* MDM6600 */
                        ret = cpcap_audio_reg_write(codec, 2, 0xAE02);
                        if (rate == 16000) {
                                ret |= cpcap_audio_reg_write(codec, 1, 0x6720);
                        } else {
                                ret |= cpcap_audio_reg_write(codec, 1, 0x6120);
                        }


> > > "audio-graph-card" is not capable of doing this. I was planning to
> > > try "audio-graph-scu-card" in combination with adding codecs for the
> > > modem and BT to DT. If that does not work we need a Droid 4 specific
> > > soundcard driver.
> > > 
> > > Either way "audio-graph-card" is not the correct driver for D4. I
> > > added it nevertheless, since it gets audio working for now and there
> > > is no risk of DT breakage. Old *.dtb will continue to work with the
> > > "audio-graph-card" even after we switch to something else.
> > 
> > Well, you'll still cause regressions when you change the dts, as
> > people will have wrong .config for new dts.
> 
> That's correct, the .config needs to change. I think that's
> ok, because the only alternative is having no audio support
> at all until the soundcard driver is ready. This means, that
> you also need to change .config once its ready (in case you
> want to use it).

Ok, another problem seems to be that spaces in audio device name seem
to confuse the userland.

Aha, here:

user@devuan:~$ cat /proc/asound/cards
 0 [H58006000encode]: HDMI_58006000_e - HDMI 58006000.encoder
                       HDMI 58006000.encoder
 1 [Audio          ]: Droid_4_Audio - Droid 4 Audio
                       Droid 4 Audio
		       
See how the card is refered simply as "Audio"? Same thing then happens
in alsa "state" file:

state.Audio {
        control.1 {

.

Best regards,

									Pavel
Tony Lindgren March 27, 2018, 8:51 p.m. UTC | #6
* Pavel Machek <pavel@ucw.cz> [180327 20:42]:
> But Motorola code seems to do different magic according to modem type,
> so things may not be as easy.
> 
>                 if (pdata->voice_type == VOICE_TYPE_STE) {
>                         /* STE_M570 */
>                         ret = cpcap_audio_reg_write(codec, 2, 0xAE06);
>                         if (rate == 16000)
> 				ret |= cpcap_audio_reg_write(codec, 1, 0x8720);
>                         else
>                                 ret |= cpcap_audio_reg_write(codec, 1, 0x8120);
>                 } else if (pdata->voice_type == VOICE_TYPE_QC) {
>                         /* MDM6600 */
>                         ret = cpcap_audio_reg_write(codec, 2, 0xAE02);
>                         if (rate == 16000) {
>                                 ret |= cpcap_audio_reg_write(codec, 1, 0x6720);
>                         } else {
>                                 ret |= cpcap_audio_reg_write(codec, 1, 0x6120);
>                         }

The parts not related to mdm6600 can be ignored until somebody
gets some device other modems working with mainline kernel.

And if there are any refrerences to W3GLTE, or wrigley, it
supposedly never worked for voice calls and only data.

Regards,

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Sebastian Reichel March 27, 2018, 10:22 p.m. UTC | #7
Hi Mark,

On Tue, Mar 27, 2018 at 08:14:41PM +0800, Mark Brown wrote:
> On Mon, Mar 26, 2018 at 05:58:28PM +0200, Sebastian Reichel wrote:
> 
> > My understanding is, that we only need to replace the audio-graph-card
> > driver to something more complex. The VOICE DAI needs to be configured
> > differently based on the use case:
> 
> No, this is exactly the sort of use case with multiple DAIs that the
> graph card is intended to enable over the old simple-card.

Oh nice. So the Droid 4 hardware wiring looks like this (at least
according to my understanding):

+----------+         +-------------+
| OMAP4    |         | CPCAP       |
|          |         |             |
| [McBSP2] | <-----> | [HiFi DAI]  |
|          |         |             |
| [McBSP3] | <--+--> | [Voice DAI] |
|          |    |    |             |
+----------+    |    +-------------+
                |
+----------+    |    +-------------+
| MDM6600  |    |    | WL1285      |
|          |    |    |             |
|    [DAI] | <--+--> | [DAI]       |
|          |         |             |
+----------+         +-------------+

Legend:
    OMAP4   = SoC running Linux
    CPCAP   = Audio codec
    MDM6600 = Baseband
    WL1285  = Bluetooth

Re-reading the audio-graph-card binding document I still don't see
how the network (OMAP.McBSP3, CPCAP.Voice, MDM6600, WL1285) is
supposed to look like. It seems to expect point-to-point DAI
connections.

> > "audio-graph-card" is not capable of doing this. I was planning to
> > try "audio-graph-scu-card" in combination with adding codecs for the
> > modem and BT to DT. If that does not work we need a Droid 4 specific
> > soundcard driver.
> 
> That's just the audio graph card with some hacks for working with a DPCM
> based SoC driver set.

Ok.

-- Sebastian
Mark Brown March 28, 2018, 2:29 a.m. UTC | #8
On Wed, Mar 28, 2018 at 12:22:37AM +0200, Sebastian Reichel wrote:
> On Tue, Mar 27, 2018 at 08:14:41PM +0800, Mark Brown wrote:

> > No, this is exactly the sort of use case with multiple DAIs that the
> > graph card is intended to enable over the old simple-card.

> +----------+         +-------------+
> | OMAP4    |         | CPCAP       |
> |          |         |             |
> | [McBSP2] | <-----> | [HiFi DAI]  |
> |          |         |             |
> | [McBSP3] | <--+--> | [Voice DAI] |
> |          |    |    |             |
> +----------+    |    +-------------+
>                 |
> +----------+    |    +-------------+
> | MDM6600  |    |    | WL1285      |
> |          |    |    |             |
> |    [DAI] | <--+--> | [DAI]       |
> |          |         |             |
> +----------+         +-------------+

> Legend:
>     OMAP4   = SoC running Linux
>     CPCAP   = Audio codec
>     MDM6600 = Baseband
>     WL1285  = Bluetooth

> Re-reading the audio-graph-card binding document I still don't see
> how the network (OMAP.McBSP3, CPCAP.Voice, MDM6600, WL1285) is
> supposed to look like. It seems to expect point-to-point DAI
> connections.

Ugh, a TDM mux?  That's really unusual and not particularly supported
yet, you'd need to extend the graph card to do it.  It's where things
should end up for a generic card though.
Pavel Machek March 28, 2018, 9 a.m. UTC | #9
Hi!

> > I can talk to the modem and start a call.
> 
> Doing an AT query is the easy part :)
> 
> > Then something like this (untested!) is certainly needed.
> > Probably more...
> 
> I intentionally left this part out. The CPCAP codec has two DAIs
> and not 3+. The code you just added is a hack from Motorola. Their
> driver is full of hacks and it's obvious its author(s) did not
> fully understand the ASoC APIs.
> 
> My understanding is, that we only need to replace the audio-graph-card
> driver to something more complex. The VOICE DAI needs to be configured
> differently based on the use case:

Does the voice part work for you? I configured all the mixers to
voice, and then am using

sudo aplay -D plughw:CARD=Audio,DEV=1 /usr/share/sounds/alsa/Front_Center.wav  -r 16000
X11 connection rejected because of wrong authentication.
xcb_connection_has_error() returned true
Playing WAVE '/usr/share/sounds/alsa/Front_Center.wav' : Signed 16 bit
Little Endian, Rate 48000 Hz, Mono
user@devuan:/my/tui/rweb$

to play the test sound. But I get white noise, not a test sound
:-(. [This also shows problem with card naming.]

Any ideas?
									Pavel
Pavel Machek March 28, 2018, 9:36 a.m. UTC | #10
Hi!

> > > I can talk to the modem and start a call.
> > 
> > Doing an AT query is the easy part :)
> > 
> > > Then something like this (untested!) is certainly needed.
> > > Probably more...
> > 
> > I intentionally left this part out. The CPCAP codec has two DAIs
> > and not 3+. The code you just added is a hack from Motorola. Their
> > driver is full of hacks and it's obvious its author(s) did not
> > fully understand the ASoC APIs.
> > 
> > My understanding is, that we only need to replace the audio-graph-card
> > driver to something more complex. The VOICE DAI needs to be configured
> > differently based on the use case:
> 
> Does the voice part work for you? I configured all the mixers to
> voice, and then am using

I tried with 8kHz, 8-bit, too:

user@devuan:/my/tui/rweb$ arecord -D plughw:CARD=Audio,DEV=1 -t wav
--max-file-time 30 mon.wav
Recording WAVE 'mon.wav' : Unsigned 8 bit, Rate 8000 Hz, Mono
^CAborted by signal Interrupt...
arecord: pcm_read:2103: read error: Interrupted system call
user@devuan:/my/tui/rweb$ aplay -D plughw:CARD=Audio,DEV=1 -t wav
mon.wav
Playing WAVE 'mon.wav' : Unsigned 8 bit, Rate 8000 Hz, Mono
^CAborted by signal Interrupt...

Recording works okay, but playback produces ugly noise (not white this
time). If I copy mon.wav to PC, it playes back in pretty acceptable
quality.

So summary

HIFI DAI works
VOICE DAI recording is ok
VOICE DAI playbacks plays noise.

Best regards,
									Pavel
Sebastian Reichel March 28, 2018, 2:02 p.m. UTC | #11
Hi,

On Wed, Mar 28, 2018 at 10:29:10AM +0800, Mark Brown wrote:
> On Wed, Mar 28, 2018 at 12:22:37AM +0200, Sebastian Reichel wrote:
> > On Tue, Mar 27, 2018 at 08:14:41PM +0800, Mark Brown wrote:
> 
> > > No, this is exactly the sort of use case with multiple DAIs that the
> > > graph card is intended to enable over the old simple-card.
> 
> > +----------+         +-------------+
> > | OMAP4    |         | CPCAP       |
> > |          |         |             |
> > | [McBSP2] | <-----> | [HiFi DAI]  |
> > |          |         |             |
> > | [McBSP3] | <--+--> | [Voice DAI] |
> > |          |    |    |             |
> > +----------+    |    +-------------+
> >                 |
> > +----------+    |    +-------------+
> > | MDM6600  |    |    | WL1285      |
> > |          |    |    |             |
> > |    [DAI] | <--+--> | [DAI]       |
> > |          |         |             |
> > +----------+         +-------------+
> 
> > Legend:
> >     OMAP4   = SoC running Linux
> >     CPCAP   = Audio codec
> >     MDM6600 = Baseband
> >     WL1285  = Bluetooth
> 
> > Re-reading the audio-graph-card binding document I still don't see
> > how the network (OMAP.McBSP3, CPCAP.Voice, MDM6600, WL1285) is
> > supposed to look like. It seems to expect point-to-point DAI
> > connections.
> 
> Ugh, a TDM mux?

Yes, at least that's how I understood Motorola's code.

> That's really unusual and not particularly supported yet, you'd
> need to extend the graph card to do it.  It's where things should
> end up for a generic card though.

Motorola's driver provided the following modes:

OMAP4 <-> CPCAP      (voice recording)
MDM6600 <-> CPCAP    (voice call, CPU not involved)
OMAP4 <-> WL1285     (bluetooth HFP/HSP)
MDM6600 <-> WL1285   (bluetooth voice call)

In case of the last two variants, the bus clock is provided by
CPCAP, so it needs to be enabled for any audio stream. I suppose
the codec <-> codec as part of TDM is out of scope for the graph
card and we need a Droid 4 specific card driver?

-- Sebastian
Mark Brown April 2, 2018, 3:06 p.m. UTC | #12
On Wed, Mar 28, 2018 at 04:02:19PM +0200, Sebastian Reichel wrote:

> In case of the last two variants, the bus clock is provided by
> CPCAP, so it needs to be enabled for any audio stream. I suppose
> the codec <-> codec as part of TDM is out of scope for the graph
> card and we need a Droid 4 specific card driver?

It's definitely pushing it towards being more useful to consider at
least in the short term, basically nobody ever did these TDM muxes since
usually you end up needing something more than just straight digital
data muxing (mixing for example) so things usually get routed through a
chip that can do more with the data.
diff mbox

Patch

diff --git a/sound/soc/codecs/cpcap.c b/sound/soc/codecs/cpcap.c
index aedb267..7646f68 100644
--- a/sound/soc/codecs/cpcap.c
+++ b/sound/soc/codecs/cpcap.c
@@ -1280,6 +1280,60 @@  static int cpcap_voice_hw_params(struct snd_pcm_substream *substream,
 	return 0;
 }
 
+static int cpcap_incall_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *params,
+				 struct snd_soc_dai *dai)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	struct device *dev = codec->dev;
+	struct cpcap_audio *cpcap = snd_soc_codec_get_drvdata(codec);
+	static const u16 reg_cdi = CPCAP_REG_CDI;
+	int rate = params_rate(params);
+	int channels = params_channels(params);
+	int direction = substream->stream;
+	u16 val, mask;
+	int err;
+
+	dev_dbg(dev, "Incall setup HW params: rate=%d, direction=%d, chan=%d",
+		rate, direction, channels);
+
+	/* codec, 1 in original code is CPCAP_REG_CC
+	   codec, 2 is CPCAP_REG_CDI
+	   codec, 5 is CPCAP_REG_TXI */
+
+	if (/* cpcap->codec_strm_cnt == */ 1) {
+		/*
+		if (pdata->voice_type != VOICE_TYPE_QC)
+			printk("FIXME: Only MDM6600 support is implemented here.\n");
+		*/
+
+		err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, 0xffff, 0xAE02);
+		if (err) printk("cpcap error %d\n", __LINE__);
+
+		err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CC, 0xffff, 0x6120);
+		if (err) printk("cpcap error %d\n", __LINE__);
+
+		err = cpcap_set_samprate(cpcap, CPCAP_DAI_VOICE, rate);
+		printk("Configured stream\n");
+	}
+
+	/* (direction == SNDRV_PCM_STREAM_CAPTURE) ?? */
+	if (substream->stream) { /* up link */
+		unsigned int set =  CPCAP_BIT_AUDIHPF_1 | CPCAP_BIT_AUDIHPF_0;
+		err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CC, set, set);
+		if (err) printk("cpcap error %d\n", __LINE__);
+
+		set = CPCAP_BIT_MB_ON1L | CPCAP_BIT_MB_ON1R;
+		err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI, set, set);
+	} else { /* down link */
+		unsigned int set =  CPCAP_BIT_AUDOHPF_1 | CPCAP_BIT_AUDOHPF_0;
+		err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CC, set, set);
+		if (err) printk("cpcap error %d\n", __LINE__);
+	}
+
+	return err;
+}
+
 static int cpcap_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
 				      unsigned int freq, int dir)
 {
@@ -1394,6 +1448,14 @@  static const struct snd_soc_dai_ops cpcap_dai_voice_ops = {
 	.digital_mute	= cpcap_voice_set_mute,
 };
 
+static const struct snd_soc_dai_ops cpcap_dai_incall_ops = {
+	/* FIXME */
+	.hw_params	= cpcap_incall_hw_params,
+	.set_sysclk	= cpcap_voice_set_dai_sysclk,
+	.set_fmt	= cpcap_voice_set_dai_fmt,
+	.digital_mute	= cpcap_voice_set_mute,
+};
+
 static struct snd_soc_dai_driver cpcap_dai[] = {
 {
 	.id = 0,
@@ -1426,6 +1488,26 @@  static struct snd_soc_dai_driver cpcap_dai[] = {
 	},
 	.ops = &cpcap_dai_voice_ops,
 },
+{
+	.id = 2,
+	.name = "cpcap in-call",
+	.playback = {
+		.stream_name = "InCall DL",
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+	},
+	.capture = {
+		.stream_name = "Capture",
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+	},
+	.ops = &cpcap_dai_incall_ops,
+},
+/* FIXME: this misses bt-call, cpcap bt, BPvoice, FM */
 };
 
 static int cpcap_dai_mux(struct cpcap_audio *cpcap, bool swap_dai_configuration)