From patchwork Fri May 24 03:55:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mohammad Rafi Shaik X-Patchwork-Id: 798950 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2B457C25B7A for ; Fri, 24 May 2024 04:00:54 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 72BAFDEC; Fri, 24 May 2024 06:00:42 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 72BAFDEC DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1716523252; bh=HpzsEM1j54Mm6stWqCCqRta1D4uz8qQDHXF9mF77gNA=; h=From:To:CC:Subject:Date:In-Reply-To:References:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=gh3cmo68ArRMv4i2LjVGFHu9GpqYCsuyEyD0CX51Hl5LFDobpUtul4amcWdy5mywH A7BekiWoH25I2zjmC5lw0k0yR0jyMQyvAJs81u+qDrIC2eFxi3PzPCfYKDyHUPb7dI DN3itLdO+tCnsrP+5N3GgRrriUu3b28R9dQ4tsgg= Received: by alsa1.perex.cz (Postfix, from userid 50401) id 32A46F80671; Fri, 24 May 2024 05:59:16 +0200 (CEST) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id A5173F8067E; Fri, 24 May 2024 05:59:16 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id DBCBCF805AB; Fri, 24 May 2024 05:57:10 +0200 (CEST) Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 00AEDF8051D for ; Fri, 24 May 2024 05:56:59 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 00AEDF8051D Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=quicinc.com header.i=@quicinc.com header.a=rsa-sha256 header.s=qcppdkim1 header.b=VwGLFtO1 Received: from pps.filterd (m0279873.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 44NNPt1u013094; Fri, 24 May 2024 03:56:58 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= kxeak7j2X/vTjMnZOkyJl6dka7ghfJLwINS3QrlIbAY=; b=VwGLFtO1V5niC5Y0 gUxWuM4VPRGQVQrKvi0fiAYumRuHYOnF8WJcgZo3eiy0KB9oIWxuWG8P4wLC4CGr o2if2TEGk0gIpO//6iO1Bj5NunhmBhh/OhzMVJcJAkjCGNBMl9Gd6x9qe9zJt6v9 ej8upGn8i76wBuE0mdmQCFf1exVqSO8P5w+K0yZgqwf2UiguKy0Xai+xmyrqfES9 Jo0B6gzS9fWz0rGwNRrMlmK7BwGxblK9uwZ8M+fcaTjY86fnCZpVzrYkNcj9aaeD cVtaZcQjMwBnNXB7qIxq+OG9CreyHUMSvHTeJq5HtFacBpY5pFIjEZAZtZgNzTLI csqWAw== Received: from nasanppmta02.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3yaa97s4aa-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 24 May 2024 03:56:58 +0000 (GMT) Received: from nasanex01c.na.qualcomm.com (nasanex01c.na.qualcomm.com [10.45.79.139]) by NASANPPMTA02.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 44O3uv7M007464 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 24 May 2024 03:56:57 GMT Received: from hu-mohs-hyd.qualcomm.com (10.80.80.8) by nasanex01c.na.qualcomm.com (10.45.79.139) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Thu, 23 May 2024 20:56:52 -0700 From: Mohammad Rafi Shaik To: Srinivas Kandagatla , Banajit Goswami , Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jaroslav Kysela , Takashi Iwai CC: , , , , , , , Mohammad Rafi Shaik Subject: [PATCH v5 4/7] ASoC: codecs: wcd937x: add basic controls Date: Fri, 24 May 2024 09:25:32 +0530 Message-ID: <20240524035535.3119208-5-quic_mohs@quicinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240524035535.3119208-1-quic_mohs@quicinc.com> References: <20240524035535.3119208-1-quic_mohs@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nasanex01c.na.qualcomm.com (10.45.79.139) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: 9NERlY0s5rxcGRa4ccr3y7gnrZwkF90R X-Proofpoint-ORIG-GUID: 9NERlY0s5rxcGRa4ccr3y7gnrZwkF90R X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.650,FMLib:17.12.28.16 definitions=2024-05-23_15,2024-05-23_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 lowpriorityscore=0 mlxscore=0 bulkscore=0 spamscore=0 phishscore=0 impostorscore=0 suspectscore=0 priorityscore=1501 malwarescore=0 clxscore=1015 mlxlogscore=911 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2405170001 definitions=main-2405240026 Message-ID-Hash: RZGKDA5LMXAXGWPIYAHEJZQOKDLAK7V7 X-Message-ID-Hash: RZGKDA5LMXAXGWPIYAHEJZQOKDLAK7V7 X-MailFrom: quic_mohs@quicinc.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.9 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Prasad Kumpatla This patch adds basic controls found in WCD9370/WCD9375 codec. Signed-off-by: Prasad Kumpatla Co-developed-by: Mohammad Rafi Shaik Signed-off-by: Mohammad Rafi Shaik --- sound/soc/codecs/wcd937x.c | 201 +++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) diff --git a/sound/soc/codecs/wcd937x.c b/sound/soc/codecs/wcd937x.c index 4470ee0ecae6..293a84a53918 100644 --- a/sound/soc/codecs/wcd937x.c +++ b/sound/soc/codecs/wcd937x.c @@ -120,6 +120,10 @@ struct wcd937x_priv { atomic_t ana_clk_count; }; +static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(ear_pa_gain, 600, -1800); +static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); +static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); + struct wcd937x_mbhc_zdet_param { u16 ldo_ctl; u16 noff; @@ -476,6 +480,157 @@ static int wcd937x_connect_port(struct wcd937x_sdw_priv *wcd, u8 port_idx, u8 ch return 0; } +static int wcd937x_rx_hph_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = wcd937x->hph_mode; + return 0; +} + +static int wcd937x_rx_hph_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); + u32 mode_val; + + mode_val = ucontrol->value.enumerated.item[0]; + + if (!mode_val) + mode_val = CLS_AB; + + if (mode_val == wcd937x->hph_mode) + return 0; + + switch (mode_val) { + case CLS_H_NORMAL: + case CLS_H_HIFI: + case CLS_H_LP: + case CLS_AB: + case CLS_H_LOHIFI: + case CLS_H_ULP: + case CLS_AB_LP: + case CLS_AB_HIFI: + wcd937x->hph_mode = mode_val; + return 1; + } + + dev_dbg(component->dev, "%s: Invalid HPH Mode\n", __func__); + return -EINVAL; +} + +static int wcd937x_get_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); + struct soc_mixer_control *mc; + bool hphr; + + mc = (struct soc_mixer_control *)(kcontrol->private_value); + hphr = mc->shift; + + ucontrol->value.integer.value[0] = hphr ? wcd937x->comp2_enable : + wcd937x->comp1_enable; + return 0; +} + +static int wcd937x_set_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); + struct wcd937x_sdw_priv *wcd = wcd937x->sdw_priv[AIF1_PB]; + int value = ucontrol->value.integer.value[0]; + struct soc_mixer_control *mc; + int portidx; + bool hphr; + + mc = (struct soc_mixer_control *)(kcontrol->private_value); + hphr = mc->shift; + + if (hphr) { + if (value == wcd937x->comp2_enable) + return 0; + + wcd937x->comp2_enable = value; + } else { + if (value == wcd937x->comp1_enable) + return 0; + + wcd937x->comp1_enable = value; + } + + portidx = wcd->ch_info[mc->reg].port_num; + + if (value) + wcd937x_connect_port(wcd, portidx, mc->reg, true); + else + wcd937x_connect_port(wcd, portidx, mc->reg, false); + + return 1; +} + +static int wcd937x_get_swr_port(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(comp); + struct wcd937x_sdw_priv *wcd; + int dai_id = mixer->shift; + int ch_idx = mixer->reg; + int portidx; + + wcd = wcd937x->sdw_priv[dai_id]; + portidx = wcd->ch_info[ch_idx].port_num; + + ucontrol->value.integer.value[0] = wcd->port_enable[portidx]; + + return 0; +} + +static int wcd937x_set_swr_port(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(comp); + struct wcd937x_sdw_priv *wcd; + int dai_id = mixer->shift; + int ch_idx = mixer->reg; + int portidx; + bool enable; + + wcd = wcd937x->sdw_priv[dai_id]; + + portidx = wcd->ch_info[ch_idx].port_num; + + enable = ucontrol->value.integer.value[0]; + + if (enable == wcd->port_enable[portidx]) { + wcd937x_connect_port(wcd, portidx, ch_idx, enable); + return 0; + } + + wcd->port_enable[portidx] = enable; + wcd937x_connect_port(wcd, portidx, ch_idx, enable); + + return 1; +} + +static const char * const rx_hph_mode_mux_text[] = { + "CLS_H_NORMAL", "CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", + "CLS_H_LOHIFI", "CLS_H_ULP", "CLS_AB_LP", "CLS_AB_HIFI", +}; + +static const struct soc_enum rx_hph_mode_mux_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text), rx_hph_mode_mux_text); + /* MBHC related */ static void wcd937x_mbhc_clk_setup(struct snd_soc_component *component, bool enable) @@ -1150,6 +1305,50 @@ static void wcd937x_mbhc_deinit(struct snd_soc_component *component) /* END MBHC */ +static const struct snd_kcontrol_new wcd937x_snd_controls[] = { + SOC_SINGLE_TLV("EAR_PA Volume", WCD937X_ANA_EAR_COMPANDER_CTL, + 2, 0x10, 0, ear_pa_gain), + SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum, + wcd937x_rx_hph_mode_get, wcd937x_rx_hph_mode_put), + + SOC_SINGLE_EXT("HPHL_COMP Switch", SND_SOC_NOPM, 0, 1, 0, + wcd937x_get_compander, wcd937x_set_compander), + SOC_SINGLE_EXT("HPHR_COMP Switch", SND_SOC_NOPM, 1, 1, 0, + wcd937x_get_compander, wcd937x_set_compander), + + SOC_SINGLE_TLV("HPHL Volume", WCD937X_HPH_L_EN, 0, 20, 1, line_gain), + SOC_SINGLE_TLV("HPHR Volume", WCD937X_HPH_R_EN, 0, 20, 1, line_gain), + SOC_SINGLE_TLV("ADC1 Volume", WCD937X_ANA_TX_CH1, 0, 20, 0, analog_gain), + SOC_SINGLE_TLV("ADC2 Volume", WCD937X_ANA_TX_CH2, 0, 20, 0, analog_gain), + SOC_SINGLE_TLV("ADC3 Volume", WCD937X_ANA_TX_CH3, 0, 20, 0, analog_gain), + + SOC_SINGLE_EXT("HPHL Switch", WCD937X_HPH_L, 0, 1, 0, + wcd937x_get_swr_port, wcd937x_set_swr_port), + SOC_SINGLE_EXT("HPHR Switch", WCD937X_HPH_R, 0, 1, 0, + wcd937x_get_swr_port, wcd937x_set_swr_port), + + SOC_SINGLE_EXT("ADC1 Switch", WCD937X_ADC1, 1, 1, 0, + wcd937x_get_swr_port, wcd937x_set_swr_port), + SOC_SINGLE_EXT("ADC2 Switch", WCD937X_ADC2, 1, 1, 0, + wcd937x_get_swr_port, wcd937x_set_swr_port), + SOC_SINGLE_EXT("ADC3 Switch", WCD937X_ADC3, 1, 1, 0, + wcd937x_get_swr_port, wcd937x_set_swr_port), + SOC_SINGLE_EXT("DMIC0 Switch", WCD937X_DMIC0, 1, 1, 0, + wcd937x_get_swr_port, wcd937x_set_swr_port), + SOC_SINGLE_EXT("DMIC1 Switch", WCD937X_DMIC1, 1, 1, 0, + wcd937x_get_swr_port, wcd937x_set_swr_port), + SOC_SINGLE_EXT("MBHC Switch", WCD937X_MBHC, 1, 1, 0, + wcd937x_get_swr_port, wcd937x_set_swr_port), + SOC_SINGLE_EXT("DMIC2 Switch", WCD937X_DMIC2, 1, 1, 0, + wcd937x_get_swr_port, wcd937x_set_swr_port), + SOC_SINGLE_EXT("DMIC3 Switch", WCD937X_DMIC3, 1, 1, 0, + wcd937x_get_swr_port, wcd937x_set_swr_port), + SOC_SINGLE_EXT("DMIC4 Switch", WCD937X_DMIC4, 1, 1, 0, + wcd937x_get_swr_port, wcd937x_set_swr_port), + SOC_SINGLE_EXT("DMIC5 Switch", WCD937X_DMIC5, 1, 1, 0, + wcd937x_get_swr_port, wcd937x_set_swr_port), +}; + static int wcd937x_set_micbias_data(struct wcd937x_priv *wcd937x) { int vout_ctl[3]; @@ -1316,6 +1515,8 @@ static const struct snd_soc_component_driver soc_codec_dev_wcd937x = { .name = "wcd937x_codec", .probe = wcd937x_soc_codec_probe, .remove = wcd937x_soc_codec_remove, + .controls = wcd937x_snd_controls, + .num_controls = ARRAY_SIZE(wcd937x_snd_controls), .set_jack = wcd937x_codec_set_jack, .endianness = 1, };