linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* handling voice calls in ALSA soc (on Droid 4)
@ 2018-06-11 10:25 Pavel Machek
       [not found] ` <20180611111011.GA11580@sirena.org.uk>
  0 siblings, 1 reply; 3+ messages in thread
From: Pavel Machek @ 2018-06-11 10:25 UTC (permalink / raw)
  To: linux-arm-kernel

Hi!

During voice call, I need audio components to be active "as if" aplay
or arecord was running, because modem needs to comunicate with speaker
and microphone.

I hacked something up, but... I believe I'll need help here. Look at
"enable_call" for "interesting" stuff I had to do.

...and also. What is right interface for this? Mixer component that
says if voice call is active or not?

Any ideas?

Thanks,
									Pavel

(edited).
+++ b/sound/soc/codecs/cpcap.c
@@ -330,6 +330,10 @@ static const char * const cpcap_in_left_mux_texts[] = {
 	"Off", "Mic 2", "Ext Left"
 };
 
+static const char * const cpcap_mode_texts[] = {
+	"Normal", "Handsfree", "Call",
+};
+
 /*
  * input muxes use unusual register layout, so that we need to use custom
  * getter/setter methods
@@ -354,6 +358,8 @@ static SOC_ENUM_SINGLE_DECL(cpcap_hs_l_mux_enum, 0, 6, cpcap_out_mux_texts);
 static SOC_ENUM_SINGLE_DECL(cpcap_emu_l_mux_enum, 0, 7, cpcap_out_mux_texts);
 static SOC_ENUM_SINGLE_DECL(cpcap_emu_r_mux_enum, 0, 8, cpcap_out_mux_texts);
 
+static SOC_ENUM_SINGLE_DECL(cpcap_mode_enum, 0, 9, cpcap_mode_texts);
+
 static int cpcap_output_mux_get_enum(struct snd_kcontrol *kcontrol,
 				     struct snd_ctl_elem_value *ucontrol)
 {
@@ -442,6 +448,211 @@ static int cpcap_output_mux_put_enum(struct snd_kcontrol *kcontrol,
 	return 0;
 }
 
+static int mode;
+
+static int cpcap_mode_get_enum(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	ucontrol->value.enumerated.item[0] = mode;
+
+	return 0;
+}
+
+static struct snd_soc_dai *voice_codec_dai_hack;
+
+static int enable_call(struct snd_soc_component *component, int on)
+{
+	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);

+		struct snd_soc_pcm_runtime *rt;
+
+		rt = snd_soc_get_pcm_runtime(component->card, "40126000.mcbsp-cpcap-voice");
+		printk("num_dai: %d, got runtime %lx\n", component->num_dai, rt);
+
+		if (rt) {
+		snd_soc_dapm_stream_event(rt, SNDRV_PCM_STREAM_PLAYBACK, SND_SOC_DAPM_STREAM_START);
+		snd_soc_dapm_stream_event(rt, SNDRV_PCM_STREAM_CAPTURE, SND_SOC_DAPM_STREAM_START);
+		}
+
+		cpcap_set_sysclk(cpcap, CPCAP_DAI_VOICE, 1, 19200000);
+		cpcap_set_samprate(cpcap, CPCAP_DAI_VOICE, 8000);
+		
+		cpcap_voice_set_dai_fmt(voice_codec_dai_hack,
+					SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM );
+
+	return 0;
+}
+
+static int cpcap_mode_put_enum(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+	unsigned int muxval = ucontrol->value.enumerated.item[0];
+
+	printk("Requested mode %d\n", muxval);
+
+	mode = muxval;
+
+	switch (muxval) {
+	case 1:
+		enable_call(component, 1);
+		break;
+	case 2:
+		enable_call(component, 1);
+
+		regmap_assert(cpcap, CPCAP_REG_TXI, 0xffff, 0x0cc6);
		...
+		break;
+		
+	default:
+		break;
+	}
+
+	return 0;
+}
+
 static int cpcap_input_right_mux_get_enum(struct snd_kcontrol *kcontrol,
 					  struct snd_ctl_elem_value *ucontrol)
 {
@@ -630,6 +841,10 @@ static const struct snd_kcontrol_new cpcap_earpiece_mux =
 	SOC_DAPM_ENUM_EXT("Earpiece", cpcap_earpiece_mux_enum,
 			  cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
 
+static const struct snd_kcontrol_new cpcap_mode =
+	SOC_DAPM_ENUM_EXT("Mode", cpcap_mode_enum,
+			  cpcap_mode_get_enum, cpcap_mode_put_enum);
+
 static const struct snd_kcontrol_new cpcap_hifi_mono_mixer_controls[] = {
 	SOC_DAPM_SINGLE("HiFi Mono Playback Switch",
 		CPCAP_REG_RXSDOA, CPCAP_BIT_MONO_DAC1, 1, 0),
@@ -771,6 +986,9 @@ static const struct snd_soc_dapm_widget cpcap_dapm_widgets[] = {
 	SND_SOC_DAPM_MUX("EMU Left Playback Route", SND_SOC_NOPM, 0, 0,
 		&cpcap_emu_left_mux),
 
+	SND_SOC_DAPM_MUX("Mode", SND_SOC_NOPM, 0, 0,
+		&cpcap_mode),
+	
 	/* Output Amplifier */
 	SND_SOC_DAPM_PGA("Earpiece PGA",
 		CPCAP_REG_RXOA, CPCAP_BIT_A1_EAR_EN, 0, NULL, 0),
@@ -791,7 +1009,7 @@ static const struct snd_soc_dapm_widget cpcap_dapm_widgets[] = {
 	SND_SOC_DAPM_PGA("EMU Left PGA",
 		CPCAP_REG_RXOA, CPCAP_BIT_EMU_SPKR_L_EN, 0, NULL, 0),
 
-	/* Headet Charge Pump */
+	/* Headset Charge Pump */
 	SND_SOC_DAPM_SUPPLY("Headset Charge Pump",
 		CPCAP_REG_RXOA, CPCAP_BIT_ST_HS_CP_EN, 0, NULL, 0),
 
@@ -1304,6 +1525,7 @@ static int cpcap_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	u16 val = 0x0000;
 	int err;
 
+	voice_codec_dai_hack = codec_dai;
 	dev_dbg(component->dev, "Voice setup dai format (%08x)", fmt);
 
 	/*
@@ -1343,10 +1565,7 @@ static int cpcap_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		break;
 	}
 
-	if (val & BIT(CPCAP_BIT_CLK_INV))
-		val &= ~BIT(CPCAP_BIT_CLK_INV);
-	else
-		val |= BIT(CPCAP_BIT_CLK_INV);
+	val ^= BIT(CPCAP_BIT_CLK_INV);
 
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 	case SND_SOC_DAIFMT_I2S:

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180611/55bdfbe3/attachment.sig>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* handling voice calls in ALSA soc (on Droid 4)
       [not found] ` <20180611111011.GA11580@sirena.org.uk>
