^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * This driver supports the digital controls for the internal codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * found in Allwinner's A33 SoCs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * (C) Copyright 2010-2016
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Reuuimlla Technology Co., Ltd. <www.reuuimllatech.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * huangxin <huangxin@Reuuimllatech.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Mylène Josserand <mylene.josserand@free-electrons.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/log2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <sound/pcm_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <sound/soc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <sound/soc-dapm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define SUN8I_SYSCLK_CTL 0x00c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define SUN8I_SYSCLK_CTL_AIF1CLK_ENA 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define SUN8I_SYSCLK_CTL_AIF1CLK_SRC_PLL (0x2 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define SUN8I_SYSCLK_CTL_AIF2CLK_ENA 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define SUN8I_SYSCLK_CTL_AIF2CLK_SRC_PLL (0x2 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define SUN8I_SYSCLK_CTL_SYSCLK_ENA 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define SUN8I_SYSCLK_CTL_SYSCLK_SRC 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define SUN8I_SYSCLK_CTL_SYSCLK_SRC_AIF1CLK (0x0 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define SUN8I_SYSCLK_CTL_SYSCLK_SRC_AIF2CLK (0x1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define SUN8I_MOD_CLK_ENA 0x010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define SUN8I_MOD_CLK_ENA_AIF1 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define SUN8I_MOD_CLK_ENA_ADC 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define SUN8I_MOD_CLK_ENA_DAC 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define SUN8I_MOD_RST_CTL 0x014
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define SUN8I_MOD_RST_CTL_AIF1 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define SUN8I_MOD_RST_CTL_ADC 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define SUN8I_MOD_RST_CTL_DAC 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define SUN8I_SYS_SR_CTRL 0x018
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define SUN8I_SYS_SR_CTRL_AIF1_FS 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define SUN8I_SYS_SR_CTRL_AIF2_FS 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define SUN8I_AIF1CLK_CTRL 0x040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ_16 (1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define SUN8I_AIF1_ADCDAT_CTRL 0x044
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0L_ENA 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0R_ENA 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0L_SRC 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0R_SRC 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define SUN8I_AIF1_DACDAT_CTRL 0x048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_SRC 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_SRC 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define SUN8I_AIF1_MXR_SRC 0x04c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF1DA0L 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF2DACL 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_ADCL 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF2DACR 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF1DA0R 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACR 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_ADCR 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACL 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define SUN8I_ADC_DIG_CTRL 0x100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define SUN8I_ADC_DIG_CTRL_ENAD 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define SUN8I_ADC_DIG_CTRL_ADOUT_DTS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define SUN8I_ADC_DIG_CTRL_ADOUT_DLY 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define SUN8I_DAC_DIG_CTRL 0x120
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define SUN8I_DAC_DIG_CTRL_ENDA 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define SUN8I_DAC_MXR_SRC 0x130
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define SUN8I_SYSCLK_CTL_AIF1CLK_SRC_MASK GENMASK(9, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define SUN8I_SYSCLK_CTL_AIF2CLK_SRC_MASK GENMASK(5, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define SUN8I_SYS_SR_CTRL_AIF1_FS_MASK GENMASK(15, 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define SUN8I_SYS_SR_CTRL_AIF2_FS_MASK GENMASK(11, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV_MASK GENMASK(12, 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_MASK GENMASK(8, 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ_MASK GENMASK(5, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT_MASK GENMASK(3, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct sun8i_codec_quirks {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) bool legacy_widgets : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) bool lrck_inversion : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct sun8i_codec {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct clk *clk_module;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) const struct sun8i_codec_quirks *quirks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static int sun8i_codec_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct sun8i_codec *scodec = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) regcache_cache_only(scodec->regmap, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) ret = regcache_sync(scodec->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) dev_err(dev, "Failed to sync regmap cache\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static int sun8i_codec_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct sun8i_codec *scodec = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) regcache_cache_only(scodec->regmap, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) regcache_mark_dirty(scodec->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static int sun8i_codec_get_hw_rate(struct snd_pcm_hw_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) unsigned int rate = params_rate(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) switch (rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) case 8000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) case 7350:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) case 11025:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) case 12000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return 0x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) case 16000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) case 22050:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return 0x4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) case 24000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return 0x5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) case 32000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return 0x6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) case 44100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) case 48000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return 0x8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) case 96000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return 0x9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) case 192000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return 0xa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct sun8i_codec *scodec = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /* clock masters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) case SND_SOC_DAIFMT_CBS_CFS: /* Codec slave, DAI master */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) value = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) case SND_SOC_DAIFMT_CBM_CFM: /* Codec Master, DAI slave */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) value = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) BIT(SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) value << SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* clock inversion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) case SND_SOC_DAIFMT_NB_NF: /* Normal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) value = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) case SND_SOC_DAIFMT_IB_IF: /* Inversion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) value = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) BIT(SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) value << SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * It appears that the DAI and the codec in the A33 SoC don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * share the same polarity for the LRCK signal when they mean
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * 'normal' and 'inverted' in the datasheet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * Since the DAI here is our regular i2s driver that have been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * tested with way more codecs than just this one, it means
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * that the codec probably gets it backward, and we have to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * invert the value here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) value ^= scodec->quirks->lrck_inversion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) BIT(SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) value << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /* DAI format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) case SND_SOC_DAIFMT_I2S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) value = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) case SND_SOC_DAIFMT_LEFT_J:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) value = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) case SND_SOC_DAIFMT_RIGHT_J:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) value = 0x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) case SND_SOC_DAIFMT_DSP_A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) case SND_SOC_DAIFMT_DSP_B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) value = 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) value << SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct sun8i_codec_clk_div {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) u8 div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static const struct sun8i_codec_clk_div sun8i_codec_bclk_div[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) { .div = 1, .val = 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) { .div = 2, .val = 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) { .div = 4, .val = 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) { .div = 6, .val = 3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) { .div = 8, .val = 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) { .div = 12, .val = 5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) { .div = 16, .val = 6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) { .div = 24, .val = 7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) { .div = 32, .val = 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) { .div = 48, .val = 9 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) { .div = 64, .val = 10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) { .div = 96, .val = 11 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) { .div = 128, .val = 12 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) { .div = 192, .val = 13 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static u8 sun8i_codec_get_bclk_div(struct sun8i_codec *scodec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) unsigned int rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) unsigned int word_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) unsigned long clk_rate = clk_get_rate(scodec->clk_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) unsigned int div = clk_rate / rate / word_size / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) unsigned int best_val = 0, best_diff = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) for (i = 0; i < ARRAY_SIZE(sun8i_codec_bclk_div); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) const struct sun8i_codec_clk_div *bdiv = &sun8i_codec_bclk_div[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) unsigned int diff = abs(bdiv->div - div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (diff < best_diff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) best_diff = diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) best_val = bdiv->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return best_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) static int sun8i_codec_get_lrck_div(unsigned int channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) unsigned int word_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) unsigned int div = word_size * channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (div < 16 || div > 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return ilog2(div) - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct sun8i_codec *scodec = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) int sample_rate, lrck_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) u8 bclk_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * The CPU DAI handles only a sample of 16 bits. Configure the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * codec to handle this type of sample resolution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ_16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) bclk_div = sun8i_codec_get_bclk_div(scodec, params_rate(params), 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) bclk_div << SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) lrck_div = sun8i_codec_get_lrck_div(params_channels(params),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) params_physical_width(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (lrck_div < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return lrck_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) lrck_div << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) sample_rate = sun8i_codec_get_hw_rate(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (sample_rate < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) regmap_update_bits(scodec->regmap, SUN8I_SYS_SR_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) SUN8I_SYS_SR_CTRL_AIF1_FS_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) sample_rate << SUN8I_SYS_SR_CTRL_AIF1_FS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static const char *const sun8i_aif_stereo_mux_enum_values[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) "Stereo", "Reverse Stereo", "Sum Mono", "Mix Mono"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static SOC_ENUM_DOUBLE_DECL(sun8i_aif1_ad0_stereo_mux_enum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) SUN8I_AIF1_ADCDAT_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0L_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0R_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) sun8i_aif_stereo_mux_enum_values);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) static const struct snd_kcontrol_new sun8i_aif1_ad0_stereo_mux_control =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) SOC_DAPM_ENUM("AIF1 AD0 Stereo Capture Route",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) sun8i_aif1_ad0_stereo_mux_enum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static const struct snd_kcontrol_new sun8i_aif1_ad0_mixer_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) SOC_DAPM_DOUBLE("AIF1 Slot 0 Digital ADC Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) SUN8I_AIF1_MXR_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF1DA0L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF1DA0R, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) SOC_DAPM_DOUBLE("AIF2 Digital ADC Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) SUN8I_AIF1_MXR_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF2DACL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACR, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) SOC_DAPM_DOUBLE("AIF1 Data Digital ADC Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) SUN8I_AIF1_MXR_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_ADCL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_ADCR, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) SOC_DAPM_DOUBLE("AIF2 Inv Digital ADC Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) SUN8I_AIF1_MXR_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF2DACR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACL, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) static SOC_ENUM_DOUBLE_DECL(sun8i_aif1_da0_stereo_mux_enum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) SUN8I_AIF1_DACDAT_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) sun8i_aif_stereo_mux_enum_values);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static const struct snd_kcontrol_new sun8i_aif1_da0_stereo_mux_control =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) SOC_DAPM_ENUM("AIF1 DA0 Stereo Playback Route",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) sun8i_aif1_da0_stereo_mux_enum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static const struct snd_kcontrol_new sun8i_dac_mixer_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) SOC_DAPM_DOUBLE("AIF1 Slot 0 Digital DAC Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) SUN8I_DAC_MXR_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) SOC_DAPM_DOUBLE("AIF1 Slot 1 Digital DAC Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) SUN8I_DAC_MXR_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) SOC_DAPM_DOUBLE("AIF2 Digital DAC Playback Switch", SUN8I_DAC_MXR_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) SOC_DAPM_DOUBLE("ADC Digital DAC Playback Switch", SUN8I_DAC_MXR_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /* System Clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) SND_SOC_DAPM_CLOCK_SUPPLY("mod"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) SND_SOC_DAPM_SUPPLY("AIF1CLK",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) SUN8I_SYSCLK_CTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) SUN8I_SYSCLK_CTL_AIF1CLK_ENA, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) SND_SOC_DAPM_SUPPLY("SYSCLK",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) SUN8I_SYSCLK_CTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) SUN8I_SYSCLK_CTL_SYSCLK_ENA, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) /* Module Clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) SND_SOC_DAPM_SUPPLY("CLK AIF1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) SUN8I_MOD_CLK_ENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) SUN8I_MOD_CLK_ENA_AIF1, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) SND_SOC_DAPM_SUPPLY("CLK ADC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) SUN8I_MOD_CLK_ENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) SUN8I_MOD_CLK_ENA_ADC, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) SND_SOC_DAPM_SUPPLY("CLK DAC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) SUN8I_MOD_CLK_ENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) SUN8I_MOD_CLK_ENA_DAC, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /* Module Resets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) SND_SOC_DAPM_SUPPLY("RST AIF1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) SUN8I_MOD_RST_CTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) SUN8I_MOD_RST_CTL_AIF1, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) SND_SOC_DAPM_SUPPLY("RST ADC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) SUN8I_MOD_RST_CTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) SUN8I_MOD_RST_CTL_ADC, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) SND_SOC_DAPM_SUPPLY("RST DAC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) SUN8I_MOD_RST_CTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) SUN8I_MOD_RST_CTL_DAC, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /* Module Supplies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) SND_SOC_DAPM_SUPPLY("ADC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) SUN8I_ADC_DIG_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) SUN8I_ADC_DIG_CTRL_ENAD, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) SND_SOC_DAPM_SUPPLY("DAC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) SUN8I_DAC_DIG_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) SUN8I_DAC_DIG_CTRL_ENDA, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /* AIF "ADC" Outputs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) SND_SOC_DAPM_AIF_OUT("AIF1 AD0L", "Capture", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) SUN8I_AIF1_ADCDAT_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0L_ENA, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) SND_SOC_DAPM_AIF_OUT("AIF1 AD0R", "Capture", 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) SUN8I_AIF1_ADCDAT_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0R_ENA, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /* AIF "ADC" Mono/Stereo Muxes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) SND_SOC_DAPM_MUX("AIF1 AD0L Stereo Mux", SND_SOC_NOPM, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) &sun8i_aif1_ad0_stereo_mux_control),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) SND_SOC_DAPM_MUX("AIF1 AD0R Stereo Mux", SND_SOC_NOPM, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) &sun8i_aif1_ad0_stereo_mux_control),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) /* AIF "ADC" Mixers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) SOC_MIXER_ARRAY("AIF1 AD0L Mixer", SND_SOC_NOPM, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) sun8i_aif1_ad0_mixer_controls),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) SOC_MIXER_ARRAY("AIF1 AD0R Mixer", SND_SOC_NOPM, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) sun8i_aif1_ad0_mixer_controls),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) /* AIF "DAC" Mono/Stereo Muxes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) SND_SOC_DAPM_MUX("AIF1 DA0L Stereo Mux", SND_SOC_NOPM, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) &sun8i_aif1_da0_stereo_mux_control),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) SND_SOC_DAPM_MUX("AIF1 DA0R Stereo Mux", SND_SOC_NOPM, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) &sun8i_aif1_da0_stereo_mux_control),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) /* AIF "DAC" Inputs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) SND_SOC_DAPM_AIF_IN("AIF1 DA0L", "Playback", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) SUN8I_AIF1_DACDAT_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) SND_SOC_DAPM_AIF_IN("AIF1 DA0R", "Playback", 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) SUN8I_AIF1_DACDAT_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) /* ADC Inputs (connected to analog codec DAPM context) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) /* DAC Outputs (connected to analog codec DAPM context) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) SND_SOC_DAPM_DAC("DACL", NULL, SND_SOC_NOPM, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) SND_SOC_DAPM_DAC("DACR", NULL, SND_SOC_NOPM, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /* DAC Mixers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) SOC_MIXER_ARRAY("DACL Mixer", SND_SOC_NOPM, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) sun8i_dac_mixer_controls),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) SOC_MIXER_ARRAY("DACR Mixer", SND_SOC_NOPM, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) sun8i_dac_mixer_controls),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) /* Clock Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) { "AIF1CLK", NULL, "mod" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) { "SYSCLK", NULL, "AIF1CLK" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) { "CLK AIF1", NULL, "AIF1CLK" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) { "CLK AIF1", NULL, "SYSCLK" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) { "RST AIF1", NULL, "CLK AIF1" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) { "AIF1 AD0L", NULL, "RST AIF1" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) { "AIF1 AD0R", NULL, "RST AIF1" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) { "AIF1 DA0L", NULL, "RST AIF1" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) { "AIF1 DA0R", NULL, "RST AIF1" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) { "CLK ADC", NULL, "SYSCLK" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) { "RST ADC", NULL, "CLK ADC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) { "ADC", NULL, "RST ADC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) { "ADCL", NULL, "ADC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) { "ADCR", NULL, "ADC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) { "CLK DAC", NULL, "SYSCLK" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) { "RST DAC", NULL, "CLK DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) { "DAC", NULL, "RST DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) { "DACL", NULL, "DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) { "DACR", NULL, "DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) /* AIF "ADC" Output Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) { "AIF1 AD0L", NULL, "AIF1 AD0L Stereo Mux" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) { "AIF1 AD0R", NULL, "AIF1 AD0R Stereo Mux" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) /* AIF "ADC" Mono/Stereo Mux Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) { "AIF1 AD0L Stereo Mux", "Stereo", "AIF1 AD0L Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) { "AIF1 AD0L Stereo Mux", "Reverse Stereo", "AIF1 AD0R Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) { "AIF1 AD0L Stereo Mux", "Sum Mono", "AIF1 AD0L Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) { "AIF1 AD0L Stereo Mux", "Sum Mono", "AIF1 AD0R Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) { "AIF1 AD0L Stereo Mux", "Mix Mono", "AIF1 AD0L Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) { "AIF1 AD0L Stereo Mux", "Mix Mono", "AIF1 AD0R Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) { "AIF1 AD0R Stereo Mux", "Stereo", "AIF1 AD0R Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) { "AIF1 AD0R Stereo Mux", "Reverse Stereo", "AIF1 AD0L Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) { "AIF1 AD0R Stereo Mux", "Sum Mono", "AIF1 AD0L Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) { "AIF1 AD0R Stereo Mux", "Sum Mono", "AIF1 AD0R Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) { "AIF1 AD0R Stereo Mux", "Mix Mono", "AIF1 AD0L Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) { "AIF1 AD0R Stereo Mux", "Mix Mono", "AIF1 AD0R Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) /* AIF "ADC" Mixer Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) { "AIF1 AD0L Mixer", "AIF1 Slot 0 Digital ADC Capture Switch", "AIF1 DA0L Stereo Mux" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) { "AIF1 AD0L Mixer", "AIF1 Data Digital ADC Capture Switch", "ADCL" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) { "AIF1 AD0R Mixer", "AIF1 Slot 0 Digital ADC Capture Switch", "AIF1 DA0R Stereo Mux" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) { "AIF1 AD0R Mixer", "AIF1 Data Digital ADC Capture Switch", "ADCR" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /* AIF "DAC" Mono/Stereo Mux Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) { "AIF1 DA0L Stereo Mux", "Stereo", "AIF1 DA0L" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) { "AIF1 DA0L Stereo Mux", "Reverse Stereo", "AIF1 DA0R" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) { "AIF1 DA0L Stereo Mux", "Sum Mono", "AIF1 DA0L" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) { "AIF1 DA0L Stereo Mux", "Sum Mono", "AIF1 DA0R" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) { "AIF1 DA0L Stereo Mux", "Mix Mono", "AIF1 DA0L" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) { "AIF1 DA0L Stereo Mux", "Mix Mono", "AIF1 DA0R" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) { "AIF1 DA0R Stereo Mux", "Stereo", "AIF1 DA0R" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) { "AIF1 DA0R Stereo Mux", "Reverse Stereo", "AIF1 DA0L" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) { "AIF1 DA0R Stereo Mux", "Sum Mono", "AIF1 DA0L" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) { "AIF1 DA0R Stereo Mux", "Sum Mono", "AIF1 DA0R" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) { "AIF1 DA0R Stereo Mux", "Mix Mono", "AIF1 DA0L" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) { "AIF1 DA0R Stereo Mux", "Mix Mono", "AIF1 DA0R" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) /* DAC Output Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) { "DACL", NULL, "DACL Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) { "DACR", NULL, "DACR Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) /* DAC Mixer Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) { "DACL Mixer", "AIF1 Slot 0 Digital DAC Playback Switch", "AIF1 DA0L Stereo Mux" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) { "DACL Mixer", "ADC Digital DAC Playback Switch", "ADCL" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) { "DACR Mixer", "AIF1 Slot 0 Digital DAC Playback Switch", "AIF1 DA0R Stereo Mux" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) { "DACR Mixer", "ADC Digital DAC Playback Switch", "ADCR" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) static const struct snd_soc_dapm_widget sun8i_codec_legacy_widgets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /* Legacy ADC Inputs (connected to analog codec DAPM context) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) SND_SOC_DAPM_ADC("AIF1 Slot 0 Left ADC", NULL, SND_SOC_NOPM, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) SND_SOC_DAPM_ADC("AIF1 Slot 0 Right ADC", NULL, SND_SOC_NOPM, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) /* Legacy DAC Outputs (connected to analog codec DAPM context) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) SND_SOC_DAPM_DAC("AIF1 Slot 0 Left", NULL, SND_SOC_NOPM, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) SND_SOC_DAPM_DAC("AIF1 Slot 0 Right", NULL, SND_SOC_NOPM, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) static const struct snd_soc_dapm_route sun8i_codec_legacy_routes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) /* Legacy ADC Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) { "ADCL", NULL, "AIF1 Slot 0 Left ADC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) { "ADCR", NULL, "AIF1 Slot 0 Right ADC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) /* Legacy DAC Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) { "AIF1 Slot 0 Left", NULL, "DACL" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) { "AIF1 Slot 0 Right", NULL, "DACR" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static int sun8i_codec_component_probe(struct snd_soc_component *component)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) /* Add widgets for backward compatibility with old device trees. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (scodec->quirks->legacy_widgets) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) ret = snd_soc_dapm_new_controls(dapm, sun8i_codec_legacy_widgets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) ARRAY_SIZE(sun8i_codec_legacy_widgets));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) ret = snd_soc_dapm_add_routes(dapm, sun8i_codec_legacy_routes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) ARRAY_SIZE(sun8i_codec_legacy_routes));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) * AIF1CLK and AIF2CLK share a pair of clock parents: PLL_AUDIO ("mod")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) * and MCLK (from the CPU DAI connected to AIF1). MCLK's parent is also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) * PLL_AUDIO, so using it adds no additional flexibility. Use PLL_AUDIO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) * directly to simplify the clock tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) regmap_update_bits(scodec->regmap, SUN8I_SYSCLK_CTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) SUN8I_SYSCLK_CTL_AIF1CLK_SRC_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) SUN8I_SYSCLK_CTL_AIF2CLK_SRC_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) SUN8I_SYSCLK_CTL_AIF1CLK_SRC_PLL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) SUN8I_SYSCLK_CTL_AIF2CLK_SRC_PLL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) /* Use AIF1CLK as the SYSCLK parent since AIF1 is used most often. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) regmap_update_bits(scodec->regmap, SUN8I_SYSCLK_CTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) BIT(SUN8I_SYSCLK_CTL_SYSCLK_SRC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) SUN8I_SYSCLK_CTL_SYSCLK_SRC_AIF1CLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) static const struct snd_soc_dai_ops sun8i_codec_dai_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) .hw_params = sun8i_codec_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) .set_fmt = sun8i_set_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) static struct snd_soc_dai_driver sun8i_codec_dai = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) .name = "sun8i",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) /* playback capabilities */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) .stream_name = "Playback",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) .rates = SNDRV_PCM_RATE_8000_192000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) .formats = SNDRV_PCM_FMTBIT_S16_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) /* capture capabilities */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) .capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) .stream_name = "Capture",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) .rates = SNDRV_PCM_RATE_8000_192000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) .formats = SNDRV_PCM_FMTBIT_S16_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) .sig_bits = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) /* pcm operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) .ops = &sun8i_codec_dai_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) static const struct snd_soc_component_driver sun8i_soc_component = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) .dapm_widgets = sun8i_codec_dapm_widgets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) .num_dapm_widgets = ARRAY_SIZE(sun8i_codec_dapm_widgets),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) .dapm_routes = sun8i_codec_dapm_routes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) .num_dapm_routes = ARRAY_SIZE(sun8i_codec_dapm_routes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) .probe = sun8i_codec_component_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) .idle_bias_on = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) .use_pmdown_time = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) .endianness = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) .non_legacy_dai_naming = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) static const struct regmap_config sun8i_codec_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) .max_register = SUN8I_DAC_MXR_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) .cache_type = REGCACHE_FLAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) static int sun8i_codec_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) struct sun8i_codec *scodec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (!scodec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) scodec->clk_module = devm_clk_get(&pdev->dev, "mod");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (IS_ERR(scodec->clk_module)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) dev_err(&pdev->dev, "Failed to get the module clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return PTR_ERR(scodec->clk_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) base = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (IS_ERR(base)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) dev_err(&pdev->dev, "Failed to map the registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return PTR_ERR(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) scodec->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "bus", base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) &sun8i_codec_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (IS_ERR(scodec->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) dev_err(&pdev->dev, "Failed to create our regmap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) return PTR_ERR(scodec->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) scodec->quirks = of_device_get_match_data(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) platform_set_drvdata(pdev, scodec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) pm_runtime_enable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (!pm_runtime_enabled(&pdev->dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) ret = sun8i_codec_runtime_resume(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) goto err_pm_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) ret = devm_snd_soc_register_component(&pdev->dev, &sun8i_soc_component,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) &sun8i_codec_dai, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) dev_err(&pdev->dev, "Failed to register codec\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) goto err_suspend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) err_suspend:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (!pm_runtime_status_suspended(&pdev->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) sun8i_codec_runtime_suspend(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) err_pm_disable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) static int sun8i_codec_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) if (!pm_runtime_status_suspended(&pdev->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) sun8i_codec_runtime_suspend(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) static const struct sun8i_codec_quirks sun8i_a33_quirks = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) .legacy_widgets = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) .lrck_inversion = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) static const struct sun8i_codec_quirks sun50i_a64_quirks = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) static const struct of_device_id sun8i_codec_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) { .compatible = "allwinner,sun8i-a33-codec", .data = &sun8i_a33_quirks },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) { .compatible = "allwinner,sun50i-a64-codec", .data = &sun50i_a64_quirks },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) MODULE_DEVICE_TABLE(of, sun8i_codec_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) static const struct dev_pm_ops sun8i_codec_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) SET_RUNTIME_PM_OPS(sun8i_codec_runtime_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) sun8i_codec_runtime_resume, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) static struct platform_driver sun8i_codec_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) .name = "sun8i-codec",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) .of_match_table = sun8i_codec_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) .pm = &sun8i_codec_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) .probe = sun8i_codec_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) .remove = sun8i_codec_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) module_platform_driver(sun8i_codec_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) MODULE_DESCRIPTION("Allwinner A33 (sun8i) codec driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) MODULE_AUTHOR("Mylène Josserand <mylene.josserand@free-electrons.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) MODULE_ALIAS("platform:sun8i-codec");