cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mt6797-dai-adda.c (11113B)


      1// SPDX-License-Identifier: GPL-2.0
      2//
      3// MediaTek ALSA SoC Audio DAI ADDA Control
      4//
      5// Copyright (c) 2018 MediaTek Inc.
      6// Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
      7
      8#include <linux/regmap.h>
      9#include <linux/delay.h>
     10#include "mt6797-afe-common.h"
     11#include "mt6797-interconnection.h"
     12#include "mt6797-reg.h"
     13
     14enum {
     15	MTK_AFE_ADDA_DL_RATE_8K = 0,
     16	MTK_AFE_ADDA_DL_RATE_11K = 1,
     17	MTK_AFE_ADDA_DL_RATE_12K = 2,
     18	MTK_AFE_ADDA_DL_RATE_16K = 3,
     19	MTK_AFE_ADDA_DL_RATE_22K = 4,
     20	MTK_AFE_ADDA_DL_RATE_24K = 5,
     21	MTK_AFE_ADDA_DL_RATE_32K = 6,
     22	MTK_AFE_ADDA_DL_RATE_44K = 7,
     23	MTK_AFE_ADDA_DL_RATE_48K = 8,
     24	MTK_AFE_ADDA_DL_RATE_96K = 9,
     25	MTK_AFE_ADDA_DL_RATE_192K = 10,
     26};
     27
     28enum {
     29	MTK_AFE_ADDA_UL_RATE_8K = 0,
     30	MTK_AFE_ADDA_UL_RATE_16K = 1,
     31	MTK_AFE_ADDA_UL_RATE_32K = 2,
     32	MTK_AFE_ADDA_UL_RATE_48K = 3,
     33	MTK_AFE_ADDA_UL_RATE_96K = 4,
     34	MTK_AFE_ADDA_UL_RATE_192K = 5,
     35	MTK_AFE_ADDA_UL_RATE_48K_HD = 6,
     36};
     37
     38static unsigned int adda_dl_rate_transform(struct mtk_base_afe *afe,
     39					   unsigned int rate)
     40{
     41	switch (rate) {
     42	case 8000:
     43		return MTK_AFE_ADDA_DL_RATE_8K;
     44	case 11025:
     45		return MTK_AFE_ADDA_DL_RATE_11K;
     46	case 12000:
     47		return MTK_AFE_ADDA_DL_RATE_12K;
     48	case 16000:
     49		return MTK_AFE_ADDA_DL_RATE_16K;
     50	case 22050:
     51		return MTK_AFE_ADDA_DL_RATE_22K;
     52	case 24000:
     53		return MTK_AFE_ADDA_DL_RATE_24K;
     54	case 32000:
     55		return MTK_AFE_ADDA_DL_RATE_32K;
     56	case 44100:
     57		return MTK_AFE_ADDA_DL_RATE_44K;
     58	case 48000:
     59		return MTK_AFE_ADDA_DL_RATE_48K;
     60	case 96000:
     61		return MTK_AFE_ADDA_DL_RATE_96K;
     62	case 192000:
     63		return MTK_AFE_ADDA_DL_RATE_192K;
     64	default:
     65		dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n",
     66			 __func__, rate);
     67		return MTK_AFE_ADDA_DL_RATE_48K;
     68	}
     69}
     70
     71static unsigned int adda_ul_rate_transform(struct mtk_base_afe *afe,
     72					   unsigned int rate)
     73{
     74	switch (rate) {
     75	case 8000:
     76		return MTK_AFE_ADDA_UL_RATE_8K;
     77	case 16000:
     78		return MTK_AFE_ADDA_UL_RATE_16K;
     79	case 32000:
     80		return MTK_AFE_ADDA_UL_RATE_32K;
     81	case 48000:
     82		return MTK_AFE_ADDA_UL_RATE_48K;
     83	case 96000:
     84		return MTK_AFE_ADDA_UL_RATE_96K;
     85	case 192000:
     86		return MTK_AFE_ADDA_UL_RATE_192K;
     87	default:
     88		dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n",
     89			 __func__, rate);
     90		return MTK_AFE_ADDA_UL_RATE_48K;
     91	}
     92}
     93
     94/* dai component */
     95static const struct snd_kcontrol_new mtk_adda_dl_ch1_mix[] = {
     96	SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN3, I_DL1_CH1, 1, 0),
     97	SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN3, I_DL2_CH1, 1, 0),
     98	SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN3, I_DL3_CH1, 1, 0),
     99	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN3,
    100				    I_ADDA_UL_CH2, 1, 0),
    101	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN3,
    102				    I_ADDA_UL_CH1, 1, 0),
    103	SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN3,
    104				    I_PCM_1_CAP_CH1, 1, 0),
    105	SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN3,
    106				    I_PCM_2_CAP_CH1, 1, 0),
    107};
    108
    109static const struct snd_kcontrol_new mtk_adda_dl_ch2_mix[] = {
    110	SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN4, I_DL1_CH1, 1, 0),
    111	SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN4, I_DL1_CH2, 1, 0),
    112	SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN4, I_DL2_CH1, 1, 0),
    113	SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN4, I_DL2_CH2, 1, 0),
    114	SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN4, I_DL3_CH1, 1, 0),
    115	SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN4, I_DL3_CH2, 1, 0),
    116	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN4,
    117				    I_ADDA_UL_CH2, 1, 0),
    118	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN4,
    119				    I_ADDA_UL_CH1, 1, 0),
    120	SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN4,
    121				    I_PCM_1_CAP_CH1, 1, 0),
    122	SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN4,
    123				    I_PCM_2_CAP_CH1, 1, 0),
    124	SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN4,
    125				    I_PCM_1_CAP_CH2, 1, 0),
    126	SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN4,
    127				    I_PCM_2_CAP_CH2, 1, 0),
    128};
    129
    130static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,
    131			     struct snd_kcontrol *kcontrol,
    132			     int event)
    133{
    134	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
    135	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
    136
    137	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
    138		__func__, w->name, event);
    139
    140	switch (event) {
    141	case SND_SOC_DAPM_POST_PMD:
    142		/* should delayed 1/fs(smallest is 8k) = 125us before afe off */
    143		usleep_range(125, 135);
    144		break;
    145	default:
    146		break;
    147	}
    148
    149	return 0;
    150}
    151
    152enum {
    153	SUPPLY_SEQ_AUD_TOP_PDN,
    154	SUPPLY_SEQ_ADDA_AFE_ON,
    155	SUPPLY_SEQ_ADDA_DL_ON,
    156	SUPPLY_SEQ_ADDA_UL_ON,
    157};
    158
    159static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = {
    160	/* adda */
    161	SND_SOC_DAPM_MIXER("ADDA_DL_CH1", SND_SOC_NOPM, 0, 0,
    162			   mtk_adda_dl_ch1_mix,
    163			   ARRAY_SIZE(mtk_adda_dl_ch1_mix)),
    164	SND_SOC_DAPM_MIXER("ADDA_DL_CH2", SND_SOC_NOPM, 0, 0,
    165			   mtk_adda_dl_ch2_mix,
    166			   ARRAY_SIZE(mtk_adda_dl_ch2_mix)),
    167
    168	SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON,
    169			      AFE_ADDA_UL_DL_CON0, ADDA_AFE_ON_SFT, 0,
    170			      NULL, 0),
    171
    172	SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON,
    173			      AFE_ADDA_DL_SRC2_CON0,
    174			      DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0,
    175			      NULL, 0),
    176
    177	SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON,
    178			      AFE_ADDA_UL_SRC_CON0,
    179			      UL_SRC_ON_TMP_CTL_SFT, 0,
    180			      mtk_adda_ul_event,
    181			      SND_SOC_DAPM_POST_PMD),
    182
    183	SND_SOC_DAPM_SUPPLY_S("aud_dac_clk", SUPPLY_SEQ_AUD_TOP_PDN,
    184			      AUDIO_TOP_CON0, PDN_DAC_SFT, 1,
    185			      NULL, 0),
    186	SND_SOC_DAPM_SUPPLY_S("aud_dac_predis_clk", SUPPLY_SEQ_AUD_TOP_PDN,
    187			      AUDIO_TOP_CON0, PDN_DAC_PREDIS_SFT, 1,
    188			      NULL, 0),
    189
    190	SND_SOC_DAPM_SUPPLY_S("aud_adc_clk", SUPPLY_SEQ_AUD_TOP_PDN,
    191			      AUDIO_TOP_CON0, PDN_ADC_SFT, 1,
    192			      NULL, 0),
    193
    194	SND_SOC_DAPM_CLOCK_SUPPLY("mtkaif_26m_clk"),
    195};
    196
    197static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
    198	/* playback */
    199	{"ADDA_DL_CH1", "DL1_CH1", "DL1"},
    200	{"ADDA_DL_CH2", "DL1_CH1", "DL1"},
    201	{"ADDA_DL_CH2", "DL1_CH2", "DL1"},
    202
    203	{"ADDA_DL_CH1", "DL2_CH1", "DL2"},
    204	{"ADDA_DL_CH2", "DL2_CH1", "DL2"},
    205	{"ADDA_DL_CH2", "DL2_CH2", "DL2"},
    206
    207	{"ADDA_DL_CH1", "DL3_CH1", "DL3"},
    208	{"ADDA_DL_CH2", "DL3_CH1", "DL3"},
    209	{"ADDA_DL_CH2", "DL3_CH2", "DL3"},
    210
    211	{"ADDA Playback", NULL, "ADDA_DL_CH1"},
    212	{"ADDA Playback", NULL, "ADDA_DL_CH2"},
    213
    214	/* adda enable */
    215	{"ADDA Playback", NULL, "ADDA Enable"},
    216	{"ADDA Playback", NULL, "ADDA Playback Enable"},
    217	{"ADDA Capture", NULL, "ADDA Enable"},
    218	{"ADDA Capture", NULL, "ADDA Capture Enable"},
    219
    220	/* clk */
    221	{"ADDA Playback", NULL, "mtkaif_26m_clk"},
    222	{"ADDA Playback", NULL, "aud_dac_clk"},
    223	{"ADDA Playback", NULL, "aud_dac_predis_clk"},
    224
    225	{"ADDA Capture", NULL, "mtkaif_26m_clk"},
    226	{"ADDA Capture", NULL, "aud_adc_clk"},
    227};
    228
    229/* dai ops */
    230static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream,
    231				  struct snd_pcm_hw_params *params,
    232				  struct snd_soc_dai *dai)
    233{
    234	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
    235	unsigned int rate = params_rate(params);
    236
    237	dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n",
    238		__func__, dai->id, substream->stream, rate);
    239
    240	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
    241		unsigned int dl_src2_con0 = 0;
    242		unsigned int dl_src2_con1 = 0;
    243
    244		/* clean predistortion */
    245		regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON0, 0);
    246		regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON1, 0);
    247
    248		/* set input sampling rate */
    249		dl_src2_con0 = adda_dl_rate_transform(afe, rate) << 28;
    250
    251		/* set output mode */
    252		switch (rate) {
    253		case 192000:
    254			dl_src2_con0 |= (0x1 << 24); /* UP_SAMPLING_RATE_X2 */
    255			dl_src2_con0 |= 1 << 14;
    256			break;
    257		case 96000:
    258			dl_src2_con0 |= (0x2 << 24); /* UP_SAMPLING_RATE_X4 */
    259			dl_src2_con0 |= 1 << 14;
    260			break;
    261		default:
    262			dl_src2_con0 |= (0x3 << 24); /* UP_SAMPLING_RATE_X8 */
    263			break;
    264		}
    265
    266		/* turn off mute function */
    267		dl_src2_con0 |= (0x03 << 11);
    268
    269		/* set voice input data if input sample rate is 8k or 16k */
    270		if (rate == 8000 || rate == 16000)
    271			dl_src2_con0 |= 0x01 << 5;
    272
    273		if (rate < 96000) {
    274			/* SA suggest apply -0.3db to audio/speech path */
    275			dl_src2_con1 = 0xf74f0000;
    276		} else {
    277			/* SA suggest apply -0.3db to audio/speech path
    278			 * with DL gain set to half,
    279			 * 0xFFFF = 0dB -> 0x8000 = 0dB when 96k, 192k
    280			 */
    281			dl_src2_con1 = 0x7ba70000;
    282		}
    283
    284		/* turn on down-link gain */
    285		dl_src2_con0 = dl_src2_con0 | (0x01 << 1);
    286
    287		regmap_write(afe->regmap, AFE_ADDA_DL_SRC2_CON0, dl_src2_con0);
    288		regmap_write(afe->regmap, AFE_ADDA_DL_SRC2_CON1, dl_src2_con1);
    289	} else {
    290		unsigned int voice_mode = 0;
    291		unsigned int ul_src_con0 = 0;	/* default value */
    292
    293		/* Using Internal ADC */
    294		regmap_update_bits(afe->regmap,
    295				   AFE_ADDA_TOP_CON0,
    296				   0x1 << 0,
    297				   0x0 << 0);
    298
    299		voice_mode = adda_ul_rate_transform(afe, rate);
    300
    301		ul_src_con0 |= (voice_mode << 17) & (0x7 << 17);
    302
    303		/* up8x txif sat on */
    304		regmap_write(afe->regmap, AFE_ADDA_NEWIF_CFG0, 0x03F87201);
    305
    306		if (rate >= 96000) {	/* hires */
    307			/* use hires format [1 0 23] */
    308			regmap_update_bits(afe->regmap,
    309					   AFE_ADDA_NEWIF_CFG0,
    310					   0x1 << 5,
    311					   0x1 << 5);
    312
    313			regmap_update_bits(afe->regmap,
    314					   AFE_ADDA_NEWIF_CFG2,
    315					   0xf << 28,
    316					   voice_mode << 28);
    317		} else {	/* normal 8~48k */
    318			/* use fixed 260k anc path */
    319			regmap_update_bits(afe->regmap,
    320					   AFE_ADDA_NEWIF_CFG2,
    321					   0xf << 28,
    322					   8 << 28);
    323
    324			/* ul_use_cic_out */
    325			ul_src_con0 |= 0x1 << 20;
    326		}
    327
    328		regmap_update_bits(afe->regmap,
    329				   AFE_ADDA_NEWIF_CFG2,
    330				   0xf << 28,
    331				   8 << 28);
    332
    333		regmap_update_bits(afe->regmap,
    334				   AFE_ADDA_UL_SRC_CON0,
    335				   0xfffffffe,
    336				   ul_src_con0);
    337	}
    338
    339	return 0;
    340}
    341
    342static const struct snd_soc_dai_ops mtk_dai_adda_ops = {
    343	.hw_params = mtk_dai_adda_hw_params,
    344};
    345
    346/* dai driver */
    347#define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\
    348				 SNDRV_PCM_RATE_96000 |\
    349				 SNDRV_PCM_RATE_192000)
    350
    351#define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\
    352				SNDRV_PCM_RATE_16000 |\
    353				SNDRV_PCM_RATE_32000 |\
    354				SNDRV_PCM_RATE_48000 |\
    355				SNDRV_PCM_RATE_96000 |\
    356				SNDRV_PCM_RATE_192000)
    357
    358#define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
    359			  SNDRV_PCM_FMTBIT_S24_LE |\
    360			  SNDRV_PCM_FMTBIT_S32_LE)
    361
    362static struct snd_soc_dai_driver mtk_dai_adda_driver[] = {
    363	{
    364		.name = "ADDA",
    365		.id = MT6797_DAI_ADDA,
    366		.playback = {
    367			.stream_name = "ADDA Playback",
    368			.channels_min = 1,
    369			.channels_max = 2,
    370			.rates = MTK_ADDA_PLAYBACK_RATES,
    371			.formats = MTK_ADDA_FORMATS,
    372		},
    373		.capture = {
    374			.stream_name = "ADDA Capture",
    375			.channels_min = 1,
    376			.channels_max = 2,
    377			.rates = MTK_ADDA_CAPTURE_RATES,
    378			.formats = MTK_ADDA_FORMATS,
    379		},
    380		.ops = &mtk_dai_adda_ops,
    381	},
    382};
    383
    384int mt6797_dai_adda_register(struct mtk_base_afe *afe)
    385{
    386	struct mtk_base_afe_dai *dai;
    387
    388	dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
    389	if (!dai)
    390		return -ENOMEM;
    391
    392	list_add(&dai->list, &afe->sub_dais);
    393
    394	dai->dai_drivers = mtk_dai_adda_driver;
    395	dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver);
    396
    397	dai->dapm_widgets = mtk_dai_adda_widgets;
    398	dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets);
    399	dai->dapm_routes = mtk_dai_adda_routes;
    400	dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes);
    401	return 0;
    402}