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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On Wed, Mar 28, 2018 at 06:45:07PM -0700, Tony Lindgren wrote:
> Hi,
> 
> * Sebastian Reichel <sebastian.reichel@xxxxxxxxxxxxxxx> [180328 14:03]:
> > 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.
> 
> Hmm is there some active component doing the muxing then?
> Maybe the "AT+CMUT=0" part below?

I don't think, that there is a special hardware mux. I think each
device is configured to use a proper timeslot and/or is being used
exclusively.

> > > 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?
> 
> Hmm well I got audio call hacked to work as a proof of concept hack,
> see below. Maybe it can be used to verify some of the assumptions
> above.

Your proof of concept verifies the assumption, that the modem is
connected to the CPCAP voice DAI. This patchset is a proof, that the
voice DAI is connected to OMAP. So we can tell for sure, that this
is not a common direct DAI-to-DAI connection.

> Then.. To split the work a bit, can you guys maybe try to decode
> the cpcap register values and try to do a proper ASoC driver patch?
>
> Meanwhile, I can try to make voice calls more reproducable with
> qmi or MM for example instead of just n_gsm.. And then I'll try
> to fix my n_gsm pile of hacks for posting..
> 
> Cheers,
> 
> Tony
> 
> 8< --------------------------
> From tony Mon Sep 17 00:00:00 2001
> From: Tony Lindgren <tony@xxxxxxxxxxx>
> Date: Wed, 28 Mar 2018 08:29:38 -0700
> Subject: [PATCH] NOT FOR MERGING: Quick hack for droid 4 mdm6600 voice
>  call
> 
> Here's quick hack to allow making a voice call on mdm6600 based on
> diffing the cpcap registers in Android. The patch just keeps overwriting
> the cpcap values every second so it's nowhere near usable for merging,
> just a test patch.
> 
> Looks like the cpcap register changes during a speaker phone audio call are:
> 
> @@ -510,17 +510,17 @@
>  07f4: 0000
>  07f8: 0000
>  07fc: 0000
> -0800: 0065
> -0804: 0000
> -0808: 0040
> +0800: 0025     # CPCAP_REG_VAUDIOC     VAUDIO Control

enable vaudio (obviously required :))

> +0804: 60cf     # CPCAP_REG_CC          Codec Control, moto cpcap.c:1337 sets 0x0093?

0x6000 => clkfreq=19200000

The following bits are automatically set via DAPM by cpcap codec,
once it is used:

0x00c0 => "ADC Left" + "DAC Voice"
0x000f => "Highpass Filter TX" + "Highpass Filter RX"

> +0808: ae0a     # CPCAP_REG_CDI         Codec Digital Interface

0xa000 => enable PLL & use clock 1

This should be used by default for VOICE DAI.

0x0e00 => "Voice DAI Clock"=1 (handled by DAPM) , mode=I2S
0x000a => CPCAP_BIT_CLK_INV | CPCAP_BIT_MIC1_RX_TIMESLOT0

>  080c: 0000
>  0810: 0004
> -0814: 0804
> -0818: 079c
> -081c: 0000
> -0820: 0924
> -0824: 0000
> -0828: 0000
> +0814: 0cc0     # CPCAP_REG_TXI         TX Inputs, moto cpcap.c:1340 sets 0x0CC6?
> +0818: 0610     # CPCAP_REG_TXMP        TX MIC PGA's, moto cpcap.c:1343 sets 0x0273?
> +081c: 0006     # CPCAP_REG_RXOA        RX Output Amplifiers
> +0820: 0b2c     # CPCAP_REG_RXVC        RX Volume Control
> +0824: 0606     # CPCAP_REG_RXCOA       RX Codec to Output Amps
> +0828: 0600     # CPCAP_REG_RXSDOA      RX Stereo DAC to Output Amps

This configures the loudspeaker, mics and volume and enables the
required clocks/DACs/... This is already covered by the cpcap codec
driver. You just need to configure everything correctly in
alsamixer.

>  082c: 0400
>  0830: 0000
>  0834: 0030
> 
> I wonder if mdm6600 is the i2s master during the voice call?

I think cpcap is always the clock and frame master, but I think
mdm6600 is the remote side and OMAP is not involved at all.

-- Sebastian

