Path: blob/master/sound/soc/mediatek/mt8195/mt8195-dai-adda.c
26488 views
// SPDX-License-Identifier: GPL-2.01/*2* MediaTek ALSA SoC Audio DAI ADDA Control3*4* Copyright (c) 2021 MediaTek Inc.5* Author: Bicycle Tsai <[email protected]>6* Trevor Wu <[email protected]>7*/89#include <linux/delay.h>10#include <linux/regmap.h>11#include "mt8195-afe-clk.h"12#include "mt8195-afe-common.h"13#include "mt8195-reg.h"14#include "../common/mtk-dai-adda-common.h"1516#define ADDA_DL_GAIN_LOOPBACK 0x180017#define ADDA_HIRES_THRES 480001819enum {20SUPPLY_SEQ_CLOCK_SEL,21SUPPLY_SEQ_CLOCK_ON,22SUPPLY_SEQ_ADDA_DL_ON,23SUPPLY_SEQ_ADDA_MTKAIF_CFG,24SUPPLY_SEQ_ADDA_UL_ON,25SUPPLY_SEQ_ADDA_AFE_ON,26};2728enum {29MTK_AFE_ADDA,30MTK_AFE_ADDA6,31};3233struct mtk_dai_adda_priv {34bool hires_required;35};3637static int mt8195_adda_mtkaif_init(struct mtk_base_afe *afe)38{39struct mt8195_afe_private *afe_priv = afe->platform_priv;40struct mtkaif_param *param = &afe_priv->mtkaif_params;41int delay_data;42int delay_cycle;43unsigned int mask = 0;44unsigned int val = 0;4546/* set rx protocol 2 & mtkaif_rxif_clkinv_adc inverse */47mask = (MTKAIF_RXIF_CLKINV_ADC | MTKAIF_RXIF_PROTOCOL2);48val = (MTKAIF_RXIF_CLKINV_ADC | MTKAIF_RXIF_PROTOCOL2);4950regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_CFG0, mask, val);51regmap_update_bits(afe->regmap, AFE_ADDA6_MTKAIF_CFG0, mask, val);5253mask = RG_RX_PROTOCOL2;54val = RG_RX_PROTOCOL2;55regmap_update_bits(afe->regmap, AFE_AUD_PAD_TOP, mask, val);5657if (!param->mtkaif_calibration_ok) {58dev_info(afe->dev, "%s(), calibration fail\n", __func__);59return 0;60}6162/* set delay for ch1, ch2 */63if (param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0] >=64param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1]) {65delay_data = DELAY_DATA_MISO1;66delay_cycle =67param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0] -68param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1];69} else {70delay_data = DELAY_DATA_MISO0;71delay_cycle =72param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1] -73param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0];74}7576val = 0;77mask = (MTKAIF_RXIF_DELAY_DATA | MTKAIF_RXIF_DELAY_CYCLE_MASK);78val |= MTKAIF_RXIF_DELAY_CYCLE(delay_cycle) &79MTKAIF_RXIF_DELAY_CYCLE_MASK;80val |= delay_data << MTKAIF_RXIF_DELAY_DATA_SHIFT;81regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG2, mask, val);8283/* set delay between ch3 and ch2 */84if (param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2] >=85param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1]) {86delay_data = DELAY_DATA_MISO1;87delay_cycle =88param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2] -89param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1];90} else {91delay_data = DELAY_DATA_MISO2;92delay_cycle =93param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1] -94param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2];95}9697val = 0;98mask = (MTKAIF_RXIF_DELAY_DATA | MTKAIF_RXIF_DELAY_CYCLE_MASK);99val |= MTKAIF_RXIF_DELAY_CYCLE(delay_cycle) &100MTKAIF_RXIF_DELAY_CYCLE_MASK;101val |= delay_data << MTKAIF_RXIF_DELAY_DATA_SHIFT;102regmap_update_bits(afe->regmap, AFE_ADDA6_MTKAIF_RX_CFG2, mask, val);103104return 0;105}106107static int mtk_adda_mtkaif_cfg_event(struct snd_soc_dapm_widget *w,108struct snd_kcontrol *kcontrol,109int event)110{111struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);112struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);113114dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",115__func__, w->name, event);116117switch (event) {118case SND_SOC_DAPM_PRE_PMU:119mt8195_adda_mtkaif_init(afe);120break;121default:122break;123}124125return 0;126}127128static int mtk_adda_dl_event(struct snd_soc_dapm_widget *w,129struct snd_kcontrol *kcontrol,130int event)131{132struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);133struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);134135dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",136__func__, w->name, event);137138switch (event) {139case SND_SOC_DAPM_POST_PMD:140/* should delayed 1/fs(smallest is 8k) = 125us before afe off */141usleep_range(125, 135);142break;143default:144break;145}146147return 0;148}149150static void mtk_adda_ul_mictype(struct mtk_base_afe *afe, int adda, bool dmic)151{152unsigned int reg = 0;153unsigned int mask = 0;154unsigned int val = 0;155156switch (adda) {157case MTK_AFE_ADDA:158reg = AFE_ADDA_UL_SRC_CON0;159break;160case MTK_AFE_ADDA6:161reg = AFE_ADDA6_UL_SRC_CON0;162break;163default:164dev_info(afe->dev, "%s(), wrong parameter\n", __func__);165return;166}167168mask = (UL_SDM3_LEVEL_CTL | UL_MODE_3P25M_CH1_CTL |169UL_MODE_3P25M_CH2_CTL);170171/* turn on dmic, ch1, ch2 */172if (dmic)173val = mask;174175regmap_update_bits(afe->regmap, reg, mask, val);176}177178static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,179struct snd_kcontrol *kcontrol,180int event)181{182struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);183struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);184struct mt8195_afe_private *afe_priv = afe->platform_priv;185struct mtkaif_param *param = &afe_priv->mtkaif_params;186187dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",188__func__, w->name, event);189190switch (event) {191case SND_SOC_DAPM_PRE_PMU:192mtk_adda_ul_mictype(afe, MTK_AFE_ADDA, param->mtkaif_dmic_on);193break;194case SND_SOC_DAPM_POST_PMD:195/* should delayed 1/fs(smallest is 8k) = 125us before afe off */196usleep_range(125, 135);197break;198default:199break;200}201202return 0;203}204205static int mtk_adda6_ul_event(struct snd_soc_dapm_widget *w,206struct snd_kcontrol *kcontrol,207int event)208{209struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);210struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);211struct mt8195_afe_private *afe_priv = afe->platform_priv;212struct mtkaif_param *param = &afe_priv->mtkaif_params;213unsigned int val;214215dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",216__func__, w->name, event);217218switch (event) {219case SND_SOC_DAPM_PRE_PMU:220mtk_adda_ul_mictype(afe, MTK_AFE_ADDA6, param->mtkaif_dmic_on);221222val = (param->mtkaif_adda6_only ?223ADDA6_MTKAIF_RX_SYNC_WORD2_DISABLE : 0);224225regmap_update_bits(afe->regmap,226AFE_ADDA_MTKAIF_SYNCWORD_CFG,227ADDA6_MTKAIF_RX_SYNC_WORD2_DISABLE,228val);229break;230case SND_SOC_DAPM_POST_PMD:231/* should delayed 1/fs(smallest is 8k) = 125us before afe off */232usleep_range(125, 135);233break;234default:235break;236}237238return 0;239}240241static int mtk_audio_hires_event(struct snd_soc_dapm_widget *w,242struct snd_kcontrol *kcontrol,243int event)244{245struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);246struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);247struct mt8195_afe_private *afe_priv = afe->platform_priv;248struct clk *clk = afe_priv->clk[MT8195_CLK_TOP_AUDIO_H_SEL];249struct clk *clk_parent;250251dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",252__func__, w->name, event);253254switch (event) {255case SND_SOC_DAPM_PRE_PMU:256clk_parent = afe_priv->clk[MT8195_CLK_TOP_APLL1];257break;258case SND_SOC_DAPM_POST_PMD:259clk_parent = afe_priv->clk[MT8195_CLK_XTAL_26M];260break;261default:262return 0;263}264mt8195_afe_set_clk_parent(afe, clk, clk_parent);265266return 0;267}268269static struct mtk_dai_adda_priv *get_adda_priv_by_name(struct mtk_base_afe *afe,270const char *name)271{272struct mt8195_afe_private *afe_priv = afe->platform_priv;273int dai_id;274275if (strstr(name, "aud_adc_hires"))276dai_id = MT8195_AFE_IO_UL_SRC1;277else if (strstr(name, "aud_adda6_adc_hires"))278dai_id = MT8195_AFE_IO_UL_SRC2;279else if (strstr(name, "aud_dac_hires"))280dai_id = MT8195_AFE_IO_DL_SRC;281else282return NULL;283284return afe_priv->dai_priv[dai_id];285}286287static int mtk_afe_adda_hires_connect(struct snd_soc_dapm_widget *source,288struct snd_soc_dapm_widget *sink)289{290struct snd_soc_dapm_widget *w = source;291struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);292struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);293struct mtk_dai_adda_priv *adda_priv;294295adda_priv = get_adda_priv_by_name(afe, w->name);296297if (!adda_priv) {298dev_info(afe->dev, "adda_priv == NULL");299return 0;300}301302return (adda_priv->hires_required) ? 1 : 0;303}304305static const struct snd_kcontrol_new mtk_dai_adda_o176_mix[] = {306SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN176, 0, 1, 0),307SOC_DAPM_SINGLE_AUTODISABLE("I002 Switch", AFE_CONN176, 2, 1, 0),308SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN176, 20, 1, 0),309SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN176, 22, 1, 0),310SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN176_2, 6, 1, 0),311};312313static const struct snd_kcontrol_new mtk_dai_adda_o177_mix[] = {314SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN177, 1, 1, 0),315SOC_DAPM_SINGLE_AUTODISABLE("I003 Switch", AFE_CONN177, 3, 1, 0),316SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN177, 21, 1, 0),317SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN177, 23, 1, 0),318SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN177_2, 7, 1, 0),319};320321static const char * const adda_dlgain_mux_map[] = {322"Bypass", "Connect",323};324325static SOC_ENUM_SINGLE_DECL(adda_dlgain_mux_map_enum,326SND_SOC_NOPM, 0,327adda_dlgain_mux_map);328329static const struct snd_kcontrol_new adda_dlgain_mux_control =330SOC_DAPM_ENUM("DL_GAIN_MUX", adda_dlgain_mux_map_enum);331332static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = {333SND_SOC_DAPM_MIXER("I168", SND_SOC_NOPM, 0, 0, NULL, 0),334SND_SOC_DAPM_MIXER("I169", SND_SOC_NOPM, 0, 0, NULL, 0),335SND_SOC_DAPM_MIXER("I170", SND_SOC_NOPM, 0, 0, NULL, 0),336SND_SOC_DAPM_MIXER("I171", SND_SOC_NOPM, 0, 0, NULL, 0),337338SND_SOC_DAPM_MIXER("O176", SND_SOC_NOPM, 0, 0,339mtk_dai_adda_o176_mix,340ARRAY_SIZE(mtk_dai_adda_o176_mix)),341SND_SOC_DAPM_MIXER("O177", SND_SOC_NOPM, 0, 0,342mtk_dai_adda_o177_mix,343ARRAY_SIZE(mtk_dai_adda_o177_mix)),344345SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON,346AFE_ADDA_UL_DL_CON0,347ADDA_AFE_ON_SHIFT, 0,348NULL,3490),350351SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON,352AFE_ADDA_DL_SRC2_CON0,353DL_2_SRC_ON_TMP_CTRL_PRE_SHIFT, 0,354mtk_adda_dl_event,355SND_SOC_DAPM_POST_PMD),356357SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON,358AFE_ADDA_UL_SRC_CON0,359UL_SRC_ON_TMP_CTL_SHIFT, 0,360mtk_adda_ul_event,361SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),362363SND_SOC_DAPM_SUPPLY_S("ADDA6 Capture Enable", SUPPLY_SEQ_ADDA_UL_ON,364AFE_ADDA6_UL_SRC_CON0,365UL_SRC_ON_TMP_CTL_SHIFT, 0,366mtk_adda6_ul_event,367SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),368369SND_SOC_DAPM_SUPPLY_S("AUDIO_HIRES", SUPPLY_SEQ_CLOCK_SEL,370SND_SOC_NOPM,3710, 0,372mtk_audio_hires_event,373SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),374375SND_SOC_DAPM_SUPPLY_S("ADDA_MTKAIF_CFG", SUPPLY_SEQ_ADDA_MTKAIF_CFG,376SND_SOC_NOPM,3770, 0,378mtk_adda_mtkaif_cfg_event,379SND_SOC_DAPM_PRE_PMU),380381SND_SOC_DAPM_MUX("DL_GAIN_MUX", SND_SOC_NOPM, 0, 0,382&adda_dlgain_mux_control),383384SND_SOC_DAPM_PGA("DL_GAIN", AFE_ADDA_DL_SRC2_CON0,385DL_2_GAIN_ON_CTL_PRE_SHIFT, 0, NULL, 0),386387SND_SOC_DAPM_INPUT("ADDA_INPUT"),388SND_SOC_DAPM_OUTPUT("ADDA_OUTPUT"),389390SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac"),391SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc"),392SND_SOC_DAPM_CLOCK_SUPPLY("aud_adda6_adc"),393SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac_hires"),394SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc_hires"),395SND_SOC_DAPM_CLOCK_SUPPLY("aud_adda6_adc_hires"),396};397398static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {399{"ADDA Capture", NULL, "ADDA Enable"},400{"ADDA Capture", NULL, "ADDA Capture Enable"},401{"ADDA Capture", NULL, "ADDA_MTKAIF_CFG"},402{"ADDA Capture", NULL, "aud_adc"},403{"ADDA Capture", NULL, "aud_adc_hires", mtk_afe_adda_hires_connect},404{"aud_adc_hires", NULL, "AUDIO_HIRES"},405406{"ADDA6 Capture", NULL, "ADDA Enable"},407{"ADDA6 Capture", NULL, "ADDA6 Capture Enable"},408{"ADDA6 Capture", NULL, "ADDA_MTKAIF_CFG"},409{"ADDA6 Capture", NULL, "aud_adda6_adc"},410{"ADDA6 Capture", NULL, "aud_adda6_adc_hires",411mtk_afe_adda_hires_connect},412{"aud_adda6_adc_hires", NULL, "AUDIO_HIRES"},413414{"I168", NULL, "ADDA Capture"},415{"I169", NULL, "ADDA Capture"},416{"I170", NULL, "ADDA6 Capture"},417{"I171", NULL, "ADDA6 Capture"},418419{"ADDA Playback", NULL, "ADDA Enable"},420{"ADDA Playback", NULL, "ADDA Playback Enable"},421{"ADDA Playback", NULL, "aud_dac"},422{"ADDA Playback", NULL, "aud_dac_hires", mtk_afe_adda_hires_connect},423{"aud_dac_hires", NULL, "AUDIO_HIRES"},424425{"DL_GAIN", NULL, "O176"},426{"DL_GAIN", NULL, "O177"},427428{"DL_GAIN_MUX", "Bypass", "O176"},429{"DL_GAIN_MUX", "Bypass", "O177"},430{"DL_GAIN_MUX", "Connect", "DL_GAIN"},431432{"ADDA Playback", NULL, "DL_GAIN_MUX"},433434{"O176", "I000 Switch", "I000"},435{"O177", "I001 Switch", "I001"},436437{"O176", "I002 Switch", "I002"},438{"O177", "I003 Switch", "I003"},439440{"O176", "I020 Switch", "I020"},441{"O177", "I021 Switch", "I021"},442443{"O176", "I022 Switch", "I022"},444{"O177", "I023 Switch", "I023"},445446{"O176", "I070 Switch", "I070"},447{"O177", "I071 Switch", "I071"},448449{"ADDA Capture", NULL, "ADDA_INPUT"},450{"ADDA6 Capture", NULL, "ADDA_INPUT"},451{"ADDA_OUTPUT", NULL, "ADDA Playback"},452};453454static int mt8195_adda_dl_gain_put(struct snd_kcontrol *kcontrol,455struct snd_ctl_elem_value *ucontrol)456{457struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);458struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);459unsigned int reg = AFE_ADDA_DL_SRC2_CON1;460unsigned int mask = DL_2_GAIN_CTL_PRE_MASK;461unsigned int value = (unsigned int)(ucontrol->value.integer.value[0]);462463regmap_update_bits(afe->regmap, reg, mask, DL_2_GAIN_CTL_PRE(value));464return 0;465}466467static int mt8195_adda_dl_gain_get(struct snd_kcontrol *kcontrol,468struct snd_ctl_elem_value *ucontrol)469{470struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);471struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);472unsigned int reg = AFE_ADDA_DL_SRC2_CON1;473unsigned int mask = DL_2_GAIN_CTL_PRE_MASK;474unsigned int value = 0;475476regmap_read(afe->regmap, reg, &value);477478ucontrol->value.integer.value[0] = ((value & mask) >>479DL_2_GAIN_CTL_PRE_SHIFT);480return 0;481}482483static int mt8195_adda6_only_get(struct snd_kcontrol *kcontrol,484struct snd_ctl_elem_value *ucontrol)485{486struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);487struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);488struct mt8195_afe_private *afe_priv = afe->platform_priv;489struct mtkaif_param *param = &afe_priv->mtkaif_params;490491ucontrol->value.integer.value[0] = param->mtkaif_adda6_only;492return 0;493}494495static int mt8195_adda6_only_set(struct snd_kcontrol *kcontrol,496struct snd_ctl_elem_value *ucontrol)497{498struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);499struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);500struct mt8195_afe_private *afe_priv = afe->platform_priv;501struct mtkaif_param *param = &afe_priv->mtkaif_params;502int mtkaif_adda6_only;503504mtkaif_adda6_only = ucontrol->value.integer.value[0];505506dev_info(afe->dev, "%s(), kcontrol name %s, mtkaif_adda6_only %d\n",507__func__, kcontrol->id.name, mtkaif_adda6_only);508509param->mtkaif_adda6_only = mtkaif_adda6_only;510511return 0;512}513514static int mt8195_adda_dmic_get(struct snd_kcontrol *kcontrol,515struct snd_ctl_elem_value *ucontrol)516{517struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);518struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);519struct mt8195_afe_private *afe_priv = afe->platform_priv;520struct mtkaif_param *param = &afe_priv->mtkaif_params;521522ucontrol->value.integer.value[0] = param->mtkaif_dmic_on;523return 0;524}525526static int mt8195_adda_dmic_set(struct snd_kcontrol *kcontrol,527struct snd_ctl_elem_value *ucontrol)528{529struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);530struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);531struct mt8195_afe_private *afe_priv = afe->platform_priv;532struct mtkaif_param *param = &afe_priv->mtkaif_params;533int dmic_on;534535dmic_on = ucontrol->value.integer.value[0];536537dev_dbg(afe->dev, "%s(), kcontrol name %s, dmic_on %d\n",538__func__, kcontrol->id.name, dmic_on);539540param->mtkaif_dmic_on = dmic_on;541return 0;542}543544static const struct snd_kcontrol_new mtk_dai_adda_controls[] = {545SOC_SINGLE_EXT("ADDA_DL_Gain", SND_SOC_NOPM, 0, 65535, 0,546mt8195_adda_dl_gain_get, mt8195_adda_dl_gain_put),547SOC_SINGLE_BOOL_EXT("MTKAIF_DMIC", 0,548mt8195_adda_dmic_get, mt8195_adda_dmic_set),549SOC_SINGLE_BOOL_EXT("MTKAIF_ADDA6_ONLY", 0,550mt8195_adda6_only_get,551mt8195_adda6_only_set),552};553554static int mtk_dai_da_configure(struct mtk_base_afe *afe,555unsigned int rate, int id)556{557unsigned int val = 0;558unsigned int mask = 0;559560/* set sampling rate */561mask |= DL_2_INPUT_MODE_CTL_MASK;562val |= DL_2_INPUT_MODE_CTL(mtk_adda_dl_rate_transform(afe, rate));563564/* turn off saturation */565mask |= DL_2_CH1_SATURATION_EN_CTL;566mask |= DL_2_CH2_SATURATION_EN_CTL;567568/* turn off mute function */569mask |= DL_2_MUTE_CH1_OFF_CTL_PRE;570mask |= DL_2_MUTE_CH2_OFF_CTL_PRE;571val |= DL_2_MUTE_CH1_OFF_CTL_PRE;572val |= DL_2_MUTE_CH2_OFF_CTL_PRE;573574/* set voice input data if input sample rate is 8k or 16k */575mask |= DL_2_VOICE_MODE_CTL_PRE;576if (rate == 8000 || rate == 16000)577val |= DL_2_VOICE_MODE_CTL_PRE;578579regmap_update_bits(afe->regmap, AFE_ADDA_DL_SRC2_CON0, mask, val);580581mask = 0;582val = 0;583584/* new 2nd sdm */585mask |= DL_USE_NEW_2ND_SDM;586val |= DL_USE_NEW_2ND_SDM;587regmap_update_bits(afe->regmap, AFE_ADDA_DL_SDM_DCCOMP_CON, mask, val);588589return 0;590}591592static int mtk_dai_ad_configure(struct mtk_base_afe *afe,593unsigned int rate, int id)594{595unsigned int val = 0;596unsigned int mask = 0;597598mask |= UL_VOICE_MODE_CTL_MASK;599val |= UL_VOICE_MODE_CTL(mtk_adda_ul_rate_transform(afe, rate));600601switch (id) {602case MT8195_AFE_IO_UL_SRC1:603regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0,604mask, val);605break;606case MT8195_AFE_IO_UL_SRC2:607regmap_update_bits(afe->regmap, AFE_ADDA6_UL_SRC_CON0,608mask, val);609break;610default:611break;612}613return 0;614}615616static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream,617struct snd_pcm_hw_params *params,618struct snd_soc_dai *dai)619{620struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);621struct mt8195_afe_private *afe_priv = afe->platform_priv;622struct mtk_dai_adda_priv *adda_priv;623unsigned int rate = params_rate(params);624int ret;625626if (dai->id != MT8195_AFE_IO_DL_SRC &&627dai->id != MT8195_AFE_IO_UL_SRC1 &&628dai->id != MT8195_AFE_IO_UL_SRC2)629return -EINVAL;630adda_priv = afe_priv->dai_priv[dai->id];631632dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n",633__func__, dai->id, substream->stream, rate);634635if (rate > ADDA_HIRES_THRES)636adda_priv->hires_required = 1;637else638adda_priv->hires_required = 0;639640if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)641ret = mtk_dai_da_configure(afe, rate, dai->id);642else643ret = mtk_dai_ad_configure(afe, rate, dai->id);644645return ret;646}647648static const struct snd_soc_dai_ops mtk_dai_adda_ops = {649.hw_params = mtk_dai_adda_hw_params,650};651652/* dai driver */653#define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\654SNDRV_PCM_RATE_96000 |\655SNDRV_PCM_RATE_192000)656657#define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\658SNDRV_PCM_RATE_16000 |\659SNDRV_PCM_RATE_32000 |\660SNDRV_PCM_RATE_48000 |\661SNDRV_PCM_RATE_96000 |\662SNDRV_PCM_RATE_192000)663664#define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\665SNDRV_PCM_FMTBIT_S24_LE |\666SNDRV_PCM_FMTBIT_S32_LE)667668static struct snd_soc_dai_driver mtk_dai_adda_driver[] = {669{670.name = "DL_SRC",671.id = MT8195_AFE_IO_DL_SRC,672.playback = {673.stream_name = "ADDA Playback",674.channels_min = 1,675.channels_max = 2,676.rates = MTK_ADDA_PLAYBACK_RATES,677.formats = MTK_ADDA_FORMATS,678},679.ops = &mtk_dai_adda_ops,680},681{682.name = "UL_SRC1",683.id = MT8195_AFE_IO_UL_SRC1,684.capture = {685.stream_name = "ADDA Capture",686.channels_min = 1,687.channels_max = 2,688.rates = MTK_ADDA_CAPTURE_RATES,689.formats = MTK_ADDA_FORMATS,690},691.ops = &mtk_dai_adda_ops,692},693{694.name = "UL_SRC2",695.id = MT8195_AFE_IO_UL_SRC2,696.capture = {697.stream_name = "ADDA6 Capture",698.channels_min = 1,699.channels_max = 2,700.rates = MTK_ADDA_CAPTURE_RATES,701.formats = MTK_ADDA_FORMATS,702},703.ops = &mtk_dai_adda_ops,704},705};706707static int init_adda_priv_data(struct mtk_base_afe *afe)708{709struct mt8195_afe_private *afe_priv = afe->platform_priv;710struct mtk_dai_adda_priv *adda_priv;711static const int adda_dai_list[] = {712MT8195_AFE_IO_DL_SRC,713MT8195_AFE_IO_UL_SRC1,714MT8195_AFE_IO_UL_SRC2715};716int i;717718for (i = 0; i < ARRAY_SIZE(adda_dai_list); i++) {719adda_priv = devm_kzalloc(afe->dev,720sizeof(struct mtk_dai_adda_priv),721GFP_KERNEL);722if (!adda_priv)723return -ENOMEM;724725afe_priv->dai_priv[adda_dai_list[i]] = adda_priv;726}727728return 0;729}730731int mt8195_dai_adda_register(struct mtk_base_afe *afe)732{733struct mtk_base_afe_dai *dai;734735dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);736if (!dai)737return -ENOMEM;738739list_add(&dai->list, &afe->sub_dais);740741dai->dai_drivers = mtk_dai_adda_driver;742dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver);743744dai->dapm_widgets = mtk_dai_adda_widgets;745dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets);746dai->dapm_routes = mtk_dai_adda_routes;747dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes);748dai->controls = mtk_dai_adda_controls;749dai->num_controls = ARRAY_SIZE(mtk_dai_adda_controls);750751return init_adda_priv_data(afe);752}753754755