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