> Then using the n_gsm ts 27.010 uart mux, I dial:
> 
> ./ngsm-rw 1 "AT+CFUN=1"		# connect to network
> U0001+CFUN:OK
> ./ngsm-rw 2 "AT+CMUT=0"		# unmute speaker over ch2, do this over qmi?
> U0001+CMUT:OK
> ./ngsm-rw 1 "ATD#123"		# dial number
> U0001D:OK
> 
> And I do hear a voice talking over the speakerphone :) Sorry have not tested the
> mic yet..
> 
> FYI, the ngsm-rw script I use is just:
> 
> #!/bin/sh
> 
> if [ "${1}" == "" ]; then
>         echo "Usage: $0 port command"
>         exit 1
> fi
> 
> port=${1}
> command=${2}
> 
> exec 3<>/dev/gsmtty${port}
> printf "U0001%s\r\0" ${command} >&3
> read result <&3
> exec 3>&-
> exec 3<&-
> 
> echo ${result}
> 
> My n_gsm patches are not quite ready yet sorry.. But meanwhile hopefully this
> can be somehow also done using qmi. At least "AT+CMUT=0" fails over ttyUSB4.
> ---
>  sound/soc/codecs/cpcap.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 69 insertions(+), 1 deletion(-)
> 
> diff --git a/sound/soc/codecs/cpcap.c b/sound/soc/codecs/cpcap.c
> --- a/sound/soc/codecs/cpcap.c
> +++ b/sound/soc/codecs/cpcap.c
> @@ -251,6 +251,8 @@ struct cpcap_audio {
>  	int codec_clk_id;
>  	int codec_freq;
>  	int codec_format;
> +
> +	struct delayed_work work;
>  };
>  
>  static int cpcap_st_workaround(struct snd_soc_dapm_widget *w,
> @@ -1500,6 +1502,57 @@ static int cpcap_audio_reset(struct snd_soc_component *component,
>  	return 0;
>  }
>  
> +static void cpcap_soc_work(struct work_struct *work)
> +{
> +	struct cpcap_audio *cpcap = container_of(work,
> +						 struct cpcap_audio,
> +						 work.work);
> +	struct device *dev = cpcap->component->dev;
> +	int error;
> +
> +	dev_info(dev, "Somebody do a proper driver please %s\n", __func__);
> +
> +	error = regmap_update_bits(cpcap->regmap, CPCAP_REG_VAUDIOC,
> +				   0xffff, 0x0025);
> +	if (error)
> +		goto out;
> +	error = regmap_update_bits(cpcap->regmap, CPCAP_REG_CC,
> +				   0xffff, 0x60cf);
> +	if (error)
> +		goto out;
> +	error = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI,
> +				   0xffff, 0xae0a);
> +	if (error)
> +		goto out;
> +	error = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI,
> +				   0xffff, 0x0cc0);
> +	if (error)
> +		goto out;
> +	error = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXMP,
> +				   0xffff, 0x0610);
> +	if (error)
> +		goto out;
> +	error = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXOA,
> +				   0xffff, 0x0006);
> +	if (error)
> +		goto out;
> +	error = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXVC,
> +				   0xffff, 0x0b2c);
> +	if (error)
> +		goto out;
> +	error = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXCOA,
> +				   0xffff, 0x0606);
> +	if (error)
> +		goto out;
> +	error = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXSDOA,
> +				   0xffff, 0x0600);
> +	if (error)
> +		goto out;
> +
> +out:
> +	schedule_delayed_work(&cpcap->work, msecs_to_jiffies(1000));
> +}
> +
>  static int cpcap_soc_probe(struct snd_soc_component *component)
>  {
>  	struct cpcap_audio *cpcap;
> @@ -1520,11 +1573,26 @@ static int cpcap_soc_probe(struct snd_soc_component *component)
>  	if (err)
>  		return err;
>  
> -	return cpcap_audio_reset(component, false);
> +	err = cpcap_audio_reset(component, false);
> +	if (err)
> +		return err;
> +
> +	INIT_DELAYED_WORK(&cpcap->work, cpcap_soc_work);
> +	schedule_delayed_work(&cpcap->work, msecs_to_jiffies(1000));
> +
> +	return 0;
> +}
> +
> +static void cpcap_soc_remove(struct snd_soc_component *component)
> +{
> +	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
> +
> +	cancel_delayed_work_sync(&cpcap->work);
>  }
>  
>  static struct snd_soc_component_driver soc_codec_dev_cpcap = {
>  	.probe			= cpcap_soc_probe,
> +	.remove			= cpcap_soc_remove,
>  	.controls		= cpcap_snd_controls,
>  	.num_controls		= ARRAY_SIZE(cpcap_snd_controls),
>  	.dapm_widgets		= cpcap_dapm_widgets,
> -- 
> 2.16.3

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux