Path: blob/master/sound/soc/mediatek/mt8365/mt8365-afe-pcm.c
26488 views
// SPDX-License-Identifier: GPL-2.01/*2* MediaTek 8365 ALSA SoC AFE platform driver3*4* Copyright (c) 2024 MediaTek Inc.5* Authors: Jia Zeng <[email protected]>6* Alexandre Mergnat <[email protected]>7*/89#include <linux/delay.h>10#include <linux/module.h>11#include <linux/of.h>12#include <linux/of_address.h>13#include <linux/dma-mapping.h>14#include <linux/pm_runtime.h>15#include <sound/soc.h>16#include <sound/pcm_params.h>17#include "mt8365-afe-common.h"18#include "mt8365-afe-clk.h"19#include "mt8365-reg.h"20#include "../common/mtk-base-afe.h"21#include "../common/mtk-afe-platform-driver.h"22#include "../common/mtk-afe-fe-dai.h"2324#define AFE_BASE_END_OFFSET 82526static unsigned int mCM2Input;2728static const unsigned int mt8365_afe_backup_list[] = {29AUDIO_TOP_CON0,30AFE_CONN0,31AFE_CONN1,32AFE_CONN3,33AFE_CONN4,34AFE_CONN5,35AFE_CONN6,36AFE_CONN7,37AFE_CONN8,38AFE_CONN9,39AFE_CONN10,40AFE_CONN11,41AFE_CONN12,42AFE_CONN13,43AFE_CONN14,44AFE_CONN15,45AFE_CONN16,46AFE_CONN17,47AFE_CONN18,48AFE_CONN19,49AFE_CONN20,50AFE_CONN21,51AFE_CONN26,52AFE_CONN27,53AFE_CONN28,54AFE_CONN29,55AFE_CONN30,56AFE_CONN31,57AFE_CONN32,58AFE_CONN33,59AFE_CONN34,60AFE_CONN35,61AFE_CONN36,62AFE_CONN_24BIT,63AFE_CONN_24BIT_1,64AFE_DAC_CON0,65AFE_DAC_CON1,66AFE_DL1_BASE,67AFE_DL1_END,68AFE_DL2_BASE,69AFE_DL2_END,70AFE_VUL_BASE,71AFE_VUL_END,72AFE_AWB_BASE,73AFE_AWB_END,74AFE_VUL3_BASE,75AFE_VUL3_END,76AFE_HDMI_OUT_BASE,77AFE_HDMI_OUT_END,78AFE_HDMI_IN_2CH_BASE,79AFE_HDMI_IN_2CH_END,80AFE_ADDA_UL_DL_CON0,81AFE_ADDA_DL_SRC2_CON0,82AFE_ADDA_DL_SRC2_CON1,83AFE_I2S_CON,84AFE_I2S_CON1,85AFE_I2S_CON2,86AFE_I2S_CON3,87AFE_ADDA_UL_SRC_CON0,88AFE_AUD_PAD_TOP,89AFE_HD_ENGEN_ENABLE,90};9192static const struct snd_pcm_hardware mt8365_afe_hardware = {93.info = (SNDRV_PCM_INFO_MMAP |94SNDRV_PCM_INFO_INTERLEAVED |95SNDRV_PCM_INFO_MMAP_VALID),96.buffer_bytes_max = 256 * 1024,97.period_bytes_min = 512,98.period_bytes_max = 128 * 1024,99.periods_min = 2,100.periods_max = 256,101.fifo_size = 0,102};103104struct mt8365_afe_rate {105unsigned int rate;106unsigned int reg_val;107};108109static const struct mt8365_afe_rate mt8365_afe_fs_rates[] = {110{ .rate = 8000, .reg_val = MT8365_FS_8K },111{ .rate = 11025, .reg_val = MT8365_FS_11D025K },112{ .rate = 12000, .reg_val = MT8365_FS_12K },113{ .rate = 16000, .reg_val = MT8365_FS_16K },114{ .rate = 22050, .reg_val = MT8365_FS_22D05K },115{ .rate = 24000, .reg_val = MT8365_FS_24K },116{ .rate = 32000, .reg_val = MT8365_FS_32K },117{ .rate = 44100, .reg_val = MT8365_FS_44D1K },118{ .rate = 48000, .reg_val = MT8365_FS_48K },119{ .rate = 88200, .reg_val = MT8365_FS_88D2K },120{ .rate = 96000, .reg_val = MT8365_FS_96K },121{ .rate = 176400, .reg_val = MT8365_FS_176D4K },122{ .rate = 192000, .reg_val = MT8365_FS_192K },123};124125int mt8365_afe_fs_timing(unsigned int rate)126{127int i;128129for (i = 0; i < ARRAY_SIZE(mt8365_afe_fs_rates); i++)130if (mt8365_afe_fs_rates[i].rate == rate)131return mt8365_afe_fs_rates[i].reg_val;132133return -EINVAL;134}135136bool mt8365_afe_rate_supported(unsigned int rate, unsigned int id)137{138switch (id) {139case MT8365_AFE_IO_TDM_IN:140if (rate >= 8000 && rate <= 192000)141return true;142break;143case MT8365_AFE_IO_DMIC:144if (rate >= 8000 && rate <= 48000)145return true;146break;147default:148break;149}150151return false;152}153154bool mt8365_afe_channel_supported(unsigned int channel, unsigned int id)155{156switch (id) {157case MT8365_AFE_IO_TDM_IN:158if (channel >= 1 && channel <= 8)159return true;160break;161case MT8365_AFE_IO_DMIC:162if (channel >= 1 && channel <= 8)163return true;164break;165default:166break;167}168169return false;170}171172static bool mt8365_afe_clk_group_44k(int sample_rate)173{174if (sample_rate == 11025 ||175sample_rate == 22050 ||176sample_rate == 44100 ||177sample_rate == 88200 ||178sample_rate == 176400)179return true;180else181return false;182}183184static bool mt8365_afe_clk_group_48k(int sample_rate)185{186return (!mt8365_afe_clk_group_44k(sample_rate));187}188189int mt8365_dai_set_priv(struct mtk_base_afe *afe, int id,190int priv_size, const void *priv_data)191{192struct mt8365_afe_private *afe_priv = afe->platform_priv;193void *temp_data;194195temp_data = devm_kzalloc(afe->dev, priv_size, GFP_KERNEL);196if (!temp_data)197return -ENOMEM;198199if (priv_data)200memcpy(temp_data, priv_data, priv_size);201202afe_priv->dai_priv[id] = temp_data;203204return 0;205}206207static int mt8365_afe_irq_direction_enable(struct mtk_base_afe *afe,208int irq_id, int direction)209{210struct mtk_base_afe_irq *irq;211212if (irq_id >= MT8365_AFE_IRQ_NUM)213return -1;214215irq = &afe->irqs[irq_id];216217if (direction == MT8365_AFE_IRQ_DIR_MCU) {218regmap_update_bits(afe->regmap, AFE_IRQ_MCU_DSP_EN,219(1 << irq->irq_data->irq_clr_shift),2200);221regmap_update_bits(afe->regmap, AFE_IRQ_MCU_EN,222(1 << irq->irq_data->irq_clr_shift),223(1 << irq->irq_data->irq_clr_shift));224} else if (direction == MT8365_AFE_IRQ_DIR_DSP) {225regmap_update_bits(afe->regmap, AFE_IRQ_MCU_DSP_EN,226(1 << irq->irq_data->irq_clr_shift),227(1 << irq->irq_data->irq_clr_shift));228regmap_update_bits(afe->regmap, AFE_IRQ_MCU_EN,229(1 << irq->irq_data->irq_clr_shift),2300);231} else {232regmap_update_bits(afe->regmap, AFE_IRQ_MCU_DSP_EN,233(1 << irq->irq_data->irq_clr_shift),234(1 << irq->irq_data->irq_clr_shift));235regmap_update_bits(afe->regmap, AFE_IRQ_MCU_EN,236(1 << irq->irq_data->irq_clr_shift),237(1 << irq->irq_data->irq_clr_shift));238}239return 0;240}241242static int mt8365_memif_fs(struct snd_pcm_substream *substream,243unsigned int rate)244{245return mt8365_afe_fs_timing(rate);246}247248static int mt8365_irq_fs(struct snd_pcm_substream *substream,249unsigned int rate)250{251return mt8365_memif_fs(substream, rate);252}253254static const struct mt8365_cm_ctrl_reg cm_ctrl_reg[MT8365_CM_NUM] = {255[MT8365_CM1] = {256.con0 = AFE_CM1_CON0,257.con1 = AFE_CM1_CON1,258.con2 = AFE_CM1_CON2,259.con3 = AFE_CM1_CON3,260.con4 = AFE_CM1_CON4,261},262[MT8365_CM2] = {263.con0 = AFE_CM2_CON0,264.con1 = AFE_CM2_CON1,265.con2 = AFE_CM2_CON2,266.con3 = AFE_CM2_CON3,267.con4 = AFE_CM2_CON4,268}269};270271static int mt8365_afe_cm2_mux_conn(struct mtk_base_afe *afe)272{273struct mt8365_afe_private *afe_priv = afe->platform_priv;274unsigned int input = afe_priv->cm2_mux_input;275276/* TDM_IN interconnect to CM2 */277regmap_update_bits(afe->regmap, AFE_CM2_CONN0,278CM2_AFE_CM2_CONN_CFG1_MASK,279CM2_AFE_CM2_CONN_CFG1(TDM_IN_CH0));280regmap_update_bits(afe->regmap, AFE_CM2_CONN0,281CM2_AFE_CM2_CONN_CFG2_MASK,282CM2_AFE_CM2_CONN_CFG2(TDM_IN_CH1));283regmap_update_bits(afe->regmap, AFE_CM2_CONN0,284CM2_AFE_CM2_CONN_CFG3_MASK,285CM2_AFE_CM2_CONN_CFG3(TDM_IN_CH2));286regmap_update_bits(afe->regmap, AFE_CM2_CONN0,287CM2_AFE_CM2_CONN_CFG4_MASK,288CM2_AFE_CM2_CONN_CFG4(TDM_IN_CH3));289regmap_update_bits(afe->regmap, AFE_CM2_CONN0,290CM2_AFE_CM2_CONN_CFG5_MASK,291CM2_AFE_CM2_CONN_CFG5(TDM_IN_CH4));292regmap_update_bits(afe->regmap, AFE_CM2_CONN0,293CM2_AFE_CM2_CONN_CFG6_MASK,294CM2_AFE_CM2_CONN_CFG6(TDM_IN_CH5));295regmap_update_bits(afe->regmap, AFE_CM2_CONN1,296CM2_AFE_CM2_CONN_CFG7_MASK,297CM2_AFE_CM2_CONN_CFG7(TDM_IN_CH6));298regmap_update_bits(afe->regmap, AFE_CM2_CONN1,299CM2_AFE_CM2_CONN_CFG8_MASK,300CM2_AFE_CM2_CONN_CFG8(TDM_IN_CH7));301302/* ref data interconnect to CM2 */303if (input == MT8365_FROM_GASRC1) {304regmap_update_bits(afe->regmap, AFE_CM2_CONN1,305CM2_AFE_CM2_CONN_CFG9_MASK,306CM2_AFE_CM2_CONN_CFG9(GENERAL1_ASRC_OUT_LCH));307regmap_update_bits(afe->regmap, AFE_CM2_CONN1,308CM2_AFE_CM2_CONN_CFG10_MASK,309CM2_AFE_CM2_CONN_CFG10(GENERAL1_ASRC_OUT_RCH));310} else if (input == MT8365_FROM_GASRC2) {311regmap_update_bits(afe->regmap, AFE_CM2_CONN1,312CM2_AFE_CM2_CONN_CFG9_MASK,313CM2_AFE_CM2_CONN_CFG9(GENERAL2_ASRC_OUT_LCH));314regmap_update_bits(afe->regmap, AFE_CM2_CONN1,315CM2_AFE_CM2_CONN_CFG10_MASK,316CM2_AFE_CM2_CONN_CFG10(GENERAL2_ASRC_OUT_RCH));317} else if (input == MT8365_FROM_TDM_ASRC) {318regmap_update_bits(afe->regmap, AFE_CM2_CONN1,319CM2_AFE_CM2_CONN_CFG9_MASK,320CM2_AFE_CM2_CONN_CFG9(TDM_OUT_ASRC_CH0));321regmap_update_bits(afe->regmap, AFE_CM2_CONN1,322CM2_AFE_CM2_CONN_CFG10_MASK,323CM2_AFE_CM2_CONN_CFG10(TDM_OUT_ASRC_CH1));324regmap_update_bits(afe->regmap, AFE_CM2_CONN1,325CM2_AFE_CM2_CONN_CFG11_MASK,326CM2_AFE_CM2_CONN_CFG11(TDM_OUT_ASRC_CH2));327regmap_update_bits(afe->regmap, AFE_CM2_CONN1,328CM2_AFE_CM2_CONN_CFG12_MASK,329CM2_AFE_CM2_CONN_CFG12(TDM_OUT_ASRC_CH3));330regmap_update_bits(afe->regmap, AFE_CM2_CONN2,331CM2_AFE_CM2_CONN_CFG13_MASK,332CM2_AFE_CM2_CONN_CFG13(TDM_OUT_ASRC_CH4));333regmap_update_bits(afe->regmap, AFE_CM2_CONN2,334CM2_AFE_CM2_CONN_CFG14_MASK,335CM2_AFE_CM2_CONN_CFG14(TDM_OUT_ASRC_CH5));336regmap_update_bits(afe->regmap, AFE_CM2_CONN2,337CM2_AFE_CM2_CONN_CFG15_MASK,338CM2_AFE_CM2_CONN_CFG15(TDM_OUT_ASRC_CH6));339regmap_update_bits(afe->regmap, AFE_CM2_CONN2,340CM2_AFE_CM2_CONN_CFG16_MASK,341CM2_AFE_CM2_CONN_CFG16(TDM_OUT_ASRC_CH7));342} else {343dev_err(afe->dev, "%s wrong CM2 input %d\n", __func__, input);344return -1;345}346347return 0;348}349350static int mt8365_afe_get_cm_update_cnt(struct mtk_base_afe *afe,351enum mt8365_cm_num cmNum,352unsigned int rate, unsigned int channel)353{354unsigned int total_cnt, div_cnt, ch_pair, best_cnt;355unsigned int ch_update_cnt[MT8365_CM_UPDATA_CNT_SET];356int i;357358/* calculate cm update cnt359* total_cnt = clk / fs, clk is 26m or 24m or 22m360* div_cnt = total_cnt / ch_pair, max ch 16ch ,2ch is a set361* best_cnt < div_cnt ,we set best_cnt = div_cnt -10362* ch01 = best_cnt, ch23 = 2* ch01_up_cnt363* ch45 = 3* ch01_up_cnt ...ch1415 = 8* ch01_up_cnt364*/365366if (cmNum == MT8365_CM1) {367total_cnt = MT8365_CLK_26M / rate;368} else if (cmNum == MT8365_CM2) {369if (mt8365_afe_clk_group_48k(rate))370total_cnt = MT8365_CLK_24M / rate;371else372total_cnt = MT8365_CLK_22M / rate;373} else {374return -1;375}376377if (channel % 2)378ch_pair = (channel / 2) + 1;379else380ch_pair = channel / 2;381382div_cnt = total_cnt / ch_pair;383best_cnt = div_cnt - 10;384385if (best_cnt <= 0)386return -1;387388for (i = 0; i < ch_pair; i++)389ch_update_cnt[i] = (i + 1) * best_cnt;390391switch (channel) {392case 16:393fallthrough;394case 15:395regmap_update_bits(afe->regmap, cm_ctrl_reg[cmNum].con4,396CM_AFE_CM_UPDATE_CNT2_MASK,397CM_AFE_CM_UPDATE_CNT2(ch_update_cnt[7]));398fallthrough;399case 14:400fallthrough;401case 13:402regmap_update_bits(afe->regmap, cm_ctrl_reg[cmNum].con4,403CM_AFE_CM_UPDATE_CNT1_MASK,404CM_AFE_CM_UPDATE_CNT1(ch_update_cnt[6]));405fallthrough;406case 12:407fallthrough;408case 11:409regmap_update_bits(afe->regmap, cm_ctrl_reg[cmNum].con3,410CM_AFE_CM_UPDATE_CNT2_MASK,411CM_AFE_CM_UPDATE_CNT2(ch_update_cnt[5]));412fallthrough;413case 10:414fallthrough;415case 9:416regmap_update_bits(afe->regmap, cm_ctrl_reg[cmNum].con3,417CM_AFE_CM_UPDATE_CNT1_MASK,418CM_AFE_CM_UPDATE_CNT1(ch_update_cnt[4]));419fallthrough;420case 8:421fallthrough;422case 7:423regmap_update_bits(afe->regmap, cm_ctrl_reg[cmNum].con2,424CM_AFE_CM_UPDATE_CNT2_MASK,425CM_AFE_CM_UPDATE_CNT2(ch_update_cnt[3]));426fallthrough;427case 6:428fallthrough;429case 5:430regmap_update_bits(afe->regmap, cm_ctrl_reg[cmNum].con2,431CM_AFE_CM_UPDATE_CNT1_MASK,432CM_AFE_CM_UPDATE_CNT1(ch_update_cnt[2]));433fallthrough;434case 4:435fallthrough;436case 3:437regmap_update_bits(afe->regmap, cm_ctrl_reg[cmNum].con1,438CM_AFE_CM_UPDATE_CNT2_MASK,439CM_AFE_CM_UPDATE_CNT2(ch_update_cnt[1]));440fallthrough;441case 2:442fallthrough;443case 1:444regmap_update_bits(afe->regmap, cm_ctrl_reg[cmNum].con1,445CM_AFE_CM_UPDATE_CNT1_MASK,446CM_AFE_CM_UPDATE_CNT1(ch_update_cnt[0]));447break;448default:449return -1;450}451452return 0;453}454455static int mt8365_afe_configure_cm(struct mtk_base_afe *afe,456enum mt8365_cm_num cmNum,457unsigned int channels,458unsigned int rate)459{460unsigned int val, mask;461unsigned int fs = mt8365_afe_fs_timing(rate);462463val = FIELD_PREP(CM_AFE_CM_CH_NUM_MASK, (channels - 1)) |464FIELD_PREP(CM_AFE_CM_START_DATA_MASK, 0);465466mask = CM_AFE_CM_CH_NUM_MASK |467CM_AFE_CM_START_DATA_MASK;468469if (cmNum == MT8365_CM1) {470val |= FIELD_PREP(CM_AFE_CM1_IN_MODE_MASK, fs);471472mask |= CM_AFE_CM1_VUL_SEL |473CM_AFE_CM1_IN_MODE_MASK;474} else if (cmNum == MT8365_CM2) {475if (mt8365_afe_clk_group_48k(rate))476val |= FIELD_PREP(CM_AFE_CM2_CLK_SEL, 0);477else478val |= FIELD_PREP(CM_AFE_CM2_CLK_SEL, 1);479480val |= FIELD_PREP(CM_AFE_CM2_TDM_SEL, 1);481482mask |= CM_AFE_CM2_TDM_SEL |483CM_AFE_CM1_IN_MODE_MASK |484CM_AFE_CM2_CLK_SEL;485486mt8365_afe_cm2_mux_conn(afe);487} else {488return -1;489}490491regmap_update_bits(afe->regmap, cm_ctrl_reg[cmNum].con0, mask, val);492493mt8365_afe_get_cm_update_cnt(afe, cmNum, rate, channels);494495return 0;496}497498static int mt8365_afe_fe_startup(struct snd_pcm_substream *substream,499struct snd_soc_dai *dai)500{501struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);502struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);503struct snd_pcm_runtime *runtime = substream->runtime;504int memif_num = snd_soc_rtd_to_cpu(rtd, 0)->id;505struct mtk_base_afe_memif *memif = &afe->memif[memif_num];506int ret;507508memif->substream = substream;509510snd_pcm_hw_constraint_step(substream->runtime, 0,511SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 16);512513snd_soc_set_runtime_hwparams(substream, afe->mtk_afe_hardware);514515ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);516if (ret < 0)517dev_err(afe->dev, "snd_pcm_hw_constraint_integer failed\n");518519mt8365_afe_enable_main_clk(afe);520return ret;521}522523static void mt8365_afe_fe_shutdown(struct snd_pcm_substream *substream,524struct snd_soc_dai *dai)525{526struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);527struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);528int memif_num = snd_soc_rtd_to_cpu(rtd, 0)->id;529struct mtk_base_afe_memif *memif = &afe->memif[memif_num];530531memif->substream = NULL;532533mt8365_afe_disable_main_clk(afe);534}535536static int mt8365_afe_fe_hw_params(struct snd_pcm_substream *substream,537struct snd_pcm_hw_params *params,538struct snd_soc_dai *dai)539{540struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);541struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);542struct mt8365_afe_private *afe_priv = afe->platform_priv;543struct mt8365_control_data *ctrl_data = &afe_priv->ctrl_data;544int dai_id = snd_soc_rtd_to_cpu(rtd, 0)->id;545struct mtk_base_afe_memif *memif = &afe->memif[dai_id];546struct mt8365_fe_dai_data *fe_data = &afe_priv->fe_data[dai_id];547size_t request_size = params_buffer_bytes(params);548unsigned int channels = params_channels(params);549unsigned int rate = params_rate(params);550unsigned int base_end_offset = 8;551int ret, fs;552553dev_info(afe->dev, "%s %s period = %d rate = %d channels = %d\n",554__func__, memif->data->name, params_period_size(params),555rate, channels);556557if (dai_id == MT8365_AFE_MEMIF_VUL2) {558if (!ctrl_data->bypass_cm1)559/* configure cm1 */560mt8365_afe_configure_cm(afe, MT8365_CM1,561channels, rate);562else563regmap_update_bits(afe->regmap, AFE_CM1_CON0,564CM_AFE_CM1_VUL_SEL,565CM_AFE_CM1_VUL_SEL);566} else if (dai_id == MT8365_AFE_MEMIF_TDM_IN) {567if (!ctrl_data->bypass_cm2)568/* configure cm2 */569mt8365_afe_configure_cm(afe, MT8365_CM2,570channels, rate);571else572regmap_update_bits(afe->regmap, AFE_CM2_CON0,573CM_AFE_CM2_TDM_SEL,574~CM_AFE_CM2_TDM_SEL);575576base_end_offset = 4;577}578579if (request_size > fe_data->sram_size) {580ret = snd_pcm_lib_malloc_pages(substream, request_size);581if (ret < 0) {582dev_err(afe->dev,583"%s %s malloc pages %zu bytes failed %d\n",584__func__, memif->data->name, request_size, ret);585return ret;586}587588fe_data->use_sram = false;589590mt8365_afe_emi_clk_on(afe);591} else {592struct snd_dma_buffer *dma_buf = &substream->dma_buffer;593594dma_buf->dev.type = SNDRV_DMA_TYPE_DEV;595dma_buf->dev.dev = substream->pcm->card->dev;596dma_buf->area = (unsigned char *)fe_data->sram_vir_addr;597dma_buf->addr = fe_data->sram_phy_addr;598dma_buf->bytes = request_size;599snd_pcm_set_runtime_buffer(substream, dma_buf);600601fe_data->use_sram = true;602}603604memif->phys_buf_addr = lower_32_bits(substream->runtime->dma_addr);605memif->buffer_size = substream->runtime->dma_bytes;606607/* start */608regmap_write(afe->regmap, memif->data->reg_ofs_base,609memif->phys_buf_addr);610/* end */611regmap_write(afe->regmap,612memif->data->reg_ofs_base + base_end_offset,613memif->phys_buf_addr + memif->buffer_size - 1);614615/* set channel */616if (memif->data->mono_shift >= 0) {617unsigned int mono = (params_channels(params) == 1) ? 1 : 0;618619if (memif->data->mono_reg < 0)620dev_info(afe->dev, "%s mono_reg is NULL\n", __func__);621else622regmap_update_bits(afe->regmap, memif->data->mono_reg,6231 << memif->data->mono_shift,624mono << memif->data->mono_shift);625}626627/* set rate */628if (memif->data->fs_shift < 0)629return 0;630631fs = afe->memif_fs(substream, params_rate(params));632633if (fs < 0)634return -EINVAL;635636if (memif->data->fs_reg < 0)637dev_info(afe->dev, "%s fs_reg is NULL\n", __func__);638else639regmap_update_bits(afe->regmap, memif->data->fs_reg,640memif->data->fs_maskbit << memif->data->fs_shift,641fs << memif->data->fs_shift);642643return 0;644}645646static int mt8365_afe_fe_hw_free(struct snd_pcm_substream *substream,647struct snd_soc_dai *dai)648{649struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);650struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);651struct mt8365_afe_private *afe_priv = afe->platform_priv;652int dai_id = snd_soc_rtd_to_cpu(rtd, 0)->id;653struct mt8365_fe_dai_data *fe_data = &afe_priv->fe_data[dai_id];654int ret = 0;655656if (fe_data->use_sram) {657snd_pcm_set_runtime_buffer(substream, NULL);658} else {659ret = snd_pcm_lib_free_pages(substream);660661mt8365_afe_emi_clk_off(afe);662}663664return ret;665}666667static int mt8365_afe_fe_prepare(struct snd_pcm_substream *substream,668struct snd_soc_dai *dai)669{670struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);671struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);672int dai_id = snd_soc_rtd_to_cpu(rtd, 0)->id;673struct mtk_base_afe_memif *memif = &afe->memif[dai_id];674675/* set format */676if (memif->data->hd_reg >= 0) {677switch (substream->runtime->format) {678case SNDRV_PCM_FORMAT_S16_LE:679regmap_update_bits(afe->regmap, memif->data->hd_reg,6803 << memif->data->hd_shift,6810 << memif->data->hd_shift);682break;683case SNDRV_PCM_FORMAT_S32_LE:684regmap_update_bits(afe->regmap, memif->data->hd_reg,6853 << memif->data->hd_shift,6863 << memif->data->hd_shift);687688if (dai_id == MT8365_AFE_MEMIF_TDM_IN) {689regmap_update_bits(afe->regmap,690memif->data->hd_reg,6913 << memif->data->hd_shift,6921 << memif->data->hd_shift);693regmap_update_bits(afe->regmap,694memif->data->hd_reg,6951 << memif->data->hd_align_mshift,6961 << memif->data->hd_align_mshift);697}698break;699case SNDRV_PCM_FORMAT_S24_LE:700regmap_update_bits(afe->regmap, memif->data->hd_reg,7013 << memif->data->hd_shift,7021 << memif->data->hd_shift);703break;704default:705return -EINVAL;706}707}708709mt8365_afe_irq_direction_enable(afe, memif->irq_usage,710MT8365_AFE_IRQ_DIR_MCU);711712return 0;713}714715static int mt8365_afe_fe_trigger(struct snd_pcm_substream *substream, int cmd,716struct snd_soc_dai *dai)717{718struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);719struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);720struct mt8365_afe_private *afe_priv = afe->platform_priv;721int dai_id = snd_soc_rtd_to_cpu(rtd, 0)->id;722struct mt8365_control_data *ctrl_data = &afe_priv->ctrl_data;723724switch (cmd) {725case SNDRV_PCM_TRIGGER_START:726case SNDRV_PCM_TRIGGER_RESUME:727/* enable channel merge */728if (dai_id == MT8365_AFE_MEMIF_VUL2 &&729!ctrl_data->bypass_cm1) {730regmap_update_bits(afe->regmap, AFE_CM1_CON0,731CM_AFE_CM_ON, CM_AFE_CM_ON);732} else if (dai_id == MT8365_AFE_MEMIF_TDM_IN &&733!ctrl_data->bypass_cm2) {734regmap_update_bits(afe->regmap, AFE_CM2_CON0,735CM_AFE_CM_ON, CM_AFE_CM_ON);736}737break;738case SNDRV_PCM_TRIGGER_STOP:739case SNDRV_PCM_TRIGGER_SUSPEND:740/* disable channel merge */741if (dai_id == MT8365_AFE_MEMIF_VUL2 &&742!ctrl_data->bypass_cm1) {743regmap_update_bits(afe->regmap, AFE_CM1_CON0,744CM_AFE_CM_ON, ~CM_AFE_CM_ON);745} else if (dai_id == MT8365_AFE_MEMIF_TDM_IN &&746!ctrl_data->bypass_cm2) {747regmap_update_bits(afe->regmap, AFE_CM2_CON0,748CM_AFE_CM_ON, ~CM_AFE_CM_ON);749}750break;751default:752break;753}754755return mtk_afe_fe_trigger(substream, cmd, dai);756}757758static int mt8365_afe_hw_gain1_startup(struct snd_pcm_substream *substream,759struct snd_soc_dai *dai)760{761struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);762763mt8365_afe_enable_main_clk(afe);764return 0;765}766767static void mt8365_afe_hw_gain1_shutdown(struct snd_pcm_substream *substream,768struct snd_soc_dai *dai)769{770struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);771struct mt8365_afe_private *afe_priv = afe->platform_priv;772struct mt8365_be_dai_data *be =773&afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE];774775if (be->prepared[substream->stream]) {776regmap_update_bits(afe->regmap, AFE_GAIN1_CON0,777AFE_GAIN1_CON0_EN_MASK, 0);778be->prepared[substream->stream] = false;779}780mt8365_afe_disable_main_clk(afe);781}782783static int mt8365_afe_hw_gain1_prepare(struct snd_pcm_substream *substream,784struct snd_soc_dai *dai)785{786struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);787struct mt8365_afe_private *afe_priv = afe->platform_priv;788struct mt8365_be_dai_data *be =789&afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE];790791int fs;792unsigned int val1 = 0, val2 = 0;793794if (be->prepared[substream->stream]) {795dev_info(afe->dev, "%s prepared already\n", __func__);796return 0;797}798799fs = mt8365_afe_fs_timing(substream->runtime->rate);800regmap_update_bits(afe->regmap, AFE_GAIN1_CON0,801AFE_GAIN1_CON0_MODE_MASK, (unsigned int)fs << 4);802803regmap_read(afe->regmap, AFE_GAIN1_CON1, &val1);804regmap_read(afe->regmap, AFE_GAIN1_CUR, &val2);805if ((val1 & AFE_GAIN1_CON1_MASK) != (val2 & AFE_GAIN1_CUR_MASK))806regmap_update_bits(afe->regmap, AFE_GAIN1_CUR,807AFE_GAIN1_CUR_MASK, val1);808809regmap_update_bits(afe->regmap, AFE_GAIN1_CON0,810AFE_GAIN1_CON0_EN_MASK, 1);811be->prepared[substream->stream] = true;812813return 0;814}815816static const struct snd_pcm_hardware mt8365_hostless_hardware = {817.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |818SNDRV_PCM_INFO_MMAP_VALID),819.period_bytes_min = 256,820.period_bytes_max = 4 * 48 * 1024,821.periods_min = 2,822.periods_max = 256,823.buffer_bytes_max = 8 * 48 * 1024,824.fifo_size = 0,825};826827/* dai ops */828static int mtk_dai_hostless_startup(struct snd_pcm_substream *substream,829struct snd_soc_dai *dai)830{831struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);832struct snd_pcm_runtime *runtime = substream->runtime;833int ret;834835snd_soc_set_runtime_hwparams(substream, &mt8365_hostless_hardware);836837ret = snd_pcm_hw_constraint_integer(runtime,838SNDRV_PCM_HW_PARAM_PERIODS);839if (ret < 0)840dev_err(afe->dev, "snd_pcm_hw_constraint_integer failed\n");841return ret;842}843844/* FE DAIs */845static const struct snd_soc_dai_ops mt8365_afe_fe_dai_ops = {846.startup = mt8365_afe_fe_startup,847.shutdown = mt8365_afe_fe_shutdown,848.hw_params = mt8365_afe_fe_hw_params,849.hw_free = mt8365_afe_fe_hw_free,850.prepare = mt8365_afe_fe_prepare,851.trigger = mt8365_afe_fe_trigger,852};853854static const struct snd_soc_dai_ops mt8365_dai_hostless_ops = {855.startup = mtk_dai_hostless_startup,856};857858static const struct snd_soc_dai_ops mt8365_afe_hw_gain1_ops = {859.startup = mt8365_afe_hw_gain1_startup,860.shutdown = mt8365_afe_hw_gain1_shutdown,861.prepare = mt8365_afe_hw_gain1_prepare,862};863864static struct snd_soc_dai_driver mt8365_memif_dai_driver[] = {865/* FE DAIs: memory intefaces to CPU */866{867.name = "DL1",868.id = MT8365_AFE_MEMIF_DL1,869.playback = {870.stream_name = "DL1",871.channels_min = 1,872.channels_max = 2,873.rates = SNDRV_PCM_RATE_8000_192000,874.formats = SNDRV_PCM_FMTBIT_S16_LE |875SNDRV_PCM_FMTBIT_S32_LE,876},877.ops = &mt8365_afe_fe_dai_ops,878}, {879.name = "DL2",880.id = MT8365_AFE_MEMIF_DL2,881.playback = {882.stream_name = "DL2",883.channels_min = 1,884.channels_max = 2,885.rates = SNDRV_PCM_RATE_8000_192000,886.formats = SNDRV_PCM_FMTBIT_S16_LE |887SNDRV_PCM_FMTBIT_S32_LE,888},889.ops = &mt8365_afe_fe_dai_ops,890}, {891.name = "TDM_OUT",892.id = MT8365_AFE_MEMIF_TDM_OUT,893.playback = {894.stream_name = "TDM_OUT",895.channels_min = 1,896.channels_max = 8,897.rates = SNDRV_PCM_RATE_8000_192000,898.formats = SNDRV_PCM_FMTBIT_S16_LE |899SNDRV_PCM_FMTBIT_S32_LE,900},901.ops = &mt8365_afe_fe_dai_ops,902}, {903.name = "AWB",904.id = MT8365_AFE_MEMIF_AWB,905.capture = {906.stream_name = "AWB",907.channels_min = 1,908.channels_max = 2,909.rates = SNDRV_PCM_RATE_8000_192000,910.formats = SNDRV_PCM_FMTBIT_S16_LE |911SNDRV_PCM_FMTBIT_S32_LE,912},913.ops = &mt8365_afe_fe_dai_ops,914}, {915.name = "VUL",916.id = MT8365_AFE_MEMIF_VUL,917.capture = {918.stream_name = "VUL",919.channels_min = 1,920.channels_max = 2,921.rates = SNDRV_PCM_RATE_8000_192000,922.formats = SNDRV_PCM_FMTBIT_S16_LE |923SNDRV_PCM_FMTBIT_S32_LE,924},925.ops = &mt8365_afe_fe_dai_ops,926}, {927.name = "VUL2",928.id = MT8365_AFE_MEMIF_VUL2,929.capture = {930.stream_name = "VUL2",931.channels_min = 1,932.channels_max = 16,933.rates = SNDRV_PCM_RATE_8000_192000,934.formats = SNDRV_PCM_FMTBIT_S16_LE |935SNDRV_PCM_FMTBIT_S32_LE,936},937.ops = &mt8365_afe_fe_dai_ops,938}, {939.name = "VUL3",940.id = MT8365_AFE_MEMIF_VUL3,941.capture = {942.stream_name = "VUL3",943.channels_min = 1,944.channels_max = 2,945.rates = SNDRV_PCM_RATE_8000_192000,946.formats = SNDRV_PCM_FMTBIT_S16_LE |947SNDRV_PCM_FMTBIT_S32_LE,948},949.ops = &mt8365_afe_fe_dai_ops,950}, {951.name = "TDM_IN",952.id = MT8365_AFE_MEMIF_TDM_IN,953.capture = {954.stream_name = "TDM_IN",955.channels_min = 1,956.channels_max = 16,957.rates = SNDRV_PCM_RATE_8000_192000,958.formats = SNDRV_PCM_FMTBIT_S16_LE |959SNDRV_PCM_FMTBIT_S32_LE,960},961.ops = &mt8365_afe_fe_dai_ops,962}, {963.name = "Hostless FM DAI",964.id = MT8365_AFE_IO_VIRTUAL_FM,965.playback = {966.stream_name = "Hostless FM DL",967.channels_min = 1,968.channels_max = 2,969.rates = SNDRV_PCM_RATE_8000_192000,970.formats = SNDRV_PCM_FMTBIT_S16_LE |971SNDRV_PCM_FMTBIT_S24_LE |972SNDRV_PCM_FMTBIT_S32_LE,973},974.capture = {975.stream_name = "Hostless FM UL",976.channels_min = 1,977.channels_max = 2,978.rates = SNDRV_PCM_RATE_8000_192000,979.formats = SNDRV_PCM_FMTBIT_S16_LE |980SNDRV_PCM_FMTBIT_S24_LE |981SNDRV_PCM_FMTBIT_S32_LE,982},983.ops = &mt8365_dai_hostless_ops,984}, {985.name = "HW_GAIN1",986.id = MT8365_AFE_IO_HW_GAIN1,987.playback = {988.stream_name = "HW Gain 1 In",989.channels_min = 1,990.channels_max = 2,991.rates = SNDRV_PCM_RATE_8000_192000,992.formats = SNDRV_PCM_FMTBIT_S16_LE |993SNDRV_PCM_FMTBIT_S24_LE |994SNDRV_PCM_FMTBIT_S32_LE,995},996.capture = {997.stream_name = "HW Gain 1 Out",998.channels_min = 1,999.channels_max = 2,1000.rates = SNDRV_PCM_RATE_8000_192000,1001.formats = SNDRV_PCM_FMTBIT_S16_LE |1002SNDRV_PCM_FMTBIT_S24_LE |1003SNDRV_PCM_FMTBIT_S32_LE,1004},1005.ops = &mt8365_afe_hw_gain1_ops,1006.symmetric_rate = 1,1007.symmetric_channels = 1,1008.symmetric_sample_bits = 1,1009},1010};10111012static const struct snd_kcontrol_new mt8365_afe_o00_mix[] = {1013SOC_DAPM_SINGLE_AUTODISABLE("I05 Switch", AFE_CONN0, 5, 1, 0),1014SOC_DAPM_SINGLE_AUTODISABLE("I07 Switch", AFE_CONN0, 7, 1, 0),1015};10161017static const struct snd_kcontrol_new mt8365_afe_o01_mix[] = {1018SOC_DAPM_SINGLE_AUTODISABLE("I06 Switch", AFE_CONN1, 6, 1, 0),1019SOC_DAPM_SINGLE_AUTODISABLE("I08 Switch", AFE_CONN1, 8, 1, 0),1020};10211022static const struct snd_kcontrol_new mt8365_afe_o03_mix[] = {1023SOC_DAPM_SINGLE_AUTODISABLE("I05 Switch", AFE_CONN3, 5, 1, 0),1024SOC_DAPM_SINGLE_AUTODISABLE("I07 Switch", AFE_CONN3, 7, 1, 0),1025SOC_DAPM_SINGLE_AUTODISABLE("I00 Switch", AFE_CONN3, 0, 1, 0),1026SOC_DAPM_SINGLE_AUTODISABLE("I10 Switch", AFE_CONN3, 10, 1, 0),1027};10281029static const struct snd_kcontrol_new mt8365_afe_o04_mix[] = {1030SOC_DAPM_SINGLE_AUTODISABLE("I06 Switch", AFE_CONN4, 6, 1, 0),1031SOC_DAPM_SINGLE_AUTODISABLE("I08 Switch", AFE_CONN4, 8, 1, 0),1032SOC_DAPM_SINGLE_AUTODISABLE("I01 Switch", AFE_CONN4, 1, 1, 0),1033SOC_DAPM_SINGLE_AUTODISABLE("I11 Switch", AFE_CONN4, 11, 1, 0),1034};10351036static const struct snd_kcontrol_new mt8365_afe_o05_mix[] = {1037SOC_DAPM_SINGLE_AUTODISABLE("I00 Switch", AFE_CONN5, 0, 1, 0),1038SOC_DAPM_SINGLE_AUTODISABLE("I03 Switch", AFE_CONN5, 3, 1, 0),1039SOC_DAPM_SINGLE_AUTODISABLE("I05 Switch", AFE_CONN5, 5, 1, 0),1040SOC_DAPM_SINGLE_AUTODISABLE("I07 Switch", AFE_CONN5, 7, 1, 0),1041SOC_DAPM_SINGLE_AUTODISABLE("I09 Switch", AFE_CONN5, 9, 1, 0),1042SOC_DAPM_SINGLE_AUTODISABLE("I14 Switch", AFE_CONN5, 14, 1, 0),1043SOC_DAPM_SINGLE_AUTODISABLE("I16 Switch", AFE_CONN5, 16, 1, 0),1044SOC_DAPM_SINGLE_AUTODISABLE("I18 Switch", AFE_CONN5, 18, 1, 0),1045SOC_DAPM_SINGLE_AUTODISABLE("I20 Switch", AFE_CONN5, 20, 1, 0),1046SOC_DAPM_SINGLE_AUTODISABLE("I23 Switch", AFE_CONN5, 23, 1, 0),1047SOC_DAPM_SINGLE_AUTODISABLE("I10L Switch", AFE_CONN5, 10, 1, 0),1048};10491050static const struct snd_kcontrol_new mt8365_afe_o06_mix[] = {1051SOC_DAPM_SINGLE_AUTODISABLE("I01 Switch", AFE_CONN6, 1, 1, 0),1052SOC_DAPM_SINGLE_AUTODISABLE("I04 Switch", AFE_CONN6, 4, 1, 0),1053SOC_DAPM_SINGLE_AUTODISABLE("I06 Switch", AFE_CONN6, 6, 1, 0),1054SOC_DAPM_SINGLE_AUTODISABLE("I08 Switch", AFE_CONN6, 8, 1, 0),1055SOC_DAPM_SINGLE_AUTODISABLE("I22 Switch", AFE_CONN6, 22, 1, 0),1056SOC_DAPM_SINGLE_AUTODISABLE("I15 Switch", AFE_CONN6, 15, 1, 0),1057SOC_DAPM_SINGLE_AUTODISABLE("I17 Switch", AFE_CONN6, 17, 1, 0),1058SOC_DAPM_SINGLE_AUTODISABLE("I19 Switch", AFE_CONN6, 19, 1, 0),1059SOC_DAPM_SINGLE_AUTODISABLE("I21 Switch", AFE_CONN6, 21, 1, 0),1060SOC_DAPM_SINGLE_AUTODISABLE("I24 Switch", AFE_CONN6, 24, 1, 0),1061SOC_DAPM_SINGLE_AUTODISABLE("I11L Switch", AFE_CONN6, 11, 1, 0),1062};10631064static const struct snd_kcontrol_new mt8365_afe_o07_mix[] = {1065SOC_DAPM_SINGLE_AUTODISABLE("I05 Switch", AFE_CONN7, 5, 1, 0),1066SOC_DAPM_SINGLE_AUTODISABLE("I07 Switch", AFE_CONN7, 7, 1, 0),1067};10681069static const struct snd_kcontrol_new mt8365_afe_o08_mix[] = {1070SOC_DAPM_SINGLE_AUTODISABLE("I06 Switch", AFE_CONN8, 6, 1, 0),1071SOC_DAPM_SINGLE_AUTODISABLE("I08 Switch", AFE_CONN8, 8, 1, 0),1072};10731074static const struct snd_kcontrol_new mt8365_afe_o09_mix[] = {1075SOC_DAPM_SINGLE_AUTODISABLE("I00 Switch", AFE_CONN9, 0, 1, 0),1076SOC_DAPM_SINGLE_AUTODISABLE("I03 Switch", AFE_CONN9, 3, 1, 0),1077SOC_DAPM_SINGLE_AUTODISABLE("I09 Switch", AFE_CONN9, 9, 1, 0),1078SOC_DAPM_SINGLE_AUTODISABLE("I14 Switch", AFE_CONN9, 14, 1, 0),1079SOC_DAPM_SINGLE_AUTODISABLE("I16 Switch", AFE_CONN9, 16, 1, 0),1080SOC_DAPM_SINGLE_AUTODISABLE("I18 Switch", AFE_CONN9, 18, 1, 0),1081SOC_DAPM_SINGLE_AUTODISABLE("I20 Switch", AFE_CONN9, 20, 1, 0),1082};10831084static const struct snd_kcontrol_new mt8365_afe_o10_mix[] = {1085SOC_DAPM_SINGLE_AUTODISABLE("I01 Switch", AFE_CONN10, 1, 1, 0),1086SOC_DAPM_SINGLE_AUTODISABLE("I04 Switch", AFE_CONN10, 4, 1, 0),1087SOC_DAPM_SINGLE_AUTODISABLE("I22 Switch", AFE_CONN10, 22, 1, 0),1088SOC_DAPM_SINGLE_AUTODISABLE("I15 Switch", AFE_CONN10, 15, 1, 0),1089SOC_DAPM_SINGLE_AUTODISABLE("I17 Switch", AFE_CONN10, 17, 1, 0),1090SOC_DAPM_SINGLE_AUTODISABLE("I19 Switch", AFE_CONN10, 19, 1, 0),1091SOC_DAPM_SINGLE_AUTODISABLE("I21 Switch", AFE_CONN10, 21, 1, 0),1092};10931094static const struct snd_kcontrol_new mt8365_afe_o11_mix[] = {1095SOC_DAPM_SINGLE_AUTODISABLE("I00 Switch", AFE_CONN11, 0, 1, 0),1096SOC_DAPM_SINGLE_AUTODISABLE("I03 Switch", AFE_CONN11, 3, 1, 0),1097SOC_DAPM_SINGLE_AUTODISABLE("I09 Switch", AFE_CONN11, 9, 1, 0),1098SOC_DAPM_SINGLE_AUTODISABLE("I14 Switch", AFE_CONN11, 14, 1, 0),1099SOC_DAPM_SINGLE_AUTODISABLE("I16 Switch", AFE_CONN11, 16, 1, 0),1100SOC_DAPM_SINGLE_AUTODISABLE("I18 Switch", AFE_CONN11, 18, 1, 0),1101SOC_DAPM_SINGLE_AUTODISABLE("I20 Switch", AFE_CONN11, 20, 1, 0),1102};11031104static const struct snd_kcontrol_new mt8365_afe_o12_mix[] = {1105SOC_DAPM_SINGLE_AUTODISABLE("I01 Switch", AFE_CONN12, 1, 1, 0),1106SOC_DAPM_SINGLE_AUTODISABLE("I04 Switch", AFE_CONN12, 4, 1, 0),1107SOC_DAPM_SINGLE_AUTODISABLE("I22 Switch", AFE_CONN12, 22, 1, 0),1108SOC_DAPM_SINGLE_AUTODISABLE("I15 Switch", AFE_CONN12, 15, 1, 0),1109SOC_DAPM_SINGLE_AUTODISABLE("I17 Switch", AFE_CONN12, 17, 1, 0),1110SOC_DAPM_SINGLE_AUTODISABLE("I19 Switch", AFE_CONN12, 19, 1, 0),1111SOC_DAPM_SINGLE_AUTODISABLE("I21 Switch", AFE_CONN12, 21, 1, 0),1112};11131114static const struct snd_kcontrol_new mt8365_afe_o13_mix[] = {1115SOC_DAPM_SINGLE_AUTODISABLE("I00 Switch", AFE_CONN13, 0, 1, 0),1116};11171118static const struct snd_kcontrol_new mt8365_afe_o14_mix[] = {1119SOC_DAPM_SINGLE_AUTODISABLE("I01 Switch", AFE_CONN14, 1, 1, 0),1120};11211122static const struct snd_kcontrol_new mt8365_afe_o15_mix[] = {1123};11241125static const struct snd_kcontrol_new mt8365_afe_o16_mix[] = {1126};11271128static const struct snd_kcontrol_new mt8365_afe_o17_mix[] = {1129SOC_DAPM_SINGLE_AUTODISABLE("I03 Switch", AFE_CONN17, 3, 1, 0),1130SOC_DAPM_SINGLE_AUTODISABLE("I14 Switch", AFE_CONN17, 14, 1, 0),1131};11321133static const struct snd_kcontrol_new mt8365_afe_o18_mix[] = {1134SOC_DAPM_SINGLE_AUTODISABLE("I04 Switch", AFE_CONN18, 4, 1, 0),1135SOC_DAPM_SINGLE_AUTODISABLE("I15 Switch", AFE_CONN18, 15, 1, 0),1136SOC_DAPM_SINGLE_AUTODISABLE("I23 Switch", AFE_CONN18, 23, 1, 0),1137SOC_DAPM_SINGLE_AUTODISABLE("I25 Switch", AFE_CONN18, 25, 1, 0),1138};11391140static const struct snd_kcontrol_new mt8365_afe_o19_mix[] = {1141SOC_DAPM_SINGLE_AUTODISABLE("I04 Switch", AFE_CONN19, 4, 1, 0),1142SOC_DAPM_SINGLE_AUTODISABLE("I16 Switch", AFE_CONN19, 16, 1, 0),1143SOC_DAPM_SINGLE_AUTODISABLE("I23 Switch", AFE_CONN19, 23, 1, 0),1144SOC_DAPM_SINGLE_AUTODISABLE("I24 Switch", AFE_CONN19, 24, 1, 0),1145SOC_DAPM_SINGLE_AUTODISABLE("I25 Switch", AFE_CONN19, 25, 1, 0),1146SOC_DAPM_SINGLE_AUTODISABLE("I26 Switch", AFE_CONN19, 26, 1, 0),1147};11481149static const struct snd_kcontrol_new mt8365_afe_o20_mix[] = {1150SOC_DAPM_SINGLE_AUTODISABLE("I17 Switch", AFE_CONN20, 17, 1, 0),1151SOC_DAPM_SINGLE_AUTODISABLE("I24 Switch", AFE_CONN20, 24, 1, 0),1152SOC_DAPM_SINGLE_AUTODISABLE("I26 Switch", AFE_CONN20, 26, 1, 0),1153};11541155static const struct snd_kcontrol_new mt8365_afe_o21_mix[] = {1156SOC_DAPM_SINGLE_AUTODISABLE("I18 Switch", AFE_CONN21, 18, 1, 0),1157SOC_DAPM_SINGLE_AUTODISABLE("I23 Switch", AFE_CONN21, 23, 1, 0),1158SOC_DAPM_SINGLE_AUTODISABLE("I25 Switch", AFE_CONN21, 25, 1, 0),1159};11601161static const struct snd_kcontrol_new mt8365_afe_o22_mix[] = {1162SOC_DAPM_SINGLE_AUTODISABLE("I19 Switch", AFE_CONN22, 19, 1, 0),1163SOC_DAPM_SINGLE_AUTODISABLE("I24 Switch", AFE_CONN22, 24, 1, 0),1164SOC_DAPM_SINGLE_AUTODISABLE("I26 Switch", AFE_CONN22, 26, 1, 0),1165};11661167static const struct snd_kcontrol_new mt8365_afe_o23_mix[] = {1168SOC_DAPM_SINGLE_AUTODISABLE("I20 Switch", AFE_CONN23, 20, 1, 0),1169SOC_DAPM_SINGLE_AUTODISABLE("I23 Switch", AFE_CONN23, 23, 1, 0),1170SOC_DAPM_SINGLE_AUTODISABLE("I25 Switch", AFE_CONN23, 25, 1, 0),1171};11721173static const struct snd_kcontrol_new mt8365_afe_o24_mix[] = {1174SOC_DAPM_SINGLE_AUTODISABLE("I21 Switch", AFE_CONN24, 21, 1, 0),1175SOC_DAPM_SINGLE_AUTODISABLE("I24 Switch", AFE_CONN24, 24, 1, 0),1176SOC_DAPM_SINGLE_AUTODISABLE("I26 Switch", AFE_CONN24, 26, 1, 0),1177SOC_DAPM_SINGLE_AUTODISABLE("I23 Switch", AFE_CONN24, 23, 1, 0),1178SOC_DAPM_SINGLE_AUTODISABLE("I25 Switch", AFE_CONN24, 25, 1, 0),1179};11801181static const struct snd_kcontrol_new mt8365_afe_o25_mix[] = {1182SOC_DAPM_SINGLE_AUTODISABLE("I27 Switch", AFE_CONN25, 27, 1, 0),1183SOC_DAPM_SINGLE_AUTODISABLE("I23 Switch", AFE_CONN25, 23, 1, 0),1184SOC_DAPM_SINGLE_AUTODISABLE("I25 Switch", AFE_CONN25, 25, 1, 0),1185};11861187static const struct snd_kcontrol_new mt8365_afe_o26_mix[] = {1188SOC_DAPM_SINGLE_AUTODISABLE("I28 Switch", AFE_CONN26, 28, 1, 0),1189SOC_DAPM_SINGLE_AUTODISABLE("I24 Switch", AFE_CONN26, 24, 1, 0),1190SOC_DAPM_SINGLE_AUTODISABLE("I26 Switch", AFE_CONN26, 26, 1, 0),1191};11921193static const struct snd_kcontrol_new mt8365_afe_o27_mix[] = {1194SOC_DAPM_SINGLE_AUTODISABLE("I05 Switch", AFE_CONN27, 5, 1, 0),1195SOC_DAPM_SINGLE_AUTODISABLE("I07 Switch", AFE_CONN27, 7, 1, 0),1196};11971198static const struct snd_kcontrol_new mt8365_afe_o28_mix[] = {1199SOC_DAPM_SINGLE_AUTODISABLE("I06 Switch", AFE_CONN28, 6, 1, 0),1200SOC_DAPM_SINGLE_AUTODISABLE("I08 Switch", AFE_CONN28, 8, 1, 0),1201};12021203static const struct snd_kcontrol_new mt8365_afe_o29_mix[] = {1204SOC_DAPM_SINGLE_AUTODISABLE("I05 Switch", AFE_CONN29, 5, 1, 0),1205SOC_DAPM_SINGLE_AUTODISABLE("I07 Switch", AFE_CONN29, 7, 1, 0),1206};12071208static const struct snd_kcontrol_new mt8365_afe_o30_mix[] = {1209SOC_DAPM_SINGLE_AUTODISABLE("I06 Switch", AFE_CONN30, 6, 1, 0),1210SOC_DAPM_SINGLE_AUTODISABLE("I08 Switch", AFE_CONN30, 8, 1, 0),1211};12121213static const struct snd_kcontrol_new mt8365_afe_o31_mix[] = {1214SOC_DAPM_SINGLE_AUTODISABLE("I29 Switch", AFE_CONN31, 29, 1, 0),1215};12161217static const struct snd_kcontrol_new mt8365_afe_o32_mix[] = {1218SOC_DAPM_SINGLE_AUTODISABLE("I30 Switch", AFE_CONN32, 30, 1, 0),1219};12201221static const struct snd_kcontrol_new mt8365_afe_o33_mix[] = {1222SOC_DAPM_SINGLE_AUTODISABLE("I31 Switch", AFE_CONN33, 31, 1, 0),1223};12241225static const struct snd_kcontrol_new mt8365_afe_o34_mix[] = {1226SOC_DAPM_SINGLE_AUTODISABLE("I32 Switch", AFE_CONN34_1, 0, 1, 0),1227};12281229static const struct snd_kcontrol_new mt8365_afe_o35_mix[] = {1230SOC_DAPM_SINGLE_AUTODISABLE("I33 Switch", AFE_CONN35_1, 1, 1, 0),1231};12321233static const struct snd_kcontrol_new mt8365_afe_o36_mix[] = {1234SOC_DAPM_SINGLE_AUTODISABLE("I34 Switch", AFE_CONN36_1, 2, 1, 0),1235};12361237static const struct snd_kcontrol_new mtk_hw_gain1_in_ch1_mix[] = {1238SOC_DAPM_SINGLE_AUTODISABLE("CONNSYS_I2S_CH1 Switch", AFE_CONN13,12390, 1, 0),1240};12411242static const struct snd_kcontrol_new mtk_hw_gain1_in_ch2_mix[] = {1243SOC_DAPM_SINGLE_AUTODISABLE("CONNSYS_I2S_CH2 Switch", AFE_CONN14,12441, 1, 0),1245};12461247static int mt8365_afe_cm2_io_input_mux_get(struct snd_kcontrol *kcontrol,1248struct snd_ctl_elem_value *ucontrol)1249{1250ucontrol->value.integer.value[0] = mCM2Input;12511252return 0;1253}12541255static int mt8365_afe_cm2_io_input_mux_put(struct snd_kcontrol *kcontrol,1256struct snd_ctl_elem_value *ucontrol)1257{1258struct snd_soc_dapm_context *dapm =1259snd_soc_dapm_kcontrol_dapm(kcontrol);1260struct snd_soc_component *comp = snd_soc_dapm_to_component(dapm);1261struct mtk_base_afe *afe = snd_soc_component_get_drvdata(comp);1262struct mt8365_afe_private *afe_priv = afe->platform_priv;1263int ret;12641265mCM2Input = ucontrol->value.enumerated.item[0];12661267afe_priv->cm2_mux_input = mCM2Input;1268ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);12691270return ret;1271}12721273static const char * const fmhwgain_text[] = {1274"OPEN", "FM_HW_GAIN_IO"1275};12761277static const char * const ain_text[] = {1278"INT ADC", "EXT ADC",1279};12801281static const char * const vul2_in_input_text[] = {1282"VUL2_IN_FROM_O17O18", "VUL2_IN_FROM_CM1",1283};12841285static const char * const mt8365_afe_cm2_mux_text[] = {1286"OPEN", "FROM_GASRC1_OUT", "FROM_GASRC2_OUT", "FROM_TDM_ASRC_OUT",1287};12881289static SOC_ENUM_SINGLE_VIRT_DECL(fmhwgain_enum, fmhwgain_text);1290static SOC_ENUM_SINGLE_DECL(ain_enum, AFE_ADDA_TOP_CON0, 0, ain_text);1291static SOC_ENUM_SINGLE_VIRT_DECL(vul2_in_input_enum, vul2_in_input_text);1292static SOC_ENUM_SINGLE_VIRT_DECL(mt8365_afe_cm2_mux_input_enum,1293mt8365_afe_cm2_mux_text);12941295static const struct snd_kcontrol_new fmhwgain_mux =1296SOC_DAPM_ENUM("FM HW Gain Source", fmhwgain_enum);12971298static const struct snd_kcontrol_new ain_mux =1299SOC_DAPM_ENUM("AIN Source", ain_enum);13001301static const struct snd_kcontrol_new vul2_in_input_mux =1302SOC_DAPM_ENUM("VUL2 Input", vul2_in_input_enum);13031304static const struct snd_kcontrol_new mt8365_afe_cm2_mux_input_mux =1305SOC_DAPM_ENUM_EXT("CM2_MUX Source", mt8365_afe_cm2_mux_input_enum,1306mt8365_afe_cm2_io_input_mux_get,1307mt8365_afe_cm2_io_input_mux_put);13081309static const struct snd_soc_dapm_widget mt8365_memif_widgets[] = {1310/* inter-connections */1311SND_SOC_DAPM_MIXER("I00", SND_SOC_NOPM, 0, 0, NULL, 0),1312SND_SOC_DAPM_MIXER("I01", SND_SOC_NOPM, 0, 0, NULL, 0),1313SND_SOC_DAPM_MIXER("I03", SND_SOC_NOPM, 0, 0, NULL, 0),1314SND_SOC_DAPM_MIXER("I04", SND_SOC_NOPM, 0, 0, NULL, 0),1315SND_SOC_DAPM_MIXER("I05", SND_SOC_NOPM, 0, 0, NULL, 0),1316SND_SOC_DAPM_MIXER("I06", SND_SOC_NOPM, 0, 0, NULL, 0),1317SND_SOC_DAPM_MIXER("I07", SND_SOC_NOPM, 0, 0, NULL, 0),1318SND_SOC_DAPM_MIXER("I08", SND_SOC_NOPM, 0, 0, NULL, 0),1319SND_SOC_DAPM_MIXER("I05L", SND_SOC_NOPM, 0, 0, NULL, 0),1320SND_SOC_DAPM_MIXER("I06L", SND_SOC_NOPM, 0, 0, NULL, 0),1321SND_SOC_DAPM_MIXER("I07L", SND_SOC_NOPM, 0, 0, NULL, 0),1322SND_SOC_DAPM_MIXER("I08L", SND_SOC_NOPM, 0, 0, NULL, 0),1323SND_SOC_DAPM_MIXER("I09", SND_SOC_NOPM, 0, 0, NULL, 0),1324SND_SOC_DAPM_MIXER("I10", SND_SOC_NOPM, 0, 0, NULL, 0),1325SND_SOC_DAPM_MIXER("I11", SND_SOC_NOPM, 0, 0, NULL, 0),1326SND_SOC_DAPM_MIXER("I10L", SND_SOC_NOPM, 0, 0, NULL, 0),1327SND_SOC_DAPM_MIXER("I11L", SND_SOC_NOPM, 0, 0, NULL, 0),1328SND_SOC_DAPM_MIXER("I12", SND_SOC_NOPM, 0, 0, NULL, 0),1329SND_SOC_DAPM_MIXER("I13", SND_SOC_NOPM, 0, 0, NULL, 0),1330SND_SOC_DAPM_MIXER("I14", SND_SOC_NOPM, 0, 0, NULL, 0),1331SND_SOC_DAPM_MIXER("I15", SND_SOC_NOPM, 0, 0, NULL, 0),1332SND_SOC_DAPM_MIXER("I16", SND_SOC_NOPM, 0, 0, NULL, 0),1333SND_SOC_DAPM_MIXER("I17", SND_SOC_NOPM, 0, 0, NULL, 0),1334SND_SOC_DAPM_MIXER("I18", SND_SOC_NOPM, 0, 0, NULL, 0),1335SND_SOC_DAPM_MIXER("I19", SND_SOC_NOPM, 0, 0, NULL, 0),1336SND_SOC_DAPM_MIXER("I20", SND_SOC_NOPM, 0, 0, NULL, 0),1337SND_SOC_DAPM_MIXER("I21", SND_SOC_NOPM, 0, 0, NULL, 0),1338SND_SOC_DAPM_MIXER("I22", SND_SOC_NOPM, 0, 0, NULL, 0),1339SND_SOC_DAPM_MIXER("I23", SND_SOC_NOPM, 0, 0, NULL, 0),1340SND_SOC_DAPM_MIXER("I24", SND_SOC_NOPM, 0, 0, NULL, 0),1341SND_SOC_DAPM_MIXER("I25", SND_SOC_NOPM, 0, 0, NULL, 0),1342SND_SOC_DAPM_MIXER("I26", SND_SOC_NOPM, 0, 0, NULL, 0),1343SND_SOC_DAPM_MIXER("I27", SND_SOC_NOPM, 0, 0, NULL, 0),1344SND_SOC_DAPM_MIXER("I28", SND_SOC_NOPM, 0, 0, NULL, 0),1345SND_SOC_DAPM_MIXER("I29", SND_SOC_NOPM, 0, 0, NULL, 0),1346SND_SOC_DAPM_MIXER("I30", SND_SOC_NOPM, 0, 0, NULL, 0),1347SND_SOC_DAPM_MIXER("I31", SND_SOC_NOPM, 0, 0, NULL, 0),1348SND_SOC_DAPM_MIXER("I32", SND_SOC_NOPM, 0, 0, NULL, 0),1349SND_SOC_DAPM_MIXER("I33", SND_SOC_NOPM, 0, 0, NULL, 0),1350SND_SOC_DAPM_MIXER("I34", SND_SOC_NOPM, 0, 0, NULL, 0),1351SND_SOC_DAPM_MIXER("O00", SND_SOC_NOPM, 0, 0,1352mt8365_afe_o00_mix, ARRAY_SIZE(mt8365_afe_o00_mix)),1353SND_SOC_DAPM_MIXER("O01", SND_SOC_NOPM, 0, 0,1354mt8365_afe_o01_mix, ARRAY_SIZE(mt8365_afe_o01_mix)),1355SND_SOC_DAPM_MIXER("O03", SND_SOC_NOPM, 0, 0,1356mt8365_afe_o03_mix, ARRAY_SIZE(mt8365_afe_o03_mix)),1357SND_SOC_DAPM_MIXER("O04", SND_SOC_NOPM, 0, 0,1358mt8365_afe_o04_mix, ARRAY_SIZE(mt8365_afe_o04_mix)),1359SND_SOC_DAPM_MIXER("O05", SND_SOC_NOPM, 0, 0,1360mt8365_afe_o05_mix, ARRAY_SIZE(mt8365_afe_o05_mix)),1361SND_SOC_DAPM_MIXER("O06", SND_SOC_NOPM, 0, 0,1362mt8365_afe_o06_mix, ARRAY_SIZE(mt8365_afe_o06_mix)),1363SND_SOC_DAPM_MIXER("O07", SND_SOC_NOPM, 0, 0,1364mt8365_afe_o07_mix, ARRAY_SIZE(mt8365_afe_o07_mix)),1365SND_SOC_DAPM_MIXER("O08", SND_SOC_NOPM, 0, 0,1366mt8365_afe_o08_mix, ARRAY_SIZE(mt8365_afe_o08_mix)),1367SND_SOC_DAPM_MIXER("O09", SND_SOC_NOPM, 0, 0,1368mt8365_afe_o09_mix, ARRAY_SIZE(mt8365_afe_o09_mix)),1369SND_SOC_DAPM_MIXER("O10", SND_SOC_NOPM, 0, 0,1370mt8365_afe_o10_mix, ARRAY_SIZE(mt8365_afe_o10_mix)),1371SND_SOC_DAPM_MIXER("O11", SND_SOC_NOPM, 0, 0,1372mt8365_afe_o11_mix, ARRAY_SIZE(mt8365_afe_o11_mix)),1373SND_SOC_DAPM_MIXER("O12", SND_SOC_NOPM, 0, 0,1374mt8365_afe_o12_mix, ARRAY_SIZE(mt8365_afe_o12_mix)),1375SND_SOC_DAPM_MIXER("O13", SND_SOC_NOPM, 0, 0,1376mt8365_afe_o13_mix, ARRAY_SIZE(mt8365_afe_o13_mix)),1377SND_SOC_DAPM_MIXER("O14", SND_SOC_NOPM, 0, 0,1378mt8365_afe_o14_mix, ARRAY_SIZE(mt8365_afe_o14_mix)),1379SND_SOC_DAPM_MIXER("O15", SND_SOC_NOPM, 0, 0,1380mt8365_afe_o15_mix, ARRAY_SIZE(mt8365_afe_o15_mix)),1381SND_SOC_DAPM_MIXER("O16", SND_SOC_NOPM, 0, 0,1382mt8365_afe_o16_mix, ARRAY_SIZE(mt8365_afe_o16_mix)),1383SND_SOC_DAPM_MIXER("O17", SND_SOC_NOPM, 0, 0,1384mt8365_afe_o17_mix, ARRAY_SIZE(mt8365_afe_o17_mix)),1385SND_SOC_DAPM_MIXER("O18", SND_SOC_NOPM, 0, 0,1386mt8365_afe_o18_mix, ARRAY_SIZE(mt8365_afe_o18_mix)),1387SND_SOC_DAPM_MIXER("O19", SND_SOC_NOPM, 0, 0,1388mt8365_afe_o19_mix, ARRAY_SIZE(mt8365_afe_o19_mix)),1389SND_SOC_DAPM_MIXER("O20", SND_SOC_NOPM, 0, 0,1390mt8365_afe_o20_mix, ARRAY_SIZE(mt8365_afe_o20_mix)),1391SND_SOC_DAPM_MIXER("O21", SND_SOC_NOPM, 0, 0,1392mt8365_afe_o21_mix, ARRAY_SIZE(mt8365_afe_o21_mix)),1393SND_SOC_DAPM_MIXER("O22", SND_SOC_NOPM, 0, 0,1394mt8365_afe_o22_mix, ARRAY_SIZE(mt8365_afe_o22_mix)),1395SND_SOC_DAPM_MIXER("O23", SND_SOC_NOPM, 0, 0,1396mt8365_afe_o23_mix, ARRAY_SIZE(mt8365_afe_o23_mix)),1397SND_SOC_DAPM_MIXER("O24", SND_SOC_NOPM, 0, 0,1398mt8365_afe_o24_mix, ARRAY_SIZE(mt8365_afe_o24_mix)),1399SND_SOC_DAPM_MIXER("O25", SND_SOC_NOPM, 0, 0,1400mt8365_afe_o25_mix, ARRAY_SIZE(mt8365_afe_o25_mix)),1401SND_SOC_DAPM_MIXER("O26", SND_SOC_NOPM, 0, 0,1402mt8365_afe_o26_mix, ARRAY_SIZE(mt8365_afe_o26_mix)),1403SND_SOC_DAPM_MIXER("O27", SND_SOC_NOPM, 0, 0,1404mt8365_afe_o27_mix, ARRAY_SIZE(mt8365_afe_o27_mix)),1405SND_SOC_DAPM_MIXER("O28", SND_SOC_NOPM, 0, 0,1406mt8365_afe_o28_mix, ARRAY_SIZE(mt8365_afe_o28_mix)),1407SND_SOC_DAPM_MIXER("O29", SND_SOC_NOPM, 0, 0,1408mt8365_afe_o29_mix, ARRAY_SIZE(mt8365_afe_o29_mix)),1409SND_SOC_DAPM_MIXER("O30", SND_SOC_NOPM, 0, 0,1410mt8365_afe_o30_mix, ARRAY_SIZE(mt8365_afe_o30_mix)),1411SND_SOC_DAPM_MIXER("O31", SND_SOC_NOPM, 0, 0,1412mt8365_afe_o31_mix, ARRAY_SIZE(mt8365_afe_o31_mix)),1413SND_SOC_DAPM_MIXER("O32", SND_SOC_NOPM, 0, 0,1414mt8365_afe_o32_mix, ARRAY_SIZE(mt8365_afe_o32_mix)),1415SND_SOC_DAPM_MIXER("O33", SND_SOC_NOPM, 0, 0,1416mt8365_afe_o33_mix, ARRAY_SIZE(mt8365_afe_o33_mix)),1417SND_SOC_DAPM_MIXER("O34", SND_SOC_NOPM, 0, 0,1418mt8365_afe_o34_mix, ARRAY_SIZE(mt8365_afe_o34_mix)),1419SND_SOC_DAPM_MIXER("O35", SND_SOC_NOPM, 0, 0,1420mt8365_afe_o35_mix, ARRAY_SIZE(mt8365_afe_o35_mix)),1421SND_SOC_DAPM_MIXER("O36", SND_SOC_NOPM, 0, 0,1422mt8365_afe_o36_mix, ARRAY_SIZE(mt8365_afe_o36_mix)),1423SND_SOC_DAPM_MIXER("CM2_Mux IO", SND_SOC_NOPM, 0, 0, NULL, 0),1424SND_SOC_DAPM_MIXER("CM1_IO", SND_SOC_NOPM, 0, 0, NULL, 0),1425SND_SOC_DAPM_MIXER("O17O18", SND_SOC_NOPM, 0, 0, NULL, 0),1426/* inter-connections */1427SND_SOC_DAPM_MIXER("HW_GAIN1_IN_CH1", SND_SOC_NOPM, 0, 0,1428mtk_hw_gain1_in_ch1_mix,1429ARRAY_SIZE(mtk_hw_gain1_in_ch1_mix)),1430SND_SOC_DAPM_MIXER("HW_GAIN1_IN_CH2", SND_SOC_NOPM, 0, 0,1431mtk_hw_gain1_in_ch2_mix,1432ARRAY_SIZE(mtk_hw_gain1_in_ch2_mix)),14331434SND_SOC_DAPM_INPUT("DL Source"),14351436SND_SOC_DAPM_MUX("CM2_Mux_IO Input Mux", SND_SOC_NOPM, 0, 0,1437&mt8365_afe_cm2_mux_input_mux),14381439SND_SOC_DAPM_MUX("AIN Mux", SND_SOC_NOPM, 0, 0, &ain_mux),1440SND_SOC_DAPM_MUX("VUL2 Input Mux", SND_SOC_NOPM, 0, 0,1441&vul2_in_input_mux),14421443SND_SOC_DAPM_MUX("FM HW Gain Mux", SND_SOC_NOPM, 0, 0, &fmhwgain_mux),14441445SND_SOC_DAPM_INPUT("HW Gain 1 Out Endpoint"),1446SND_SOC_DAPM_OUTPUT("HW Gain 1 In Endpoint"),1447};14481449static const struct snd_soc_dapm_route mt8365_memif_routes[] = {1450/* downlink */1451{"I00", NULL, "2ND I2S Capture"},1452{"I01", NULL, "2ND I2S Capture"},1453{"I05", NULL, "DL1"},1454{"I06", NULL, "DL1"},1455{"I07", NULL, "DL2"},1456{"I08", NULL, "DL2"},14571458{"O03", "I05 Switch", "I05"},1459{"O04", "I06 Switch", "I06"},1460{"O00", "I05 Switch", "I05"},1461{"O01", "I06 Switch", "I06"},1462{"O07", "I05 Switch", "I05"},1463{"O08", "I06 Switch", "I06"},1464{"O27", "I05 Switch", "I05"},1465{"O28", "I06 Switch", "I06"},1466{"O29", "I05 Switch", "I05"},1467{"O30", "I06 Switch", "I06"},14681469{"O03", "I07 Switch", "I07"},1470{"O04", "I08 Switch", "I08"},1471{"O00", "I07 Switch", "I07"},1472{"O01", "I08 Switch", "I08"},1473{"O07", "I07 Switch", "I07"},1474{"O08", "I08 Switch", "I08"},14751476/* uplink */1477{"AWB", NULL, "O05"},1478{"AWB", NULL, "O06"},1479{"VUL", NULL, "O09"},1480{"VUL", NULL, "O10"},1481{"VUL3", NULL, "O11"},1482{"VUL3", NULL, "O12"},14831484{"AIN Mux", "EXT ADC", "I2S Capture"},1485{"I03", NULL, "AIN Mux"},1486{"I04", NULL, "AIN Mux"},14871488{"HW_GAIN1_IN_CH1", "CONNSYS_I2S_CH1", "Hostless FM DL"},1489{"HW_GAIN1_IN_CH2", "CONNSYS_I2S_CH2", "Hostless FM DL"},14901491{"HW Gain 1 In Endpoint", NULL, "HW Gain 1 In"},1492{"HW Gain 1 Out", NULL, "HW Gain 1 Out Endpoint"},1493{"HW Gain 1 In", NULL, "HW_GAIN1_IN_CH1"},1494{"HW Gain 1 In", NULL, "HW_GAIN1_IN_CH2"},14951496{"FM HW Gain Mux", "FM_HW_GAIN_IO", "HW Gain 1 Out"},1497{"Hostless FM UL", NULL, "FM HW Gain Mux"},1498{"Hostless FM UL", NULL, "FM 2ND I2S Mux"},14991500{"O05", "I05 Switch", "I05L"},1501{"O06", "I06 Switch", "I06L"},1502{"O05", "I07 Switch", "I07L"},1503{"O06", "I08 Switch", "I08L"},15041505{"O05", "I03 Switch", "I03"},1506{"O06", "I04 Switch", "I04"},1507{"O05", "I00 Switch", "I00"},1508{"O06", "I01 Switch", "I01"},1509{"O05", "I09 Switch", "I09"},1510{"O06", "I22 Switch", "I22"},1511{"O05", "I14 Switch", "I14"},1512{"O06", "I15 Switch", "I15"},1513{"O05", "I16 Switch", "I16"},1514{"O06", "I17 Switch", "I17"},1515{"O05", "I18 Switch", "I18"},1516{"O06", "I19 Switch", "I19"},1517{"O05", "I20 Switch", "I20"},1518{"O06", "I21 Switch", "I21"},1519{"O05", "I23 Switch", "I23"},1520{"O06", "I24 Switch", "I24"},15211522{"O09", "I03 Switch", "I03"},1523{"O10", "I04 Switch", "I04"},1524{"O09", "I00 Switch", "I00"},1525{"O10", "I01 Switch", "I01"},1526{"O09", "I09 Switch", "I09"},1527{"O10", "I22 Switch", "I22"},1528{"O09", "I14 Switch", "I14"},1529{"O10", "I15 Switch", "I15"},1530{"O09", "I16 Switch", "I16"},1531{"O10", "I17 Switch", "I17"},1532{"O09", "I18 Switch", "I18"},1533{"O10", "I19 Switch", "I19"},1534{"O09", "I20 Switch", "I20"},1535{"O10", "I21 Switch", "I21"},15361537{"O11", "I03 Switch", "I03"},1538{"O12", "I04 Switch", "I04"},1539{"O11", "I00 Switch", "I00"},1540{"O12", "I01 Switch", "I01"},1541{"O11", "I09 Switch", "I09"},1542{"O12", "I22 Switch", "I22"},1543{"O11", "I14 Switch", "I14"},1544{"O12", "I15 Switch", "I15"},1545{"O11", "I16 Switch", "I16"},1546{"O12", "I17 Switch", "I17"},1547{"O11", "I18 Switch", "I18"},1548{"O12", "I19 Switch", "I19"},1549{"O11", "I20 Switch", "I20"},1550{"O12", "I21 Switch", "I21"},15511552/* CM2_Mux*/1553{"CM2_Mux IO", NULL, "CM2_Mux_IO Input Mux"},15541555/* VUL2 */1556{"VUL2", NULL, "VUL2 Input Mux"},1557{"VUL2 Input Mux", "VUL2_IN_FROM_O17O18", "O17O18"},1558{"VUL2 Input Mux", "VUL2_IN_FROM_CM1", "CM1_IO"},15591560{"O17O18", NULL, "O17"},1561{"O17O18", NULL, "O18"},1562{"CM1_IO", NULL, "O17"},1563{"CM1_IO", NULL, "O18"},1564{"CM1_IO", NULL, "O19"},1565{"CM1_IO", NULL, "O20"},1566{"CM1_IO", NULL, "O21"},1567{"CM1_IO", NULL, "O22"},1568{"CM1_IO", NULL, "O23"},1569{"CM1_IO", NULL, "O24"},1570{"CM1_IO", NULL, "O25"},1571{"CM1_IO", NULL, "O26"},1572{"CM1_IO", NULL, "O31"},1573{"CM1_IO", NULL, "O32"},1574{"CM1_IO", NULL, "O33"},1575{"CM1_IO", NULL, "O34"},1576{"CM1_IO", NULL, "O35"},1577{"CM1_IO", NULL, "O36"},15781579{"O17", "I14 Switch", "I14"},1580{"O18", "I15 Switch", "I15"},1581{"O19", "I16 Switch", "I16"},1582{"O20", "I17 Switch", "I17"},1583{"O21", "I18 Switch", "I18"},1584{"O22", "I19 Switch", "I19"},1585{"O23", "I20 Switch", "I20"},1586{"O24", "I21 Switch", "I21"},1587{"O25", "I23 Switch", "I23"},1588{"O26", "I24 Switch", "I24"},1589{"O25", "I25 Switch", "I25"},1590{"O26", "I26 Switch", "I26"},15911592{"O17", "I03 Switch", "I03"},1593{"O18", "I04 Switch", "I04"},1594{"O18", "I23 Switch", "I23"},1595{"O18", "I25 Switch", "I25"},1596{"O19", "I04 Switch", "I04"},1597{"O19", "I23 Switch", "I23"},1598{"O19", "I24 Switch", "I24"},1599{"O19", "I25 Switch", "I25"},1600{"O19", "I26 Switch", "I26"},1601{"O20", "I24 Switch", "I24"},1602{"O20", "I26 Switch", "I26"},1603{"O21", "I23 Switch", "I23"},1604{"O21", "I25 Switch", "I25"},1605{"O22", "I24 Switch", "I24"},1606{"O22", "I26 Switch", "I26"},16071608{"O23", "I23 Switch", "I23"},1609{"O23", "I25 Switch", "I25"},1610{"O24", "I24 Switch", "I24"},1611{"O24", "I26 Switch", "I26"},1612{"O24", "I23 Switch", "I23"},1613{"O24", "I25 Switch", "I25"},1614{"O13", "I00 Switch", "I00"},1615{"O14", "I01 Switch", "I01"},1616{"O03", "I10 Switch", "I10"},1617{"O04", "I11 Switch", "I11"},1618};16191620static const struct mtk_base_memif_data memif_data[MT8365_AFE_MEMIF_NUM] = {1621{1622.name = "DL1",1623.id = MT8365_AFE_MEMIF_DL1,1624.reg_ofs_base = AFE_DL1_BASE,1625.reg_ofs_cur = AFE_DL1_CUR,1626.fs_reg = AFE_DAC_CON1,1627.fs_shift = 0,1628.fs_maskbit = 0xf,1629.mono_reg = AFE_DAC_CON1,1630.mono_shift = 21,1631.hd_reg = AFE_MEMIF_PBUF_SIZE,1632.hd_shift = 16,1633.enable_reg = AFE_DAC_CON0,1634.enable_shift = 1,1635.msb_reg = -1,1636.msb_shift = -1,1637.agent_disable_reg = -1,1638.agent_disable_shift = -1,1639}, {1640.name = "DL2",1641.id = MT8365_AFE_MEMIF_DL2,1642.reg_ofs_base = AFE_DL2_BASE,1643.reg_ofs_cur = AFE_DL2_CUR,1644.fs_reg = AFE_DAC_CON1,1645.fs_shift = 4,1646.fs_maskbit = 0xf,1647.mono_reg = AFE_DAC_CON1,1648.mono_shift = 22,1649.hd_reg = AFE_MEMIF_PBUF_SIZE,1650.hd_shift = 18,1651.enable_reg = AFE_DAC_CON0,1652.enable_shift = 2,1653.msb_reg = -1,1654.msb_shift = -1,1655.agent_disable_reg = -1,1656.agent_disable_shift = -1,1657}, {1658.name = "TDM OUT",1659.id = MT8365_AFE_MEMIF_TDM_OUT,1660.reg_ofs_base = AFE_HDMI_OUT_BASE,1661.reg_ofs_cur = AFE_HDMI_OUT_CUR,1662.fs_reg = -1,1663.fs_shift = -1,1664.fs_maskbit = -1,1665.mono_reg = -1,1666.mono_shift = -1,1667.hd_reg = AFE_MEMIF_PBUF_SIZE,1668.hd_shift = 28,1669.enable_reg = AFE_HDMI_OUT_CON0,1670.enable_shift = 0,1671.msb_reg = -1,1672.msb_shift = -1,1673.agent_disable_reg = -1,1674.agent_disable_shift = -1,1675}, {1676.name = "AWB",1677.id = MT8365_AFE_MEMIF_AWB,1678.reg_ofs_base = AFE_AWB_BASE,1679.reg_ofs_cur = AFE_AWB_CUR,1680.fs_reg = AFE_DAC_CON1,1681.fs_shift = 12,1682.fs_maskbit = 0xf,1683.mono_reg = AFE_DAC_CON1,1684.mono_shift = 24,1685.hd_reg = AFE_MEMIF_PBUF_SIZE,1686.hd_shift = 20,1687.enable_reg = AFE_DAC_CON0,1688.enable_shift = 6,1689.msb_reg = AFE_MEMIF_MSB,1690.msb_shift = 17,1691.agent_disable_reg = -1,1692.agent_disable_shift = -1,1693}, {1694.name = "VUL",1695.id = MT8365_AFE_MEMIF_VUL,1696.reg_ofs_base = AFE_VUL_BASE,1697.reg_ofs_cur = AFE_VUL_CUR,1698.fs_reg = AFE_DAC_CON1,1699.fs_shift = 16,1700.fs_maskbit = 0xf,1701.mono_reg = AFE_DAC_CON1,1702.mono_shift = 27,1703.hd_reg = AFE_MEMIF_PBUF_SIZE,1704.hd_shift = 22,1705.enable_reg = AFE_DAC_CON0,1706.enable_shift = 3,1707.msb_reg = AFE_MEMIF_MSB,1708.msb_shift = 20,1709.agent_disable_reg = -1,1710.agent_disable_shift = -1,1711}, {1712.name = "VUL2",1713.id = MT8365_AFE_MEMIF_VUL2,1714.reg_ofs_base = AFE_VUL_D2_BASE,1715.reg_ofs_cur = AFE_VUL_D2_CUR,1716.fs_reg = AFE_DAC_CON0,1717.fs_shift = 20,1718.fs_maskbit = 0xf,1719.mono_reg = -1,1720.mono_shift = -1,1721.hd_reg = AFE_MEMIF_PBUF_SIZE,1722.hd_shift = 14,1723.enable_reg = AFE_DAC_CON0,1724.enable_shift = 9,1725.msb_reg = AFE_MEMIF_MSB,1726.msb_shift = 21,1727.agent_disable_reg = -1,1728.agent_disable_shift = -1,1729}, {1730.name = "VUL3",1731.id = MT8365_AFE_MEMIF_VUL3,1732.reg_ofs_base = AFE_VUL3_BASE,1733.reg_ofs_cur = AFE_VUL3_CUR,1734.fs_reg = AFE_DAC_CON1,1735.fs_shift = 8,1736.fs_maskbit = 0xf,1737.mono_reg = AFE_DAC_CON0,1738.mono_shift = 13,1739.hd_reg = AFE_MEMIF_PBUF2_SIZE,1740.hd_shift = 10,1741.enable_reg = AFE_DAC_CON0,1742.enable_shift = 12,1743.msb_reg = AFE_MEMIF_MSB,1744.msb_shift = 27,1745.agent_disable_reg = -1,1746.agent_disable_shift = -1,1747}, {1748.name = "TDM IN",1749.id = MT8365_AFE_MEMIF_TDM_IN,1750.reg_ofs_base = AFE_HDMI_IN_2CH_BASE,1751.reg_ofs_cur = AFE_HDMI_IN_2CH_CUR,1752.fs_reg = -1,1753.fs_shift = -1,1754.fs_maskbit = -1,1755.mono_reg = AFE_HDMI_IN_2CH_CON0,1756.mono_shift = 1,1757.hd_reg = AFE_MEMIF_PBUF2_SIZE,1758.hd_shift = 8,1759.hd_align_mshift = 5,1760.enable_reg = AFE_HDMI_IN_2CH_CON0,1761.enable_shift = 0,1762.msb_reg = AFE_MEMIF_MSB,1763.msb_shift = 28,1764.agent_disable_reg = -1,1765.agent_disable_shift = -1,1766},1767};17681769static const struct mtk_base_irq_data irq_data[MT8365_AFE_IRQ_NUM] = {1770{1771.id = MT8365_AFE_IRQ1,1772.irq_cnt_reg = AFE_IRQ_MCU_CNT1,1773.irq_cnt_shift = 0,1774.irq_cnt_maskbit = 0x3ffff,1775.irq_en_reg = AFE_IRQ_MCU_CON,1776.irq_en_shift = 0,1777.irq_fs_reg = AFE_IRQ_MCU_CON,1778.irq_fs_shift = 4,1779.irq_fs_maskbit = 0xf,1780.irq_clr_reg = AFE_IRQ_MCU_CLR,1781.irq_clr_shift = 0,1782}, {1783.id = MT8365_AFE_IRQ2,1784.irq_cnt_reg = AFE_IRQ_MCU_CNT2,1785.irq_cnt_shift = 0,1786.irq_cnt_maskbit = 0x3ffff,1787.irq_en_reg = AFE_IRQ_MCU_CON,1788.irq_en_shift = 1,1789.irq_fs_reg = AFE_IRQ_MCU_CON,1790.irq_fs_shift = 8,1791.irq_fs_maskbit = 0xf,1792.irq_clr_reg = AFE_IRQ_MCU_CLR,1793.irq_clr_shift = 1,1794}, {1795.id = MT8365_AFE_IRQ3,1796.irq_cnt_reg = AFE_IRQ_MCU_CNT3,1797.irq_cnt_shift = 0,1798.irq_cnt_maskbit = 0x3ffff,1799.irq_en_reg = AFE_IRQ_MCU_CON,1800.irq_en_shift = 2,1801.irq_fs_reg = AFE_IRQ_MCU_CON,1802.irq_fs_shift = 16,1803.irq_fs_maskbit = 0xf,1804.irq_clr_reg = AFE_IRQ_MCU_CLR,1805.irq_clr_shift = 2,1806}, {1807.id = MT8365_AFE_IRQ4,1808.irq_cnt_reg = AFE_IRQ_MCU_CNT4,1809.irq_cnt_shift = 0,1810.irq_cnt_maskbit = 0x3ffff,1811.irq_en_reg = AFE_IRQ_MCU_CON,1812.irq_en_shift = 3,1813.irq_fs_reg = AFE_IRQ_MCU_CON,1814.irq_fs_shift = 20,1815.irq_fs_maskbit = 0xf,1816.irq_clr_reg = AFE_IRQ_MCU_CLR,1817.irq_clr_shift = 3,1818}, {1819.id = MT8365_AFE_IRQ5,1820.irq_cnt_reg = AFE_IRQ_MCU_CNT5,1821.irq_cnt_shift = 0,1822.irq_cnt_maskbit = 0x3ffff,1823.irq_en_reg = AFE_IRQ_MCU_CON2,1824.irq_en_shift = 3,1825.irq_fs_reg = -1,1826.irq_fs_shift = 0,1827.irq_fs_maskbit = 0x0,1828.irq_clr_reg = AFE_IRQ_MCU_CLR,1829.irq_clr_shift = 4,1830}, {1831.id = MT8365_AFE_IRQ6,1832.irq_cnt_reg = -1,1833.irq_cnt_shift = 0,1834.irq_cnt_maskbit = 0x0,1835.irq_en_reg = AFE_IRQ_MCU_CON,1836.irq_en_shift = 13,1837.irq_fs_reg = -1,1838.irq_fs_shift = 0,1839.irq_fs_maskbit = 0x0,1840.irq_clr_reg = AFE_IRQ_MCU_CLR,1841.irq_clr_shift = 5,1842}, {1843.id = MT8365_AFE_IRQ7,1844.irq_cnt_reg = AFE_IRQ_MCU_CNT7,1845.irq_cnt_shift = 0,1846.irq_cnt_maskbit = 0x3ffff,1847.irq_en_reg = AFE_IRQ_MCU_CON,1848.irq_en_shift = 14,1849.irq_fs_reg = AFE_IRQ_MCU_CON,1850.irq_fs_shift = 24,1851.irq_fs_maskbit = 0xf,1852.irq_clr_reg = AFE_IRQ_MCU_CLR,1853.irq_clr_shift = 6,1854}, {1855.id = MT8365_AFE_IRQ8,1856.irq_cnt_reg = AFE_IRQ_MCU_CNT8,1857.irq_cnt_shift = 0,1858.irq_cnt_maskbit = 0x3ffff,1859.irq_en_reg = AFE_IRQ_MCU_CON,1860.irq_en_shift = 15,1861.irq_fs_reg = AFE_IRQ_MCU_CON,1862.irq_fs_shift = 28,1863.irq_fs_maskbit = 0xf,1864.irq_clr_reg = AFE_IRQ_MCU_CLR,1865.irq_clr_shift = 7,1866}, {1867.id = MT8365_AFE_IRQ9,1868.irq_cnt_reg = -1,1869.irq_cnt_shift = 0,1870.irq_cnt_maskbit = 0x0,1871.irq_en_reg = AFE_IRQ_MCU_CON2,1872.irq_en_shift = 2,1873.irq_fs_reg = -1,1874.irq_fs_shift = 0,1875.irq_fs_maskbit = 0x0,1876.irq_clr_reg = AFE_IRQ_MCU_CLR,1877.irq_clr_shift = 8,1878}, {1879.id = MT8365_AFE_IRQ10,1880.irq_cnt_reg = AFE_IRQ_MCU_CNT10,1881.irq_cnt_shift = 0,1882.irq_cnt_maskbit = 0x3ffff,1883.irq_en_reg = AFE_IRQ_MCU_CON2,1884.irq_en_shift = 4,1885.irq_fs_reg = -1,1886.irq_fs_shift = 0,1887.irq_fs_maskbit = 0x0,1888.irq_clr_reg = AFE_IRQ_MCU_CLR,1889.irq_clr_shift = 9,1890},1891};18921893static int memif_specified_irqs[MT8365_AFE_MEMIF_NUM] = {1894[MT8365_AFE_MEMIF_DL1] = MT8365_AFE_IRQ1,1895[MT8365_AFE_MEMIF_DL2] = MT8365_AFE_IRQ2,1896[MT8365_AFE_MEMIF_TDM_OUT] = MT8365_AFE_IRQ5,1897[MT8365_AFE_MEMIF_AWB] = MT8365_AFE_IRQ3,1898[MT8365_AFE_MEMIF_VUL] = MT8365_AFE_IRQ4,1899[MT8365_AFE_MEMIF_VUL2] = MT8365_AFE_IRQ7,1900[MT8365_AFE_MEMIF_VUL3] = MT8365_AFE_IRQ8,1901[MT8365_AFE_MEMIF_TDM_IN] = MT8365_AFE_IRQ10,1902};19031904static const struct regmap_config mt8365_afe_regmap_config = {1905.reg_bits = 32,1906.reg_stride = 4,1907.val_bits = 32,1908.max_register = MAX_REGISTER,1909.cache_type = REGCACHE_NONE,1910};19111912static irqreturn_t mt8365_afe_irq_handler(int irq, void *dev_id)1913{1914struct mtk_base_afe *afe = dev_id;1915unsigned int reg_value;1916unsigned int mcu_irq_mask;1917int i, ret;19181919ret = regmap_read(afe->regmap, AFE_IRQ_MCU_STATUS, ®_value);1920if (ret) {1921dev_err_ratelimited(afe->dev, "%s irq status err\n", __func__);1922reg_value = AFE_IRQ_STATUS_BITS;1923goto err_irq;1924}19251926ret = regmap_read(afe->regmap, AFE_IRQ_MCU_EN, &mcu_irq_mask);1927if (ret) {1928dev_err_ratelimited(afe->dev, "%s irq mcu_en err\n", __func__);1929reg_value = AFE_IRQ_STATUS_BITS;1930goto err_irq;1931}19321933/* only clr cpu irq */1934reg_value &= mcu_irq_mask;19351936for (i = 0; i < MT8365_AFE_MEMIF_NUM; i++) {1937struct mtk_base_afe_memif *memif = &afe->memif[i];1938struct mtk_base_afe_irq *mcu_irq;19391940if (memif->irq_usage < 0)1941continue;19421943mcu_irq = &afe->irqs[memif->irq_usage];19441945if (!(reg_value & (1 << mcu_irq->irq_data->irq_clr_shift)))1946continue;19471948snd_pcm_period_elapsed(memif->substream);1949}19501951err_irq:1952/* clear irq */1953regmap_write(afe->regmap, AFE_IRQ_MCU_CLR,1954reg_value & AFE_IRQ_STATUS_BITS);19551956return IRQ_HANDLED;1957}19581959static int mt8365_afe_runtime_suspend(struct device *dev)1960{1961return 0;1962}19631964static int mt8365_afe_runtime_resume(struct device *dev)1965{1966return 0;1967}19681969static int mt8365_afe_suspend(struct device *dev)1970{1971struct mtk_base_afe *afe = dev_get_drvdata(dev);1972struct regmap *regmap = afe->regmap;1973int i;19741975mt8365_afe_enable_main_clk(afe);19761977if (!afe->reg_back_up)1978afe->reg_back_up =1979devm_kcalloc(dev, afe->reg_back_up_list_num,1980sizeof(unsigned int), GFP_KERNEL);19811982for (i = 0; i < afe->reg_back_up_list_num; i++)1983regmap_read(regmap, afe->reg_back_up_list[i],1984&afe->reg_back_up[i]);19851986mt8365_afe_disable_main_clk(afe);19871988return 0;1989}19901991static int mt8365_afe_resume(struct device *dev)1992{1993struct mtk_base_afe *afe = dev_get_drvdata(dev);1994struct regmap *regmap = afe->regmap;1995int i = 0;19961997if (!afe->reg_back_up)1998return 0;19992000mt8365_afe_enable_main_clk(afe);20012002for (i = 0; i < afe->reg_back_up_list_num; i++)2003regmap_write(regmap, afe->reg_back_up_list[i],2004afe->reg_back_up[i]);20052006mt8365_afe_disable_main_clk(afe);20072008return 0;2009}20102011static int mt8365_afe_dev_runtime_suspend(struct device *dev)2012{2013struct mtk_base_afe *afe = dev_get_drvdata(dev);20142015if (pm_runtime_status_suspended(dev) || afe->suspended)2016return 0;20172018mt8365_afe_suspend(dev);2019afe->suspended = true;2020return 0;2021}20222023static int mt8365_afe_dev_runtime_resume(struct device *dev)2024{2025struct mtk_base_afe *afe = dev_get_drvdata(dev);20262027if (pm_runtime_status_suspended(dev) || !afe->suspended)2028return 0;20292030mt8365_afe_resume(dev);2031afe->suspended = false;2032return 0;2033}20342035static int mt8365_afe_init_registers(struct mtk_base_afe *afe)2036{2037size_t i;20382039static struct {2040unsigned int reg;2041unsigned int mask;2042unsigned int val;2043} init_regs[] = {2044{ AFE_CONN_24BIT, GENMASK(31, 0), GENMASK(31, 0) },2045{ AFE_CONN_24BIT_1, GENMASK(21, 0), GENMASK(21, 0) },2046};20472048mt8365_afe_enable_main_clk(afe);20492050for (i = 0; i < ARRAY_SIZE(init_regs); i++)2051regmap_update_bits(afe->regmap, init_regs[i].reg,2052init_regs[i].mask, init_regs[i].val);20532054mt8365_afe_disable_main_clk(afe);20552056return 0;2057}20582059static int mt8365_dai_memif_register(struct mtk_base_afe *afe)2060{2061struct mtk_base_afe_dai *dai;20622063dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);2064if (!dai)2065return -ENOMEM;20662067list_add(&dai->list, &afe->sub_dais);20682069dai->dai_drivers = mt8365_memif_dai_driver;2070dai->num_dai_drivers = ARRAY_SIZE(mt8365_memif_dai_driver);20712072dai->dapm_widgets = mt8365_memif_widgets;2073dai->num_dapm_widgets = ARRAY_SIZE(mt8365_memif_widgets);2074dai->dapm_routes = mt8365_memif_routes;2075dai->num_dapm_routes = ARRAY_SIZE(mt8365_memif_routes);2076return 0;2077}20782079typedef int (*dai_register_cb)(struct mtk_base_afe *);2080static const dai_register_cb dai_register_cbs[] = {2081mt8365_dai_pcm_register,2082mt8365_dai_i2s_register,2083mt8365_dai_adda_register,2084mt8365_dai_dmic_register,2085mt8365_dai_memif_register,2086};20872088static int mt8365_afe_pcm_dev_probe(struct platform_device *pdev)2089{2090struct mtk_base_afe *afe;2091struct mt8365_afe_private *afe_priv;2092struct device *dev;2093int ret, i, sel_irq;2094unsigned int irq_id;2095struct resource *res;20962097afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL);2098if (!afe)2099return -ENOMEM;2100platform_set_drvdata(pdev, afe);21012102afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv),2103GFP_KERNEL);2104if (!afe->platform_priv)2105return -ENOMEM;21062107afe_priv = afe->platform_priv;2108afe->dev = &pdev->dev;2109dev = afe->dev;21102111spin_lock_init(&afe_priv->afe_ctrl_lock);2112mutex_init(&afe_priv->afe_clk_mutex);21132114res = platform_get_resource(pdev, IORESOURCE_MEM, 0);2115afe->base_addr = devm_ioremap_resource(&pdev->dev, res);2116if (IS_ERR(afe->base_addr))2117return PTR_ERR(afe->base_addr);21182119res = platform_get_resource(pdev, IORESOURCE_MEM, 1);2120if (res) {2121afe_priv->afe_sram_vir_addr =2122devm_ioremap_resource(&pdev->dev, res);2123if (!IS_ERR(afe_priv->afe_sram_vir_addr)) {2124afe_priv->afe_sram_phy_addr = res->start;2125afe_priv->afe_sram_size = resource_size(res);2126}2127}21282129/* initial audio related clock */2130ret = mt8365_afe_init_audio_clk(afe);2131if (ret)2132return dev_err_probe(afe->dev, ret, "mt8365_afe_init_audio_clk fail\n");21332134afe->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "top_audio_sel",2135afe->base_addr,2136&mt8365_afe_regmap_config);2137if (IS_ERR(afe->regmap))2138return PTR_ERR(afe->regmap);21392140/* memif % irq initialize*/2141afe->memif_size = MT8365_AFE_MEMIF_NUM;2142afe->memif = devm_kcalloc(afe->dev, afe->memif_size,2143sizeof(*afe->memif), GFP_KERNEL);2144if (!afe->memif)2145return -ENOMEM;21462147afe->irqs_size = MT8365_AFE_IRQ_NUM;2148afe->irqs = devm_kcalloc(afe->dev, afe->irqs_size,2149sizeof(*afe->irqs), GFP_KERNEL);2150if (!afe->irqs)2151return -ENOMEM;21522153for (i = 0; i < afe->irqs_size; i++)2154afe->irqs[i].irq_data = &irq_data[i];21552156ret = platform_get_irq(pdev, 0);2157if (ret < 0)2158return ret;21592160irq_id = ret;2161ret = devm_request_irq(afe->dev, irq_id, mt8365_afe_irq_handler,21620, "Afe_ISR_Handle", (void *)afe);2163if (ret)2164return dev_err_probe(afe->dev, ret, "could not request_irq\n");21652166/* init sub_dais */2167INIT_LIST_HEAD(&afe->sub_dais);21682169for (i = 0; i < ARRAY_SIZE(dai_register_cbs); i++) {2170ret = dai_register_cbs[i](afe);2171if (ret) {2172dev_warn(afe->dev, "dai register i %d fail, ret %d\n",2173i, ret);2174return ret;2175}2176}21772178/* init dai_driver and component_driver */2179ret = mtk_afe_combine_sub_dai(afe);2180if (ret) {2181dev_warn(afe->dev, "mtk_afe_combine_sub_dai fail, ret %d\n",2182ret);2183return ret;2184}21852186for (i = 0; i < afe->memif_size; i++) {2187afe->memif[i].data = &memif_data[i];2188sel_irq = memif_specified_irqs[i];2189if (sel_irq >= 0) {2190afe->memif[i].irq_usage = sel_irq;2191afe->memif[i].const_irq = 1;2192afe->irqs[sel_irq].irq_occupyed = true;2193} else {2194afe->memif[i].irq_usage = -1;2195}2196}21972198afe->mtk_afe_hardware = &mt8365_afe_hardware;2199afe->memif_fs = mt8365_memif_fs;2200afe->irq_fs = mt8365_irq_fs;22012202ret = devm_pm_runtime_enable(&pdev->dev);2203if (ret)2204return ret;22052206pm_runtime_get_sync(&pdev->dev);2207afe->reg_back_up_list = mt8365_afe_backup_list;2208afe->reg_back_up_list_num = ARRAY_SIZE(mt8365_afe_backup_list);2209afe->runtime_resume = mt8365_afe_runtime_resume;2210afe->runtime_suspend = mt8365_afe_runtime_suspend;22112212/* open afe pdn for dapm read/write audio register */2213mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_AFE);22142215/* Set 26m parent clk */2216mt8365_afe_set_clk_parent(afe,2217afe_priv->clocks[MT8365_CLK_TOP_AUD_SEL],2218afe_priv->clocks[MT8365_CLK_CLK26M]);22192220ret = devm_snd_soc_register_component(&pdev->dev,2221&mtk_afe_pcm_platform,2222afe->dai_drivers,2223afe->num_dai_drivers);2224if (ret) {2225dev_warn(dev, "err_platform\n");2226return ret;2227}22282229mt8365_afe_init_registers(afe);22302231return 0;2232}22332234static void mt8365_afe_pcm_dev_remove(struct platform_device *pdev)2235{2236struct mtk_base_afe *afe = platform_get_drvdata(pdev);22372238mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_AFE);22392240pm_runtime_disable(&pdev->dev);2241if (!pm_runtime_status_suspended(&pdev->dev))2242mt8365_afe_runtime_suspend(&pdev->dev);2243}22442245static const struct of_device_id mt8365_afe_pcm_dt_match[] = {2246{ .compatible = "mediatek,mt8365-afe-pcm", },2247{ }2248};2249MODULE_DEVICE_TABLE(of, mt8365_afe_pcm_dt_match);22502251static const struct dev_pm_ops mt8365_afe_pm_ops = {2252RUNTIME_PM_OPS(mt8365_afe_dev_runtime_suspend,2253mt8365_afe_dev_runtime_resume, NULL)2254SYSTEM_SLEEP_PM_OPS(mt8365_afe_suspend, mt8365_afe_resume)2255};22562257static struct platform_driver mt8365_afe_pcm_driver = {2258.driver = {2259.name = "mt8365-afe-pcm",2260.of_match_table = mt8365_afe_pcm_dt_match,2261.pm = pm_ptr(&mt8365_afe_pm_ops),2262},2263.probe = mt8365_afe_pcm_dev_probe,2264.remove = mt8365_afe_pcm_dev_remove,2265};22662267module_platform_driver(mt8365_afe_pcm_driver);22682269MODULE_DESCRIPTION("MediaTek ALSA SoC AFE platform driver");2270MODULE_AUTHOR("Jia Zeng <[email protected]>");2271MODULE_AUTHOR("Alexandre Mergnat <[email protected]>");2272MODULE_LICENSE("GPL");227322742275