^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) * Copyright 2014 Emilio López <emilio@elopez.com.ar>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright 2014 Jon Smirl <jonsmirl@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2015 Maxime Ripard <maxime.ripard@free-electrons.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright 2015 Adam Sampson <ats@offog.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright 2016 Chen-Yu Tsai <wens@csie.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Based on the Allwinner SDK driver, released under the GPL.
^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/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/reset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <sound/pcm_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <sound/soc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <sound/tlv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <sound/dmaengine_pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* Codec DAC digital controls and FIFO registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define SUN4I_CODEC_DAC_DPC (0x00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define SUN4I_CODEC_DAC_DPC_EN_DA (31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define SUN4I_CODEC_DAC_DPC_DVOL (12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define SUN4I_CODEC_DAC_FIFOC (0x04)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define SUN4I_CODEC_DAC_FIFOC_DAC_FS (29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define SUN4I_CODEC_DAC_FIFOC_FIR_VERSION (28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define SUN4I_CODEC_DAC_FIFOC_SEND_LASAT (26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE (24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define SUN4I_CODEC_DAC_FIFOC_DRQ_CLR_CNT (21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL (8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define SUN4I_CODEC_DAC_FIFOC_MONO_EN (6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS (5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN (4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define SUN4I_CODEC_DAC_FIFOS (0x08)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define SUN4I_CODEC_DAC_TXDATA (0x0c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* Codec DAC side analog signal controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define SUN4I_CODEC_DAC_ACTL (0x10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define SUN4I_CODEC_DAC_ACTL_DACAENR (31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define SUN4I_CODEC_DAC_ACTL_DACAENL (30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define SUN4I_CODEC_DAC_ACTL_MIXEN (29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define SUN4I_CODEC_DAC_ACTL_LNG (26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define SUN4I_CODEC_DAC_ACTL_FMG (23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define SUN4I_CODEC_DAC_ACTL_MICG (20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define SUN4I_CODEC_DAC_ACTL_LLNS (19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define SUN4I_CODEC_DAC_ACTL_RLNS (18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define SUN4I_CODEC_DAC_ACTL_LFMS (17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define SUN4I_CODEC_DAC_ACTL_RFMS (16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define SUN4I_CODEC_DAC_ACTL_LDACLMIXS (15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define SUN4I_CODEC_DAC_ACTL_RDACRMIXS (14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define SUN4I_CODEC_DAC_ACTL_LDACRMIXS (13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define SUN4I_CODEC_DAC_ACTL_MIC1LS (12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define SUN4I_CODEC_DAC_ACTL_MIC1RS (11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define SUN4I_CODEC_DAC_ACTL_MIC2LS (10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define SUN4I_CODEC_DAC_ACTL_MIC2RS (9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define SUN4I_CODEC_DAC_ACTL_DACPAS (8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define SUN4I_CODEC_DAC_ACTL_MIXPAS (7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define SUN4I_CODEC_DAC_ACTL_PA_MUTE (6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define SUN4I_CODEC_DAC_ACTL_PA_VOL (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define SUN4I_CODEC_DAC_TUNE (0x14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define SUN4I_CODEC_DAC_DEBUG (0x18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* Codec ADC digital controls and FIFO registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define SUN4I_CODEC_ADC_FIFOC (0x1c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define SUN4I_CODEC_ADC_FIFOC_ADC_FS (29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define SUN4I_CODEC_ADC_FIFOC_EN_AD (28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE (24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL (8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define SUN4I_CODEC_ADC_FIFOC_MONO_EN (7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define SUN4I_CODEC_ADC_FIFOC_RX_SAMPLE_BITS (6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN (4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define SUN4I_CODEC_ADC_FIFOS (0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define SUN4I_CODEC_ADC_RXDATA (0x24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* Codec ADC side analog signal controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define SUN4I_CODEC_ADC_ACTL (0x28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define SUN4I_CODEC_ADC_ACTL_ADC_R_EN (31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define SUN4I_CODEC_ADC_ACTL_ADC_L_EN (30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define SUN4I_CODEC_ADC_ACTL_PREG1EN (29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define SUN4I_CODEC_ADC_ACTL_PREG2EN (28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define SUN4I_CODEC_ADC_ACTL_VMICEN (27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define SUN4I_CODEC_ADC_ACTL_PREG1 (25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define SUN4I_CODEC_ADC_ACTL_PREG2 (23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define SUN4I_CODEC_ADC_ACTL_VADCG (20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define SUN4I_CODEC_ADC_ACTL_ADCIS (17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define SUN4I_CODEC_ADC_ACTL_LNPREG (13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define SUN4I_CODEC_ADC_ACTL_PA_EN (4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define SUN4I_CODEC_ADC_ACTL_DDE (3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define SUN4I_CODEC_ADC_DEBUG (0x2c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* FIFO counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define SUN4I_CODEC_DAC_TXCNT (0x30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define SUN4I_CODEC_ADC_RXCNT (0x34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* Calibration register (sun7i only) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define SUN7I_CODEC_AC_DAC_CAL (0x38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /* Microphone controls (sun7i only) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define SUN7I_CODEC_AC_MIC_PHONE_CAL (0x3c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG1 (29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG2 (26)
^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) * sun6i specific registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * sun6i shares the same digital control and FIFO registers as sun4i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * but only the DAC digital controls are at the same offset. The others
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * have been moved around to accommodate extra analog controls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* Codec DAC digital controls and FIFO registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define SUN6I_CODEC_ADC_FIFOC (0x10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define SUN6I_CODEC_ADC_FIFOC_EN_AD (28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define SUN6I_CODEC_ADC_FIFOS (0x14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define SUN6I_CODEC_ADC_RXDATA (0x18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /* Output mixer and gain controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define SUN6I_CODEC_OM_DACA_CTRL (0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define SUN6I_CODEC_OM_DACA_CTRL_DACAREN (31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define SUN6I_CODEC_OM_DACA_CTRL_DACALEN (30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define SUN6I_CODEC_OM_DACA_CTRL_RMIXEN (29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define SUN6I_CODEC_OM_DACA_CTRL_LMIXEN (28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define SUN6I_CODEC_OM_DACA_CTRL_RMIX_MIC1 (23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define SUN6I_CODEC_OM_DACA_CTRL_RMIX_MIC2 (22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define SUN6I_CODEC_OM_DACA_CTRL_RMIX_PHONE (21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define SUN6I_CODEC_OM_DACA_CTRL_RMIX_PHONEP (20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define SUN6I_CODEC_OM_DACA_CTRL_RMIX_LINEINR (19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define SUN6I_CODEC_OM_DACA_CTRL_RMIX_DACR (18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define SUN6I_CODEC_OM_DACA_CTRL_RMIX_DACL (17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define SUN6I_CODEC_OM_DACA_CTRL_LMIX_MIC1 (16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define SUN6I_CODEC_OM_DACA_CTRL_LMIX_MIC2 (15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define SUN6I_CODEC_OM_DACA_CTRL_LMIX_PHONE (14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define SUN6I_CODEC_OM_DACA_CTRL_LMIX_PHONEN (13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define SUN6I_CODEC_OM_DACA_CTRL_LMIX_LINEINL (12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define SUN6I_CODEC_OM_DACA_CTRL_LMIX_DACL (11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define SUN6I_CODEC_OM_DACA_CTRL_LMIX_DACR (10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define SUN6I_CODEC_OM_DACA_CTRL_RHPIS (9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define SUN6I_CODEC_OM_DACA_CTRL_LHPIS (8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define SUN6I_CODEC_OM_DACA_CTRL_RHPPAMUTE (7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define SUN6I_CODEC_OM_DACA_CTRL_LHPPAMUTE (6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define SUN6I_CODEC_OM_DACA_CTRL_HPVOL (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #define SUN6I_CODEC_OM_PA_CTRL (0x24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define SUN6I_CODEC_OM_PA_CTRL_HPPAEN (31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define SUN6I_CODEC_OM_PA_CTRL_HPCOM_CTL (29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define SUN6I_CODEC_OM_PA_CTRL_COMPTEN (28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define SUN6I_CODEC_OM_PA_CTRL_MIC1G (15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define SUN6I_CODEC_OM_PA_CTRL_MIC2G (12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define SUN6I_CODEC_OM_PA_CTRL_LINEING (9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define SUN6I_CODEC_OM_PA_CTRL_PHONEG (6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define SUN6I_CODEC_OM_PA_CTRL_PHONEPG (3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #define SUN6I_CODEC_OM_PA_CTRL_PHONENG (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /* Microphone, line out and phone out controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define SUN6I_CODEC_MIC_CTRL (0x28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define SUN6I_CODEC_MIC_CTRL_HBIASEN (31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define SUN6I_CODEC_MIC_CTRL_MBIASEN (30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #define SUN6I_CODEC_MIC_CTRL_MIC1AMPEN (28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define SUN6I_CODEC_MIC_CTRL_MIC1BOOST (25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define SUN6I_CODEC_MIC_CTRL_MIC2AMPEN (24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #define SUN6I_CODEC_MIC_CTRL_MIC2BOOST (21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define SUN6I_CODEC_MIC_CTRL_MIC2SLT (20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #define SUN6I_CODEC_MIC_CTRL_LINEOUTLEN (19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define SUN6I_CODEC_MIC_CTRL_LINEOUTREN (18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define SUN6I_CODEC_MIC_CTRL_LINEOUTLSRC (17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #define SUN6I_CODEC_MIC_CTRL_LINEOUTRSRC (16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define SUN6I_CODEC_MIC_CTRL_LINEOUTVC (11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #define SUN6I_CODEC_MIC_CTRL_PHONEPREG (8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* ADC mixer controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) #define SUN6I_CODEC_ADC_ACTL (0x2c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #define SUN6I_CODEC_ADC_ACTL_ADCREN (31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #define SUN6I_CODEC_ADC_ACTL_ADCLEN (30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #define SUN6I_CODEC_ADC_ACTL_ADCRG (27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #define SUN6I_CODEC_ADC_ACTL_ADCLG (24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) #define SUN6I_CODEC_ADC_ACTL_RADCMIX_MIC1 (13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) #define SUN6I_CODEC_ADC_ACTL_RADCMIX_MIC2 (12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #define SUN6I_CODEC_ADC_ACTL_RADCMIX_PHONE (11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #define SUN6I_CODEC_ADC_ACTL_RADCMIX_PHONEP (10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #define SUN6I_CODEC_ADC_ACTL_RADCMIX_LINEINR (9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #define SUN6I_CODEC_ADC_ACTL_RADCMIX_OMIXR (8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #define SUN6I_CODEC_ADC_ACTL_RADCMIX_OMIXL (7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) #define SUN6I_CODEC_ADC_ACTL_LADCMIX_MIC1 (6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) #define SUN6I_CODEC_ADC_ACTL_LADCMIX_MIC2 (5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) #define SUN6I_CODEC_ADC_ACTL_LADCMIX_PHONE (4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) #define SUN6I_CODEC_ADC_ACTL_LADCMIX_PHONEN (3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #define SUN6I_CODEC_ADC_ACTL_LADCMIX_LINEINL (2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #define SUN6I_CODEC_ADC_ACTL_LADCMIX_OMIXL (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define SUN6I_CODEC_ADC_ACTL_LADCMIX_OMIXR (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) /* Analog performance tuning controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) #define SUN6I_CODEC_ADDA_TUNE (0x30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* Calibration controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) #define SUN6I_CODEC_CALIBRATION (0x34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /* FIFO counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) #define SUN6I_CODEC_DAC_TXCNT (0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #define SUN6I_CODEC_ADC_RXCNT (0x44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /* headset jack detection and button support registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) #define SUN6I_CODEC_HMIC_CTL (0x50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #define SUN6I_CODEC_HMIC_DATA (0x54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* TODO sun6i DAP (Digital Audio Processing) bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /* FIFO counters moved on A23 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) #define SUN8I_A23_CODEC_DAC_TXCNT (0x1c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) #define SUN8I_A23_CODEC_ADC_RXCNT (0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) /* TX FIFO moved on H3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) #define SUN8I_H3_CODEC_DAC_TXDATA (0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) #define SUN8I_H3_CODEC_DAC_DBG (0x48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) #define SUN8I_H3_CODEC_ADC_DBG (0x4c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* TODO H3 DAP (Digital Audio Processing) bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct sun4i_codec {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct clk *clk_apb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct clk *clk_module;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct reset_control *rst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct gpio_desc *gpio_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /* ADC_FIFOC register is at different offset on different SoCs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct regmap_field *reg_adc_fifoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct snd_dmaengine_dai_dma_data capture_dma_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct snd_dmaengine_dai_dma_data playback_dma_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static void sun4i_codec_start_playback(struct sun4i_codec *scodec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /* Flush TX FIFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /* Enable DAC DRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static void sun4i_codec_stop_playback(struct sun4i_codec *scodec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) /* Disable DAC DRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static void sun4i_codec_start_capture(struct sun4i_codec *scodec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) /* Enable ADC DRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) regmap_field_update_bits(scodec->reg_adc_fifoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static void sun4i_codec_stop_capture(struct sun4i_codec *scodec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* Disable ADC DRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) regmap_field_update_bits(scodec->reg_adc_fifoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) sun4i_codec_start_playback(scodec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) sun4i_codec_start_capture(scodec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) sun4i_codec_stop_playback(scodec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) sun4i_codec_stop_capture(scodec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static int sun4i_codec_prepare_capture(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) /* Flush RX FIFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) regmap_field_update_bits(scodec->reg_adc_fifoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) /* Set RX FIFO trigger level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) regmap_field_update_bits(scodec->reg_adc_fifoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 0xf << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 0x7 << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * FIXME: Undocumented in the datasheet, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * Allwinner's code mentions that it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * related to microphone gain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (of_device_is_compatible(scodec->dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) "allwinner,sun4i-a10-codec") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) of_device_is_compatible(scodec->dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) "allwinner,sun7i-a20-codec")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 0x3 << 25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 0x1 << 25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (of_device_is_compatible(scodec->dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) "allwinner,sun7i-a20-codec"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /* FIXME: Undocumented bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_TUNE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 0x3 << 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 0x1 << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static int sun4i_codec_prepare_playback(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /* Flush the TX FIFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /* Set TX FIFO Empty Trigger Level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 0x3f << SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 0xf << SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (substream->runtime->rate > 32000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /* Use 64 bits FIR filter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) /* Use 32 bits FIR filter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) val = BIT(SUN4I_CODEC_DAC_FIFOC_FIR_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) BIT(SUN4I_CODEC_DAC_FIFOC_FIR_VERSION),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) /* Send zeros when we have an underrun */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) BIT(SUN4I_CODEC_DAC_FIFOC_SEND_LASAT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static int sun4i_codec_prepare(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return sun4i_codec_prepare_playback(substream, dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return sun4i_codec_prepare_capture(substream, dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) static unsigned long sun4i_codec_get_mod_freq(struct snd_pcm_hw_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) unsigned int rate = params_rate(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) switch (rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) case 176400:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) case 88200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) case 44100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) case 33075:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) case 22050:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) case 14700:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) case 11025:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) case 7350:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return 22579200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) case 192000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) case 96000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) case 48000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) case 32000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) case 24000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) case 16000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) case 12000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) case 8000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return 24576000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) static int sun4i_codec_get_hw_rate(struct snd_pcm_hw_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) unsigned int rate = params_rate(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) switch (rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) case 192000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) case 176400:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) case 96000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) case 88200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) case 48000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) case 44100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) case 32000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) case 33075:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) case 24000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) case 22050:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) case 16000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) case 14700:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) case 12000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) case 11025:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) case 8000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) case 7350:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) static int sun4i_codec_hw_params_capture(struct sun4i_codec *scodec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) unsigned int hwrate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /* Set ADC sample rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) regmap_field_update_bits(scodec->reg_adc_fifoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 7 << SUN4I_CODEC_ADC_FIFOC_ADC_FS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) hwrate << SUN4I_CODEC_ADC_FIFOC_ADC_FS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* Set the number of channels we want to use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (params_channels(params) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) regmap_field_update_bits(scodec->reg_adc_fifoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) regmap_field_update_bits(scodec->reg_adc_fifoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) /* Set the number of sample bits to either 16 or 24 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min == 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) regmap_field_update_bits(scodec->reg_adc_fifoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) BIT(SUN4I_CODEC_ADC_FIFOC_RX_SAMPLE_BITS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) BIT(SUN4I_CODEC_ADC_FIFOC_RX_SAMPLE_BITS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) regmap_field_update_bits(scodec->reg_adc_fifoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) regmap_field_update_bits(scodec->reg_adc_fifoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) BIT(SUN4I_CODEC_ADC_FIFOC_RX_SAMPLE_BITS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) /* Fill most significant bits with valid data MSB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) regmap_field_update_bits(scodec->reg_adc_fifoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) static int sun4i_codec_hw_params_playback(struct sun4i_codec *scodec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) unsigned int hwrate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) /* Set DAC sample rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 7 << SUN4I_CODEC_DAC_FIFOC_DAC_FS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) hwrate << SUN4I_CODEC_DAC_FIFOC_DAC_FS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) /* Set the number of channels we want to use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (params_channels(params) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) val = BIT(SUN4I_CODEC_DAC_FIFOC_MONO_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) BIT(SUN4I_CODEC_DAC_FIFOC_MONO_EN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) /* Set the number of sample bits to either 16 or 24 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min == 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /* Set TX FIFO mode to padding the LSBs with 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) /* Set TX FIFO mode to repeat the MSB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) static int sun4i_codec_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) unsigned long clk_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) int ret, hwrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) clk_freq = sun4i_codec_get_mod_freq(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (!clk_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) ret = clk_set_rate(scodec->clk_module, clk_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) hwrate = sun4i_codec_get_hw_rate(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (hwrate < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) return hwrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) return sun4i_codec_hw_params_playback(scodec, params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) hwrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return sun4i_codec_hw_params_capture(scodec, params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) hwrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) static unsigned int sun4i_codec_src_rates[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 8000, 11025, 12000, 16000, 22050, 24000, 32000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 44100, 48000, 96000, 192000
^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) static struct snd_pcm_hw_constraint_list sun4i_codec_constraints = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) .count = ARRAY_SIZE(sun4i_codec_src_rates),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) .list = sun4i_codec_src_rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) static int sun4i_codec_startup(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) snd_pcm_hw_constraint_list(substream->runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) SNDRV_PCM_HW_PARAM_RATE, &sun4i_codec_constraints);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) * Stop issuing DRQ when we have room for less than 16 samples
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) * in our TX FIFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 3 << SUN4I_CODEC_DAC_FIFOC_DRQ_CLR_CNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 3 << SUN4I_CODEC_DAC_FIFOC_DRQ_CLR_CNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return clk_prepare_enable(scodec->clk_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) static void sun4i_codec_shutdown(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) clk_disable_unprepare(scodec->clk_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) static const struct snd_soc_dai_ops sun4i_codec_dai_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) .startup = sun4i_codec_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) .shutdown = sun4i_codec_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) .trigger = sun4i_codec_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) .hw_params = sun4i_codec_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) .prepare = sun4i_codec_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) static struct snd_soc_dai_driver sun4i_codec_dai = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) .name = "Codec",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) .ops = &sun4i_codec_dai_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) .stream_name = "Codec Playback",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) .rate_min = 8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) .rate_max = 192000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) .rates = SNDRV_PCM_RATE_CONTINUOUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) .formats = SNDRV_PCM_FMTBIT_S16_LE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) SNDRV_PCM_FMTBIT_S32_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) .sig_bits = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) .capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) .stream_name = "Codec Capture",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) .rate_min = 8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) .rate_max = 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) .rates = SNDRV_PCM_RATE_CONTINUOUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) .formats = SNDRV_PCM_FMTBIT_S16_LE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) SNDRV_PCM_FMTBIT_S32_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) .sig_bits = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) /*** sun4i Codec ***/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) static const struct snd_kcontrol_new sun4i_codec_pa_mute =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) SOC_DAPM_SINGLE("Switch", SUN4I_CODEC_DAC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) SUN4I_CODEC_DAC_ACTL_PA_MUTE, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) static DECLARE_TLV_DB_SCALE(sun4i_codec_pa_volume_scale, -6300, 100, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) static DECLARE_TLV_DB_SCALE(sun4i_codec_linein_loopback_gain_scale, -150, 150,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) static DECLARE_TLV_DB_SCALE(sun4i_codec_linein_preamp_gain_scale, -1200, 300,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) static DECLARE_TLV_DB_SCALE(sun4i_codec_fmin_loopback_gain_scale, -450, 150,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) static DECLARE_TLV_DB_SCALE(sun4i_codec_micin_loopback_gain_scale, -450, 150,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) static DECLARE_TLV_DB_RANGE(sun4i_codec_micin_preamp_gain_scale,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 1, 7, TLV_DB_SCALE_ITEM(3500, 300, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) static DECLARE_TLV_DB_RANGE(sun7i_codec_micin_preamp_gain_scale,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 1, 7, TLV_DB_SCALE_ITEM(2400, 300, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) static const struct snd_kcontrol_new sun4i_codec_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) SOC_SINGLE_TLV("Power Amplifier Volume", SUN4I_CODEC_DAC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) sun4i_codec_pa_volume_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) SOC_SINGLE_TLV("Line Playback Volume", SUN4I_CODEC_DAC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) SUN4I_CODEC_DAC_ACTL_LNG, 1, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) sun4i_codec_linein_loopback_gain_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) SOC_SINGLE_TLV("Line Boost Volume", SUN4I_CODEC_ADC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) SUN4I_CODEC_ADC_ACTL_LNPREG, 7, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) sun4i_codec_linein_preamp_gain_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) SOC_SINGLE_TLV("FM Playback Volume", SUN4I_CODEC_DAC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) SUN4I_CODEC_DAC_ACTL_FMG, 3, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) sun4i_codec_fmin_loopback_gain_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) SOC_SINGLE_TLV("Mic Playback Volume", SUN4I_CODEC_DAC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) SUN4I_CODEC_DAC_ACTL_MICG, 7, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) sun4i_codec_micin_loopback_gain_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) SOC_SINGLE_TLV("Mic1 Boost Volume", SUN4I_CODEC_ADC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) SUN4I_CODEC_ADC_ACTL_PREG1, 3, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) sun4i_codec_micin_preamp_gain_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) SOC_SINGLE_TLV("Mic2 Boost Volume", SUN4I_CODEC_ADC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) SUN4I_CODEC_ADC_ACTL_PREG2, 3, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) sun4i_codec_micin_preamp_gain_scale),
^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) static const struct snd_kcontrol_new sun7i_codec_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) SOC_SINGLE_TLV("Power Amplifier Volume", SUN4I_CODEC_DAC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) sun4i_codec_pa_volume_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) SOC_SINGLE_TLV("Line Playback Volume", SUN4I_CODEC_DAC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) SUN4I_CODEC_DAC_ACTL_LNG, 1, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) sun4i_codec_linein_loopback_gain_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) SOC_SINGLE_TLV("Line Boost Volume", SUN4I_CODEC_ADC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) SUN4I_CODEC_ADC_ACTL_LNPREG, 7, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) sun4i_codec_linein_preamp_gain_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) SOC_SINGLE_TLV("FM Playback Volume", SUN4I_CODEC_DAC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) SUN4I_CODEC_DAC_ACTL_FMG, 3, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) sun4i_codec_fmin_loopback_gain_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) SOC_SINGLE_TLV("Mic Playback Volume", SUN4I_CODEC_DAC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) SUN4I_CODEC_DAC_ACTL_MICG, 7, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) sun4i_codec_micin_loopback_gain_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) SOC_SINGLE_TLV("Mic1 Boost Volume", SUN7I_CODEC_AC_MIC_PHONE_CAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG1, 7, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) sun7i_codec_micin_preamp_gain_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) SOC_SINGLE_TLV("Mic2 Boost Volume", SUN7I_CODEC_AC_MIC_PHONE_CAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG2, 7, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) sun7i_codec_micin_preamp_gain_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) static const struct snd_kcontrol_new sun4i_codec_mixer_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) SOC_DAPM_SINGLE("Left Mixer Left DAC Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) SUN4I_CODEC_DAC_ACTL, SUN4I_CODEC_DAC_ACTL_LDACLMIXS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) SOC_DAPM_SINGLE("Right Mixer Right DAC Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) SUN4I_CODEC_DAC_ACTL, SUN4I_CODEC_DAC_ACTL_RDACRMIXS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) SOC_DAPM_SINGLE("Right Mixer Left DAC Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) SUN4I_CODEC_DAC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) SUN4I_CODEC_DAC_ACTL_LDACRMIXS, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) SOC_DAPM_DOUBLE("Line Playback Switch", SUN4I_CODEC_DAC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) SUN4I_CODEC_DAC_ACTL_LLNS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) SUN4I_CODEC_DAC_ACTL_RLNS, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) SOC_DAPM_DOUBLE("FM Playback Switch", SUN4I_CODEC_DAC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) SUN4I_CODEC_DAC_ACTL_LFMS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) SUN4I_CODEC_DAC_ACTL_RFMS, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) SOC_DAPM_DOUBLE("Mic1 Playback Switch", SUN4I_CODEC_DAC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) SUN4I_CODEC_DAC_ACTL_MIC1LS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) SUN4I_CODEC_DAC_ACTL_MIC1RS, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) SOC_DAPM_DOUBLE("Mic2 Playback Switch", SUN4I_CODEC_DAC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) SUN4I_CODEC_DAC_ACTL_MIC2LS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) SUN4I_CODEC_DAC_ACTL_MIC2RS, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) static const struct snd_kcontrol_new sun4i_codec_pa_mixer_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) SOC_DAPM_SINGLE("DAC Playback Switch", SUN4I_CODEC_DAC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) SUN4I_CODEC_DAC_ACTL_DACPAS, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) SOC_DAPM_SINGLE("Mixer Playback Switch", SUN4I_CODEC_DAC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) SUN4I_CODEC_DAC_ACTL_MIXPAS, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) static const struct snd_soc_dapm_widget sun4i_codec_codec_dapm_widgets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) /* Digital parts of the ADCs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) SND_SOC_DAPM_SUPPLY("ADC", SUN4I_CODEC_ADC_FIFOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) SUN4I_CODEC_ADC_FIFOC_EN_AD, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) /* Digital parts of the DACs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) SND_SOC_DAPM_SUPPLY("DAC", SUN4I_CODEC_DAC_DPC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) SUN4I_CODEC_DAC_DPC_EN_DA, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) /* Analog parts of the ADCs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) SND_SOC_DAPM_ADC("Left ADC", "Codec Capture", SUN4I_CODEC_ADC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) SUN4I_CODEC_ADC_ACTL_ADC_L_EN, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) SND_SOC_DAPM_ADC("Right ADC", "Codec Capture", SUN4I_CODEC_ADC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) SUN4I_CODEC_ADC_ACTL_ADC_R_EN, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) /* Analog parts of the DACs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) SND_SOC_DAPM_DAC("Left DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) SUN4I_CODEC_DAC_ACTL_DACAENL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) SND_SOC_DAPM_DAC("Right DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) SUN4I_CODEC_DAC_ACTL_DACAENR, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) /* Mixers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) sun4i_codec_mixer_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) ARRAY_SIZE(sun4i_codec_mixer_controls)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) sun4i_codec_mixer_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) ARRAY_SIZE(sun4i_codec_mixer_controls)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) /* Global Mixer Enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) SND_SOC_DAPM_SUPPLY("Mixer Enable", SUN4I_CODEC_DAC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) SUN4I_CODEC_DAC_ACTL_MIXEN, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) /* VMIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) SND_SOC_DAPM_SUPPLY("VMIC", SUN4I_CODEC_ADC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) SUN4I_CODEC_ADC_ACTL_VMICEN, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) /* Mic Pre-Amplifiers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) SND_SOC_DAPM_PGA("MIC1 Pre-Amplifier", SUN4I_CODEC_ADC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) SUN4I_CODEC_ADC_ACTL_PREG1EN, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) SND_SOC_DAPM_PGA("MIC2 Pre-Amplifier", SUN4I_CODEC_ADC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) SUN4I_CODEC_ADC_ACTL_PREG2EN, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) /* Power Amplifier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) SND_SOC_DAPM_MIXER("Power Amplifier", SUN4I_CODEC_ADC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) SUN4I_CODEC_ADC_ACTL_PA_EN, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) sun4i_codec_pa_mixer_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) ARRAY_SIZE(sun4i_codec_pa_mixer_controls)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) SND_SOC_DAPM_SWITCH("Power Amplifier Mute", SND_SOC_NOPM, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) &sun4i_codec_pa_mute),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) SND_SOC_DAPM_INPUT("Line Right"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) SND_SOC_DAPM_INPUT("Line Left"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) SND_SOC_DAPM_INPUT("FM Right"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) SND_SOC_DAPM_INPUT("FM Left"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) SND_SOC_DAPM_INPUT("Mic1"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) SND_SOC_DAPM_INPUT("Mic2"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) SND_SOC_DAPM_OUTPUT("HP Right"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) SND_SOC_DAPM_OUTPUT("HP Left"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) static const struct snd_soc_dapm_route sun4i_codec_codec_dapm_routes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) /* Left ADC / DAC Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) { "Left ADC", NULL, "ADC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) { "Left DAC", NULL, "DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) /* Right ADC / DAC Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) { "Right ADC", NULL, "ADC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) { "Right DAC", NULL, "DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) /* Right Mixer Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) { "Right Mixer", NULL, "Mixer Enable" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) { "Right Mixer", "Right Mixer Left DAC Playback Switch", "Left DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) { "Right Mixer", "Right Mixer Right DAC Playback Switch", "Right DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) { "Right Mixer", "Line Playback Switch", "Line Right" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) { "Right Mixer", "FM Playback Switch", "FM Right" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) { "Right Mixer", "Mic1 Playback Switch", "MIC1 Pre-Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) { "Right Mixer", "Mic2 Playback Switch", "MIC2 Pre-Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) /* Left Mixer Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) { "Left Mixer", NULL, "Mixer Enable" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) { "Left Mixer", "Left Mixer Left DAC Playback Switch", "Left DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) { "Left Mixer", "Line Playback Switch", "Line Left" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) { "Left Mixer", "FM Playback Switch", "FM Left" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) { "Left Mixer", "Mic1 Playback Switch", "MIC1 Pre-Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) { "Left Mixer", "Mic2 Playback Switch", "MIC2 Pre-Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) /* Power Amplifier Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) { "Power Amplifier", "Mixer Playback Switch", "Left Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) { "Power Amplifier", "Mixer Playback Switch", "Right Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) { "Power Amplifier", "DAC Playback Switch", "Left DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) { "Power Amplifier", "DAC Playback Switch", "Right DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) /* Headphone Output Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) { "Power Amplifier Mute", "Switch", "Power Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) { "HP Right", NULL, "Power Amplifier Mute" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) { "HP Left", NULL, "Power Amplifier Mute" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) /* Mic1 Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) { "Left ADC", NULL, "MIC1 Pre-Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) { "Right ADC", NULL, "MIC1 Pre-Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) { "MIC1 Pre-Amplifier", NULL, "Mic1"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) { "Mic1", NULL, "VMIC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) /* Mic2 Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) { "Left ADC", NULL, "MIC2 Pre-Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) { "Right ADC", NULL, "MIC2 Pre-Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) { "MIC2 Pre-Amplifier", NULL, "Mic2"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) { "Mic2", NULL, "VMIC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) static const struct snd_soc_component_driver sun4i_codec_codec = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) .controls = sun4i_codec_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) .num_controls = ARRAY_SIZE(sun4i_codec_controls),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) .dapm_widgets = sun4i_codec_codec_dapm_widgets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) .num_dapm_widgets = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) .dapm_routes = sun4i_codec_codec_dapm_routes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) .num_dapm_routes = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) .idle_bias_on = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) .use_pmdown_time = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) .endianness = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) .non_legacy_dai_naming = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) static const struct snd_soc_component_driver sun7i_codec_codec = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) .controls = sun7i_codec_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) .num_controls = ARRAY_SIZE(sun7i_codec_controls),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) .dapm_widgets = sun4i_codec_codec_dapm_widgets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) .num_dapm_widgets = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) .dapm_routes = sun4i_codec_codec_dapm_routes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) .num_dapm_routes = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) .idle_bias_on = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) .use_pmdown_time = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) .endianness = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) .non_legacy_dai_naming = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) /*** sun6i Codec ***/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) /* mixer controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) static const struct snd_kcontrol_new sun6i_codec_mixer_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) SOC_DAPM_DOUBLE("DAC Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) SUN6I_CODEC_OM_DACA_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) SUN6I_CODEC_OM_DACA_CTRL_LMIX_DACL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) SUN6I_CODEC_OM_DACA_CTRL_RMIX_DACR, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) SOC_DAPM_DOUBLE("DAC Reversed Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) SUN6I_CODEC_OM_DACA_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) SUN6I_CODEC_OM_DACA_CTRL_LMIX_DACR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) SUN6I_CODEC_OM_DACA_CTRL_RMIX_DACL, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) SOC_DAPM_DOUBLE("Line In Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) SUN6I_CODEC_OM_DACA_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) SUN6I_CODEC_OM_DACA_CTRL_LMIX_LINEINL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) SUN6I_CODEC_OM_DACA_CTRL_RMIX_LINEINR, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) SOC_DAPM_DOUBLE("Mic1 Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) SUN6I_CODEC_OM_DACA_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) SUN6I_CODEC_OM_DACA_CTRL_LMIX_MIC1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) SUN6I_CODEC_OM_DACA_CTRL_RMIX_MIC1, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) SOC_DAPM_DOUBLE("Mic2 Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) SUN6I_CODEC_OM_DACA_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) SUN6I_CODEC_OM_DACA_CTRL_LMIX_MIC2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) SUN6I_CODEC_OM_DACA_CTRL_RMIX_MIC2, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) /* ADC mixer controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) static const struct snd_kcontrol_new sun6i_codec_adc_mixer_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) SOC_DAPM_DOUBLE("Mixer Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) SUN6I_CODEC_ADC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) SUN6I_CODEC_ADC_ACTL_LADCMIX_OMIXL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) SUN6I_CODEC_ADC_ACTL_RADCMIX_OMIXR, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) SOC_DAPM_DOUBLE("Mixer Reversed Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) SUN6I_CODEC_ADC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) SUN6I_CODEC_ADC_ACTL_LADCMIX_OMIXR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) SUN6I_CODEC_ADC_ACTL_RADCMIX_OMIXL, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) SOC_DAPM_DOUBLE("Line In Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) SUN6I_CODEC_ADC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) SUN6I_CODEC_ADC_ACTL_LADCMIX_LINEINL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) SUN6I_CODEC_ADC_ACTL_RADCMIX_LINEINR, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) SOC_DAPM_DOUBLE("Mic1 Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) SUN6I_CODEC_ADC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) SUN6I_CODEC_ADC_ACTL_LADCMIX_MIC1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) SUN6I_CODEC_ADC_ACTL_RADCMIX_MIC1, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) SOC_DAPM_DOUBLE("Mic2 Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) SUN6I_CODEC_ADC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) SUN6I_CODEC_ADC_ACTL_LADCMIX_MIC2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) SUN6I_CODEC_ADC_ACTL_RADCMIX_MIC2, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) /* headphone controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) static const char * const sun6i_codec_hp_src_enum_text[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) "DAC", "Mixer",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) static SOC_ENUM_DOUBLE_DECL(sun6i_codec_hp_src_enum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) SUN6I_CODEC_OM_DACA_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) SUN6I_CODEC_OM_DACA_CTRL_LHPIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) SUN6I_CODEC_OM_DACA_CTRL_RHPIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) sun6i_codec_hp_src_enum_text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) static const struct snd_kcontrol_new sun6i_codec_hp_src[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) SOC_DAPM_ENUM("Headphone Source Playback Route",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) sun6i_codec_hp_src_enum),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) /* microphone controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) static const char * const sun6i_codec_mic2_src_enum_text[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) "Mic2", "Mic3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) static SOC_ENUM_SINGLE_DECL(sun6i_codec_mic2_src_enum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) SUN6I_CODEC_MIC_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) SUN6I_CODEC_MIC_CTRL_MIC2SLT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) sun6i_codec_mic2_src_enum_text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) static const struct snd_kcontrol_new sun6i_codec_mic2_src[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) SOC_DAPM_ENUM("Mic2 Amplifier Source Route",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) sun6i_codec_mic2_src_enum),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) /* line out controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) static const char * const sun6i_codec_lineout_src_enum_text[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) "Stereo", "Mono Differential",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) static SOC_ENUM_DOUBLE_DECL(sun6i_codec_lineout_src_enum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) SUN6I_CODEC_MIC_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) SUN6I_CODEC_MIC_CTRL_LINEOUTLSRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) SUN6I_CODEC_MIC_CTRL_LINEOUTRSRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) sun6i_codec_lineout_src_enum_text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) static const struct snd_kcontrol_new sun6i_codec_lineout_src[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) SOC_DAPM_ENUM("Line Out Source Playback Route",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) sun6i_codec_lineout_src_enum),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) /* volume / mute controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) static const DECLARE_TLV_DB_SCALE(sun6i_codec_dvol_scale, -7308, 116, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) static const DECLARE_TLV_DB_SCALE(sun6i_codec_hp_vol_scale, -6300, 100, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) static const DECLARE_TLV_DB_SCALE(sun6i_codec_out_mixer_pregain_scale,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) -450, 150, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) static const DECLARE_TLV_DB_RANGE(sun6i_codec_lineout_vol_scale,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 0, 1, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 2, 31, TLV_DB_SCALE_ITEM(-4350, 150, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) static const DECLARE_TLV_DB_RANGE(sun6i_codec_mic_gain_scale,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 1, 7, TLV_DB_SCALE_ITEM(2400, 300, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static const struct snd_kcontrol_new sun6i_codec_codec_widgets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) SOC_SINGLE_TLV("DAC Playback Volume", SUN4I_CODEC_DAC_DPC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) SUN4I_CODEC_DAC_DPC_DVOL, 0x3f, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) sun6i_codec_dvol_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) SOC_SINGLE_TLV("Headphone Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) SUN6I_CODEC_OM_DACA_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) SUN6I_CODEC_OM_DACA_CTRL_HPVOL, 0x3f, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) sun6i_codec_hp_vol_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) SOC_SINGLE_TLV("Line Out Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) SUN6I_CODEC_MIC_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) SUN6I_CODEC_MIC_CTRL_LINEOUTVC, 0x1f, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) sun6i_codec_lineout_vol_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) SOC_DOUBLE("Headphone Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) SUN6I_CODEC_OM_DACA_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) SUN6I_CODEC_OM_DACA_CTRL_LHPPAMUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) SUN6I_CODEC_OM_DACA_CTRL_RHPPAMUTE, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) SOC_DOUBLE("Line Out Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) SUN6I_CODEC_MIC_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) SUN6I_CODEC_MIC_CTRL_LINEOUTLEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) SUN6I_CODEC_MIC_CTRL_LINEOUTREN, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) /* Mixer pre-gains */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) SOC_SINGLE_TLV("Line In Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) SUN6I_CODEC_OM_PA_CTRL, SUN6I_CODEC_OM_PA_CTRL_LINEING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 0x7, 0, sun6i_codec_out_mixer_pregain_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) SOC_SINGLE_TLV("Mic1 Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) SUN6I_CODEC_OM_PA_CTRL, SUN6I_CODEC_OM_PA_CTRL_MIC1G,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 0x7, 0, sun6i_codec_out_mixer_pregain_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) SOC_SINGLE_TLV("Mic2 Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) SUN6I_CODEC_OM_PA_CTRL, SUN6I_CODEC_OM_PA_CTRL_MIC2G,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 0x7, 0, sun6i_codec_out_mixer_pregain_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) /* Microphone Amp boost gains */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) SOC_SINGLE_TLV("Mic1 Boost Volume", SUN6I_CODEC_MIC_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) SUN6I_CODEC_MIC_CTRL_MIC1BOOST, 0x7, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) sun6i_codec_mic_gain_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) SOC_SINGLE_TLV("Mic2 Boost Volume", SUN6I_CODEC_MIC_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) SUN6I_CODEC_MIC_CTRL_MIC2BOOST, 0x7, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) sun6i_codec_mic_gain_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) SOC_DOUBLE_TLV("ADC Capture Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) SUN6I_CODEC_ADC_ACTL, SUN6I_CODEC_ADC_ACTL_ADCLG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) SUN6I_CODEC_ADC_ACTL_ADCRG, 0x7, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) sun6i_codec_out_mixer_pregain_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) static const struct snd_soc_dapm_widget sun6i_codec_codec_dapm_widgets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) /* Microphone inputs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) SND_SOC_DAPM_INPUT("MIC1"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) SND_SOC_DAPM_INPUT("MIC2"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) SND_SOC_DAPM_INPUT("MIC3"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) /* Microphone Bias */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) SND_SOC_DAPM_SUPPLY("HBIAS", SUN6I_CODEC_MIC_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) SUN6I_CODEC_MIC_CTRL_HBIASEN, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) SND_SOC_DAPM_SUPPLY("MBIAS", SUN6I_CODEC_MIC_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) SUN6I_CODEC_MIC_CTRL_MBIASEN, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) /* Mic input path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) SND_SOC_DAPM_MUX("Mic2 Amplifier Source Route",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) SND_SOC_NOPM, 0, 0, sun6i_codec_mic2_src),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) SND_SOC_DAPM_PGA("Mic1 Amplifier", SUN6I_CODEC_MIC_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) SUN6I_CODEC_MIC_CTRL_MIC1AMPEN, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) SND_SOC_DAPM_PGA("Mic2 Amplifier", SUN6I_CODEC_MIC_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) SUN6I_CODEC_MIC_CTRL_MIC2AMPEN, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) /* Line In */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) SND_SOC_DAPM_INPUT("LINEIN"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) /* Digital parts of the ADCs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) SND_SOC_DAPM_SUPPLY("ADC Enable", SUN6I_CODEC_ADC_FIFOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) SUN6I_CODEC_ADC_FIFOC_EN_AD, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) /* Analog parts of the ADCs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) SND_SOC_DAPM_ADC("Left ADC", "Codec Capture", SUN6I_CODEC_ADC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) SUN6I_CODEC_ADC_ACTL_ADCLEN, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) SND_SOC_DAPM_ADC("Right ADC", "Codec Capture", SUN6I_CODEC_ADC_ACTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) SUN6I_CODEC_ADC_ACTL_ADCREN, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) /* ADC Mixers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) SOC_MIXER_ARRAY("Left ADC Mixer", SND_SOC_NOPM, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) sun6i_codec_adc_mixer_controls),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) SOC_MIXER_ARRAY("Right ADC Mixer", SND_SOC_NOPM, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) sun6i_codec_adc_mixer_controls),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) /* Digital parts of the DACs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) SND_SOC_DAPM_SUPPLY("DAC Enable", SUN4I_CODEC_DAC_DPC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) SUN4I_CODEC_DAC_DPC_EN_DA, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) /* Analog parts of the DACs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) SND_SOC_DAPM_DAC("Left DAC", "Codec Playback",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) SUN6I_CODEC_OM_DACA_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) SUN6I_CODEC_OM_DACA_CTRL_DACALEN, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) SND_SOC_DAPM_DAC("Right DAC", "Codec Playback",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) SUN6I_CODEC_OM_DACA_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) SUN6I_CODEC_OM_DACA_CTRL_DACAREN, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) /* Mixers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) SOC_MIXER_ARRAY("Left Mixer", SUN6I_CODEC_OM_DACA_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) SUN6I_CODEC_OM_DACA_CTRL_LMIXEN, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) sun6i_codec_mixer_controls),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) SOC_MIXER_ARRAY("Right Mixer", SUN6I_CODEC_OM_DACA_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) SUN6I_CODEC_OM_DACA_CTRL_RMIXEN, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) sun6i_codec_mixer_controls),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) /* Headphone output path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) SND_SOC_DAPM_MUX("Headphone Source Playback Route",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) SND_SOC_NOPM, 0, 0, sun6i_codec_hp_src),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN6I_CODEC_OM_PA_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) SUN6I_CODEC_OM_PA_CTRL_HPPAEN, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) SND_SOC_DAPM_SUPPLY("HPCOM Protection", SUN6I_CODEC_OM_PA_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) SUN6I_CODEC_OM_PA_CTRL_COMPTEN, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) SND_SOC_DAPM_REG(snd_soc_dapm_supply, "HPCOM", SUN6I_CODEC_OM_PA_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) SUN6I_CODEC_OM_PA_CTRL_HPCOM_CTL, 0x3, 0x3, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) SND_SOC_DAPM_OUTPUT("HP"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) /* Line Out path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) SND_SOC_DAPM_MUX("Line Out Source Playback Route",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) SND_SOC_NOPM, 0, 0, sun6i_codec_lineout_src),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) SND_SOC_DAPM_OUTPUT("LINEOUT"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) static const struct snd_soc_dapm_route sun6i_codec_codec_dapm_routes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) /* DAC Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) { "Left DAC", NULL, "DAC Enable" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) { "Right DAC", NULL, "DAC Enable" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) /* Microphone Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) { "Mic1 Amplifier", NULL, "MIC1"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) { "Mic2 Amplifier Source Route", "Mic2", "MIC2" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) { "Mic2 Amplifier Source Route", "Mic3", "MIC3" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) { "Mic2 Amplifier", NULL, "Mic2 Amplifier Source Route"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) /* Left Mixer Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) { "Left Mixer", "DAC Playback Switch", "Left DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) { "Left Mixer", "DAC Reversed Playback Switch", "Right DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) { "Left Mixer", "Line In Playback Switch", "LINEIN" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) { "Left Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) { "Left Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) /* Right Mixer Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) { "Right Mixer", "DAC Playback Switch", "Right DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) { "Right Mixer", "DAC Reversed Playback Switch", "Left DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) { "Right Mixer", "Line In Playback Switch", "LINEIN" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) { "Right Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) { "Right Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) /* Left ADC Mixer Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) { "Left ADC Mixer", "Mixer Capture Switch", "Left Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) { "Left ADC Mixer", "Mixer Reversed Capture Switch", "Right Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) { "Left ADC Mixer", "Line In Capture Switch", "LINEIN" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) { "Left ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) { "Left ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) /* Right ADC Mixer Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) { "Right ADC Mixer", "Mixer Capture Switch", "Right Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) { "Right ADC Mixer", "Mixer Reversed Capture Switch", "Left Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) { "Right ADC Mixer", "Line In Capture Switch", "LINEIN" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) { "Right ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) { "Right ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) /* Headphone Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) { "Headphone Source Playback Route", "DAC", "Left DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) { "Headphone Source Playback Route", "DAC", "Right DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) { "Headphone Source Playback Route", "Mixer", "Left Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) { "Headphone Source Playback Route", "Mixer", "Right Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) { "Headphone Amp", NULL, "Headphone Source Playback Route" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) { "HP", NULL, "Headphone Amp" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) { "HPCOM", NULL, "HPCOM Protection" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) /* Line Out Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) { "Line Out Source Playback Route", "Stereo", "Left Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) { "Line Out Source Playback Route", "Stereo", "Right Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) { "Line Out Source Playback Route", "Mono Differential", "Left Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) { "Line Out Source Playback Route", "Mono Differential", "Right Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) { "LINEOUT", NULL, "Line Out Source Playback Route" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) /* ADC Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) { "Left ADC", NULL, "ADC Enable" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) { "Right ADC", NULL, "ADC Enable" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) { "Left ADC", NULL, "Left ADC Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) { "Right ADC", NULL, "Right ADC Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) static const struct snd_soc_component_driver sun6i_codec_codec = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) .controls = sun6i_codec_codec_widgets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) .num_controls = ARRAY_SIZE(sun6i_codec_codec_widgets),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) .dapm_widgets = sun6i_codec_codec_dapm_widgets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) .num_dapm_widgets = ARRAY_SIZE(sun6i_codec_codec_dapm_widgets),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) .dapm_routes = sun6i_codec_codec_dapm_routes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) .num_dapm_routes = ARRAY_SIZE(sun6i_codec_codec_dapm_routes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) .idle_bias_on = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) .use_pmdown_time = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) .endianness = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) .non_legacy_dai_naming = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) /* sun8i A23 codec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) static const struct snd_kcontrol_new sun8i_a23_codec_codec_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) SOC_SINGLE_TLV("DAC Playback Volume", SUN4I_CODEC_DAC_DPC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) SUN4I_CODEC_DAC_DPC_DVOL, 0x3f, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) sun6i_codec_dvol_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) static const struct snd_soc_dapm_widget sun8i_a23_codec_codec_widgets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) /* Digital parts of the ADCs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) SND_SOC_DAPM_SUPPLY("ADC Enable", SUN6I_CODEC_ADC_FIFOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) SUN6I_CODEC_ADC_FIFOC_EN_AD, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) /* Digital parts of the DACs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) SND_SOC_DAPM_SUPPLY("DAC Enable", SUN4I_CODEC_DAC_DPC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) SUN4I_CODEC_DAC_DPC_EN_DA, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) static const struct snd_soc_component_driver sun8i_a23_codec_codec = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) .controls = sun8i_a23_codec_codec_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) .num_controls = ARRAY_SIZE(sun8i_a23_codec_codec_controls),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) .dapm_widgets = sun8i_a23_codec_codec_widgets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) .num_dapm_widgets = ARRAY_SIZE(sun8i_a23_codec_codec_widgets),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) .idle_bias_on = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) .use_pmdown_time = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) .endianness = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) .non_legacy_dai_naming = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) static const struct snd_soc_component_driver sun4i_codec_component = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) .name = "sun4i-codec",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) #define SUN4I_CODEC_RATES SNDRV_PCM_RATE_CONTINUOUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) #define SUN4I_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) SNDRV_PCM_FMTBIT_S32_LE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) static int sun4i_codec_dai_probe(struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) snd_soc_dai_init_dma_data(dai, &scodec->playback_dma_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) &scodec->capture_dma_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) static struct snd_soc_dai_driver dummy_cpu_dai = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) .name = "sun4i-codec-cpu-dai",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) .probe = sun4i_codec_dai_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) .stream_name = "Playback",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) .rates = SUN4I_CODEC_RATES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) .formats = SUN4I_CODEC_FORMATS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) .sig_bits = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) .capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) .stream_name = "Capture",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) .rates = SUN4I_CODEC_RATES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) .formats = SUN4I_CODEC_FORMATS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) .sig_bits = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) int *num_links)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) struct snd_soc_dai_link *link = devm_kzalloc(dev, sizeof(*link),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) struct snd_soc_dai_link_component *dlc = devm_kzalloc(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 3 * sizeof(*dlc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) if (!link || !dlc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) link->cpus = &dlc[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) link->codecs = &dlc[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) link->platforms = &dlc[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) link->num_cpus = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) link->num_codecs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) link->num_platforms = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) link->name = "cdc";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) link->stream_name = "CDC PCM";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) link->codecs->dai_name = "Codec";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) link->cpus->dai_name = dev_name(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) link->codecs->name = dev_name(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) link->platforms->name = dev_name(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) link->dai_fmt = SND_SOC_DAIFMT_I2S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) *num_links = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) return link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) static int sun4i_codec_spk_event(struct snd_soc_dapm_widget *w,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) struct snd_kcontrol *k, int event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) struct sun4i_codec *scodec = snd_soc_card_get_drvdata(w->dapm->card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) gpiod_set_value_cansleep(scodec->gpio_pa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) !!SND_SOC_DAPM_EVENT_ON(event));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) if (SND_SOC_DAPM_EVENT_ON(event)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) * Need a delay to wait for DAC to push the data. 700ms seems
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) * to be the best compromise not to feel this delay while
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) * playing a sound.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) msleep(700);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) static const struct snd_soc_dapm_widget sun4i_codec_card_dapm_widgets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) SND_SOC_DAPM_SPK("Speaker", sun4i_codec_spk_event),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) static const struct snd_soc_dapm_route sun4i_codec_card_dapm_routes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) { "Speaker", NULL, "HP Right" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) { "Speaker", NULL, "HP Left" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) static struct snd_soc_card *sun4i_codec_create_card(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) struct snd_soc_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) if (!card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) if (!card->dai_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) card->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) card->owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) card->name = "sun4i-codec";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) card->dapm_widgets = sun4i_codec_card_dapm_widgets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) card->num_dapm_widgets = ARRAY_SIZE(sun4i_codec_card_dapm_widgets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) card->dapm_routes = sun4i_codec_card_dapm_routes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) card->num_dapm_routes = ARRAY_SIZE(sun4i_codec_card_dapm_routes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) return card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) static const struct snd_soc_dapm_widget sun6i_codec_card_dapm_widgets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) SND_SOC_DAPM_HP("Headphone", NULL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) SND_SOC_DAPM_LINE("Line In", NULL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) SND_SOC_DAPM_LINE("Line Out", NULL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) SND_SOC_DAPM_MIC("Headset Mic", NULL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) SND_SOC_DAPM_MIC("Mic", NULL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) SND_SOC_DAPM_SPK("Speaker", sun4i_codec_spk_event),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) static struct snd_soc_card *sun6i_codec_create_card(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) struct snd_soc_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) if (!card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) if (!card->dai_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) card->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) card->owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) card->name = "A31 Audio Codec";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) card->dapm_widgets = sun6i_codec_card_dapm_widgets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) card->num_dapm_widgets = ARRAY_SIZE(sun6i_codec_card_dapm_widgets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) card->fully_routed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) dev_warn(dev, "failed to parse audio-routing: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) return card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) /* Connect digital side enables to analog side widgets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) static const struct snd_soc_dapm_route sun8i_codec_card_routes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) /* ADC Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) { "Left ADC", NULL, "ADC Enable" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) { "Right ADC", NULL, "ADC Enable" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) { "Codec Capture", NULL, "Left ADC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) { "Codec Capture", NULL, "Right ADC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) /* DAC Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) { "Left DAC", NULL, "DAC Enable" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) { "Right DAC", NULL, "DAC Enable" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) { "Left DAC", NULL, "Codec Playback" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) { "Right DAC", NULL, "Codec Playback" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) static struct snd_soc_aux_dev aux_dev = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) .dlc = COMP_EMPTY(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) static struct snd_soc_card *sun8i_a23_codec_create_card(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) struct snd_soc_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) if (!card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) aux_dev.dlc.of_node = of_parse_phandle(dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) "allwinner,codec-analog-controls",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) if (!aux_dev.dlc.of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) dev_err(dev, "Can't find analog controls for codec.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) if (!card->dai_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) card->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) card->owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) card->name = "A23 Audio Codec";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) card->dapm_widgets = sun6i_codec_card_dapm_widgets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) card->num_dapm_widgets = ARRAY_SIZE(sun6i_codec_card_dapm_widgets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) card->dapm_routes = sun8i_codec_card_routes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) card->num_dapm_routes = ARRAY_SIZE(sun8i_codec_card_routes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) card->aux_dev = &aux_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) card->num_aux_devs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) card->fully_routed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) dev_warn(dev, "failed to parse audio-routing: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) return card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) static struct snd_soc_card *sun8i_h3_codec_create_card(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) struct snd_soc_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) if (!card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) aux_dev.dlc.of_node = of_parse_phandle(dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) "allwinner,codec-analog-controls",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) if (!aux_dev.dlc.of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) dev_err(dev, "Can't find analog controls for codec.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) if (!card->dai_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) card->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) card->owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) card->name = "H3 Audio Codec";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) card->dapm_widgets = sun6i_codec_card_dapm_widgets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) card->num_dapm_widgets = ARRAY_SIZE(sun6i_codec_card_dapm_widgets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) card->dapm_routes = sun8i_codec_card_routes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) card->num_dapm_routes = ARRAY_SIZE(sun8i_codec_card_routes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) card->aux_dev = &aux_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) card->num_aux_devs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) card->fully_routed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) dev_warn(dev, "failed to parse audio-routing: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) return card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) static struct snd_soc_card *sun8i_v3s_codec_create_card(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) struct snd_soc_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) if (!card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) aux_dev.dlc.of_node = of_parse_phandle(dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) "allwinner,codec-analog-controls",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) if (!aux_dev.dlc.of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) dev_err(dev, "Can't find analog controls for codec.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) if (!card->dai_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) card->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) card->owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) card->name = "V3s Audio Codec";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) card->dapm_widgets = sun6i_codec_card_dapm_widgets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) card->num_dapm_widgets = ARRAY_SIZE(sun6i_codec_card_dapm_widgets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) card->dapm_routes = sun8i_codec_card_routes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) card->num_dapm_routes = ARRAY_SIZE(sun8i_codec_card_routes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) card->aux_dev = &aux_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) card->num_aux_devs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) card->fully_routed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) dev_warn(dev, "failed to parse audio-routing: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) return card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) static const struct regmap_config sun4i_codec_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) .max_register = SUN4I_CODEC_ADC_RXCNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) static const struct regmap_config sun6i_codec_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) .max_register = SUN6I_CODEC_HMIC_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) static const struct regmap_config sun7i_codec_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) .max_register = SUN7I_CODEC_AC_MIC_PHONE_CAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) static const struct regmap_config sun8i_a23_codec_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) .max_register = SUN8I_A23_CODEC_ADC_RXCNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) static const struct regmap_config sun8i_h3_codec_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) .max_register = SUN8I_H3_CODEC_ADC_DBG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) static const struct regmap_config sun8i_v3s_codec_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) .max_register = SUN8I_H3_CODEC_ADC_DBG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) struct sun4i_codec_quirks {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) const struct regmap_config *regmap_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) const struct snd_soc_component_driver *codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) struct snd_soc_card * (*create_card)(struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) struct reg_field reg_adc_fifoc; /* used for regmap_field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) unsigned int reg_dac_txdata; /* TX FIFO offset for DMA config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) unsigned int reg_adc_rxdata; /* RX FIFO offset for DMA config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) bool has_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) static const struct sun4i_codec_quirks sun4i_codec_quirks = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) .regmap_config = &sun4i_codec_regmap_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) .codec = &sun4i_codec_codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) .create_card = sun4i_codec_create_card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) .reg_adc_fifoc = REG_FIELD(SUN4I_CODEC_ADC_FIFOC, 0, 31),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) .reg_dac_txdata = SUN4I_CODEC_DAC_TXDATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) .reg_adc_rxdata = SUN4I_CODEC_ADC_RXDATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) static const struct sun4i_codec_quirks sun6i_a31_codec_quirks = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) .regmap_config = &sun6i_codec_regmap_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) .codec = &sun6i_codec_codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) .create_card = sun6i_codec_create_card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) .reg_adc_fifoc = REG_FIELD(SUN6I_CODEC_ADC_FIFOC, 0, 31),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) .reg_dac_txdata = SUN4I_CODEC_DAC_TXDATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) .reg_adc_rxdata = SUN6I_CODEC_ADC_RXDATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) .has_reset = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) static const struct sun4i_codec_quirks sun7i_codec_quirks = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) .regmap_config = &sun7i_codec_regmap_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) .codec = &sun7i_codec_codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) .create_card = sun4i_codec_create_card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) .reg_adc_fifoc = REG_FIELD(SUN4I_CODEC_ADC_FIFOC, 0, 31),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) .reg_dac_txdata = SUN4I_CODEC_DAC_TXDATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) .reg_adc_rxdata = SUN4I_CODEC_ADC_RXDATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) static const struct sun4i_codec_quirks sun8i_a23_codec_quirks = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) .regmap_config = &sun8i_a23_codec_regmap_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) .codec = &sun8i_a23_codec_codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) .create_card = sun8i_a23_codec_create_card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) .reg_adc_fifoc = REG_FIELD(SUN6I_CODEC_ADC_FIFOC, 0, 31),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) .reg_dac_txdata = SUN4I_CODEC_DAC_TXDATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) .reg_adc_rxdata = SUN6I_CODEC_ADC_RXDATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) .has_reset = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) static const struct sun4i_codec_quirks sun8i_h3_codec_quirks = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) .regmap_config = &sun8i_h3_codec_regmap_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) * TODO Share the codec structure with A23 for now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) * This should be split out when adding digital audio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) * processing support for the H3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) .codec = &sun8i_a23_codec_codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) .create_card = sun8i_h3_codec_create_card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) .reg_adc_fifoc = REG_FIELD(SUN6I_CODEC_ADC_FIFOC, 0, 31),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) .reg_dac_txdata = SUN8I_H3_CODEC_DAC_TXDATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) .reg_adc_rxdata = SUN6I_CODEC_ADC_RXDATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) .has_reset = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) static const struct sun4i_codec_quirks sun8i_v3s_codec_quirks = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) .regmap_config = &sun8i_v3s_codec_regmap_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) * TODO The codec structure should be split out, like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) * H3, when adding digital audio processing support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) .codec = &sun8i_a23_codec_codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) .create_card = sun8i_v3s_codec_create_card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) .reg_adc_fifoc = REG_FIELD(SUN6I_CODEC_ADC_FIFOC, 0, 31),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) .reg_dac_txdata = SUN8I_H3_CODEC_DAC_TXDATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) .reg_adc_rxdata = SUN6I_CODEC_ADC_RXDATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) .has_reset = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) static const struct of_device_id sun4i_codec_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) .compatible = "allwinner,sun4i-a10-codec",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) .data = &sun4i_codec_quirks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) .compatible = "allwinner,sun6i-a31-codec",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) .data = &sun6i_a31_codec_quirks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) .compatible = "allwinner,sun7i-a20-codec",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) .data = &sun7i_codec_quirks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) .compatible = "allwinner,sun8i-a23-codec",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) .data = &sun8i_a23_codec_quirks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) .compatible = "allwinner,sun8i-h3-codec",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) .data = &sun8i_h3_codec_quirks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) .compatible = "allwinner,sun8i-v3s-codec",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) .data = &sun8i_v3s_codec_quirks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) MODULE_DEVICE_TABLE(of, sun4i_codec_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) static int sun4i_codec_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) struct snd_soc_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) struct sun4i_codec *scodec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) const struct sun4i_codec_quirks *quirks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) if (!scodec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) scodec->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) base = devm_ioremap_resource(&pdev->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) if (IS_ERR(base)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) dev_err(&pdev->dev, "Failed to map the registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) return PTR_ERR(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) quirks = of_device_get_match_data(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) if (quirks == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) quirks->regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) if (IS_ERR(scodec->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) dev_err(&pdev->dev, "Failed to create our regmap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) return PTR_ERR(scodec->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) /* Get the clocks from the DT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) scodec->clk_apb = devm_clk_get(&pdev->dev, "apb");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) if (IS_ERR(scodec->clk_apb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) dev_err(&pdev->dev, "Failed to get the APB clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) return PTR_ERR(scodec->clk_apb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) scodec->clk_module = devm_clk_get(&pdev->dev, "codec");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) if (IS_ERR(scodec->clk_module)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) dev_err(&pdev->dev, "Failed to get the module clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) return PTR_ERR(scodec->clk_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) if (quirks->has_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) scodec->rst = devm_reset_control_get_exclusive(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) if (IS_ERR(scodec->rst)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) dev_err(&pdev->dev, "Failed to get reset control\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) return PTR_ERR(scodec->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) scodec->gpio_pa = devm_gpiod_get_optional(&pdev->dev, "allwinner,pa",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) GPIOD_OUT_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) if (IS_ERR(scodec->gpio_pa)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) ret = PTR_ERR(scodec->gpio_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) if (ret != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) dev_err(&pdev->dev, "Failed to get pa gpio: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) /* reg_field setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) scodec->reg_adc_fifoc = devm_regmap_field_alloc(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) scodec->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) quirks->reg_adc_fifoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) if (IS_ERR(scodec->reg_adc_fifoc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) ret = PTR_ERR(scodec->reg_adc_fifoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) dev_err(&pdev->dev, "Failed to create regmap fields: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) /* Enable the bus clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) if (clk_prepare_enable(scodec->clk_apb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) dev_err(&pdev->dev, "Failed to enable the APB clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) /* Deassert the reset control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) if (scodec->rst) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) ret = reset_control_deassert(scodec->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) dev_err(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) "Failed to deassert the reset control\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) goto err_clk_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) /* DMA configuration for TX FIFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) scodec->playback_dma_data.addr = res->start + quirks->reg_dac_txdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) scodec->playback_dma_data.maxburst = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) /* DMA configuration for RX FIFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) scodec->capture_dma_data.addr = res->start + quirks->reg_adc_rxdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) scodec->capture_dma_data.maxburst = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) ret = devm_snd_soc_register_component(&pdev->dev, quirks->codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) &sun4i_codec_dai, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) dev_err(&pdev->dev, "Failed to register our codec\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) goto err_assert_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) ret = devm_snd_soc_register_component(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) &sun4i_codec_component,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) &dummy_cpu_dai, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) dev_err(&pdev->dev, "Failed to register our DAI\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) goto err_assert_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) dev_err(&pdev->dev, "Failed to register against DMAEngine\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) goto err_assert_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) card = quirks->create_card(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) if (IS_ERR(card)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) ret = PTR_ERR(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) dev_err(&pdev->dev, "Failed to create our card\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) goto err_assert_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) snd_soc_card_set_drvdata(card, scodec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) ret = snd_soc_register_card(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) dev_err(&pdev->dev, "Failed to register our card\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) goto err_assert_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) err_assert_reset:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) if (scodec->rst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) reset_control_assert(scodec->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) err_clk_disable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) clk_disable_unprepare(scodec->clk_apb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) static int sun4i_codec_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) struct snd_soc_card *card = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) snd_soc_unregister_card(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) if (scodec->rst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) reset_control_assert(scodec->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) clk_disable_unprepare(scodec->clk_apb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) static struct platform_driver sun4i_codec_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) .name = "sun4i-codec",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) .of_match_table = sun4i_codec_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) .probe = sun4i_codec_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) .remove = sun4i_codec_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) module_platform_driver(sun4i_codec_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) MODULE_DESCRIPTION("Allwinner A10 codec driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) MODULE_AUTHOR("Emilio López <emilio@elopez.com.ar>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) MODULE_LICENSE("GPL");