From patchwork Sat Mar 31 14:55:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Machek X-Patchwork-Id: 10318961 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9214060212 for ; Sat, 31 Mar 2018 14:55:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7DE1D29469 for ; Sat, 31 Mar 2018 14:55:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 728902946B; Sat, 31 Mar 2018 14:55:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_TVD_MIME_EPI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CBF3329469 for ; Sat, 31 Mar 2018 14:55:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752501AbeCaOzf (ORCPT ); Sat, 31 Mar 2018 10:55:35 -0400 Received: from atrey.karlin.mff.cuni.cz ([195.113.26.193]:47022 "EHLO atrey.karlin.mff.cuni.cz" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752358AbeCaOze (ORCPT ); Sat, 31 Mar 2018 10:55:34 -0400 Received: by atrey.karlin.mff.cuni.cz (Postfix, from userid 512) id 6F01A803E8; Sat, 31 Mar 2018 16:55:32 +0200 (CEST) Date: Sat, 31 Mar 2018 16:55:32 +0200 From: Pavel Machek To: Tony Lindgren Cc: Sebastian Reichel , Mark Brown , Liam Girdwood , Rob Herring , Lee Jones , Jaroslav Kysela , Takashi Iwai , alsa-devel@alsa-project.org, linux-omap@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, kernel@collabora.com, Dan Williams Subject: call/normal switch was Re: omap4-droid4: voice call support was Message-ID: <20180331145531.GA10404@amd> References: <20180322234832.o24ut5ahon46mdu4@earth.universe> <20180323100930.GA21644@amd> <20180323103006.alymgb3ywftb4gek@earth.universe> <20180326141638.GB1450@amd> <20180326155828.ttnduivadob4iqmd@earth.universe> <20180327121441.GH29239@sirena.org.uk> <20180327222237.wcx2aqznvdrvbaa5@earth.universe> <20180328022910.GM29239@sirena.org.uk> <20180328140219.f6667up5evrrafkv@earth.universe> <20180329014507.GM5700@atomide.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20180329014507.GM5700@atomide.com> User-Agent: Mutt/1.5.23 (2014-03-12) Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Hi! > 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. > > 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? This is not proper patch yet, but it should be a step in that direction... If someone knows how to express cleanly "active support for modem is the same as active audio playback", let me know.... Best regards, Pavel diff --git a/sound/soc/codecs/cpcap.c b/sound/soc/codecs/cpcap.c index 3b53bd0..7aaa4db 100644 --- a/sound/soc/codecs/cpcap.c +++ b/sound/soc/codecs/cpcap.c @@ -221,18 +221,18 @@ struct cpcap_reg_info { }; static const struct cpcap_reg_info cpcap_default_regs[] = { - { CPCAP_REG_CC, 0xFFFF, 0x0000 }, - { CPCAP_REG_CC, 0xFFFF, 0x0000 }, - { CPCAP_REG_CDI, 0xBFFF, 0x0000 }, + { CPCAP_REG_CC, 0xFFFF, 0x60cf }, + { CPCAP_REG_CDI, 0xBFFF, 0xae0a }, { CPCAP_REG_SDAC, 0x0FFF, 0x0000 }, { CPCAP_REG_SDACDI, 0x3FFF, 0x0000 }, - { CPCAP_REG_TXI, 0x0FDF, 0x0000 }, - { CPCAP_REG_TXMP, 0x0FFF, 0x0400 }, - { CPCAP_REG_RXOA, 0x01FF, 0x0000 }, - { CPCAP_REG_RXVC, 0xFF3C, 0x0000 }, - { CPCAP_REG_RXCOA, 0x07FF, 0x0000 }, - { CPCAP_REG_RXSDOA, 0x1FFF, 0x0000 }, + { CPCAP_REG_TXI, 0x0FFF, 0x0CC0 }, + { CPCAP_REG_TXMP, 0x0FFF, 0x0610 }, + { CPCAP_REG_RXOA, 0x01FF, 0x0006 }, + { CPCAP_REG_RXVC, 0xFF3C, 0x0B2C }, + { CPCAP_REG_RXCOA, 0x07FF, 0x0606 }, + { CPCAP_REG_RXSDOA, 0x1FFF, 0x0600 }, { CPCAP_REG_RXEPOA, 0x7FFF, 0x0000 }, + { CPCAP_REG_VAUDIOC, 0xFFFF, 0x0025 }, { CPCAP_REG_A2LA, BIT(CPCAP_BIT_A2_FREE_RUN), BIT(CPCAP_BIT_A2_FREE_RUN) }, }; @@ -330,6 +330,11 @@ static const char * const cpcap_in_left_mux_texts[] = { "Off", "Mic 2", "Ext Left" }; +static const char * const cpcap_mode_texts[] = { + "Normal", "Call" +}; + + /* * input muxes use unusual register layout, so that we need to use custom * getter/setter methods @@ -354,6 +359,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 +449,86 @@ 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) +{ + struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); + struct cpcap_audio *cpcap = snd_soc_codec_get_drvdata(codec); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + int err; + + ucontrol->value.enumerated.item[0] = mode; + + return 0; +} + +static int cpcap_mode_put_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); + struct cpcap_audio *cpcap = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = + snd_soc_dapm_kcontrol_dapm(kcontrol); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int muxval = ucontrol->value.enumerated.item[0]; + unsigned int mask = BIT(e->shift_l); + int err; + + printk("Requested mode %d\n", muxval); + + mode = muxval; + + switch (muxval) { + case 1: + + err = regmap_update_bits(cpcap->regmap, CPCAP_REG_VAUDIOC, + 0xffff, 0x0025); // OK + if (err) + goto out; + err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CC, + 0xffff, 0x60cf); // OK + if (err) + goto out; + err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, + 0xffff, 0xae0a); // OK + if (err) + goto out; + err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI, + 0xffff, 0x0cc0); + if (err) + goto out; + + mask = 1 << CPCAP_BIT_PGA_CDC_EN | 0x200; + err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXCOA, + mask, mask); + if (err) + printk("error #3\n"); + + mask = 1 << CPCAP_BIT_A2_LDSP_L_EN | 1 << CPCAP_BIT_A2_LDSP_R_EN; + err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXOA, + mask, mask); + if (err) + printk("error #2\n"); + + err = regmap_update_bits(cpcap->regmap, 0x814, + 0x0400, 0x0400); + if (err) + printk("error #1\n"); + + default: + break; + } + + // FIXME +// snd_soc_dapm_mux_update_power(dapm, kcontrol, muxval, e, NULL); + + return 0; +out: printk("Something failed\n"); + return -EINVAL; +} + static int cpcap_input_right_mux_get_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -630,6 +717,11 @@ 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 +863,10 @@ 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), @@ -816,6 +912,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"Microphone 1 PGA", NULL, "VAUDIO"}, {"Microphone 2 PGA", NULL, "VAUDIO"}, + /* FIXME */ + {"Mode", NULL, "Voice TX"}, + /* Stream -> AIF */ {"HiFi RX", NULL, "HiFi Playback"}, {"Voice RX", NULL, "Voice Playback"},