18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * This driver supports the analog controls for the internal codec 48c2ecf20Sopenharmony_ci * found in Allwinner's A64 SoC. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org> 78c2ecf20Sopenharmony_ci * Copyright (C) 2017 Marcus Cooper <codekipper@gmail.com> 88c2ecf20Sopenharmony_ci * Copyright (C) 2018 Vasily Khoruzhick <anarsoul@gmail.com> 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * Based on sun8i-codec-analog.c 118c2ecf20Sopenharmony_ci * 128c2ecf20Sopenharmony_ci */ 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#include <linux/io.h> 158c2ecf20Sopenharmony_ci#include <linux/kernel.h> 168c2ecf20Sopenharmony_ci#include <linux/module.h> 178c2ecf20Sopenharmony_ci#include <linux/of.h> 188c2ecf20Sopenharmony_ci#include <linux/of_device.h> 198c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 208c2ecf20Sopenharmony_ci#include <linux/regmap.h> 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#include <sound/soc.h> 238c2ecf20Sopenharmony_ci#include <sound/soc-dapm.h> 248c2ecf20Sopenharmony_ci#include <sound/tlv.h> 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#include "sun8i-adda-pr-regmap.h" 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci/* Codec analog control register offsets and bit fields */ 298c2ecf20Sopenharmony_ci#define SUN50I_ADDA_HP_CTRL 0x00 308c2ecf20Sopenharmony_ci#define SUN50I_ADDA_HP_CTRL_PA_CLK_GATE 7 318c2ecf20Sopenharmony_ci#define SUN50I_ADDA_HP_CTRL_HPPA_EN 6 328c2ecf20Sopenharmony_ci#define SUN50I_ADDA_HP_CTRL_HPVOL 0 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci#define SUN50I_ADDA_OL_MIX_CTRL 0x01 358c2ecf20Sopenharmony_ci#define SUN50I_ADDA_OL_MIX_CTRL_MIC1 6 368c2ecf20Sopenharmony_ci#define SUN50I_ADDA_OL_MIX_CTRL_MIC2 5 378c2ecf20Sopenharmony_ci#define SUN50I_ADDA_OL_MIX_CTRL_PHONE 4 388c2ecf20Sopenharmony_ci#define SUN50I_ADDA_OL_MIX_CTRL_PHONEN 3 398c2ecf20Sopenharmony_ci#define SUN50I_ADDA_OL_MIX_CTRL_LINEINL 2 408c2ecf20Sopenharmony_ci#define SUN50I_ADDA_OL_MIX_CTRL_DACL 1 418c2ecf20Sopenharmony_ci#define SUN50I_ADDA_OL_MIX_CTRL_DACR 0 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci#define SUN50I_ADDA_OR_MIX_CTRL 0x02 448c2ecf20Sopenharmony_ci#define SUN50I_ADDA_OR_MIX_CTRL_MIC1 6 458c2ecf20Sopenharmony_ci#define SUN50I_ADDA_OR_MIX_CTRL_MIC2 5 468c2ecf20Sopenharmony_ci#define SUN50I_ADDA_OR_MIX_CTRL_PHONE 4 478c2ecf20Sopenharmony_ci#define SUN50I_ADDA_OR_MIX_CTRL_PHONEP 3 488c2ecf20Sopenharmony_ci#define SUN50I_ADDA_OR_MIX_CTRL_LINEINR 2 498c2ecf20Sopenharmony_ci#define SUN50I_ADDA_OR_MIX_CTRL_DACR 1 508c2ecf20Sopenharmony_ci#define SUN50I_ADDA_OR_MIX_CTRL_DACL 0 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci#define SUN50I_ADDA_EARPIECE_CTRL0 0x03 538c2ecf20Sopenharmony_ci#define SUN50I_ADDA_EARPIECE_CTRL0_EAR_RAMP_TIME 4 548c2ecf20Sopenharmony_ci#define SUN50I_ADDA_EARPIECE_CTRL0_ESPSR 0 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci#define SUN50I_ADDA_EARPIECE_CTRL1 0x04 578c2ecf20Sopenharmony_ci#define SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_EN 7 588c2ecf20Sopenharmony_ci#define SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_MUTE 6 598c2ecf20Sopenharmony_ci#define SUN50I_ADDA_EARPIECE_CTRL1_ESP_VOL 0 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci#define SUN50I_ADDA_LINEOUT_CTRL0 0x05 628c2ecf20Sopenharmony_ci#define SUN50I_ADDA_LINEOUT_CTRL0_LEN 7 638c2ecf20Sopenharmony_ci#define SUN50I_ADDA_LINEOUT_CTRL0_REN 6 648c2ecf20Sopenharmony_ci#define SUN50I_ADDA_LINEOUT_CTRL0_LSRC_SEL 5 658c2ecf20Sopenharmony_ci#define SUN50I_ADDA_LINEOUT_CTRL0_RSRC_SEL 4 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci#define SUN50I_ADDA_LINEOUT_CTRL1 0x06 688c2ecf20Sopenharmony_ci#define SUN50I_ADDA_LINEOUT_CTRL1_VOL 0 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci#define SUN50I_ADDA_MIC1_CTRL 0x07 718c2ecf20Sopenharmony_ci#define SUN50I_ADDA_MIC1_CTRL_MIC1G 4 728c2ecf20Sopenharmony_ci#define SUN50I_ADDA_MIC1_CTRL_MIC1AMPEN 3 738c2ecf20Sopenharmony_ci#define SUN50I_ADDA_MIC1_CTRL_MIC1BOOST 0 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci#define SUN50I_ADDA_MIC2_CTRL 0x08 768c2ecf20Sopenharmony_ci#define SUN50I_ADDA_MIC2_CTRL_MIC2G 4 778c2ecf20Sopenharmony_ci#define SUN50I_ADDA_MIC2_CTRL_MIC2AMPEN 3 788c2ecf20Sopenharmony_ci#define SUN50I_ADDA_MIC2_CTRL_MIC2BOOST 0 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci#define SUN50I_ADDA_LINEIN_CTRL 0x09 818c2ecf20Sopenharmony_ci#define SUN50I_ADDA_LINEIN_CTRL_LINEING 0 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci#define SUN50I_ADDA_MIX_DAC_CTRL 0x0a 848c2ecf20Sopenharmony_ci#define SUN50I_ADDA_MIX_DAC_CTRL_DACAREN 7 858c2ecf20Sopenharmony_ci#define SUN50I_ADDA_MIX_DAC_CTRL_DACALEN 6 868c2ecf20Sopenharmony_ci#define SUN50I_ADDA_MIX_DAC_CTRL_RMIXEN 5 878c2ecf20Sopenharmony_ci#define SUN50I_ADDA_MIX_DAC_CTRL_LMIXEN 4 888c2ecf20Sopenharmony_ci#define SUN50I_ADDA_MIX_DAC_CTRL_RHPPAMUTE 3 898c2ecf20Sopenharmony_ci#define SUN50I_ADDA_MIX_DAC_CTRL_LHPPAMUTE 2 908c2ecf20Sopenharmony_ci#define SUN50I_ADDA_MIX_DAC_CTRL_RHPIS 1 918c2ecf20Sopenharmony_ci#define SUN50I_ADDA_MIX_DAC_CTRL_LHPIS 0 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci#define SUN50I_ADDA_L_ADCMIX_SRC 0x0b 948c2ecf20Sopenharmony_ci#define SUN50I_ADDA_L_ADCMIX_SRC_MIC1 6 958c2ecf20Sopenharmony_ci#define SUN50I_ADDA_L_ADCMIX_SRC_MIC2 5 968c2ecf20Sopenharmony_ci#define SUN50I_ADDA_L_ADCMIX_SRC_PHONE 4 978c2ecf20Sopenharmony_ci#define SUN50I_ADDA_L_ADCMIX_SRC_PHONEN 3 988c2ecf20Sopenharmony_ci#define SUN50I_ADDA_L_ADCMIX_SRC_LINEINL 2 998c2ecf20Sopenharmony_ci#define SUN50I_ADDA_L_ADCMIX_SRC_OMIXRL 1 1008c2ecf20Sopenharmony_ci#define SUN50I_ADDA_L_ADCMIX_SRC_OMIXRR 0 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci#define SUN50I_ADDA_R_ADCMIX_SRC 0x0c 1038c2ecf20Sopenharmony_ci#define SUN50I_ADDA_R_ADCMIX_SRC_MIC1 6 1048c2ecf20Sopenharmony_ci#define SUN50I_ADDA_R_ADCMIX_SRC_MIC2 5 1058c2ecf20Sopenharmony_ci#define SUN50I_ADDA_R_ADCMIX_SRC_PHONE 4 1068c2ecf20Sopenharmony_ci#define SUN50I_ADDA_R_ADCMIX_SRC_PHONEP 3 1078c2ecf20Sopenharmony_ci#define SUN50I_ADDA_R_ADCMIX_SRC_LINEINR 2 1088c2ecf20Sopenharmony_ci#define SUN50I_ADDA_R_ADCMIX_SRC_OMIXR 1 1098c2ecf20Sopenharmony_ci#define SUN50I_ADDA_R_ADCMIX_SRC_OMIXL 0 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci#define SUN50I_ADDA_ADC_CTRL 0x0d 1128c2ecf20Sopenharmony_ci#define SUN50I_ADDA_ADC_CTRL_ADCREN 7 1138c2ecf20Sopenharmony_ci#define SUN50I_ADDA_ADC_CTRL_ADCLEN 6 1148c2ecf20Sopenharmony_ci#define SUN50I_ADDA_ADC_CTRL_ADCG 0 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci#define SUN50I_ADDA_HS_MBIAS_CTRL 0x0e 1178c2ecf20Sopenharmony_ci#define SUN50I_ADDA_HS_MBIAS_CTRL_MMICBIASEN 7 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci#define SUN50I_ADDA_JACK_MIC_CTRL 0x1d 1208c2ecf20Sopenharmony_ci#define SUN50I_ADDA_JACK_MIC_CTRL_HMICBIASEN 5 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci/* mixer controls */ 1238c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new sun50i_a64_codec_mixer_controls[] = { 1248c2ecf20Sopenharmony_ci SOC_DAPM_DOUBLE_R("Mic1 Playback Switch", 1258c2ecf20Sopenharmony_ci SUN50I_ADDA_OL_MIX_CTRL, 1268c2ecf20Sopenharmony_ci SUN50I_ADDA_OR_MIX_CTRL, 1278c2ecf20Sopenharmony_ci SUN50I_ADDA_OL_MIX_CTRL_MIC1, 1, 0), 1288c2ecf20Sopenharmony_ci SOC_DAPM_DOUBLE_R("Mic2 Playback Switch", 1298c2ecf20Sopenharmony_ci SUN50I_ADDA_OL_MIX_CTRL, 1308c2ecf20Sopenharmony_ci SUN50I_ADDA_OR_MIX_CTRL, 1318c2ecf20Sopenharmony_ci SUN50I_ADDA_OL_MIX_CTRL_MIC2, 1, 0), 1328c2ecf20Sopenharmony_ci SOC_DAPM_DOUBLE_R("Line In Playback Switch", 1338c2ecf20Sopenharmony_ci SUN50I_ADDA_OL_MIX_CTRL, 1348c2ecf20Sopenharmony_ci SUN50I_ADDA_OR_MIX_CTRL, 1358c2ecf20Sopenharmony_ci SUN50I_ADDA_OL_MIX_CTRL_LINEINL, 1, 0), 1368c2ecf20Sopenharmony_ci SOC_DAPM_DOUBLE_R("DAC Playback Switch", 1378c2ecf20Sopenharmony_ci SUN50I_ADDA_OL_MIX_CTRL, 1388c2ecf20Sopenharmony_ci SUN50I_ADDA_OR_MIX_CTRL, 1398c2ecf20Sopenharmony_ci SUN50I_ADDA_OL_MIX_CTRL_DACL, 1, 0), 1408c2ecf20Sopenharmony_ci SOC_DAPM_DOUBLE_R("DAC Reversed Playback Switch", 1418c2ecf20Sopenharmony_ci SUN50I_ADDA_OL_MIX_CTRL, 1428c2ecf20Sopenharmony_ci SUN50I_ADDA_OR_MIX_CTRL, 1438c2ecf20Sopenharmony_ci SUN50I_ADDA_OL_MIX_CTRL_DACR, 1, 0), 1448c2ecf20Sopenharmony_ci}; 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci/* ADC mixer controls */ 1478c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new sun50i_codec_adc_mixer_controls[] = { 1488c2ecf20Sopenharmony_ci SOC_DAPM_DOUBLE_R("Mic1 Capture Switch", 1498c2ecf20Sopenharmony_ci SUN50I_ADDA_L_ADCMIX_SRC, 1508c2ecf20Sopenharmony_ci SUN50I_ADDA_R_ADCMIX_SRC, 1518c2ecf20Sopenharmony_ci SUN50I_ADDA_L_ADCMIX_SRC_MIC1, 1, 0), 1528c2ecf20Sopenharmony_ci SOC_DAPM_DOUBLE_R("Mic2 Capture Switch", 1538c2ecf20Sopenharmony_ci SUN50I_ADDA_L_ADCMIX_SRC, 1548c2ecf20Sopenharmony_ci SUN50I_ADDA_R_ADCMIX_SRC, 1558c2ecf20Sopenharmony_ci SUN50I_ADDA_L_ADCMIX_SRC_MIC2, 1, 0), 1568c2ecf20Sopenharmony_ci SOC_DAPM_DOUBLE_R("Line In Capture Switch", 1578c2ecf20Sopenharmony_ci SUN50I_ADDA_L_ADCMIX_SRC, 1588c2ecf20Sopenharmony_ci SUN50I_ADDA_R_ADCMIX_SRC, 1598c2ecf20Sopenharmony_ci SUN50I_ADDA_L_ADCMIX_SRC_LINEINL, 1, 0), 1608c2ecf20Sopenharmony_ci SOC_DAPM_DOUBLE_R("Mixer Capture Switch", 1618c2ecf20Sopenharmony_ci SUN50I_ADDA_L_ADCMIX_SRC, 1628c2ecf20Sopenharmony_ci SUN50I_ADDA_R_ADCMIX_SRC, 1638c2ecf20Sopenharmony_ci SUN50I_ADDA_L_ADCMIX_SRC_OMIXRL, 1, 0), 1648c2ecf20Sopenharmony_ci SOC_DAPM_DOUBLE_R("Mixer Reversed Capture Switch", 1658c2ecf20Sopenharmony_ci SUN50I_ADDA_L_ADCMIX_SRC, 1668c2ecf20Sopenharmony_ci SUN50I_ADDA_R_ADCMIX_SRC, 1678c2ecf20Sopenharmony_ci SUN50I_ADDA_L_ADCMIX_SRC_OMIXRR, 1, 0), 1688c2ecf20Sopenharmony_ci}; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(sun50i_codec_out_mixer_pregain_scale, 1718c2ecf20Sopenharmony_ci -450, 150, 0); 1728c2ecf20Sopenharmony_cistatic const DECLARE_TLV_DB_RANGE(sun50i_codec_mic_gain_scale, 1738c2ecf20Sopenharmony_ci 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), 1748c2ecf20Sopenharmony_ci 1, 7, TLV_DB_SCALE_ITEM(2400, 300, 0), 1758c2ecf20Sopenharmony_ci); 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(sun50i_codec_hp_vol_scale, -6300, 100, 1); 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_cistatic const DECLARE_TLV_DB_RANGE(sun50i_codec_lineout_vol_scale, 1808c2ecf20Sopenharmony_ci 0, 1, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1), 1818c2ecf20Sopenharmony_ci 2, 31, TLV_DB_SCALE_ITEM(-4350, 150, 0), 1828c2ecf20Sopenharmony_ci); 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_cistatic const DECLARE_TLV_DB_RANGE(sun50i_codec_earpiece_vol_scale, 1858c2ecf20Sopenharmony_ci 0, 1, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1), 1868c2ecf20Sopenharmony_ci 2, 31, TLV_DB_SCALE_ITEM(-4350, 150, 0), 1878c2ecf20Sopenharmony_ci); 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci/* volume / mute controls */ 1908c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new sun50i_a64_codec_controls[] = { 1918c2ecf20Sopenharmony_ci SOC_SINGLE_TLV("Headphone Playback Volume", 1928c2ecf20Sopenharmony_ci SUN50I_ADDA_HP_CTRL, 1938c2ecf20Sopenharmony_ci SUN50I_ADDA_HP_CTRL_HPVOL, 0x3f, 0, 1948c2ecf20Sopenharmony_ci sun50i_codec_hp_vol_scale), 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci /* Mixer pre-gain */ 1978c2ecf20Sopenharmony_ci SOC_SINGLE_TLV("Mic1 Playback Volume", SUN50I_ADDA_MIC1_CTRL, 1988c2ecf20Sopenharmony_ci SUN50I_ADDA_MIC1_CTRL_MIC1G, 1998c2ecf20Sopenharmony_ci 0x7, 0, sun50i_codec_out_mixer_pregain_scale), 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci /* Microphone Amp boost gain */ 2028c2ecf20Sopenharmony_ci SOC_SINGLE_TLV("Mic1 Boost Volume", SUN50I_ADDA_MIC1_CTRL, 2038c2ecf20Sopenharmony_ci SUN50I_ADDA_MIC1_CTRL_MIC1BOOST, 0x7, 0, 2048c2ecf20Sopenharmony_ci sun50i_codec_mic_gain_scale), 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci /* Mixer pre-gain */ 2078c2ecf20Sopenharmony_ci SOC_SINGLE_TLV("Mic2 Playback Volume", 2088c2ecf20Sopenharmony_ci SUN50I_ADDA_MIC2_CTRL, SUN50I_ADDA_MIC2_CTRL_MIC2G, 2098c2ecf20Sopenharmony_ci 0x7, 0, sun50i_codec_out_mixer_pregain_scale), 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci /* Microphone Amp boost gain */ 2128c2ecf20Sopenharmony_ci SOC_SINGLE_TLV("Mic2 Boost Volume", SUN50I_ADDA_MIC2_CTRL, 2138c2ecf20Sopenharmony_ci SUN50I_ADDA_MIC2_CTRL_MIC2BOOST, 0x7, 0, 2148c2ecf20Sopenharmony_ci sun50i_codec_mic_gain_scale), 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci /* ADC */ 2178c2ecf20Sopenharmony_ci SOC_SINGLE_TLV("ADC Gain Capture Volume", SUN50I_ADDA_ADC_CTRL, 2188c2ecf20Sopenharmony_ci SUN50I_ADDA_ADC_CTRL_ADCG, 0x7, 0, 2198c2ecf20Sopenharmony_ci sun50i_codec_out_mixer_pregain_scale), 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci /* Mixer pre-gain */ 2228c2ecf20Sopenharmony_ci SOC_SINGLE_TLV("Line In Playback Volume", SUN50I_ADDA_LINEIN_CTRL, 2238c2ecf20Sopenharmony_ci SUN50I_ADDA_LINEIN_CTRL_LINEING, 2248c2ecf20Sopenharmony_ci 0x7, 0, sun50i_codec_out_mixer_pregain_scale), 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci SOC_SINGLE_TLV("Line Out Playback Volume", 2278c2ecf20Sopenharmony_ci SUN50I_ADDA_LINEOUT_CTRL1, 2288c2ecf20Sopenharmony_ci SUN50I_ADDA_LINEOUT_CTRL1_VOL, 0x1f, 0, 2298c2ecf20Sopenharmony_ci sun50i_codec_lineout_vol_scale), 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci SOC_SINGLE_TLV("Earpiece Playback Volume", 2328c2ecf20Sopenharmony_ci SUN50I_ADDA_EARPIECE_CTRL1, 2338c2ecf20Sopenharmony_ci SUN50I_ADDA_EARPIECE_CTRL1_ESP_VOL, 0x1f, 0, 2348c2ecf20Sopenharmony_ci sun50i_codec_earpiece_vol_scale), 2358c2ecf20Sopenharmony_ci}; 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_cistatic const char * const sun50i_codec_hp_src_enum_text[] = { 2388c2ecf20Sopenharmony_ci "DAC", "Mixer", 2398c2ecf20Sopenharmony_ci}; 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_cistatic SOC_ENUM_DOUBLE_DECL(sun50i_codec_hp_src_enum, 2428c2ecf20Sopenharmony_ci SUN50I_ADDA_MIX_DAC_CTRL, 2438c2ecf20Sopenharmony_ci SUN50I_ADDA_MIX_DAC_CTRL_LHPIS, 2448c2ecf20Sopenharmony_ci SUN50I_ADDA_MIX_DAC_CTRL_RHPIS, 2458c2ecf20Sopenharmony_ci sun50i_codec_hp_src_enum_text); 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new sun50i_codec_hp_src[] = { 2488c2ecf20Sopenharmony_ci SOC_DAPM_ENUM("Headphone Source Playback Route", 2498c2ecf20Sopenharmony_ci sun50i_codec_hp_src_enum), 2508c2ecf20Sopenharmony_ci}; 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new sun50i_codec_hp_switch = 2538c2ecf20Sopenharmony_ci SOC_DAPM_DOUBLE("Headphone Playback Switch", 2548c2ecf20Sopenharmony_ci SUN50I_ADDA_MIX_DAC_CTRL, 2558c2ecf20Sopenharmony_ci SUN50I_ADDA_MIX_DAC_CTRL_LHPPAMUTE, 2568c2ecf20Sopenharmony_ci SUN50I_ADDA_MIX_DAC_CTRL_RHPPAMUTE, 1, 0); 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_cistatic const char * const sun50i_codec_lineout_src_enum_text[] = { 2598c2ecf20Sopenharmony_ci "Stereo", "Mono Differential", 2608c2ecf20Sopenharmony_ci}; 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_cistatic SOC_ENUM_DOUBLE_DECL(sun50i_codec_lineout_src_enum, 2638c2ecf20Sopenharmony_ci SUN50I_ADDA_LINEOUT_CTRL0, 2648c2ecf20Sopenharmony_ci SUN50I_ADDA_LINEOUT_CTRL0_LSRC_SEL, 2658c2ecf20Sopenharmony_ci SUN50I_ADDA_LINEOUT_CTRL0_RSRC_SEL, 2668c2ecf20Sopenharmony_ci sun50i_codec_lineout_src_enum_text); 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new sun50i_codec_lineout_src[] = { 2698c2ecf20Sopenharmony_ci SOC_DAPM_ENUM("Line Out Source Playback Route", 2708c2ecf20Sopenharmony_ci sun50i_codec_lineout_src_enum), 2718c2ecf20Sopenharmony_ci}; 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new sun50i_codec_lineout_switch = 2748c2ecf20Sopenharmony_ci SOC_DAPM_DOUBLE("Line Out Playback Switch", 2758c2ecf20Sopenharmony_ci SUN50I_ADDA_LINEOUT_CTRL0, 2768c2ecf20Sopenharmony_ci SUN50I_ADDA_LINEOUT_CTRL0_LEN, 2778c2ecf20Sopenharmony_ci SUN50I_ADDA_LINEOUT_CTRL0_REN, 1, 0); 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_cistatic const char * const sun50i_codec_earpiece_src_enum_text[] = { 2808c2ecf20Sopenharmony_ci "DACR", "DACL", "Right Mixer", "Left Mixer", 2818c2ecf20Sopenharmony_ci}; 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(sun50i_codec_earpiece_src_enum, 2848c2ecf20Sopenharmony_ci SUN50I_ADDA_EARPIECE_CTRL0, 2858c2ecf20Sopenharmony_ci SUN50I_ADDA_EARPIECE_CTRL0_ESPSR, 2868c2ecf20Sopenharmony_ci sun50i_codec_earpiece_src_enum_text); 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new sun50i_codec_earpiece_src[] = { 2898c2ecf20Sopenharmony_ci SOC_DAPM_ENUM("Earpiece Source Playback Route", 2908c2ecf20Sopenharmony_ci sun50i_codec_earpiece_src_enum), 2918c2ecf20Sopenharmony_ci}; 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new sun50i_codec_earpiece_switch[] = { 2948c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("Earpiece Playback Switch", 2958c2ecf20Sopenharmony_ci SUN50I_ADDA_EARPIECE_CTRL1, 2968c2ecf20Sopenharmony_ci SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_MUTE, 1, 0), 2978c2ecf20Sopenharmony_ci}; 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_cistatic const struct snd_soc_dapm_widget sun50i_a64_codec_widgets[] = { 3008c2ecf20Sopenharmony_ci /* DAC */ 3018c2ecf20Sopenharmony_ci SND_SOC_DAPM_DAC("Left DAC", NULL, SUN50I_ADDA_MIX_DAC_CTRL, 3028c2ecf20Sopenharmony_ci SUN50I_ADDA_MIX_DAC_CTRL_DACALEN, 0), 3038c2ecf20Sopenharmony_ci SND_SOC_DAPM_DAC("Right DAC", NULL, SUN50I_ADDA_MIX_DAC_CTRL, 3048c2ecf20Sopenharmony_ci SUN50I_ADDA_MIX_DAC_CTRL_DACAREN, 0), 3058c2ecf20Sopenharmony_ci /* ADC */ 3068c2ecf20Sopenharmony_ci SND_SOC_DAPM_ADC("Left ADC", NULL, SUN50I_ADDA_ADC_CTRL, 3078c2ecf20Sopenharmony_ci SUN50I_ADDA_ADC_CTRL_ADCLEN, 0), 3088c2ecf20Sopenharmony_ci SND_SOC_DAPM_ADC("Right ADC", NULL, SUN50I_ADDA_ADC_CTRL, 3098c2ecf20Sopenharmony_ci SUN50I_ADDA_ADC_CTRL_ADCREN, 0), 3108c2ecf20Sopenharmony_ci /* 3118c2ecf20Sopenharmony_ci * Due to this component and the codec belonging to separate DAPM 3128c2ecf20Sopenharmony_ci * contexts, we need to manually link the above widgets to their 3138c2ecf20Sopenharmony_ci * stream widgets at the card level. 3148c2ecf20Sopenharmony_ci */ 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_ci SND_SOC_DAPM_REGULATOR_SUPPLY("cpvdd", 0, 0), 3178c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("Left Headphone Source", 3188c2ecf20Sopenharmony_ci SND_SOC_NOPM, 0, 0, sun50i_codec_hp_src), 3198c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("Right Headphone Source", 3208c2ecf20Sopenharmony_ci SND_SOC_NOPM, 0, 0, sun50i_codec_hp_src), 3218c2ecf20Sopenharmony_ci SND_SOC_DAPM_SWITCH("Left Headphone Switch", 3228c2ecf20Sopenharmony_ci SND_SOC_NOPM, 0, 0, &sun50i_codec_hp_switch), 3238c2ecf20Sopenharmony_ci SND_SOC_DAPM_SWITCH("Right Headphone Switch", 3248c2ecf20Sopenharmony_ci SND_SOC_NOPM, 0, 0, &sun50i_codec_hp_switch), 3258c2ecf20Sopenharmony_ci SND_SOC_DAPM_OUT_DRV("Left Headphone Amp", 3268c2ecf20Sopenharmony_ci SND_SOC_NOPM, 0, 0, NULL, 0), 3278c2ecf20Sopenharmony_ci SND_SOC_DAPM_OUT_DRV("Right Headphone Amp", 3288c2ecf20Sopenharmony_ci SND_SOC_NOPM, 0, 0, NULL, 0), 3298c2ecf20Sopenharmony_ci SND_SOC_DAPM_SUPPLY("Headphone Amp", SUN50I_ADDA_HP_CTRL, 3308c2ecf20Sopenharmony_ci SUN50I_ADDA_HP_CTRL_HPPA_EN, 0, NULL, 0), 3318c2ecf20Sopenharmony_ci SND_SOC_DAPM_OUTPUT("HP"), 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("Left Line Out Source", 3348c2ecf20Sopenharmony_ci SND_SOC_NOPM, 0, 0, sun50i_codec_lineout_src), 3358c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("Right Line Out Source", 3368c2ecf20Sopenharmony_ci SND_SOC_NOPM, 0, 0, sun50i_codec_lineout_src), 3378c2ecf20Sopenharmony_ci SND_SOC_DAPM_SWITCH("Left Line Out Switch", 3388c2ecf20Sopenharmony_ci SND_SOC_NOPM, 0, 0, &sun50i_codec_lineout_switch), 3398c2ecf20Sopenharmony_ci SND_SOC_DAPM_SWITCH("Right Line Out Switch", 3408c2ecf20Sopenharmony_ci SND_SOC_NOPM, 0, 0, &sun50i_codec_lineout_switch), 3418c2ecf20Sopenharmony_ci SND_SOC_DAPM_OUTPUT("LINEOUT"), 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("Earpiece Source Playback Route", 3448c2ecf20Sopenharmony_ci SND_SOC_NOPM, 0, 0, sun50i_codec_earpiece_src), 3458c2ecf20Sopenharmony_ci SOC_MIXER_NAMED_CTL_ARRAY("Earpiece Switch", 3468c2ecf20Sopenharmony_ci SND_SOC_NOPM, 0, 0, 3478c2ecf20Sopenharmony_ci sun50i_codec_earpiece_switch), 3488c2ecf20Sopenharmony_ci SND_SOC_DAPM_OUT_DRV("Earpiece Amp", SUN50I_ADDA_EARPIECE_CTRL1, 3498c2ecf20Sopenharmony_ci SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_EN, 0, NULL, 0), 3508c2ecf20Sopenharmony_ci SND_SOC_DAPM_OUTPUT("EARPIECE"), 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_ci /* Microphone inputs */ 3538c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("MIC1"), 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci /* Microphone Bias */ 3568c2ecf20Sopenharmony_ci SND_SOC_DAPM_SUPPLY("MBIAS", SUN50I_ADDA_HS_MBIAS_CTRL, 3578c2ecf20Sopenharmony_ci SUN50I_ADDA_HS_MBIAS_CTRL_MMICBIASEN, 3588c2ecf20Sopenharmony_ci 0, NULL, 0), 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci /* Mic input path */ 3618c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("Mic1 Amplifier", SUN50I_ADDA_MIC1_CTRL, 3628c2ecf20Sopenharmony_ci SUN50I_ADDA_MIC1_CTRL_MIC1AMPEN, 0, NULL, 0), 3638c2ecf20Sopenharmony_ci 3648c2ecf20Sopenharmony_ci /* Microphone input */ 3658c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("MIC2"), 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_ci /* Microphone Bias */ 3688c2ecf20Sopenharmony_ci SND_SOC_DAPM_SUPPLY("HBIAS", SUN50I_ADDA_JACK_MIC_CTRL, 3698c2ecf20Sopenharmony_ci SUN50I_ADDA_JACK_MIC_CTRL_HMICBIASEN, 3708c2ecf20Sopenharmony_ci 0, NULL, 0), 3718c2ecf20Sopenharmony_ci 3728c2ecf20Sopenharmony_ci /* Mic input path */ 3738c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("Mic2 Amplifier", SUN50I_ADDA_MIC2_CTRL, 3748c2ecf20Sopenharmony_ci SUN50I_ADDA_MIC2_CTRL_MIC2AMPEN, 0, NULL, 0), 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_ci /* Line input */ 3778c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("LINEIN"), 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_ci /* Mixers */ 3808c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIXER("Left Mixer", SUN50I_ADDA_MIX_DAC_CTRL, 3818c2ecf20Sopenharmony_ci SUN50I_ADDA_MIX_DAC_CTRL_LMIXEN, 0, 3828c2ecf20Sopenharmony_ci sun50i_a64_codec_mixer_controls, 3838c2ecf20Sopenharmony_ci ARRAY_SIZE(sun50i_a64_codec_mixer_controls)), 3848c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIXER("Right Mixer", SUN50I_ADDA_MIX_DAC_CTRL, 3858c2ecf20Sopenharmony_ci SUN50I_ADDA_MIX_DAC_CTRL_RMIXEN, 0, 3868c2ecf20Sopenharmony_ci sun50i_a64_codec_mixer_controls, 3878c2ecf20Sopenharmony_ci ARRAY_SIZE(sun50i_a64_codec_mixer_controls)), 3888c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIXER("Left ADC Mixer", SND_SOC_NOPM, 0, 0, 3898c2ecf20Sopenharmony_ci sun50i_codec_adc_mixer_controls, 3908c2ecf20Sopenharmony_ci ARRAY_SIZE(sun50i_codec_adc_mixer_controls)), 3918c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIXER("Right ADC Mixer", SND_SOC_NOPM, 0, 0, 3928c2ecf20Sopenharmony_ci sun50i_codec_adc_mixer_controls, 3938c2ecf20Sopenharmony_ci ARRAY_SIZE(sun50i_codec_adc_mixer_controls)), 3948c2ecf20Sopenharmony_ci}; 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_cistatic const struct snd_soc_dapm_route sun50i_a64_codec_routes[] = { 3978c2ecf20Sopenharmony_ci /* Left Mixer Routes */ 3988c2ecf20Sopenharmony_ci { "Left Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" }, 3998c2ecf20Sopenharmony_ci { "Left Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" }, 4008c2ecf20Sopenharmony_ci { "Left Mixer", "Line In Playback Switch", "LINEIN" }, 4018c2ecf20Sopenharmony_ci { "Left Mixer", "DAC Playback Switch", "Left DAC" }, 4028c2ecf20Sopenharmony_ci { "Left Mixer", "DAC Reversed Playback Switch", "Right DAC" }, 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci /* Right Mixer Routes */ 4058c2ecf20Sopenharmony_ci { "Right Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" }, 4068c2ecf20Sopenharmony_ci { "Right Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" }, 4078c2ecf20Sopenharmony_ci { "Right Mixer", "Line In Playback Switch", "LINEIN" }, 4088c2ecf20Sopenharmony_ci { "Right Mixer", "DAC Playback Switch", "Right DAC" }, 4098c2ecf20Sopenharmony_ci { "Right Mixer", "DAC Reversed Playback Switch", "Left DAC" }, 4108c2ecf20Sopenharmony_ci 4118c2ecf20Sopenharmony_ci /* Left ADC Mixer Routes */ 4128c2ecf20Sopenharmony_ci { "Left ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" }, 4138c2ecf20Sopenharmony_ci { "Left ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" }, 4148c2ecf20Sopenharmony_ci { "Left ADC Mixer", "Line In Capture Switch", "LINEIN" }, 4158c2ecf20Sopenharmony_ci { "Left ADC Mixer", "Mixer Capture Switch", "Left Mixer" }, 4168c2ecf20Sopenharmony_ci { "Left ADC Mixer", "Mixer Reversed Capture Switch", "Right Mixer" }, 4178c2ecf20Sopenharmony_ci 4188c2ecf20Sopenharmony_ci /* Right ADC Mixer Routes */ 4198c2ecf20Sopenharmony_ci { "Right ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" }, 4208c2ecf20Sopenharmony_ci { "Right ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" }, 4218c2ecf20Sopenharmony_ci { "Right ADC Mixer", "Line In Capture Switch", "LINEIN" }, 4228c2ecf20Sopenharmony_ci { "Right ADC Mixer", "Mixer Capture Switch", "Right Mixer" }, 4238c2ecf20Sopenharmony_ci { "Right ADC Mixer", "Mixer Reversed Capture Switch", "Left Mixer" }, 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_ci /* ADC Routes */ 4268c2ecf20Sopenharmony_ci { "Left ADC", NULL, "Left ADC Mixer" }, 4278c2ecf20Sopenharmony_ci { "Right ADC", NULL, "Right ADC Mixer" }, 4288c2ecf20Sopenharmony_ci 4298c2ecf20Sopenharmony_ci /* Headphone Routes */ 4308c2ecf20Sopenharmony_ci { "Left Headphone Source", "DAC", "Left DAC" }, 4318c2ecf20Sopenharmony_ci { "Left Headphone Source", "Mixer", "Left Mixer" }, 4328c2ecf20Sopenharmony_ci { "Left Headphone Switch", "Headphone Playback Switch", "Left Headphone Source" }, 4338c2ecf20Sopenharmony_ci { "Left Headphone Amp", NULL, "Left Headphone Switch" }, 4348c2ecf20Sopenharmony_ci { "Left Headphone Amp", NULL, "Headphone Amp" }, 4358c2ecf20Sopenharmony_ci { "HP", NULL, "Left Headphone Amp" }, 4368c2ecf20Sopenharmony_ci 4378c2ecf20Sopenharmony_ci { "Right Headphone Source", "DAC", "Right DAC" }, 4388c2ecf20Sopenharmony_ci { "Right Headphone Source", "Mixer", "Right Mixer" }, 4398c2ecf20Sopenharmony_ci { "Right Headphone Switch", "Headphone Playback Switch", "Right Headphone Source" }, 4408c2ecf20Sopenharmony_ci { "Right Headphone Amp", NULL, "Right Headphone Switch" }, 4418c2ecf20Sopenharmony_ci { "Right Headphone Amp", NULL, "Headphone Amp" }, 4428c2ecf20Sopenharmony_ci { "HP", NULL, "Right Headphone Amp" }, 4438c2ecf20Sopenharmony_ci 4448c2ecf20Sopenharmony_ci { "Headphone Amp", NULL, "cpvdd" }, 4458c2ecf20Sopenharmony_ci 4468c2ecf20Sopenharmony_ci /* Microphone Routes */ 4478c2ecf20Sopenharmony_ci { "Mic1 Amplifier", NULL, "MIC1"}, 4488c2ecf20Sopenharmony_ci 4498c2ecf20Sopenharmony_ci /* Microphone Routes */ 4508c2ecf20Sopenharmony_ci { "Mic2 Amplifier", NULL, "MIC2"}, 4518c2ecf20Sopenharmony_ci 4528c2ecf20Sopenharmony_ci /* Line-out Routes */ 4538c2ecf20Sopenharmony_ci { "Left Line Out Source", "Stereo", "Left Mixer" }, 4548c2ecf20Sopenharmony_ci { "Left Line Out Source", "Mono Differential", "Left Mixer" }, 4558c2ecf20Sopenharmony_ci { "Left Line Out Source", "Mono Differential", "Right Mixer" }, 4568c2ecf20Sopenharmony_ci { "Left Line Out Switch", "Line Out Playback Switch", "Left Line Out Source" }, 4578c2ecf20Sopenharmony_ci { "LINEOUT", NULL, "Left Line Out Switch" }, 4588c2ecf20Sopenharmony_ci 4598c2ecf20Sopenharmony_ci { "Right Line Out Switch", "Line Out Playback Switch", "Right Mixer" }, 4608c2ecf20Sopenharmony_ci { "Right Line Out Source", "Stereo", "Right Line Out Switch" }, 4618c2ecf20Sopenharmony_ci { "Right Line Out Source", "Mono Differential", "Left Line Out Switch" }, 4628c2ecf20Sopenharmony_ci { "LINEOUT", NULL, "Right Line Out Source" }, 4638c2ecf20Sopenharmony_ci 4648c2ecf20Sopenharmony_ci /* Earpiece Routes */ 4658c2ecf20Sopenharmony_ci { "Earpiece Source Playback Route", "DACL", "Left DAC" }, 4668c2ecf20Sopenharmony_ci { "Earpiece Source Playback Route", "DACR", "Right DAC" }, 4678c2ecf20Sopenharmony_ci { "Earpiece Source Playback Route", "Left Mixer", "Left Mixer" }, 4688c2ecf20Sopenharmony_ci { "Earpiece Source Playback Route", "Right Mixer", "Right Mixer" }, 4698c2ecf20Sopenharmony_ci { "Earpiece Switch", "Earpiece Playback Switch", "Earpiece Source Playback Route" }, 4708c2ecf20Sopenharmony_ci { "Earpiece Amp", NULL, "Earpiece Switch" }, 4718c2ecf20Sopenharmony_ci { "EARPIECE", NULL, "Earpiece Amp" }, 4728c2ecf20Sopenharmony_ci}; 4738c2ecf20Sopenharmony_ci 4748c2ecf20Sopenharmony_cistatic int sun50i_a64_codec_suspend(struct snd_soc_component *component) 4758c2ecf20Sopenharmony_ci{ 4768c2ecf20Sopenharmony_ci return regmap_update_bits(component->regmap, SUN50I_ADDA_HP_CTRL, 4778c2ecf20Sopenharmony_ci BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE), 4788c2ecf20Sopenharmony_ci BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE)); 4798c2ecf20Sopenharmony_ci} 4808c2ecf20Sopenharmony_ci 4818c2ecf20Sopenharmony_cistatic int sun50i_a64_codec_resume(struct snd_soc_component *component) 4828c2ecf20Sopenharmony_ci{ 4838c2ecf20Sopenharmony_ci return regmap_update_bits(component->regmap, SUN50I_ADDA_HP_CTRL, 4848c2ecf20Sopenharmony_ci BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE), 0); 4858c2ecf20Sopenharmony_ci} 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_cistatic const struct snd_soc_component_driver sun50i_codec_analog_cmpnt_drv = { 4888c2ecf20Sopenharmony_ci .controls = sun50i_a64_codec_controls, 4898c2ecf20Sopenharmony_ci .num_controls = ARRAY_SIZE(sun50i_a64_codec_controls), 4908c2ecf20Sopenharmony_ci .dapm_widgets = sun50i_a64_codec_widgets, 4918c2ecf20Sopenharmony_ci .num_dapm_widgets = ARRAY_SIZE(sun50i_a64_codec_widgets), 4928c2ecf20Sopenharmony_ci .dapm_routes = sun50i_a64_codec_routes, 4938c2ecf20Sopenharmony_ci .num_dapm_routes = ARRAY_SIZE(sun50i_a64_codec_routes), 4948c2ecf20Sopenharmony_ci .suspend = sun50i_a64_codec_suspend, 4958c2ecf20Sopenharmony_ci .resume = sun50i_a64_codec_resume, 4968c2ecf20Sopenharmony_ci}; 4978c2ecf20Sopenharmony_ci 4988c2ecf20Sopenharmony_cistatic const struct of_device_id sun50i_codec_analog_of_match[] = { 4998c2ecf20Sopenharmony_ci { 5008c2ecf20Sopenharmony_ci .compatible = "allwinner,sun50i-a64-codec-analog", 5018c2ecf20Sopenharmony_ci }, 5028c2ecf20Sopenharmony_ci {} 5038c2ecf20Sopenharmony_ci}; 5048c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, sun50i_codec_analog_of_match); 5058c2ecf20Sopenharmony_ci 5068c2ecf20Sopenharmony_cistatic int sun50i_codec_analog_probe(struct platform_device *pdev) 5078c2ecf20Sopenharmony_ci{ 5088c2ecf20Sopenharmony_ci struct regmap *regmap; 5098c2ecf20Sopenharmony_ci void __iomem *base; 5108c2ecf20Sopenharmony_ci 5118c2ecf20Sopenharmony_ci base = devm_platform_ioremap_resource(pdev, 0); 5128c2ecf20Sopenharmony_ci if (IS_ERR(base)) { 5138c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "Failed to map the registers\n"); 5148c2ecf20Sopenharmony_ci return PTR_ERR(base); 5158c2ecf20Sopenharmony_ci } 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_ci regmap = sun8i_adda_pr_regmap_init(&pdev->dev, base); 5188c2ecf20Sopenharmony_ci if (IS_ERR(regmap)) { 5198c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "Failed to create regmap\n"); 5208c2ecf20Sopenharmony_ci return PTR_ERR(regmap); 5218c2ecf20Sopenharmony_ci } 5228c2ecf20Sopenharmony_ci 5238c2ecf20Sopenharmony_ci return devm_snd_soc_register_component(&pdev->dev, 5248c2ecf20Sopenharmony_ci &sun50i_codec_analog_cmpnt_drv, 5258c2ecf20Sopenharmony_ci NULL, 0); 5268c2ecf20Sopenharmony_ci} 5278c2ecf20Sopenharmony_ci 5288c2ecf20Sopenharmony_cistatic struct platform_driver sun50i_codec_analog_driver = { 5298c2ecf20Sopenharmony_ci .driver = { 5308c2ecf20Sopenharmony_ci .name = "sun50i-codec-analog", 5318c2ecf20Sopenharmony_ci .of_match_table = sun50i_codec_analog_of_match, 5328c2ecf20Sopenharmony_ci }, 5338c2ecf20Sopenharmony_ci .probe = sun50i_codec_analog_probe, 5348c2ecf20Sopenharmony_ci}; 5358c2ecf20Sopenharmony_cimodule_platform_driver(sun50i_codec_analog_driver); 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Allwinner internal codec analog controls driver for A64"); 5388c2ecf20Sopenharmony_ciMODULE_AUTHOR("Vasily Khoruzhick <anarsoul@gmail.com>"); 5398c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 5408c2ecf20Sopenharmony_ciMODULE_ALIAS("platform:sun50i-codec-analog"); 541