@ 2018-06-11 12:01   ` Pavel Machek
       [not found]     ` <20180611121548.GB11580@sirena.org.uk>
  0 siblings, 1 reply; 3+ messages in thread
From: Pavel Machek @ 2018-06-11 12:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon 2018-06-11 12:10:11, Mark Brown wrote:
> On Mon, Jun 11, 2018 at 12:25:30PM +0200, Pavel Machek wrote:
> 
> > ...and also. What is right interface for this? Mixer component that
> > says if voice call is active or not?
> 
> Your modem should be represented as a component in the system and have
> an input and an output representing the input and output on the cell
> network.  See speyside for an example of how this can look in software
> though there's a bunch of different ways modems can appear so you might
> not have a fully digital link like that.

Thanks for the pointer.

With setup like that, how does userland tell kernel that the baseband
<-> microphone/speaker connection should be activated?

Best regards,
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180611/43c03f41/attachment.sig>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* handling voice calls in ALSA soc (on Droid 4)
       [not found]     ` <20180611121548.GB11580@sirena.org.uk>
@ 2018-06-12 12:18       ` Pavel Machek
  0 siblings, 0 replies; 3+ messages in thread
From: Pavel Machek @ 2018-06-12 12:18 UTC (permalink / raw)
  To: linux-arm-kernel

Hi!

Sebastian, would you have pointer to original Motorola sources you
used for inspiration?

> > With setup like that, how does userland tell kernel that the baseband
> > <-> microphone/speaker connection should be activated?
> 
> Audio routing should be done as normal, and ideally the driver for the
> modem will be able to figure out if there's an active call or not.  If
> userspace has to enable the input and output manually then you can set
> up SOC_DAPM_PIN_SWITCH()es as normal.

Modem talks AT commands, so the driver is in userspace for now.

I tried SOC_DAPM_PIN_SWITCH(), but it results in alsamixer oopsing, I
guess I'm doing something wrong.

Message from syslogd at devuan at Jun 12 13:51:31 ...
 kernel:[  743.678588] BUG: spinlock bad magic on CPU#1,
 alsamixer/2217

Message from syslogd at devuan at Jun 12 13:51:31 ...
 kernel:[  743.684417]  lock: 0xede423a0, .magic: eee2a6a4, .owner:
 <none>/-1, .owner_cpu: -287136604
 
I'm trying to understand how it is supposed to work, but
https://www.alsa-project.org/main/index.php/DAPM has TODO's at
critical places. If there's better source of information, let me know.

Best regards,
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180612/2a174be2/attachment.sig>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-06-12 12:18 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-06-11 10:25 handling voice calls in ALSA soc (on Droid 4) Pavel Machek
     [not found] ` <20180611111011.GA11580@sirena.org.uk>
2018-06-11 12:01   ` Pavel Machek
     [not found]     ` <20180611121548.GB11580@sirena.org.uk>
2018-06-12 12:18       ` Pavel Machek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).