Linux Audio

Check our new training course

Loading...
v6.2
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * This driver supports the digital controls for the internal codec
   4 * found in Allwinner's A33 SoCs.
   5 *
   6 * (C) Copyright 2010-2016
   7 * Reuuimlla Technology Co., Ltd. <www.reuuimllatech.com>
   8 * huangxin <huangxin@Reuuimllatech.com>
   9 * Mylène Josserand <mylene.josserand@free-electrons.com>
  10 */
  11
  12#include <linux/module.h>
  13#include <linux/delay.h>
  14#include <linux/clk.h>
  15#include <linux/io.h>
  16#include <linux/of_device.h>
  17#include <linux/pm_runtime.h>
  18#include <linux/regmap.h>
  19#include <linux/log2.h>
  20
  21#include <sound/pcm_params.h>
  22#include <sound/soc.h>
  23#include <sound/soc-dapm.h>
  24#include <sound/tlv.h>
  25
  26#define SUN8I_SYSCLK_CTL				0x00c
  27#define SUN8I_SYSCLK_CTL_AIF1CLK_ENA			11
  28#define SUN8I_SYSCLK_CTL_AIF1CLK_SRC_PLL		(0x2 << 8)
  29#define SUN8I_SYSCLK_CTL_AIF2CLK_ENA			7
  30#define SUN8I_SYSCLK_CTL_AIF2CLK_SRC_PLL		(0x2 << 4)
  31#define SUN8I_SYSCLK_CTL_SYSCLK_ENA			3
  32#define SUN8I_SYSCLK_CTL_SYSCLK_SRC			0
  33#define SUN8I_SYSCLK_CTL_SYSCLK_SRC_AIF1CLK		(0x0 << 0)
  34#define SUN8I_SYSCLK_CTL_SYSCLK_SRC_AIF2CLK		(0x1 << 0)
  35#define SUN8I_MOD_CLK_ENA				0x010
  36#define SUN8I_MOD_CLK_ENA_AIF1				15
  37#define SUN8I_MOD_CLK_ENA_AIF2				14
  38#define SUN8I_MOD_CLK_ENA_AIF3				13
  39#define SUN8I_MOD_CLK_ENA_ADC				3
  40#define SUN8I_MOD_CLK_ENA_DAC				2
  41#define SUN8I_MOD_RST_CTL				0x014
  42#define SUN8I_MOD_RST_CTL_AIF1				15
  43#define SUN8I_MOD_RST_CTL_AIF2				14
  44#define SUN8I_MOD_RST_CTL_AIF3				13
  45#define SUN8I_MOD_RST_CTL_ADC				3
  46#define SUN8I_MOD_RST_CTL_DAC				2
  47#define SUN8I_SYS_SR_CTRL				0x018
  48#define SUN8I_SYS_SR_CTRL_AIF1_FS			12
  49#define SUN8I_SYS_SR_CTRL_AIF2_FS			8
  50#define SUN8I_AIF_CLK_CTRL(n)				(0x040 * (1 + (n)))
  51#define SUN8I_AIF_CLK_CTRL_MSTR_MOD			15
  52#define SUN8I_AIF_CLK_CTRL_CLK_INV			13
  53#define SUN8I_AIF_CLK_CTRL_BCLK_DIV			9
  54#define SUN8I_AIF_CLK_CTRL_LRCK_DIV			6
  55#define SUN8I_AIF_CLK_CTRL_WORD_SIZ			4
  56#define SUN8I_AIF_CLK_CTRL_DATA_FMT			2
  57#define SUN8I_AIF1_ADCDAT_CTRL				0x044
  58#define SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0L_ENA		15
  59#define SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0R_ENA		14
  60#define SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0L_SRC		10
  61#define SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0R_SRC		8
  62#define SUN8I_AIF1_DACDAT_CTRL				0x048
  63#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA		15
  64#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA		14
  65#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_SRC		10
  66#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_SRC		8
  67#define SUN8I_AIF1_MXR_SRC				0x04c
  68#define SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF1DA0L	15
  69#define SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF2DACL	14
  70#define SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_ADCL		13
  71#define SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF2DACR	12
  72#define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF1DA0R	11
  73#define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACR	10
  74#define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_ADCR		9
  75#define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACL	8
  76#define SUN8I_AIF1_VOL_CTRL1				0x050
  77#define SUN8I_AIF1_VOL_CTRL1_AD0L_VOL			8
  78#define SUN8I_AIF1_VOL_CTRL1_AD0R_VOL			0
  79#define SUN8I_AIF1_VOL_CTRL3				0x058
  80#define SUN8I_AIF1_VOL_CTRL3_DA0L_VOL			8
  81#define SUN8I_AIF1_VOL_CTRL3_DA0R_VOL			0
  82#define SUN8I_AIF2_ADCDAT_CTRL				0x084
  83#define SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCL_ENA		15
  84#define SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCR_ENA		14
  85#define SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCL_SRC		10
  86#define SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCR_SRC		8
  87#define SUN8I_AIF2_DACDAT_CTRL				0x088
  88#define SUN8I_AIF2_DACDAT_CTRL_AIF2_DACL_ENA		15
  89#define SUN8I_AIF2_DACDAT_CTRL_AIF2_DACR_ENA		14
  90#define SUN8I_AIF2_DACDAT_CTRL_AIF2_DACL_SRC		10
  91#define SUN8I_AIF2_DACDAT_CTRL_AIF2_DACR_SRC		8
  92#define SUN8I_AIF2_MXR_SRC				0x08c
  93#define SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_AIF1DA0L	15
  94#define SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_AIF1DA1L	14
  95#define SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_AIF2DACR	13
  96#define SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_ADCL		12
  97#define SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_AIF1DA0R	11
  98#define SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_AIF1DA1R	10
  99#define SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_AIF2DACL	9
 100#define SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_ADCR		8
 101#define SUN8I_AIF2_VOL_CTRL1				0x090
 102#define SUN8I_AIF2_VOL_CTRL1_ADCL_VOL			8
 103#define SUN8I_AIF2_VOL_CTRL1_ADCR_VOL			0
 104#define SUN8I_AIF2_VOL_CTRL2				0x098
 105#define SUN8I_AIF2_VOL_CTRL2_DACL_VOL			8
 106#define SUN8I_AIF2_VOL_CTRL2_DACR_VOL			0
 107#define SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_AIF1		(0x0 << 0)
 108#define SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_AIF2		(0x1 << 0)
 109#define SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_AIF1CLK	(0x2 << 0)
 110#define SUN8I_AIF3_PATH_CTRL				0x0cc
 111#define SUN8I_AIF3_PATH_CTRL_AIF3_ADC_SRC		10
 112#define SUN8I_AIF3_PATH_CTRL_AIF2_DAC_SRC		8
 113#define SUN8I_AIF3_PATH_CTRL_AIF3_PINS_TRI		7
 114#define SUN8I_ADC_DIG_CTRL				0x100
 115#define SUN8I_ADC_DIG_CTRL_ENAD				15
 116#define SUN8I_ADC_DIG_CTRL_ADOUT_DTS			2
 117#define SUN8I_ADC_DIG_CTRL_ADOUT_DLY			1
 118#define SUN8I_ADC_VOL_CTRL				0x104
 119#define SUN8I_ADC_VOL_CTRL_ADCL_VOL			8
 120#define SUN8I_ADC_VOL_CTRL_ADCR_VOL			0
 121#define SUN8I_DAC_DIG_CTRL				0x120
 122#define SUN8I_DAC_DIG_CTRL_ENDA				15
 123#define SUN8I_DAC_VOL_CTRL				0x124
 124#define SUN8I_DAC_VOL_CTRL_DACL_VOL			8
 125#define SUN8I_DAC_VOL_CTRL_DACR_VOL			0
 126#define SUN8I_DAC_MXR_SRC				0x130
 127#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L		15
 128#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L		14
 129#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL		13
 130#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL		12
 131#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R		11
 132#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R		10
 133#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR		9
 134#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR		8
 135
 136#define SUN8I_SYSCLK_CTL_AIF1CLK_SRC_MASK	GENMASK(9, 8)
 137#define SUN8I_SYSCLK_CTL_AIF2CLK_SRC_MASK	GENMASK(5, 4)
 138#define SUN8I_SYS_SR_CTRL_AIF1_FS_MASK		GENMASK(15, 12)
 139#define SUN8I_SYS_SR_CTRL_AIF2_FS_MASK		GENMASK(11, 8)
 140#define SUN8I_AIF_CLK_CTRL_CLK_INV_MASK		GENMASK(14, 13)
 141#define SUN8I_AIF_CLK_CTRL_BCLK_DIV_MASK	GENMASK(12, 9)
 142#define SUN8I_AIF_CLK_CTRL_LRCK_DIV_MASK	GENMASK(8, 6)
 143#define SUN8I_AIF_CLK_CTRL_WORD_SIZ_MASK	GENMASK(5, 4)
 144#define SUN8I_AIF_CLK_CTRL_DATA_FMT_MASK	GENMASK(3, 2)
 145#define SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_MASK	GENMASK(1, 0)
 146
 147#define SUN8I_CODEC_PASSTHROUGH_SAMPLE_RATE 48000
 148
 149#define SUN8I_CODEC_PCM_FORMATS	(SNDRV_PCM_FMTBIT_S8     |\
 150				 SNDRV_PCM_FMTBIT_S16_LE |\
 151				 SNDRV_PCM_FMTBIT_S20_LE |\
 152				 SNDRV_PCM_FMTBIT_S24_LE |\
 153				 SNDRV_PCM_FMTBIT_S20_3LE|\
 154				 SNDRV_PCM_FMTBIT_S24_3LE)
 155
 156#define SUN8I_CODEC_PCM_RATES	(SNDRV_PCM_RATE_8000_48000|\
 157				 SNDRV_PCM_RATE_88200     |\
 158				 SNDRV_PCM_RATE_96000     |\
 159				 SNDRV_PCM_RATE_176400    |\
 160				 SNDRV_PCM_RATE_192000    |\
 161				 SNDRV_PCM_RATE_KNOT)
 162
 163enum {
 164	SUN8I_CODEC_AIF1,
 165	SUN8I_CODEC_AIF2,
 166	SUN8I_CODEC_AIF3,
 167	SUN8I_CODEC_NAIFS
 168};
 169
 170struct sun8i_codec_aif {
 171	unsigned int	lrck_div_order;
 172	unsigned int	sample_rate;
 173	unsigned int	slots;
 174	unsigned int	slot_width;
 175	unsigned int	active_streams	: 2;
 176	unsigned int	open_streams	: 2;
 177};
 178
 179struct sun8i_codec_quirks {
 180	bool legacy_widgets	: 1;
 181	bool lrck_inversion	: 1;
 182};
 183
 184struct sun8i_codec {
 185	struct regmap			*regmap;
 186	struct clk			*clk_module;
 187	const struct sun8i_codec_quirks	*quirks;
 188	struct sun8i_codec_aif		aifs[SUN8I_CODEC_NAIFS];
 189	unsigned int			sysclk_rate;
 190	int				sysclk_refcnt;
 191};
 192
 193static struct snd_soc_dai_driver sun8i_codec_dais[];
 194
 195static int sun8i_codec_runtime_resume(struct device *dev)
 196{
 197	struct sun8i_codec *scodec = dev_get_drvdata(dev);
 198	int ret;
 199
 200	regcache_cache_only(scodec->regmap, false);
 201
 202	ret = regcache_sync(scodec->regmap);
 203	if (ret) {
 204		dev_err(dev, "Failed to sync regmap cache\n");
 205		return ret;
 206	}
 207
 208	return 0;
 209}
 210
 211static int sun8i_codec_runtime_suspend(struct device *dev)
 212{
 213	struct sun8i_codec *scodec = dev_get_drvdata(dev);
 214
 215	regcache_cache_only(scodec->regmap, true);
 216	regcache_mark_dirty(scodec->regmap);
 217
 218	return 0;
 219}
 220
 221static int sun8i_codec_get_hw_rate(unsigned int sample_rate)
 222{
 223	switch (sample_rate) {
 224	case 7350:
 225	case 8000:
 226		return 0x0;
 227	case 11025:
 228		return 0x1;
 229	case 12000:
 230		return 0x2;
 231	case 14700:
 232	case 16000:
 233		return 0x3;
 234	case 22050:
 235		return 0x4;
 236	case 24000:
 237		return 0x5;
 238	case 29400:
 239	case 32000:
 240		return 0x6;
 241	case 44100:
 242		return 0x7;
 243	case 48000:
 244		return 0x8;
 245	case 88200:
 246	case 96000:
 247		return 0x9;
 248	case 176400:
 249	case 192000:
 250		return 0xa;
 251	default:
 252		return -EINVAL;
 253	}
 254}
 255
 256static int sun8i_codec_update_sample_rate(struct sun8i_codec *scodec)
 257{
 258	unsigned int max_rate = 0;
 259	int hw_rate, i;
 260
 261	for (i = SUN8I_CODEC_AIF1; i < SUN8I_CODEC_NAIFS; ++i) {
 262		struct sun8i_codec_aif *aif = &scodec->aifs[i];
 263
 264		if (aif->active_streams)
 265			max_rate = max(max_rate, aif->sample_rate);
 266	}
 267
 268	/* Set the sample rate for ADC->DAC passthrough when no AIF is active. */
 269	if (!max_rate)
 270		max_rate = SUN8I_CODEC_PASSTHROUGH_SAMPLE_RATE;
 271
 272	hw_rate = sun8i_codec_get_hw_rate(max_rate);
 273	if (hw_rate < 0)
 274		return hw_rate;
 275
 276	regmap_update_bits(scodec->regmap, SUN8I_SYS_SR_CTRL,
 277			   SUN8I_SYS_SR_CTRL_AIF1_FS_MASK,
 278			   hw_rate << SUN8I_SYS_SR_CTRL_AIF1_FS);
 279
 280	return 0;
 281}
 282
 283static int sun8i_codec_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 284{
 285	struct sun8i_codec *scodec = snd_soc_dai_get_drvdata(dai);
 286	u32 dsp_format, format, invert, value;
 287
 288	/* clock masters */
 289	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
 290	case SND_SOC_DAIFMT_CBC_CFC: /* Codec slave, DAI master */
 291		value = 0x1;
 292		break;
 293	case SND_SOC_DAIFMT_CBP_CFP: /* Codec Master, DAI slave */
 294		value = 0x0;
 295		break;
 296	default:
 297		return -EINVAL;
 298	}
 299
 300	if (dai->id == SUN8I_CODEC_AIF3) {
 301		/* AIF3 only supports master mode. */
 302		if (value)
 303			return -EINVAL;
 304
 305		/* Use the AIF2 BCLK and LRCK for AIF3. */
 306		regmap_update_bits(scodec->regmap, SUN8I_AIF_CLK_CTRL(dai->id),
 307				   SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_MASK,
 308				   SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_AIF2);
 309	} else {
 310		regmap_update_bits(scodec->regmap, SUN8I_AIF_CLK_CTRL(dai->id),
 311				   BIT(SUN8I_AIF_CLK_CTRL_MSTR_MOD),
 312				   value << SUN8I_AIF_CLK_CTRL_MSTR_MOD);
 313	}
 314
 315	/* DAI format */
 316	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 317	case SND_SOC_DAIFMT_I2S:
 318		format = 0x0;
 319		break;
 320	case SND_SOC_DAIFMT_LEFT_J:
 321		format = 0x1;
 322		break;
 323	case SND_SOC_DAIFMT_RIGHT_J:
 324		format = 0x2;
 325		break;
 326	case SND_SOC_DAIFMT_DSP_A:
 327		format = 0x3;
 328		dsp_format = 0x0; /* Set LRCK_INV to 0 */
 329		break;
 330	case SND_SOC_DAIFMT_DSP_B:
 331		format = 0x3;
 332		dsp_format = 0x1; /* Set LRCK_INV to 1 */
 333		break;
 334	default:
 335		return -EINVAL;
 336	}
 337
 338	if (dai->id == SUN8I_CODEC_AIF3) {
 339		/* AIF3 only supports DSP mode. */
 340		if (format != 3)
 341			return -EINVAL;
 342	} else {
 343		regmap_update_bits(scodec->regmap, SUN8I_AIF_CLK_CTRL(dai->id),
 344				   SUN8I_AIF_CLK_CTRL_DATA_FMT_MASK,
 345				   format << SUN8I_AIF_CLK_CTRL_DATA_FMT);
 346	}
 347
 348	/* clock inversion */
 349	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 350	case SND_SOC_DAIFMT_NB_NF: /* Normal */
 351		invert = 0x0;
 352		break;
 353	case SND_SOC_DAIFMT_NB_IF: /* Inverted LRCK */
 354		invert = 0x1;
 355		break;
 356	case SND_SOC_DAIFMT_IB_NF: /* Inverted BCLK */
 357		invert = 0x2;
 358		break;
 359	case SND_SOC_DAIFMT_IB_IF: /* Both inverted */
 360		invert = 0x3;
 361		break;
 362	default:
 363		return -EINVAL;
 364	}
 365
 366	if (format == 0x3) {
 367		/* Inverted LRCK is not available in DSP mode. */
 368		if (invert & BIT(0))
 369			return -EINVAL;
 370
 371		/* Instead, the bit selects between DSP A/B formats. */
 372		invert |= dsp_format;
 373	} else {
 374		/*
 375		 * It appears that the DAI and the codec in the A33 SoC don't
 376		 * share the same polarity for the LRCK signal when they mean
 377		 * 'normal' and 'inverted' in the datasheet.
 378		 *
 379		 * Since the DAI here is our regular i2s driver that have been
 380		 * tested with way more codecs than just this one, it means
 381		 * that the codec probably gets it backward, and we have to
 382		 * invert the value here.
 383		 */
 384		invert ^= scodec->quirks->lrck_inversion;
 385	}
 386
 387	regmap_update_bits(scodec->regmap, SUN8I_AIF_CLK_CTRL(dai->id),
 388			   SUN8I_AIF_CLK_CTRL_CLK_INV_MASK,
 389			   invert << SUN8I_AIF_CLK_CTRL_CLK_INV);
 390
 391	return 0;
 392}
 393
 394static int sun8i_codec_set_tdm_slot(struct snd_soc_dai *dai,
 395				    unsigned int tx_mask, unsigned int rx_mask,
 396				    int slots, int slot_width)
 397{
 398	struct sun8i_codec *scodec = snd_soc_dai_get_drvdata(dai);
 399	struct sun8i_codec_aif *aif = &scodec->aifs[dai->id];
 400
 401	if (slot_width && !is_power_of_2(slot_width))
 402		return -EINVAL;
 403
 404	aif->slots = slots;
 405	aif->slot_width = slot_width;
 406
 407	return 0;
 408}
 409
 410static const unsigned int sun8i_codec_rates[] = {
 411	  7350,   8000,  11025,  12000,  14700,  16000,  22050,  24000,
 412	 29400,  32000,  44100,  48000,  88200,  96000, 176400, 192000,
 413};
 414
 415static const struct snd_pcm_hw_constraint_list sun8i_codec_all_rates = {
 416	.list	= sun8i_codec_rates,
 417	.count	= ARRAY_SIZE(sun8i_codec_rates),
 418};
 419
 420static const struct snd_pcm_hw_constraint_list sun8i_codec_22M_rates = {
 421	.list	= sun8i_codec_rates,
 422	.count	= ARRAY_SIZE(sun8i_codec_rates),
 423	.mask	= 0x5555,
 424};
 425
 426static const struct snd_pcm_hw_constraint_list sun8i_codec_24M_rates = {
 427	.list	= sun8i_codec_rates,
 428	.count	= ARRAY_SIZE(sun8i_codec_rates),
 429	.mask	= 0xaaaa,
 430};
 431
 432static int sun8i_codec_startup(struct snd_pcm_substream *substream,
 433			       struct snd_soc_dai *dai)
 434{
 435	struct sun8i_codec *scodec = snd_soc_dai_get_drvdata(dai);
 436	const struct snd_pcm_hw_constraint_list *list;
 437
 438	/* hw_constraints is not relevant for codec2codec DAIs. */
 439	if (dai->id != SUN8I_CODEC_AIF1)
 440		return 0;
 441
 442	if (!scodec->sysclk_refcnt)
 443		list = &sun8i_codec_all_rates;
 444	else if (scodec->sysclk_rate == 22579200)
 445		list = &sun8i_codec_22M_rates;
 446	else if (scodec->sysclk_rate == 24576000)
 447		list = &sun8i_codec_24M_rates;
 448	else
 449		return -EINVAL;
 450
 451	return snd_pcm_hw_constraint_list(substream->runtime, 0,
 452					  SNDRV_PCM_HW_PARAM_RATE, list);
 453}
 454
 455struct sun8i_codec_clk_div {
 456	u8	div;
 457	u8	val;
 458};
 459
 460static const struct sun8i_codec_clk_div sun8i_codec_bclk_div[] = {
 461	{ .div = 1,	.val = 0 },
 462	{ .div = 2,	.val = 1 },
 463	{ .div = 4,	.val = 2 },
 464	{ .div = 6,	.val = 3 },
 465	{ .div = 8,	.val = 4 },
 466	{ .div = 12,	.val = 5 },
 467	{ .div = 16,	.val = 6 },
 468	{ .div = 24,	.val = 7 },
 469	{ .div = 32,	.val = 8 },
 470	{ .div = 48,	.val = 9 },
 471	{ .div = 64,	.val = 10 },
 472	{ .div = 96,	.val = 11 },
 473	{ .div = 128,	.val = 12 },
 474	{ .div = 192,	.val = 13 },
 475};
 476
 477static int sun8i_codec_get_bclk_div(unsigned int sysclk_rate,
 478				    unsigned int lrck_div_order,
 479				    unsigned int sample_rate)
 480{
 481	unsigned int div = sysclk_rate / sample_rate >> lrck_div_order;
 482	int i;
 483
 484	for (i = 0; i < ARRAY_SIZE(sun8i_codec_bclk_div); i++) {
 485		const struct sun8i_codec_clk_div *bdiv = &sun8i_codec_bclk_div[i];
 486
 487		if (bdiv->div == div)
 488			return bdiv->val;
 489	}
 490
 491	return -EINVAL;
 492}
 493
 494static int sun8i_codec_get_lrck_div_order(unsigned int slots,
 495					  unsigned int slot_width)
 496{
 497	unsigned int div = slots * slot_width;
 498
 499	if (div < 16 || div > 256)
 500		return -EINVAL;
 501
 502	return order_base_2(div);
 503}
 504
 505static unsigned int sun8i_codec_get_sysclk_rate(unsigned int sample_rate)
 506{
 507	return (sample_rate % 4000) ? 22579200 : 24576000;
 508}
 509
 510static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
 511				 struct snd_pcm_hw_params *params,
 512				 struct snd_soc_dai *dai)
 513{
 514	struct sun8i_codec *scodec = snd_soc_dai_get_drvdata(dai);
 515	struct sun8i_codec_aif *aif = &scodec->aifs[dai->id];
 516	unsigned int sample_rate = params_rate(params);
 517	unsigned int slots = aif->slots ?: params_channels(params);
 518	unsigned int slot_width = aif->slot_width ?: params_width(params);
 519	unsigned int sysclk_rate = sun8i_codec_get_sysclk_rate(sample_rate);
 520	int bclk_div, lrck_div_order, ret, word_size;
 521	u32 clk_reg;
 522
 523	/* word size */
 524	switch (params_width(params)) {
 525	case 8:
 526		word_size = 0x0;
 527		break;
 528	case 16:
 529		word_size = 0x1;
 530		break;
 531	case 20:
 532		word_size = 0x2;
 533		break;
 534	case 24:
 535		word_size = 0x3;
 536		break;
 537	default:
 538		return -EINVAL;
 539	}
 540
 541	regmap_update_bits(scodec->regmap, SUN8I_AIF_CLK_CTRL(dai->id),
 542			   SUN8I_AIF_CLK_CTRL_WORD_SIZ_MASK,
 543			   word_size << SUN8I_AIF_CLK_CTRL_WORD_SIZ);
 544
 545	/* LRCK divider (BCLK/LRCK ratio) */
 546	lrck_div_order = sun8i_codec_get_lrck_div_order(slots, slot_width);
 547	if (lrck_div_order < 0)
 548		return lrck_div_order;
 549
 550	if (dai->id == SUN8I_CODEC_AIF2 || dai->id == SUN8I_CODEC_AIF3) {
 551		/* AIF2 and AIF3 share AIF2's BCLK and LRCK generation circuitry. */
 552		int partner = (SUN8I_CODEC_AIF2 + SUN8I_CODEC_AIF3) - dai->id;
 553		const struct sun8i_codec_aif *partner_aif = &scodec->aifs[partner];
 554		const char *partner_name = sun8i_codec_dais[partner].name;
 555
 556		if (partner_aif->open_streams &&
 557		    (lrck_div_order != partner_aif->lrck_div_order ||
 558		     sample_rate != partner_aif->sample_rate)) {
 559			dev_err(dai->dev,
 560				"%s sample and bit rates must match %s when both are used\n",
 561				dai->name, partner_name);
 562			return -EBUSY;
 563		}
 564
 565		clk_reg = SUN8I_AIF_CLK_CTRL(SUN8I_CODEC_AIF2);
 566	} else {
 567		clk_reg = SUN8I_AIF_CLK_CTRL(dai->id);
 568	}
 569
 570	regmap_update_bits(scodec->regmap, clk_reg,
 571			   SUN8I_AIF_CLK_CTRL_LRCK_DIV_MASK,
 572			   (lrck_div_order - 4) << SUN8I_AIF_CLK_CTRL_LRCK_DIV);
 573
 574	/* BCLK divider (SYSCLK/BCLK ratio) */
 575	bclk_div = sun8i_codec_get_bclk_div(sysclk_rate, lrck_div_order, sample_rate);
 576	if (bclk_div < 0)
 577		return bclk_div;
 578
 579	regmap_update_bits(scodec->regmap, clk_reg,
 580			   SUN8I_AIF_CLK_CTRL_BCLK_DIV_MASK,
 581			   bclk_div << SUN8I_AIF_CLK_CTRL_BCLK_DIV);
 582
 583	/*
 584	 * SYSCLK rate
 585	 *
 586	 * Clock rate protection is reference counted; but hw_params may be
 587	 * called many times per substream, without matching calls to hw_free.
 588	 * Protect the clock rate once per AIF, on the first hw_params call
 589	 * for the first substream. clk_set_rate() will allow clock rate
 590	 * changes on subsequent calls if only one AIF has open streams.
 591	 */
 592	ret = (aif->open_streams ? clk_set_rate : clk_set_rate_exclusive)(scodec->clk_module,
 593									  sysclk_rate);
 594	if (ret == -EBUSY)
 595		dev_err(dai->dev,
 596			"%s sample rate (%u Hz) conflicts with other audio streams\n",
 597			dai->name, sample_rate);
 598	if (ret < 0)
 599		return ret;
 600
 601	if (!aif->open_streams)
 602		scodec->sysclk_refcnt++;
 603	scodec->sysclk_rate = sysclk_rate;
 604
 605	aif->lrck_div_order = lrck_div_order;
 606	aif->sample_rate = sample_rate;
 607	aif->open_streams |= BIT(substream->stream);
 608
 609	return sun8i_codec_update_sample_rate(scodec);
 610}
 611
 612static int sun8i_codec_hw_free(struct snd_pcm_substream *substream,
 613			       struct snd_soc_dai *dai)
 614{
 615	struct sun8i_codec *scodec = snd_soc_dai_get_drvdata(dai);
 616	struct sun8i_codec_aif *aif = &scodec->aifs[dai->id];
 617
 618	/* Drop references when the last substream for the AIF is freed. */
 619	if (aif->open_streams != BIT(substream->stream))
 620		goto done;
 621
 622	clk_rate_exclusive_put(scodec->clk_module);
 623	scodec->sysclk_refcnt--;
 624	aif->lrck_div_order = 0;
 625	aif->sample_rate = 0;
 626
 627done:
 628	aif->open_streams &= ~BIT(substream->stream);
 629	return 0;
 630}
 631
 632static const struct snd_soc_dai_ops sun8i_codec_dai_ops = {
 633	.set_fmt	= sun8i_codec_set_fmt,
 634	.set_tdm_slot	= sun8i_codec_set_tdm_slot,
 635	.startup	= sun8i_codec_startup,
 636	.hw_params	= sun8i_codec_hw_params,
 637	.hw_free	= sun8i_codec_hw_free,
 638};
 639
 640static struct snd_soc_dai_driver sun8i_codec_dais[] = {
 641	{
 642		.name	= "sun8i-codec-aif1",
 643		.id	= SUN8I_CODEC_AIF1,
 644		.ops	= &sun8i_codec_dai_ops,
 645		/* capture capabilities */
 646		.capture = {
 647			.stream_name	= "AIF1 Capture",
 648			.channels_min	= 1,
 649			.channels_max	= 2,
 650			.rates		= SUN8I_CODEC_PCM_RATES,
 651			.formats	= SUN8I_CODEC_PCM_FORMATS,
 652			.sig_bits	= 24,
 653		},
 654		/* playback capabilities */
 655		.playback = {
 656			.stream_name	= "AIF1 Playback",
 657			.channels_min	= 1,
 658			.channels_max	= 2,
 659			.rates		= SUN8I_CODEC_PCM_RATES,
 660			.formats	= SUN8I_CODEC_PCM_FORMATS,
 661		},
 662		.symmetric_rate		= true,
 663		.symmetric_channels	= true,
 664		.symmetric_sample_bits	= true,
 665	},
 666	{
 667		.name	= "sun8i-codec-aif2",
 668		.id	= SUN8I_CODEC_AIF2,
 669		.ops	= &sun8i_codec_dai_ops,
 670		/* capture capabilities */
 671		.capture = {
 672			.stream_name	= "AIF2 Capture",
 673			.channels_min	= 1,
 674			.channels_max	= 2,
 675			.rates		= SUN8I_CODEC_PCM_RATES,
 676			.formats	= SUN8I_CODEC_PCM_FORMATS,
 677			.sig_bits	= 24,
 678		},
 679		/* playback capabilities */
 680		.playback = {
 681			.stream_name	= "AIF2 Playback",
 682			.channels_min	= 1,
 683			.channels_max	= 2,
 684			.rates		= SUN8I_CODEC_PCM_RATES,
 685			.formats	= SUN8I_CODEC_PCM_FORMATS,
 686		},
 687		.symmetric_rate		= true,
 688		.symmetric_channels	= true,
 689		.symmetric_sample_bits	= true,
 690	},
 691	{
 692		.name	= "sun8i-codec-aif3",
 693		.id	= SUN8I_CODEC_AIF3,
 694		.ops	= &sun8i_codec_dai_ops,
 695		/* capture capabilities */
 696		.capture = {
 697			.stream_name	= "AIF3 Capture",
 698			.channels_min	= 1,
 699			.channels_max	= 1,
 700			.rates		= SUN8I_CODEC_PCM_RATES,
 701			.formats	= SUN8I_CODEC_PCM_FORMATS,
 702			.sig_bits	= 24,
 703		},
 704		/* playback capabilities */
 705		.playback = {
 706			.stream_name	= "AIF3 Playback",
 707			.channels_min	= 1,
 708			.channels_max	= 1,
 709			.rates		= SUN8I_CODEC_PCM_RATES,
 710			.formats	= SUN8I_CODEC_PCM_FORMATS,
 711		},
 712		.symmetric_rate		= true,
 713		.symmetric_channels	= true,
 714		.symmetric_sample_bits	= true,
 715	},
 716};
 717
 718static const DECLARE_TLV_DB_SCALE(sun8i_codec_vol_scale, -12000, 75, 1);
 719
 720static const struct snd_kcontrol_new sun8i_codec_controls[] = {
 721	SOC_DOUBLE_TLV("AIF1 AD0 Capture Volume",
 722		       SUN8I_AIF1_VOL_CTRL1,
 723		       SUN8I_AIF1_VOL_CTRL1_AD0L_VOL,
 724		       SUN8I_AIF1_VOL_CTRL1_AD0R_VOL,
 725		       0xc0, 0, sun8i_codec_vol_scale),
 726	SOC_DOUBLE_TLV("AIF1 DA0 Playback Volume",
 727		       SUN8I_AIF1_VOL_CTRL3,
 728		       SUN8I_AIF1_VOL_CTRL3_DA0L_VOL,
 729		       SUN8I_AIF1_VOL_CTRL3_DA0R_VOL,
 730		       0xc0, 0, sun8i_codec_vol_scale),
 731	SOC_DOUBLE_TLV("AIF2 ADC Capture Volume",
 732		       SUN8I_AIF2_VOL_CTRL1,
 733		       SUN8I_AIF2_VOL_CTRL1_ADCL_VOL,
 734		       SUN8I_AIF2_VOL_CTRL1_ADCR_VOL,
 735		       0xc0, 0, sun8i_codec_vol_scale),
 736	SOC_DOUBLE_TLV("AIF2 DAC Playback Volume",
 737		       SUN8I_AIF2_VOL_CTRL2,
 738		       SUN8I_AIF2_VOL_CTRL2_DACL_VOL,
 739		       SUN8I_AIF2_VOL_CTRL2_DACR_VOL,
 740		       0xc0, 0, sun8i_codec_vol_scale),
 741	SOC_DOUBLE_TLV("ADC Capture Volume",
 742		       SUN8I_ADC_VOL_CTRL,
 743		       SUN8I_ADC_VOL_CTRL_ADCL_VOL,
 744		       SUN8I_ADC_VOL_CTRL_ADCR_VOL,
 745		       0xc0, 0, sun8i_codec_vol_scale),
 746	SOC_DOUBLE_TLV("DAC Playback Volume",
 747		       SUN8I_DAC_VOL_CTRL,
 748		       SUN8I_DAC_VOL_CTRL_DACL_VOL,
 749		       SUN8I_DAC_VOL_CTRL_DACR_VOL,
 750		       0xc0, 0, sun8i_codec_vol_scale),
 751};
 752
 753static int sun8i_codec_aif_event(struct snd_soc_dapm_widget *w,
 754				 struct snd_kcontrol *kcontrol, int event)
 755{
 756	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 757	struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component);
 758	struct sun8i_codec_aif *aif = &scodec->aifs[w->sname[3] - '1'];
 759	int stream = w->id == snd_soc_dapm_aif_out;
 760
 761	if (SND_SOC_DAPM_EVENT_ON(event))
 762		aif->active_streams |= BIT(stream);
 763	else
 764		aif->active_streams &= ~BIT(stream);
 765
 766	return sun8i_codec_update_sample_rate(scodec);
 767}
 768
 769static const char *const sun8i_aif_stereo_mux_enum_values[] = {
 770	"Stereo", "Reverse Stereo", "Sum Mono", "Mix Mono"
 771};
 772
 773static SOC_ENUM_DOUBLE_DECL(sun8i_aif1_ad0_stereo_mux_enum,
 774			    SUN8I_AIF1_ADCDAT_CTRL,
 775			    SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0L_SRC,
 776			    SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0R_SRC,
 777			    sun8i_aif_stereo_mux_enum_values);
 778
 779static const struct snd_kcontrol_new sun8i_aif1_ad0_stereo_mux_control =
 780	SOC_DAPM_ENUM("AIF1 AD0 Stereo Capture Route",
 781		      sun8i_aif1_ad0_stereo_mux_enum);
 782
 783static SOC_ENUM_DOUBLE_DECL(sun8i_aif2_adc_stereo_mux_enum,
 784			    SUN8I_AIF2_ADCDAT_CTRL,
 785			    SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCL_SRC,
 786			    SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCR_SRC,
 787			    sun8i_aif_stereo_mux_enum_values);
 788
 789static const struct snd_kcontrol_new sun8i_aif2_adc_stereo_mux_control =
 790	SOC_DAPM_ENUM("AIF2 ADC Stereo Capture Route",
 791		      sun8i_aif2_adc_stereo_mux_enum);
 792
 793static const char *const sun8i_aif3_adc_mux_enum_values[] = {
 794	"None", "AIF2 ADCL", "AIF2 ADCR"
 795};
 796
 797static SOC_ENUM_SINGLE_DECL(sun8i_aif3_adc_mux_enum,
 798			    SUN8I_AIF3_PATH_CTRL,
 799			    SUN8I_AIF3_PATH_CTRL_AIF3_ADC_SRC,
 800			    sun8i_aif3_adc_mux_enum_values);
 801
 802static const struct snd_kcontrol_new sun8i_aif3_adc_mux_control =
 803	SOC_DAPM_ENUM("AIF3 ADC Source Capture Route",
 804		      sun8i_aif3_adc_mux_enum);
 805
 806static const struct snd_kcontrol_new sun8i_aif1_ad0_mixer_controls[] = {
 807	SOC_DAPM_DOUBLE("AIF1 Slot 0 Digital ADC Capture Switch",
 808			SUN8I_AIF1_MXR_SRC,
 809			SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF1DA0L,
 810			SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF1DA0R, 1, 0),
 811	SOC_DAPM_DOUBLE("AIF2 Digital ADC Capture Switch",
 812			SUN8I_AIF1_MXR_SRC,
 813			SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF2DACL,
 814			SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACR, 1, 0),
 815	SOC_DAPM_DOUBLE("AIF1 Data Digital ADC Capture Switch",
 816			SUN8I_AIF1_MXR_SRC,
 817			SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_ADCL,
 818			SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_ADCR, 1, 0),
 819	SOC_DAPM_DOUBLE("AIF2 Inv Digital ADC Capture Switch",
 820			SUN8I_AIF1_MXR_SRC,
 821			SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF2DACR,
 822			SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACL, 1, 0),
 823};
 824
 825static const struct snd_kcontrol_new sun8i_aif2_adc_mixer_controls[] = {
 826	SOC_DAPM_DOUBLE("AIF2 ADC Mixer AIF1 DA0 Capture Switch",
 827			SUN8I_AIF2_MXR_SRC,
 828			SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_AIF1DA0L,
 829			SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_AIF1DA0R, 1, 0),
 830	SOC_DAPM_DOUBLE("AIF2 ADC Mixer AIF1 DA1 Capture Switch",
 831			SUN8I_AIF2_MXR_SRC,
 832			SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_AIF1DA1L,
 833			SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_AIF1DA1R, 1, 0),
 834	SOC_DAPM_DOUBLE("AIF2 ADC Mixer AIF2 DAC Rev Capture Switch",
 835			SUN8I_AIF2_MXR_SRC,
 836			SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_AIF2DACR,
 837			SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_AIF2DACL, 1, 0),
 838	SOC_DAPM_DOUBLE("AIF2 ADC Mixer ADC Capture Switch",
 839			SUN8I_AIF2_MXR_SRC,
 840			SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_ADCL,
 841			SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_ADCR, 1, 0),
 842};
 843
 844static const char *const sun8i_aif2_dac_mux_enum_values[] = {
 845	"AIF2", "AIF3+2", "AIF2+3"
 846};
 847
 848static SOC_ENUM_SINGLE_DECL(sun8i_aif2_dac_mux_enum,
 849			    SUN8I_AIF3_PATH_CTRL,
 850			    SUN8I_AIF3_PATH_CTRL_AIF2_DAC_SRC,
 851			    sun8i_aif2_dac_mux_enum_values);
 852
 853static const struct snd_kcontrol_new sun8i_aif2_dac_mux_control =
 854	SOC_DAPM_ENUM("AIF2 DAC Source Playback Route",
 855		      sun8i_aif2_dac_mux_enum);
 856
 857static SOC_ENUM_DOUBLE_DECL(sun8i_aif1_da0_stereo_mux_enum,
 858			    SUN8I_AIF1_DACDAT_CTRL,
 859			    SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_SRC,
 860			    SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_SRC,
 861			    sun8i_aif_stereo_mux_enum_values);
 862
 863static const struct snd_kcontrol_new sun8i_aif1_da0_stereo_mux_control =
 864	SOC_DAPM_ENUM("AIF1 DA0 Stereo Playback Route",
 865		      sun8i_aif1_da0_stereo_mux_enum);
 866
 867static SOC_ENUM_DOUBLE_DECL(sun8i_aif2_dac_stereo_mux_enum,
 868			    SUN8I_AIF2_DACDAT_CTRL,
 869			    SUN8I_AIF2_DACDAT_CTRL_AIF2_DACL_SRC,
 870			    SUN8I_AIF2_DACDAT_CTRL_AIF2_DACR_SRC,
 871			    sun8i_aif_stereo_mux_enum_values);
 872
 873static const struct snd_kcontrol_new sun8i_aif2_dac_stereo_mux_control =
 874	SOC_DAPM_ENUM("AIF2 DAC Stereo Playback Route",
 875		      sun8i_aif2_dac_stereo_mux_enum);
 876
 877static const struct snd_kcontrol_new sun8i_dac_mixer_controls[] = {
 878	SOC_DAPM_DOUBLE("AIF1 Slot 0 Digital DAC Playback Switch",
 879			SUN8I_DAC_MXR_SRC,
 880			SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L,
 881			SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R, 1, 0),
 882	SOC_DAPM_DOUBLE("AIF1 Slot 1 Digital DAC Playback Switch",
 883			SUN8I_DAC_MXR_SRC,
 884			SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L,
 885			SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R, 1, 0),
 886	SOC_DAPM_DOUBLE("AIF2 Digital DAC Playback Switch", SUN8I_DAC_MXR_SRC,
 887			SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL,
 888			SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR, 1, 0),
 889	SOC_DAPM_DOUBLE("ADC Digital DAC Playback Switch", SUN8I_DAC_MXR_SRC,
 890			SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL,
 891			SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR, 1, 0),
 892};
 893
 894static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
 895	/* System Clocks */
 896	SND_SOC_DAPM_CLOCK_SUPPLY("mod"),
 897
 898	SND_SOC_DAPM_SUPPLY("AIF1CLK",
 899			    SUN8I_SYSCLK_CTL,
 900			    SUN8I_SYSCLK_CTL_AIF1CLK_ENA, 0, NULL, 0),
 901	SND_SOC_DAPM_SUPPLY("AIF2CLK",
 902			    SUN8I_SYSCLK_CTL,
 903			    SUN8I_SYSCLK_CTL_AIF2CLK_ENA, 0, NULL, 0),
 904	SND_SOC_DAPM_SUPPLY("SYSCLK",
 905			    SUN8I_SYSCLK_CTL,
 906			    SUN8I_SYSCLK_CTL_SYSCLK_ENA, 0, NULL, 0),
 907
 908	/* Module Clocks */
 909	SND_SOC_DAPM_SUPPLY("CLK AIF1",
 910			    SUN8I_MOD_CLK_ENA,
 911			    SUN8I_MOD_CLK_ENA_AIF1, 0, NULL, 0),
 912	SND_SOC_DAPM_SUPPLY("CLK AIF2",
 913			    SUN8I_MOD_CLK_ENA,
 914			    SUN8I_MOD_CLK_ENA_AIF2, 0, NULL, 0),
 915	SND_SOC_DAPM_SUPPLY("CLK AIF3",
 916			    SUN8I_MOD_CLK_ENA,
 917			    SUN8I_MOD_CLK_ENA_AIF3, 0, NULL, 0),
 918	SND_SOC_DAPM_SUPPLY("CLK ADC",
 919			    SUN8I_MOD_CLK_ENA,
 920			    SUN8I_MOD_CLK_ENA_ADC, 0, NULL, 0),
 921	SND_SOC_DAPM_SUPPLY("CLK DAC",
 922			    SUN8I_MOD_CLK_ENA,
 923			    SUN8I_MOD_CLK_ENA_DAC, 0, NULL, 0),
 924
 925	/* Module Resets */
 926	SND_SOC_DAPM_SUPPLY("RST AIF1",
 927			    SUN8I_MOD_RST_CTL,
 928			    SUN8I_MOD_RST_CTL_AIF1, 0, NULL, 0),
 929	SND_SOC_DAPM_SUPPLY("RST AIF2",
 930			    SUN8I_MOD_RST_CTL,
 931			    SUN8I_MOD_RST_CTL_AIF2, 0, NULL, 0),
 932	SND_SOC_DAPM_SUPPLY("RST AIF3",
 933			    SUN8I_MOD_RST_CTL,
 934			    SUN8I_MOD_RST_CTL_AIF3, 0, NULL, 0),
 935	SND_SOC_DAPM_SUPPLY("RST ADC",
 936			    SUN8I_MOD_RST_CTL,
 937			    SUN8I_MOD_RST_CTL_ADC, 0, NULL, 0),
 938	SND_SOC_DAPM_SUPPLY("RST DAC",
 939			    SUN8I_MOD_RST_CTL,
 940			    SUN8I_MOD_RST_CTL_DAC, 0, NULL, 0),
 941
 942	/* Module Supplies */
 943	SND_SOC_DAPM_SUPPLY("ADC",
 944			    SUN8I_ADC_DIG_CTRL,
 945			    SUN8I_ADC_DIG_CTRL_ENAD, 0, NULL, 0),
 946	SND_SOC_DAPM_SUPPLY("DAC",
 947			    SUN8I_DAC_DIG_CTRL,
 948			    SUN8I_DAC_DIG_CTRL_ENDA, 0, NULL, 0),
 949
 950	/* AIF "ADC" Outputs */
 951	SND_SOC_DAPM_AIF_OUT_E("AIF1 AD0L", "AIF1 Capture", 0,
 952			       SUN8I_AIF1_ADCDAT_CTRL,
 953			       SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0L_ENA, 0,
 954			       sun8i_codec_aif_event,
 955			       SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 956	SND_SOC_DAPM_AIF_OUT("AIF1 AD0R", "AIF1 Capture", 1,
 957			     SUN8I_AIF1_ADCDAT_CTRL,
 958			     SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0R_ENA, 0),
 959
 960	SND_SOC_DAPM_AIF_OUT_E("AIF2 ADCL", "AIF2 Capture", 0,
 961			       SUN8I_AIF2_ADCDAT_CTRL,
 962			       SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCL_ENA, 0,
 963			       sun8i_codec_aif_event,
 964			       SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 965	SND_SOC_DAPM_AIF_OUT("AIF2 ADCR", "AIF2 Capture", 1,
 966			     SUN8I_AIF2_ADCDAT_CTRL,
 967			     SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCR_ENA, 0),
 968
 969	SND_SOC_DAPM_AIF_OUT_E("AIF3 ADC", "AIF3 Capture", 0,
 970			       SND_SOC_NOPM, 0, 0,
 971			       sun8i_codec_aif_event,
 972			       SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 973
 974	/* AIF "ADC" Mono/Stereo Muxes */
 975	SND_SOC_DAPM_MUX("AIF1 AD0L Stereo Mux", SND_SOC_NOPM, 0, 0,
 976			 &sun8i_aif1_ad0_stereo_mux_control),
 977	SND_SOC_DAPM_MUX("AIF1 AD0R Stereo Mux", SND_SOC_NOPM, 0, 0,
 978			 &sun8i_aif1_ad0_stereo_mux_control),
 979
 980	SND_SOC_DAPM_MUX("AIF2 ADCL Stereo Mux", SND_SOC_NOPM, 0, 0,
 981			 &sun8i_aif2_adc_stereo_mux_control),
 982	SND_SOC_DAPM_MUX("AIF2 ADCR Stereo Mux", SND_SOC_NOPM, 0, 0,
 983			 &sun8i_aif2_adc_stereo_mux_control),
 984
 985	/* AIF "ADC" Output Muxes */
 986	SND_SOC_DAPM_MUX("AIF3 ADC Source Capture Route", SND_SOC_NOPM, 0, 0,
 987			 &sun8i_aif3_adc_mux_control),
 988
 989	/* AIF "ADC" Mixers */
 990	SOC_MIXER_ARRAY("AIF1 AD0L Mixer", SND_SOC_NOPM, 0, 0,
 991			sun8i_aif1_ad0_mixer_controls),
 992	SOC_MIXER_ARRAY("AIF1 AD0R Mixer", SND_SOC_NOPM, 0, 0,
 993			sun8i_aif1_ad0_mixer_controls),
 994
 995	SOC_MIXER_ARRAY("AIF2 ADCL Mixer", SND_SOC_NOPM, 0, 0,
 996			sun8i_aif2_adc_mixer_controls),
 997	SOC_MIXER_ARRAY("AIF2 ADCR Mixer", SND_SOC_NOPM, 0, 0,
 998			sun8i_aif2_adc_mixer_controls),
 999
1000	/* AIF "DAC" Input Muxes */
1001	SND_SOC_DAPM_MUX("AIF2 DACL Source", SND_SOC_NOPM, 0, 0,
1002			 &sun8i_aif2_dac_mux_control),
1003	SND_SOC_DAPM_MUX("AIF2 DACR Source", SND_SOC_NOPM, 0, 0,
1004			 &sun8i_aif2_dac_mux_control),
1005
1006	/* AIF "DAC" Mono/Stereo Muxes */
1007	SND_SOC_DAPM_MUX("AIF1 DA0L Stereo Mux", SND_SOC_NOPM, 0, 0,
1008			 &sun8i_aif1_da0_stereo_mux_control),
1009	SND_SOC_DAPM_MUX("AIF1 DA0R Stereo Mux", SND_SOC_NOPM, 0, 0,
1010			 &sun8i_aif1_da0_stereo_mux_control),
1011
1012	SND_SOC_DAPM_MUX("AIF2 DACL Stereo Mux", SND_SOC_NOPM, 0, 0,
1013			 &sun8i_aif2_dac_stereo_mux_control),
1014	SND_SOC_DAPM_MUX("AIF2 DACR Stereo Mux", SND_SOC_NOPM, 0, 0,
1015			 &sun8i_aif2_dac_stereo_mux_control),
1016
1017	/* AIF "DAC" Inputs */
1018	SND_SOC_DAPM_AIF_IN_E("AIF1 DA0L", "AIF1 Playback", 0,
1019			      SUN8I_AIF1_DACDAT_CTRL,
1020			      SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA, 0,
1021			      sun8i_codec_aif_event,
1022			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1023	SND_SOC_DAPM_AIF_IN("AIF1 DA0R", "AIF1 Playback", 1,
1024			    SUN8I_AIF1_DACDAT_CTRL,
1025			    SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA, 0),
1026
1027	SND_SOC_DAPM_AIF_IN_E("AIF2 DACL", "AIF2 Playback", 0,
1028			      SUN8I_AIF2_DACDAT_CTRL,
1029			      SUN8I_AIF2_DACDAT_CTRL_AIF2_DACL_ENA, 0,
1030			      sun8i_codec_aif_event,
1031			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1032	SND_SOC_DAPM_AIF_IN("AIF2 DACR", "AIF2 Playback", 1,
1033			    SUN8I_AIF2_DACDAT_CTRL,
1034			    SUN8I_AIF2_DACDAT_CTRL_AIF2_DACR_ENA, 0),
1035
1036	SND_SOC_DAPM_AIF_IN_E("AIF3 DAC", "AIF3 Playback", 0,
1037			      SND_SOC_NOPM, 0, 0,
1038			      sun8i_codec_aif_event,
1039			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1040
1041	/* ADC Inputs (connected to analog codec DAPM context) */
1042	SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 0, 0),
1043	SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0),
1044
1045	/* DAC Outputs (connected to analog codec DAPM context) */
1046	SND_SOC_DAPM_DAC("DACL", NULL, SND_SOC_NOPM, 0, 0),
1047	SND_SOC_DAPM_DAC("DACR", NULL, SND_SOC_NOPM, 0, 0),
1048
1049	/* DAC Mixers */
1050	SOC_MIXER_ARRAY("DACL Mixer", SND_SOC_NOPM, 0, 0,
1051			sun8i_dac_mixer_controls),
1052	SOC_MIXER_ARRAY("DACR Mixer", SND_SOC_NOPM, 0, 0,
1053			sun8i_dac_mixer_controls),
1054};
1055
1056static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
1057	/* Clock Routes */
1058	{ "AIF1CLK", NULL, "mod" },
1059
1060	{ "SYSCLK", NULL, "AIF1CLK" },
1061
1062	{ "CLK AIF1", NULL, "AIF1CLK" },
1063	{ "CLK AIF1", NULL, "SYSCLK" },
1064	{ "RST AIF1", NULL, "CLK AIF1" },
1065	{ "AIF1 AD0L", NULL, "RST AIF1" },
1066	{ "AIF1 AD0R", NULL, "RST AIF1" },
1067	{ "AIF1 DA0L", NULL, "RST AIF1" },
1068	{ "AIF1 DA0R", NULL, "RST AIF1" },
1069
1070	{ "CLK AIF2", NULL, "AIF2CLK" },
1071	{ "CLK AIF2", NULL, "SYSCLK" },
1072	{ "RST AIF2", NULL, "CLK AIF2" },
1073	{ "AIF2 ADCL", NULL, "RST AIF2" },
1074	{ "AIF2 ADCR", NULL, "RST AIF2" },
1075	{ "AIF2 DACL", NULL, "RST AIF2" },
1076	{ "AIF2 DACR", NULL, "RST AIF2" },
1077
1078	{ "CLK AIF3", NULL, "AIF1CLK" },
1079	{ "CLK AIF3", NULL, "SYSCLK" },
1080	{ "RST AIF3", NULL, "CLK AIF3" },
1081	{ "AIF3 ADC", NULL, "RST AIF3" },
1082	{ "AIF3 DAC", NULL, "RST AIF3" },
1083
1084	{ "CLK ADC", NULL, "SYSCLK" },
1085	{ "RST ADC", NULL, "CLK ADC" },
1086	{ "ADC", NULL, "RST ADC" },
1087	{ "ADCL", NULL, "ADC" },
1088	{ "ADCR", NULL, "ADC" },
1089
1090	{ "CLK DAC", NULL, "SYSCLK" },
1091	{ "RST DAC", NULL, "CLK DAC" },
1092	{ "DAC", NULL, "RST DAC" },
1093	{ "DACL", NULL, "DAC" },
1094	{ "DACR", NULL, "DAC" },
1095
1096	/* AIF "ADC" Output Routes */
1097	{ "AIF1 AD0L", NULL, "AIF1 AD0L Stereo Mux" },
1098	{ "AIF1 AD0R", NULL, "AIF1 AD0R Stereo Mux" },
1099
1100	{ "AIF2 ADCL", NULL, "AIF2 ADCL Stereo Mux" },
1101	{ "AIF2 ADCR", NULL, "AIF2 ADCR Stereo Mux" },
1102
1103	{ "AIF3 ADC", NULL, "AIF3 ADC Source Capture Route" },
1104
1105	/* AIF "ADC" Mono/Stereo Mux Routes */
1106	{ "AIF1 AD0L Stereo Mux", "Stereo", "AIF1 AD0L Mixer" },
1107	{ "AIF1 AD0L Stereo Mux", "Reverse Stereo", "AIF1 AD0R Mixer" },
1108	{ "AIF1 AD0L Stereo Mux", "Sum Mono", "AIF1 AD0L Mixer" },
1109	{ "AIF1 AD0L Stereo Mux", "Sum Mono", "AIF1 AD0R Mixer" },
1110	{ "AIF1 AD0L Stereo Mux", "Mix Mono", "AIF1 AD0L Mixer" },
1111	{ "AIF1 AD0L Stereo Mux", "Mix Mono", "AIF1 AD0R Mixer" },
1112
1113	{ "AIF1 AD0R Stereo Mux", "Stereo", "AIF1 AD0R Mixer" },
1114	{ "AIF1 AD0R Stereo Mux", "Reverse Stereo", "AIF1 AD0L Mixer" },
1115	{ "AIF1 AD0R Stereo Mux", "Sum Mono", "AIF1 AD0L Mixer" },
1116	{ "AIF1 AD0R Stereo Mux", "Sum Mono", "AIF1 AD0R Mixer" },
1117	{ "AIF1 AD0R Stereo Mux", "Mix Mono", "AIF1 AD0L Mixer" },
1118	{ "AIF1 AD0R Stereo Mux", "Mix Mono", "AIF1 AD0R Mixer" },
1119
1120	{ "AIF2 ADCL Stereo Mux", "Stereo", "AIF2 ADCL Mixer" },
1121	{ "AIF2 ADCL Stereo Mux", "Reverse Stereo", "AIF2 ADCR Mixer" },
1122	{ "AIF2 ADCL Stereo Mux", "Sum Mono", "AIF2 ADCL Mixer" },
1123	{ "AIF2 ADCL Stereo Mux", "Sum Mono", "AIF2 ADCR Mixer" },
1124	{ "AIF2 ADCL Stereo Mux", "Mix Mono", "AIF2 ADCL Mixer" },
1125	{ "AIF2 ADCL Stereo Mux", "Mix Mono", "AIF2 ADCR Mixer" },
1126
1127	{ "AIF2 ADCR Stereo Mux", "Stereo", "AIF2 ADCR Mixer" },
1128	{ "AIF2 ADCR Stereo Mux", "Reverse Stereo", "AIF2 ADCL Mixer" },
1129	{ "AIF2 ADCR Stereo Mux", "Sum Mono", "AIF2 ADCL Mixer" },
1130	{ "AIF2 ADCR Stereo Mux", "Sum Mono", "AIF2 ADCR Mixer" },
1131	{ "AIF2 ADCR Stereo Mux", "Mix Mono", "AIF2 ADCL Mixer" },
1132	{ "AIF2 ADCR Stereo Mux", "Mix Mono", "AIF2 ADCR Mixer" },
1133
1134	/* AIF "ADC" Output Mux Routes */
1135	{ "AIF3 ADC Source Capture Route", "AIF2 ADCL", "AIF2 ADCL Mixer" },
1136	{ "AIF3 ADC Source Capture Route", "AIF2 ADCR", "AIF2 ADCR Mixer" },
1137
1138	/* AIF "ADC" Mixer Routes */
1139	{ "AIF1 AD0L Mixer", "AIF1 Slot 0 Digital ADC Capture Switch", "AIF1 DA0L Stereo Mux" },
1140	{ "AIF1 AD0L Mixer", "AIF2 Digital ADC Capture Switch", "AIF2 DACL Source" },
1141	{ "AIF1 AD0L Mixer", "AIF1 Data Digital ADC Capture Switch", "ADCL" },
1142	{ "AIF1 AD0L Mixer", "AIF2 Inv Digital ADC Capture Switch", "AIF2 DACR Source" },
1143
1144	{ "AIF1 AD0R Mixer", "AIF1 Slot 0 Digital ADC Capture Switch", "AIF1 DA0R Stereo Mux" },
1145	{ "AIF1 AD0R Mixer", "AIF2 Digital ADC Capture Switch", "AIF2 DACR Source" },
1146	{ "AIF1 AD0R Mixer", "AIF1 Data Digital ADC Capture Switch", "ADCR" },
1147	{ "AIF1 AD0R Mixer", "AIF2 Inv Digital ADC Capture Switch", "AIF2 DACL Source" },
1148
1149	{ "AIF2 ADCL Mixer", "AIF2 ADC Mixer AIF1 DA0 Capture Switch", "AIF1 DA0L Stereo Mux" },
1150	{ "AIF2 ADCL Mixer", "AIF2 ADC Mixer AIF2 DAC Rev Capture Switch", "AIF2 DACR Source" },
1151	{ "AIF2 ADCL Mixer", "AIF2 ADC Mixer ADC Capture Switch", "ADCL" },
1152
1153	{ "AIF2 ADCR Mixer", "AIF2 ADC Mixer AIF1 DA0 Capture Switch", "AIF1 DA0R Stereo Mux" },
1154	{ "AIF2 ADCR Mixer", "AIF2 ADC Mixer AIF2 DAC Rev Capture Switch", "AIF2 DACL Source" },
1155	{ "AIF2 ADCR Mixer", "AIF2 ADC Mixer ADC Capture Switch", "ADCR" },
1156
1157	/* AIF "DAC" Input Mux Routes */
1158	{ "AIF2 DACL Source", "AIF2", "AIF2 DACL Stereo Mux" },
1159	{ "AIF2 DACL Source", "AIF3+2", "AIF3 DAC" },
1160	{ "AIF2 DACL Source", "AIF2+3", "AIF2 DACL Stereo Mux" },
1161
1162	{ "AIF2 DACR Source", "AIF2", "AIF2 DACR Stereo Mux" },
1163	{ "AIF2 DACR Source", "AIF3+2", "AIF2 DACR Stereo Mux" },
1164	{ "AIF2 DACR Source", "AIF2+3", "AIF3 DAC" },
1165
1166	/* AIF "DAC" Mono/Stereo Mux Routes */
1167	{ "AIF1 DA0L Stereo Mux", "Stereo", "AIF1 DA0L" },
1168	{ "AIF1 DA0L Stereo Mux", "Reverse Stereo", "AIF1 DA0R" },
1169	{ "AIF1 DA0L Stereo Mux", "Sum Mono", "AIF1 DA0L" },
1170	{ "AIF1 DA0L Stereo Mux", "Sum Mono", "AIF1 DA0R" },
1171	{ "AIF1 DA0L Stereo Mux", "Mix Mono", "AIF1 DA0L" },
1172	{ "AIF1 DA0L Stereo Mux", "Mix Mono", "AIF1 DA0R" },
1173
1174	{ "AIF1 DA0R Stereo Mux", "Stereo", "AIF1 DA0R" },
1175	{ "AIF1 DA0R Stereo Mux", "Reverse Stereo", "AIF1 DA0L" },
1176	{ "AIF1 DA0R Stereo Mux", "Sum Mono", "AIF1 DA0L" },
1177	{ "AIF1 DA0R Stereo Mux", "Sum Mono", "AIF1 DA0R" },
1178	{ "AIF1 DA0R Stereo Mux", "Mix Mono", "AIF1 DA0L" },
1179	{ "AIF1 DA0R Stereo Mux", "Mix Mono", "AIF1 DA0R" },
1180
1181	{ "AIF2 DACL Stereo Mux", "Stereo", "AIF2 DACL" },
1182	{ "AIF2 DACL Stereo Mux", "Reverse Stereo", "AIF2 DACR" },
1183	{ "AIF2 DACL Stereo Mux", "Sum Mono", "AIF2 DACL" },
1184	{ "AIF2 DACL Stereo Mux", "Sum Mono", "AIF2 DACR" },
1185	{ "AIF2 DACL Stereo Mux", "Mix Mono", "AIF2 DACL" },
1186	{ "AIF2 DACL Stereo Mux", "Mix Mono", "AIF2 DACR" },
1187
1188	{ "AIF2 DACR Stereo Mux", "Stereo", "AIF2 DACR" },
1189	{ "AIF2 DACR Stereo Mux", "Reverse Stereo", "AIF2 DACL" },
1190	{ "AIF2 DACR Stereo Mux", "Sum Mono", "AIF2 DACL" },
1191	{ "AIF2 DACR Stereo Mux", "Sum Mono", "AIF2 DACR" },
1192	{ "AIF2 DACR Stereo Mux", "Mix Mono", "AIF2 DACL" },
1193	{ "AIF2 DACR Stereo Mux", "Mix Mono", "AIF2 DACR" },
1194
1195	/* DAC Output Routes */
1196	{ "DACL", NULL, "DACL Mixer" },
1197	{ "DACR", NULL, "DACR Mixer" },
1198
1199	/* DAC Mixer Routes */
1200	{ "DACL Mixer", "AIF1 Slot 0 Digital DAC Playback Switch", "AIF1 DA0L Stereo Mux" },
1201	{ "DACL Mixer", "AIF2 Digital DAC Playback Switch", "AIF2 DACL Source" },
1202	{ "DACL Mixer", "ADC Digital DAC Playback Switch", "ADCL" },
1203
1204	{ "DACR Mixer", "AIF1 Slot 0 Digital DAC Playback Switch", "AIF1 DA0R Stereo Mux" },
1205	{ "DACR Mixer", "AIF2 Digital DAC Playback Switch", "AIF2 DACR Source" },
1206	{ "DACR Mixer", "ADC Digital DAC Playback Switch", "ADCR" },
1207};
1208
1209static const struct snd_soc_dapm_widget sun8i_codec_legacy_widgets[] = {
1210	/* Legacy ADC Inputs (connected to analog codec DAPM context) */
1211	SND_SOC_DAPM_ADC("AIF1 Slot 0 Left ADC", NULL, SND_SOC_NOPM, 0, 0),
1212	SND_SOC_DAPM_ADC("AIF1 Slot 0 Right ADC", NULL, SND_SOC_NOPM, 0, 0),
1213
1214	/* Legacy DAC Outputs (connected to analog codec DAPM context) */
1215	SND_SOC_DAPM_DAC("AIF1 Slot 0 Left", NULL, SND_SOC_NOPM, 0, 0),
1216	SND_SOC_DAPM_DAC("AIF1 Slot 0 Right", NULL, SND_SOC_NOPM, 0, 0),
1217};
1218
1219static const struct snd_soc_dapm_route sun8i_codec_legacy_routes[] = {
1220	/* Legacy ADC Routes */
1221	{ "ADCL", NULL, "AIF1 Slot 0 Left ADC" },
1222	{ "ADCR", NULL, "AIF1 Slot 0 Right ADC" },
1223
1224	/* Legacy DAC Routes */
1225	{ "AIF1 Slot 0 Left", NULL, "DACL" },
1226	{ "AIF1 Slot 0 Right", NULL, "DACR" },
1227};
1228
1229static int sun8i_codec_component_probe(struct snd_soc_component *component)
1230{
1231	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
1232	struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component);
1233	int ret;
1234
1235	/* Add widgets for backward compatibility with old device trees. */
1236	if (scodec->quirks->legacy_widgets) {
1237		ret = snd_soc_dapm_new_controls(dapm, sun8i_codec_legacy_widgets,
1238						ARRAY_SIZE(sun8i_codec_legacy_widgets));
1239		if (ret)
1240			return ret;
1241
1242		ret = snd_soc_dapm_add_routes(dapm, sun8i_codec_legacy_routes,
1243					      ARRAY_SIZE(sun8i_codec_legacy_routes));
1244		if (ret)
1245			return ret;
1246	}
1247
1248	/*
1249	 * AIF1CLK and AIF2CLK share a pair of clock parents: PLL_AUDIO ("mod")
1250	 * and MCLK (from the CPU DAI connected to AIF1). MCLK's parent is also
1251	 * PLL_AUDIO, so using it adds no additional flexibility. Use PLL_AUDIO
1252	 * directly to simplify the clock tree.
1253	 */
1254	regmap_update_bits(scodec->regmap, SUN8I_SYSCLK_CTL,
1255			   SUN8I_SYSCLK_CTL_AIF1CLK_SRC_MASK |
1256			   SUN8I_SYSCLK_CTL_AIF2CLK_SRC_MASK,
1257			   SUN8I_SYSCLK_CTL_AIF1CLK_SRC_PLL |
1258			   SUN8I_SYSCLK_CTL_AIF2CLK_SRC_PLL);
1259
1260	/* Use AIF1CLK as the SYSCLK parent since AIF1 is used most often. */
1261	regmap_update_bits(scodec->regmap, SUN8I_SYSCLK_CTL,
1262			   BIT(SUN8I_SYSCLK_CTL_SYSCLK_SRC),
1263			   SUN8I_SYSCLK_CTL_SYSCLK_SRC_AIF1CLK);
1264
1265	/* Program the default sample rate. */
1266	sun8i_codec_update_sample_rate(scodec);
1267
1268	return 0;
1269}
1270
1271static const struct snd_soc_component_driver sun8i_soc_component = {
1272	.controls		= sun8i_codec_controls,
1273	.num_controls		= ARRAY_SIZE(sun8i_codec_controls),
1274	.dapm_widgets		= sun8i_codec_dapm_widgets,
1275	.num_dapm_widgets	= ARRAY_SIZE(sun8i_codec_dapm_widgets),
1276	.dapm_routes		= sun8i_codec_dapm_routes,
1277	.num_dapm_routes	= ARRAY_SIZE(sun8i_codec_dapm_routes),
1278	.probe			= sun8i_codec_component_probe,
1279	.idle_bias_on		= 1,
1280	.endianness		= 1,
 
1281};
1282
1283static const struct regmap_config sun8i_codec_regmap_config = {
1284	.reg_bits	= 32,
1285	.reg_stride	= 4,
1286	.val_bits	= 32,
1287	.max_register	= SUN8I_DAC_MXR_SRC,
1288
1289	.cache_type	= REGCACHE_FLAT,
1290};
1291
1292static int sun8i_codec_probe(struct platform_device *pdev)
1293{
1294	struct sun8i_codec *scodec;
1295	void __iomem *base;
1296	int ret;
1297
1298	scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL);
1299	if (!scodec)
1300		return -ENOMEM;
1301
1302	scodec->clk_module = devm_clk_get(&pdev->dev, "mod");
1303	if (IS_ERR(scodec->clk_module)) {
1304		dev_err(&pdev->dev, "Failed to get the module clock\n");
1305		return PTR_ERR(scodec->clk_module);
1306	}
1307
1308	base = devm_platform_ioremap_resource(pdev, 0);
1309	if (IS_ERR(base)) {
1310		dev_err(&pdev->dev, "Failed to map the registers\n");
1311		return PTR_ERR(base);
1312	}
1313
1314	scodec->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "bus", base,
1315						   &sun8i_codec_regmap_config);
1316	if (IS_ERR(scodec->regmap)) {
1317		dev_err(&pdev->dev, "Failed to create our regmap\n");
1318		return PTR_ERR(scodec->regmap);
1319	}
1320
1321	scodec->quirks = of_device_get_match_data(&pdev->dev);
1322
1323	platform_set_drvdata(pdev, scodec);
1324
1325	pm_runtime_enable(&pdev->dev);
1326	if (!pm_runtime_enabled(&pdev->dev)) {
1327		ret = sun8i_codec_runtime_resume(&pdev->dev);
1328		if (ret)
1329			goto err_pm_disable;
1330	}
1331
1332	ret = devm_snd_soc_register_component(&pdev->dev, &sun8i_soc_component,
1333					      sun8i_codec_dais,
1334					      ARRAY_SIZE(sun8i_codec_dais));
1335	if (ret) {
1336		dev_err(&pdev->dev, "Failed to register codec\n");
1337		goto err_suspend;
1338	}
1339
1340	return ret;
1341
1342err_suspend:
1343	if (!pm_runtime_status_suspended(&pdev->dev))
1344		sun8i_codec_runtime_suspend(&pdev->dev);
1345
1346err_pm_disable:
1347	pm_runtime_disable(&pdev->dev);
1348
1349	return ret;
1350}
1351
1352static int sun8i_codec_remove(struct platform_device *pdev)
1353{
1354	pm_runtime_disable(&pdev->dev);
1355	if (!pm_runtime_status_suspended(&pdev->dev))
1356		sun8i_codec_runtime_suspend(&pdev->dev);
1357
1358	return 0;
1359}
1360
1361static const struct sun8i_codec_quirks sun8i_a33_quirks = {
1362	.legacy_widgets	= true,
1363	.lrck_inversion	= true,
1364};
1365
1366static const struct sun8i_codec_quirks sun50i_a64_quirks = {
1367};
1368
1369static const struct of_device_id sun8i_codec_of_match[] = {
1370	{ .compatible = "allwinner,sun8i-a33-codec", .data = &sun8i_a33_quirks },
1371	{ .compatible = "allwinner,sun50i-a64-codec", .data = &sun50i_a64_quirks },
1372	{}
1373};
1374MODULE_DEVICE_TABLE(of, sun8i_codec_of_match);
1375
1376static const struct dev_pm_ops sun8i_codec_pm_ops = {
1377	SET_RUNTIME_PM_OPS(sun8i_codec_runtime_suspend,
1378			   sun8i_codec_runtime_resume, NULL)
1379};
1380
1381static struct platform_driver sun8i_codec_driver = {
1382	.driver = {
1383		.name = "sun8i-codec",
1384		.of_match_table = sun8i_codec_of_match,
1385		.pm = &sun8i_codec_pm_ops,
1386	},
1387	.probe = sun8i_codec_probe,
1388	.remove = sun8i_codec_remove,
1389};
1390module_platform_driver(sun8i_codec_driver);
1391
1392MODULE_DESCRIPTION("Allwinner A33 (sun8i) codec driver");
1393MODULE_AUTHOR("Mylène Josserand <mylene.josserand@free-electrons.com>");
1394MODULE_LICENSE("GPL");
1395MODULE_ALIAS("platform:sun8i-codec");
v5.14.15
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * This driver supports the digital controls for the internal codec
   4 * found in Allwinner's A33 SoCs.
   5 *
   6 * (C) Copyright 2010-2016
   7 * Reuuimlla Technology Co., Ltd. <www.reuuimllatech.com>
   8 * huangxin <huangxin@Reuuimllatech.com>
   9 * Mylène Josserand <mylene.josserand@free-electrons.com>
  10 */
  11
  12#include <linux/module.h>
  13#include <linux/delay.h>
  14#include <linux/clk.h>
  15#include <linux/io.h>
  16#include <linux/of_device.h>
  17#include <linux/pm_runtime.h>
  18#include <linux/regmap.h>
  19#include <linux/log2.h>
  20
  21#include <sound/pcm_params.h>
  22#include <sound/soc.h>
  23#include <sound/soc-dapm.h>
 
  24
  25#define SUN8I_SYSCLK_CTL				0x00c
  26#define SUN8I_SYSCLK_CTL_AIF1CLK_ENA			11
  27#define SUN8I_SYSCLK_CTL_AIF1CLK_SRC_PLL		(0x2 << 8)
  28#define SUN8I_SYSCLK_CTL_AIF2CLK_ENA			7
  29#define SUN8I_SYSCLK_CTL_AIF2CLK_SRC_PLL		(0x2 << 4)
  30#define SUN8I_SYSCLK_CTL_SYSCLK_ENA			3
  31#define SUN8I_SYSCLK_CTL_SYSCLK_SRC			0
  32#define SUN8I_SYSCLK_CTL_SYSCLK_SRC_AIF1CLK		(0x0 << 0)
  33#define SUN8I_SYSCLK_CTL_SYSCLK_SRC_AIF2CLK		(0x1 << 0)
  34#define SUN8I_MOD_CLK_ENA				0x010
  35#define SUN8I_MOD_CLK_ENA_AIF1				15
  36#define SUN8I_MOD_CLK_ENA_AIF2				14
  37#define SUN8I_MOD_CLK_ENA_AIF3				13
  38#define SUN8I_MOD_CLK_ENA_ADC				3
  39#define SUN8I_MOD_CLK_ENA_DAC				2
  40#define SUN8I_MOD_RST_CTL				0x014
  41#define SUN8I_MOD_RST_CTL_AIF1				15
  42#define SUN8I_MOD_RST_CTL_AIF2				14
  43#define SUN8I_MOD_RST_CTL_AIF3				13
  44#define SUN8I_MOD_RST_CTL_ADC				3
  45#define SUN8I_MOD_RST_CTL_DAC				2
  46#define SUN8I_SYS_SR_CTRL				0x018
  47#define SUN8I_SYS_SR_CTRL_AIF1_FS			12
  48#define SUN8I_SYS_SR_CTRL_AIF2_FS			8
  49#define SUN8I_AIF_CLK_CTRL(n)				(0x040 * (1 + (n)))
  50#define SUN8I_AIF_CLK_CTRL_MSTR_MOD			15
  51#define SUN8I_AIF_CLK_CTRL_CLK_INV			13
  52#define SUN8I_AIF_CLK_CTRL_BCLK_DIV			9
  53#define SUN8I_AIF_CLK_CTRL_LRCK_DIV			6
  54#define SUN8I_AIF_CLK_CTRL_WORD_SIZ			4
  55#define SUN8I_AIF_CLK_CTRL_DATA_FMT			2
  56#define SUN8I_AIF1_ADCDAT_CTRL				0x044
  57#define SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0L_ENA		15
  58#define SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0R_ENA		14
  59#define SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0L_SRC		10
  60#define SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0R_SRC		8
  61#define SUN8I_AIF1_DACDAT_CTRL				0x048
  62#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA		15
  63#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA		14
  64#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_SRC		10
  65#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_SRC		8
  66#define SUN8I_AIF1_MXR_SRC				0x04c
  67#define SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF1DA0L	15
  68#define SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF2DACL	14
  69#define SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_ADCL		13
  70#define SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF2DACR	12
  71#define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF1DA0R	11
  72#define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACR	10
  73#define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_ADCR		9
  74#define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACL	8
 
 
 
 
 
 
  75#define SUN8I_AIF2_ADCDAT_CTRL				0x084
  76#define SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCL_ENA		15
  77#define SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCR_ENA		14
  78#define SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCL_SRC		10
  79#define SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCR_SRC		8
  80#define SUN8I_AIF2_DACDAT_CTRL				0x088
  81#define SUN8I_AIF2_DACDAT_CTRL_AIF2_DACL_ENA		15
  82#define SUN8I_AIF2_DACDAT_CTRL_AIF2_DACR_ENA		14
  83#define SUN8I_AIF2_DACDAT_CTRL_AIF2_DACL_SRC		10
  84#define SUN8I_AIF2_DACDAT_CTRL_AIF2_DACR_SRC		8
  85#define SUN8I_AIF2_MXR_SRC				0x08c
  86#define SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_AIF1DA0L	15
  87#define SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_AIF1DA1L	14
  88#define SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_AIF2DACR	13
  89#define SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_ADCL		12
  90#define SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_AIF1DA0R	11
  91#define SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_AIF1DA1R	10
  92#define SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_AIF2DACL	9
  93#define SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_ADCR		8
 
 
 
 
 
 
  94#define SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_AIF1		(0x0 << 0)
  95#define SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_AIF2		(0x1 << 0)
  96#define SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_AIF1CLK	(0x2 << 0)
  97#define SUN8I_AIF3_PATH_CTRL				0x0cc
  98#define SUN8I_AIF3_PATH_CTRL_AIF3_ADC_SRC		10
  99#define SUN8I_AIF3_PATH_CTRL_AIF2_DAC_SRC		8
 100#define SUN8I_AIF3_PATH_CTRL_AIF3_PINS_TRI		7
 101#define SUN8I_ADC_DIG_CTRL				0x100
 102#define SUN8I_ADC_DIG_CTRL_ENAD				15
 103#define SUN8I_ADC_DIG_CTRL_ADOUT_DTS			2
 104#define SUN8I_ADC_DIG_CTRL_ADOUT_DLY			1
 
 
 
 105#define SUN8I_DAC_DIG_CTRL				0x120
 106#define SUN8I_DAC_DIG_CTRL_ENDA				15
 
 
 
 107#define SUN8I_DAC_MXR_SRC				0x130
 108#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L		15
 109#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L		14
 110#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL		13
 111#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL		12
 112#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R		11
 113#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R		10
 114#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR		9
 115#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR		8
 116
 117#define SUN8I_SYSCLK_CTL_AIF1CLK_SRC_MASK	GENMASK(9, 8)
 118#define SUN8I_SYSCLK_CTL_AIF2CLK_SRC_MASK	GENMASK(5, 4)
 119#define SUN8I_SYS_SR_CTRL_AIF1_FS_MASK		GENMASK(15, 12)
 120#define SUN8I_SYS_SR_CTRL_AIF2_FS_MASK		GENMASK(11, 8)
 121#define SUN8I_AIF_CLK_CTRL_CLK_INV_MASK		GENMASK(14, 13)
 122#define SUN8I_AIF_CLK_CTRL_BCLK_DIV_MASK	GENMASK(12, 9)
 123#define SUN8I_AIF_CLK_CTRL_LRCK_DIV_MASK	GENMASK(8, 6)
 124#define SUN8I_AIF_CLK_CTRL_WORD_SIZ_MASK	GENMASK(5, 4)
 125#define SUN8I_AIF_CLK_CTRL_DATA_FMT_MASK	GENMASK(3, 2)
 126#define SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_MASK	GENMASK(1, 0)
 127
 128#define SUN8I_CODEC_PASSTHROUGH_SAMPLE_RATE 48000
 129
 130#define SUN8I_CODEC_PCM_FORMATS	(SNDRV_PCM_FMTBIT_S8     |\
 131				 SNDRV_PCM_FMTBIT_S16_LE |\
 132				 SNDRV_PCM_FMTBIT_S20_LE |\
 133				 SNDRV_PCM_FMTBIT_S24_LE |\
 134				 SNDRV_PCM_FMTBIT_S20_3LE|\
 135				 SNDRV_PCM_FMTBIT_S24_3LE)
 136
 137#define SUN8I_CODEC_PCM_RATES	(SNDRV_PCM_RATE_8000_48000|\
 138				 SNDRV_PCM_RATE_88200     |\
 139				 SNDRV_PCM_RATE_96000     |\
 140				 SNDRV_PCM_RATE_176400    |\
 141				 SNDRV_PCM_RATE_192000    |\
 142				 SNDRV_PCM_RATE_KNOT)
 143
 144enum {
 145	SUN8I_CODEC_AIF1,
 146	SUN8I_CODEC_AIF2,
 147	SUN8I_CODEC_AIF3,
 148	SUN8I_CODEC_NAIFS
 149};
 150
 151struct sun8i_codec_aif {
 152	unsigned int	lrck_div_order;
 153	unsigned int	sample_rate;
 154	unsigned int	slots;
 155	unsigned int	slot_width;
 156	unsigned int	active_streams	: 2;
 157	unsigned int	open_streams	: 2;
 158};
 159
 160struct sun8i_codec_quirks {
 161	bool legacy_widgets	: 1;
 162	bool lrck_inversion	: 1;
 163};
 164
 165struct sun8i_codec {
 166	struct regmap			*regmap;
 167	struct clk			*clk_module;
 168	const struct sun8i_codec_quirks	*quirks;
 169	struct sun8i_codec_aif		aifs[SUN8I_CODEC_NAIFS];
 170	unsigned int			sysclk_rate;
 171	int				sysclk_refcnt;
 172};
 173
 174static struct snd_soc_dai_driver sun8i_codec_dais[];
 175
 176static int sun8i_codec_runtime_resume(struct device *dev)
 177{
 178	struct sun8i_codec *scodec = dev_get_drvdata(dev);
 179	int ret;
 180
 181	regcache_cache_only(scodec->regmap, false);
 182
 183	ret = regcache_sync(scodec->regmap);
 184	if (ret) {
 185		dev_err(dev, "Failed to sync regmap cache\n");
 186		return ret;
 187	}
 188
 189	return 0;
 190}
 191
 192static int sun8i_codec_runtime_suspend(struct device *dev)
 193{
 194	struct sun8i_codec *scodec = dev_get_drvdata(dev);
 195
 196	regcache_cache_only(scodec->regmap, true);
 197	regcache_mark_dirty(scodec->regmap);
 198
 199	return 0;
 200}
 201
 202static int sun8i_codec_get_hw_rate(unsigned int sample_rate)
 203{
 204	switch (sample_rate) {
 205	case 7350:
 206	case 8000:
 207		return 0x0;
 208	case 11025:
 209		return 0x1;
 210	case 12000:
 211		return 0x2;
 212	case 14700:
 213	case 16000:
 214		return 0x3;
 215	case 22050:
 216		return 0x4;
 217	case 24000:
 218		return 0x5;
 219	case 29400:
 220	case 32000:
 221		return 0x6;
 222	case 44100:
 223		return 0x7;
 224	case 48000:
 225		return 0x8;
 226	case 88200:
 227	case 96000:
 228		return 0x9;
 229	case 176400:
 230	case 192000:
 231		return 0xa;
 232	default:
 233		return -EINVAL;
 234	}
 235}
 236
 237static int sun8i_codec_update_sample_rate(struct sun8i_codec *scodec)
 238{
 239	unsigned int max_rate = 0;
 240	int hw_rate, i;
 241
 242	for (i = SUN8I_CODEC_AIF1; i < SUN8I_CODEC_NAIFS; ++i) {
 243		struct sun8i_codec_aif *aif = &scodec->aifs[i];
 244
 245		if (aif->active_streams)
 246			max_rate = max(max_rate, aif->sample_rate);
 247	}
 248
 249	/* Set the sample rate for ADC->DAC passthrough when no AIF is active. */
 250	if (!max_rate)
 251		max_rate = SUN8I_CODEC_PASSTHROUGH_SAMPLE_RATE;
 252
 253	hw_rate = sun8i_codec_get_hw_rate(max_rate);
 254	if (hw_rate < 0)
 255		return hw_rate;
 256
 257	regmap_update_bits(scodec->regmap, SUN8I_SYS_SR_CTRL,
 258			   SUN8I_SYS_SR_CTRL_AIF1_FS_MASK,
 259			   hw_rate << SUN8I_SYS_SR_CTRL_AIF1_FS);
 260
 261	return 0;
 262}
 263
 264static int sun8i_codec_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 265{
 266	struct sun8i_codec *scodec = snd_soc_dai_get_drvdata(dai);
 267	u32 dsp_format, format, invert, value;
 268
 269	/* clock masters */
 270	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 271	case SND_SOC_DAIFMT_CBS_CFS: /* Codec slave, DAI master */
 272		value = 0x1;
 273		break;
 274	case SND_SOC_DAIFMT_CBM_CFM: /* Codec Master, DAI slave */
 275		value = 0x0;
 276		break;
 277	default:
 278		return -EINVAL;
 279	}
 280
 281	if (dai->id == SUN8I_CODEC_AIF3) {
 282		/* AIF3 only supports master mode. */
 283		if (value)
 284			return -EINVAL;
 285
 286		/* Use the AIF2 BCLK and LRCK for AIF3. */
 287		regmap_update_bits(scodec->regmap, SUN8I_AIF_CLK_CTRL(dai->id),
 288				   SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_MASK,
 289				   SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_AIF2);
 290	} else {
 291		regmap_update_bits(scodec->regmap, SUN8I_AIF_CLK_CTRL(dai->id),
 292				   BIT(SUN8I_AIF_CLK_CTRL_MSTR_MOD),
 293				   value << SUN8I_AIF_CLK_CTRL_MSTR_MOD);
 294	}
 295
 296	/* DAI format */
 297	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 298	case SND_SOC_DAIFMT_I2S:
 299		format = 0x0;
 300		break;
 301	case SND_SOC_DAIFMT_LEFT_J:
 302		format = 0x1;
 303		break;
 304	case SND_SOC_DAIFMT_RIGHT_J:
 305		format = 0x2;
 306		break;
 307	case SND_SOC_DAIFMT_DSP_A:
 308		format = 0x3;
 309		dsp_format = 0x0; /* Set LRCK_INV to 0 */
 310		break;
 311	case SND_SOC_DAIFMT_DSP_B:
 312		format = 0x3;
 313		dsp_format = 0x1; /* Set LRCK_INV to 1 */
 314		break;
 315	default:
 316		return -EINVAL;
 317	}
 318
 319	if (dai->id == SUN8I_CODEC_AIF3) {
 320		/* AIF3 only supports DSP mode. */
 321		if (format != 3)
 322			return -EINVAL;
 323	} else {
 324		regmap_update_bits(scodec->regmap, SUN8I_AIF_CLK_CTRL(dai->id),
 325				   SUN8I_AIF_CLK_CTRL_DATA_FMT_MASK,
 326				   format << SUN8I_AIF_CLK_CTRL_DATA_FMT);
 327	}
 328
 329	/* clock inversion */
 330	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 331	case SND_SOC_DAIFMT_NB_NF: /* Normal */
 332		invert = 0x0;
 333		break;
 334	case SND_SOC_DAIFMT_NB_IF: /* Inverted LRCK */
 335		invert = 0x1;
 336		break;
 337	case SND_SOC_DAIFMT_IB_NF: /* Inverted BCLK */
 338		invert = 0x2;
 339		break;
 340	case SND_SOC_DAIFMT_IB_IF: /* Both inverted */
 341		invert = 0x3;
 342		break;
 343	default:
 344		return -EINVAL;
 345	}
 346
 347	if (format == 0x3) {
 348		/* Inverted LRCK is not available in DSP mode. */
 349		if (invert & BIT(0))
 350			return -EINVAL;
 351
 352		/* Instead, the bit selects between DSP A/B formats. */
 353		invert |= dsp_format;
 354	} else {
 355		/*
 356		 * It appears that the DAI and the codec in the A33 SoC don't
 357		 * share the same polarity for the LRCK signal when they mean
 358		 * 'normal' and 'inverted' in the datasheet.
 359		 *
 360		 * Since the DAI here is our regular i2s driver that have been
 361		 * tested with way more codecs than just this one, it means
 362		 * that the codec probably gets it backward, and we have to
 363		 * invert the value here.
 364		 */
 365		invert ^= scodec->quirks->lrck_inversion;
 366	}
 367
 368	regmap_update_bits(scodec->regmap, SUN8I_AIF_CLK_CTRL(dai->id),
 369			   SUN8I_AIF_CLK_CTRL_CLK_INV_MASK,
 370			   invert << SUN8I_AIF_CLK_CTRL_CLK_INV);
 371
 372	return 0;
 373}
 374
 375static int sun8i_codec_set_tdm_slot(struct snd_soc_dai *dai,
 376				    unsigned int tx_mask, unsigned int rx_mask,
 377				    int slots, int slot_width)
 378{
 379	struct sun8i_codec *scodec = snd_soc_dai_get_drvdata(dai);
 380	struct sun8i_codec_aif *aif = &scodec->aifs[dai->id];
 381
 382	if (slot_width && !is_power_of_2(slot_width))
 383		return -EINVAL;
 384
 385	aif->slots = slots;
 386	aif->slot_width = slot_width;
 387
 388	return 0;
 389}
 390
 391static const unsigned int sun8i_codec_rates[] = {
 392	  7350,   8000,  11025,  12000,  14700,  16000,  22050,  24000,
 393	 29400,  32000,  44100,  48000,  88200,  96000, 176400, 192000,
 394};
 395
 396static const struct snd_pcm_hw_constraint_list sun8i_codec_all_rates = {
 397	.list	= sun8i_codec_rates,
 398	.count	= ARRAY_SIZE(sun8i_codec_rates),
 399};
 400
 401static const struct snd_pcm_hw_constraint_list sun8i_codec_22M_rates = {
 402	.list	= sun8i_codec_rates,
 403	.count	= ARRAY_SIZE(sun8i_codec_rates),
 404	.mask	= 0x5555,
 405};
 406
 407static const struct snd_pcm_hw_constraint_list sun8i_codec_24M_rates = {
 408	.list	= sun8i_codec_rates,
 409	.count	= ARRAY_SIZE(sun8i_codec_rates),
 410	.mask	= 0xaaaa,
 411};
 412
 413static int sun8i_codec_startup(struct snd_pcm_substream *substream,
 414			       struct snd_soc_dai *dai)
 415{
 416	struct sun8i_codec *scodec = snd_soc_dai_get_drvdata(dai);
 417	const struct snd_pcm_hw_constraint_list *list;
 418
 419	/* hw_constraints is not relevant for codec2codec DAIs. */
 420	if (dai->id != SUN8I_CODEC_AIF1)
 421		return 0;
 422
 423	if (!scodec->sysclk_refcnt)
 424		list = &sun8i_codec_all_rates;
 425	else if (scodec->sysclk_rate == 22579200)
 426		list = &sun8i_codec_22M_rates;
 427	else if (scodec->sysclk_rate == 24576000)
 428		list = &sun8i_codec_24M_rates;
 429	else
 430		return -EINVAL;
 431
 432	return snd_pcm_hw_constraint_list(substream->runtime, 0,
 433					  SNDRV_PCM_HW_PARAM_RATE, list);
 434}
 435
 436struct sun8i_codec_clk_div {
 437	u8	div;
 438	u8	val;
 439};
 440
 441static const struct sun8i_codec_clk_div sun8i_codec_bclk_div[] = {
 442	{ .div = 1,	.val = 0 },
 443	{ .div = 2,	.val = 1 },
 444	{ .div = 4,	.val = 2 },
 445	{ .div = 6,	.val = 3 },
 446	{ .div = 8,	.val = 4 },
 447	{ .div = 12,	.val = 5 },
 448	{ .div = 16,	.val = 6 },
 449	{ .div = 24,	.val = 7 },
 450	{ .div = 32,	.val = 8 },
 451	{ .div = 48,	.val = 9 },
 452	{ .div = 64,	.val = 10 },
 453	{ .div = 96,	.val = 11 },
 454	{ .div = 128,	.val = 12 },
 455	{ .div = 192,	.val = 13 },
 456};
 457
 458static int sun8i_codec_get_bclk_div(unsigned int sysclk_rate,
 459				    unsigned int lrck_div_order,
 460				    unsigned int sample_rate)
 461{
 462	unsigned int div = sysclk_rate / sample_rate >> lrck_div_order;
 463	int i;
 464
 465	for (i = 0; i < ARRAY_SIZE(sun8i_codec_bclk_div); i++) {
 466		const struct sun8i_codec_clk_div *bdiv = &sun8i_codec_bclk_div[i];
 467
 468		if (bdiv->div == div)
 469			return bdiv->val;
 470	}
 471
 472	return -EINVAL;
 473}
 474
 475static int sun8i_codec_get_lrck_div_order(unsigned int slots,
 476					  unsigned int slot_width)
 477{
 478	unsigned int div = slots * slot_width;
 479
 480	if (div < 16 || div > 256)
 481		return -EINVAL;
 482
 483	return order_base_2(div);
 484}
 485
 486static unsigned int sun8i_codec_get_sysclk_rate(unsigned int sample_rate)
 487{
 488	return (sample_rate % 4000) ? 22579200 : 24576000;
 489}
 490
 491static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
 492				 struct snd_pcm_hw_params *params,
 493				 struct snd_soc_dai *dai)
 494{
 495	struct sun8i_codec *scodec = snd_soc_dai_get_drvdata(dai);
 496	struct sun8i_codec_aif *aif = &scodec->aifs[dai->id];
 497	unsigned int sample_rate = params_rate(params);
 498	unsigned int slots = aif->slots ?: params_channels(params);
 499	unsigned int slot_width = aif->slot_width ?: params_width(params);
 500	unsigned int sysclk_rate = sun8i_codec_get_sysclk_rate(sample_rate);
 501	int bclk_div, lrck_div_order, ret, word_size;
 502	u32 clk_reg;
 503
 504	/* word size */
 505	switch (params_width(params)) {
 506	case 8:
 507		word_size = 0x0;
 508		break;
 509	case 16:
 510		word_size = 0x1;
 511		break;
 512	case 20:
 513		word_size = 0x2;
 514		break;
 515	case 24:
 516		word_size = 0x3;
 517		break;
 518	default:
 519		return -EINVAL;
 520	}
 521
 522	regmap_update_bits(scodec->regmap, SUN8I_AIF_CLK_CTRL(dai->id),
 523			   SUN8I_AIF_CLK_CTRL_WORD_SIZ_MASK,
 524			   word_size << SUN8I_AIF_CLK_CTRL_WORD_SIZ);
 525
 526	/* LRCK divider (BCLK/LRCK ratio) */
 527	lrck_div_order = sun8i_codec_get_lrck_div_order(slots, slot_width);
 528	if (lrck_div_order < 0)
 529		return lrck_div_order;
 530
 531	if (dai->id == SUN8I_CODEC_AIF2 || dai->id == SUN8I_CODEC_AIF3) {
 532		/* AIF2 and AIF3 share AIF2's BCLK and LRCK generation circuitry. */
 533		int partner = (SUN8I_CODEC_AIF2 + SUN8I_CODEC_AIF3) - dai->id;
 534		const struct sun8i_codec_aif *partner_aif = &scodec->aifs[partner];
 535		const char *partner_name = sun8i_codec_dais[partner].name;
 536
 537		if (partner_aif->open_streams &&
 538		    (lrck_div_order != partner_aif->lrck_div_order ||
 539		     sample_rate != partner_aif->sample_rate)) {
 540			dev_err(dai->dev,
 541				"%s sample and bit rates must match %s when both are used\n",
 542				dai->name, partner_name);
 543			return -EBUSY;
 544		}
 545
 546		clk_reg = SUN8I_AIF_CLK_CTRL(SUN8I_CODEC_AIF2);
 547	} else {
 548		clk_reg = SUN8I_AIF_CLK_CTRL(dai->id);
 549	}
 550
 551	regmap_update_bits(scodec->regmap, clk_reg,
 552			   SUN8I_AIF_CLK_CTRL_LRCK_DIV_MASK,
 553			   (lrck_div_order - 4) << SUN8I_AIF_CLK_CTRL_LRCK_DIV);
 554
 555	/* BCLK divider (SYSCLK/BCLK ratio) */
 556	bclk_div = sun8i_codec_get_bclk_div(sysclk_rate, lrck_div_order, sample_rate);
 557	if (bclk_div < 0)
 558		return bclk_div;
 559
 560	regmap_update_bits(scodec->regmap, clk_reg,
 561			   SUN8I_AIF_CLK_CTRL_BCLK_DIV_MASK,
 562			   bclk_div << SUN8I_AIF_CLK_CTRL_BCLK_DIV);
 563
 564	/*
 565	 * SYSCLK rate
 566	 *
 567	 * Clock rate protection is reference counted; but hw_params may be
 568	 * called many times per substream, without matching calls to hw_free.
 569	 * Protect the clock rate once per AIF, on the first hw_params call
 570	 * for the first substream. clk_set_rate() will allow clock rate
 571	 * changes on subsequent calls if only one AIF has open streams.
 572	 */
 573	ret = (aif->open_streams ? clk_set_rate : clk_set_rate_exclusive)(scodec->clk_module,
 574									  sysclk_rate);
 575	if (ret == -EBUSY)
 576		dev_err(dai->dev,
 577			"%s sample rate (%u Hz) conflicts with other audio streams\n",
 578			dai->name, sample_rate);
 579	if (ret < 0)
 580		return ret;
 581
 582	if (!aif->open_streams)
 583		scodec->sysclk_refcnt++;
 584	scodec->sysclk_rate = sysclk_rate;
 585
 586	aif->lrck_div_order = lrck_div_order;
 587	aif->sample_rate = sample_rate;
 588	aif->open_streams |= BIT(substream->stream);
 589
 590	return sun8i_codec_update_sample_rate(scodec);
 591}
 592
 593static int sun8i_codec_hw_free(struct snd_pcm_substream *substream,
 594			       struct snd_soc_dai *dai)
 595{
 596	struct sun8i_codec *scodec = snd_soc_dai_get_drvdata(dai);
 597	struct sun8i_codec_aif *aif = &scodec->aifs[dai->id];
 598
 599	/* Drop references when the last substream for the AIF is freed. */
 600	if (aif->open_streams != BIT(substream->stream))
 601		goto done;
 602
 603	clk_rate_exclusive_put(scodec->clk_module);
 604	scodec->sysclk_refcnt--;
 605	aif->lrck_div_order = 0;
 606	aif->sample_rate = 0;
 607
 608done:
 609	aif->open_streams &= ~BIT(substream->stream);
 610	return 0;
 611}
 612
 613static const struct snd_soc_dai_ops sun8i_codec_dai_ops = {
 614	.set_fmt	= sun8i_codec_set_fmt,
 615	.set_tdm_slot	= sun8i_codec_set_tdm_slot,
 616	.startup	= sun8i_codec_startup,
 617	.hw_params	= sun8i_codec_hw_params,
 618	.hw_free	= sun8i_codec_hw_free,
 619};
 620
 621static struct snd_soc_dai_driver sun8i_codec_dais[] = {
 622	{
 623		.name	= "sun8i-codec-aif1",
 624		.id	= SUN8I_CODEC_AIF1,
 625		.ops	= &sun8i_codec_dai_ops,
 626		/* capture capabilities */
 627		.capture = {
 628			.stream_name	= "AIF1 Capture",
 629			.channels_min	= 1,
 630			.channels_max	= 2,
 631			.rates		= SUN8I_CODEC_PCM_RATES,
 632			.formats	= SUN8I_CODEC_PCM_FORMATS,
 633			.sig_bits	= 24,
 634		},
 635		/* playback capabilities */
 636		.playback = {
 637			.stream_name	= "AIF1 Playback",
 638			.channels_min	= 1,
 639			.channels_max	= 2,
 640			.rates		= SUN8I_CODEC_PCM_RATES,
 641			.formats	= SUN8I_CODEC_PCM_FORMATS,
 642		},
 643		.symmetric_rate		= true,
 644		.symmetric_channels	= true,
 645		.symmetric_sample_bits	= true,
 646	},
 647	{
 648		.name	= "sun8i-codec-aif2",
 649		.id	= SUN8I_CODEC_AIF2,
 650		.ops	= &sun8i_codec_dai_ops,
 651		/* capture capabilities */
 652		.capture = {
 653			.stream_name	= "AIF2 Capture",
 654			.channels_min	= 1,
 655			.channels_max	= 2,
 656			.rates		= SUN8I_CODEC_PCM_RATES,
 657			.formats	= SUN8I_CODEC_PCM_FORMATS,
 658			.sig_bits	= 24,
 659		},
 660		/* playback capabilities */
 661		.playback = {
 662			.stream_name	= "AIF2 Playback",
 663			.channels_min	= 1,
 664			.channels_max	= 2,
 665			.rates		= SUN8I_CODEC_PCM_RATES,
 666			.formats	= SUN8I_CODEC_PCM_FORMATS,
 667		},
 668		.symmetric_rate		= true,
 669		.symmetric_channels	= true,
 670		.symmetric_sample_bits	= true,
 671	},
 672	{
 673		.name	= "sun8i-codec-aif3",
 674		.id	= SUN8I_CODEC_AIF3,
 675		.ops	= &sun8i_codec_dai_ops,
 676		/* capture capabilities */
 677		.capture = {
 678			.stream_name	= "AIF3 Capture",
 679			.channels_min	= 1,
 680			.channels_max	= 1,
 681			.rates		= SUN8I_CODEC_PCM_RATES,
 682			.formats	= SUN8I_CODEC_PCM_FORMATS,
 683			.sig_bits	= 24,
 684		},
 685		/* playback capabilities */
 686		.playback = {
 687			.stream_name	= "AIF3 Playback",
 688			.channels_min	= 1,
 689			.channels_max	= 1,
 690			.rates		= SUN8I_CODEC_PCM_RATES,
 691			.formats	= SUN8I_CODEC_PCM_FORMATS,
 692		},
 693		.symmetric_rate		= true,
 694		.symmetric_channels	= true,
 695		.symmetric_sample_bits	= true,
 696	},
 697};
 698
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 699static int sun8i_codec_aif_event(struct snd_soc_dapm_widget *w,
 700				 struct snd_kcontrol *kcontrol, int event)
 701{
 702	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 703	struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component);
 704	struct sun8i_codec_aif *aif = &scodec->aifs[w->sname[3] - '1'];
 705	int stream = w->id == snd_soc_dapm_aif_out;
 706
 707	if (SND_SOC_DAPM_EVENT_ON(event))
 708		aif->active_streams |= BIT(stream);
 709	else
 710		aif->active_streams &= ~BIT(stream);
 711
 712	return sun8i_codec_update_sample_rate(scodec);
 713}
 714
 715static const char *const sun8i_aif_stereo_mux_enum_values[] = {
 716	"Stereo", "Reverse Stereo", "Sum Mono", "Mix Mono"
 717};
 718
 719static SOC_ENUM_DOUBLE_DECL(sun8i_aif1_ad0_stereo_mux_enum,
 720			    SUN8I_AIF1_ADCDAT_CTRL,
 721			    SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0L_SRC,
 722			    SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0R_SRC,
 723			    sun8i_aif_stereo_mux_enum_values);
 724
 725static const struct snd_kcontrol_new sun8i_aif1_ad0_stereo_mux_control =
 726	SOC_DAPM_ENUM("AIF1 AD0 Stereo Capture Route",
 727		      sun8i_aif1_ad0_stereo_mux_enum);
 728
 729static SOC_ENUM_DOUBLE_DECL(sun8i_aif2_adc_stereo_mux_enum,
 730			    SUN8I_AIF2_ADCDAT_CTRL,
 731			    SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCL_SRC,
 732			    SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCR_SRC,
 733			    sun8i_aif_stereo_mux_enum_values);
 734
 735static const struct snd_kcontrol_new sun8i_aif2_adc_stereo_mux_control =
 736	SOC_DAPM_ENUM("AIF2 ADC Stereo Capture Route",
 737		      sun8i_aif2_adc_stereo_mux_enum);
 738
 739static const char *const sun8i_aif3_adc_mux_enum_values[] = {
 740	"None", "AIF2 ADCL", "AIF2 ADCR"
 741};
 742
 743static SOC_ENUM_SINGLE_DECL(sun8i_aif3_adc_mux_enum,
 744			    SUN8I_AIF3_PATH_CTRL,
 745			    SUN8I_AIF3_PATH_CTRL_AIF3_ADC_SRC,
 746			    sun8i_aif3_adc_mux_enum_values);
 747
 748static const struct snd_kcontrol_new sun8i_aif3_adc_mux_control =
 749	SOC_DAPM_ENUM("AIF3 ADC Source Capture Route",
 750		      sun8i_aif3_adc_mux_enum);
 751
 752static const struct snd_kcontrol_new sun8i_aif1_ad0_mixer_controls[] = {
 753	SOC_DAPM_DOUBLE("AIF1 Slot 0 Digital ADC Capture Switch",
 754			SUN8I_AIF1_MXR_SRC,
 755			SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF1DA0L,
 756			SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF1DA0R, 1, 0),
 757	SOC_DAPM_DOUBLE("AIF2 Digital ADC Capture Switch",
 758			SUN8I_AIF1_MXR_SRC,
 759			SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF2DACL,
 760			SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACR, 1, 0),
 761	SOC_DAPM_DOUBLE("AIF1 Data Digital ADC Capture Switch",
 762			SUN8I_AIF1_MXR_SRC,
 763			SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_ADCL,
 764			SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_ADCR, 1, 0),
 765	SOC_DAPM_DOUBLE("AIF2 Inv Digital ADC Capture Switch",
 766			SUN8I_AIF1_MXR_SRC,
 767			SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF2DACR,
 768			SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACL, 1, 0),
 769};
 770
 771static const struct snd_kcontrol_new sun8i_aif2_adc_mixer_controls[] = {
 772	SOC_DAPM_DOUBLE("AIF2 ADC Mixer AIF1 DA0 Capture Switch",
 773			SUN8I_AIF2_MXR_SRC,
 774			SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_AIF1DA0L,
 775			SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_AIF1DA0R, 1, 0),
 776	SOC_DAPM_DOUBLE("AIF2 ADC Mixer AIF1 DA1 Capture Switch",
 777			SUN8I_AIF2_MXR_SRC,
 778			SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_AIF1DA1L,
 779			SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_AIF1DA1R, 1, 0),
 780	SOC_DAPM_DOUBLE("AIF2 ADC Mixer AIF2 DAC Rev Capture Switch",
 781			SUN8I_AIF2_MXR_SRC,
 782			SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_AIF2DACR,
 783			SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_AIF2DACL, 1, 0),
 784	SOC_DAPM_DOUBLE("AIF2 ADC Mixer ADC Capture Switch",
 785			SUN8I_AIF2_MXR_SRC,
 786			SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_ADCL,
 787			SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_ADCR, 1, 0),
 788};
 789
 790static const char *const sun8i_aif2_dac_mux_enum_values[] = {
 791	"AIF2", "AIF3+2", "AIF2+3"
 792};
 793
 794static SOC_ENUM_SINGLE_DECL(sun8i_aif2_dac_mux_enum,
 795			    SUN8I_AIF3_PATH_CTRL,
 796			    SUN8I_AIF3_PATH_CTRL_AIF2_DAC_SRC,
 797			    sun8i_aif2_dac_mux_enum_values);
 798
 799static const struct snd_kcontrol_new sun8i_aif2_dac_mux_control =
 800	SOC_DAPM_ENUM("AIF2 DAC Source Playback Route",
 801		      sun8i_aif2_dac_mux_enum);
 802
 803static SOC_ENUM_DOUBLE_DECL(sun8i_aif1_da0_stereo_mux_enum,
 804			    SUN8I_AIF1_DACDAT_CTRL,
 805			    SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_SRC,
 806			    SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_SRC,
 807			    sun8i_aif_stereo_mux_enum_values);
 808
 809static const struct snd_kcontrol_new sun8i_aif1_da0_stereo_mux_control =
 810	SOC_DAPM_ENUM("AIF1 DA0 Stereo Playback Route",
 811		      sun8i_aif1_da0_stereo_mux_enum);
 812
 813static SOC_ENUM_DOUBLE_DECL(sun8i_aif2_dac_stereo_mux_enum,
 814			    SUN8I_AIF2_DACDAT_CTRL,
 815			    SUN8I_AIF2_DACDAT_CTRL_AIF2_DACL_SRC,
 816			    SUN8I_AIF2_DACDAT_CTRL_AIF2_DACR_SRC,
 817			    sun8i_aif_stereo_mux_enum_values);
 818
 819static const struct snd_kcontrol_new sun8i_aif2_dac_stereo_mux_control =
 820	SOC_DAPM_ENUM("AIF2 DAC Stereo Playback Route",
 821		      sun8i_aif2_dac_stereo_mux_enum);
 822
 823static const struct snd_kcontrol_new sun8i_dac_mixer_controls[] = {
 824	SOC_DAPM_DOUBLE("AIF1 Slot 0 Digital DAC Playback Switch",
 825			SUN8I_DAC_MXR_SRC,
 826			SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L,
 827			SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R, 1, 0),
 828	SOC_DAPM_DOUBLE("AIF1 Slot 1 Digital DAC Playback Switch",
 829			SUN8I_DAC_MXR_SRC,
 830			SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L,
 831			SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R, 1, 0),
 832	SOC_DAPM_DOUBLE("AIF2 Digital DAC Playback Switch", SUN8I_DAC_MXR_SRC,
 833			SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL,
 834			SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR, 1, 0),
 835	SOC_DAPM_DOUBLE("ADC Digital DAC Playback Switch", SUN8I_DAC_MXR_SRC,
 836			SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL,
 837			SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR, 1, 0),
 838};
 839
 840static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
 841	/* System Clocks */
 842	SND_SOC_DAPM_CLOCK_SUPPLY("mod"),
 843
 844	SND_SOC_DAPM_SUPPLY("AIF1CLK",
 845			    SUN8I_SYSCLK_CTL,
 846			    SUN8I_SYSCLK_CTL_AIF1CLK_ENA, 0, NULL, 0),
 847	SND_SOC_DAPM_SUPPLY("AIF2CLK",
 848			    SUN8I_SYSCLK_CTL,
 849			    SUN8I_SYSCLK_CTL_AIF2CLK_ENA, 0, NULL, 0),
 850	SND_SOC_DAPM_SUPPLY("SYSCLK",
 851			    SUN8I_SYSCLK_CTL,
 852			    SUN8I_SYSCLK_CTL_SYSCLK_ENA, 0, NULL, 0),
 853
 854	/* Module Clocks */
 855	SND_SOC_DAPM_SUPPLY("CLK AIF1",
 856			    SUN8I_MOD_CLK_ENA,
 857			    SUN8I_MOD_CLK_ENA_AIF1, 0, NULL, 0),
 858	SND_SOC_DAPM_SUPPLY("CLK AIF2",
 859			    SUN8I_MOD_CLK_ENA,
 860			    SUN8I_MOD_CLK_ENA_AIF2, 0, NULL, 0),
 861	SND_SOC_DAPM_SUPPLY("CLK AIF3",
 862			    SUN8I_MOD_CLK_ENA,
 863			    SUN8I_MOD_CLK_ENA_AIF3, 0, NULL, 0),
 864	SND_SOC_DAPM_SUPPLY("CLK ADC",
 865			    SUN8I_MOD_CLK_ENA,
 866			    SUN8I_MOD_CLK_ENA_ADC, 0, NULL, 0),
 867	SND_SOC_DAPM_SUPPLY("CLK DAC",
 868			    SUN8I_MOD_CLK_ENA,
 869			    SUN8I_MOD_CLK_ENA_DAC, 0, NULL, 0),
 870
 871	/* Module Resets */
 872	SND_SOC_DAPM_SUPPLY("RST AIF1",
 873			    SUN8I_MOD_RST_CTL,
 874			    SUN8I_MOD_RST_CTL_AIF1, 0, NULL, 0),
 875	SND_SOC_DAPM_SUPPLY("RST AIF2",
 876			    SUN8I_MOD_RST_CTL,
 877			    SUN8I_MOD_RST_CTL_AIF2, 0, NULL, 0),
 878	SND_SOC_DAPM_SUPPLY("RST AIF3",
 879			    SUN8I_MOD_RST_CTL,
 880			    SUN8I_MOD_RST_CTL_AIF3, 0, NULL, 0),
 881	SND_SOC_DAPM_SUPPLY("RST ADC",
 882			    SUN8I_MOD_RST_CTL,
 883			    SUN8I_MOD_RST_CTL_ADC, 0, NULL, 0),
 884	SND_SOC_DAPM_SUPPLY("RST DAC",
 885			    SUN8I_MOD_RST_CTL,
 886			    SUN8I_MOD_RST_CTL_DAC, 0, NULL, 0),
 887
 888	/* Module Supplies */
 889	SND_SOC_DAPM_SUPPLY("ADC",
 890			    SUN8I_ADC_DIG_CTRL,
 891			    SUN8I_ADC_DIG_CTRL_ENAD, 0, NULL, 0),
 892	SND_SOC_DAPM_SUPPLY("DAC",
 893			    SUN8I_DAC_DIG_CTRL,
 894			    SUN8I_DAC_DIG_CTRL_ENDA, 0, NULL, 0),
 895
 896	/* AIF "ADC" Outputs */
 897	SND_SOC_DAPM_AIF_OUT_E("AIF1 AD0L", "AIF1 Capture", 0,
 898			       SUN8I_AIF1_ADCDAT_CTRL,
 899			       SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0L_ENA, 0,
 900			       sun8i_codec_aif_event,
 901			       SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 902	SND_SOC_DAPM_AIF_OUT("AIF1 AD0R", "AIF1 Capture", 1,
 903			     SUN8I_AIF1_ADCDAT_CTRL,
 904			     SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0R_ENA, 0),
 905
 906	SND_SOC_DAPM_AIF_OUT_E("AIF2 ADCL", "AIF2 Capture", 0,
 907			       SUN8I_AIF2_ADCDAT_CTRL,
 908			       SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCL_ENA, 0,
 909			       sun8i_codec_aif_event,
 910			       SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 911	SND_SOC_DAPM_AIF_OUT("AIF2 ADCR", "AIF2 Capture", 1,
 912			     SUN8I_AIF2_ADCDAT_CTRL,
 913			     SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCR_ENA, 0),
 914
 915	SND_SOC_DAPM_AIF_OUT_E("AIF3 ADC", "AIF3 Capture", 0,
 916			       SND_SOC_NOPM, 0, 0,
 917			       sun8i_codec_aif_event,
 918			       SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 919
 920	/* AIF "ADC" Mono/Stereo Muxes */
 921	SND_SOC_DAPM_MUX("AIF1 AD0L Stereo Mux", SND_SOC_NOPM, 0, 0,
 922			 &sun8i_aif1_ad0_stereo_mux_control),
 923	SND_SOC_DAPM_MUX("AIF1 AD0R Stereo Mux", SND_SOC_NOPM, 0, 0,
 924			 &sun8i_aif1_ad0_stereo_mux_control),
 925
 926	SND_SOC_DAPM_MUX("AIF2 ADCL Stereo Mux", SND_SOC_NOPM, 0, 0,
 927			 &sun8i_aif2_adc_stereo_mux_control),
 928	SND_SOC_DAPM_MUX("AIF2 ADCR Stereo Mux", SND_SOC_NOPM, 0, 0,
 929			 &sun8i_aif2_adc_stereo_mux_control),
 930
 931	/* AIF "ADC" Output Muxes */
 932	SND_SOC_DAPM_MUX("AIF3 ADC Source Capture Route", SND_SOC_NOPM, 0, 0,
 933			 &sun8i_aif3_adc_mux_control),
 934
 935	/* AIF "ADC" Mixers */
 936	SOC_MIXER_ARRAY("AIF1 AD0L Mixer", SND_SOC_NOPM, 0, 0,
 937			sun8i_aif1_ad0_mixer_controls),
 938	SOC_MIXER_ARRAY("AIF1 AD0R Mixer", SND_SOC_NOPM, 0, 0,
 939			sun8i_aif1_ad0_mixer_controls),
 940
 941	SOC_MIXER_ARRAY("AIF2 ADCL Mixer", SND_SOC_NOPM, 0, 0,
 942			sun8i_aif2_adc_mixer_controls),
 943	SOC_MIXER_ARRAY("AIF2 ADCR Mixer", SND_SOC_NOPM, 0, 0,
 944			sun8i_aif2_adc_mixer_controls),
 945
 946	/* AIF "DAC" Input Muxes */
 947	SND_SOC_DAPM_MUX("AIF2 DACL Source", SND_SOC_NOPM, 0, 0,
 948			 &sun8i_aif2_dac_mux_control),
 949	SND_SOC_DAPM_MUX("AIF2 DACR Source", SND_SOC_NOPM, 0, 0,
 950			 &sun8i_aif2_dac_mux_control),
 951
 952	/* AIF "DAC" Mono/Stereo Muxes */
 953	SND_SOC_DAPM_MUX("AIF1 DA0L Stereo Mux", SND_SOC_NOPM, 0, 0,
 954			 &sun8i_aif1_da0_stereo_mux_control),
 955	SND_SOC_DAPM_MUX("AIF1 DA0R Stereo Mux", SND_SOC_NOPM, 0, 0,
 956			 &sun8i_aif1_da0_stereo_mux_control),
 957
 958	SND_SOC_DAPM_MUX("AIF2 DACL Stereo Mux", SND_SOC_NOPM, 0, 0,
 959			 &sun8i_aif2_dac_stereo_mux_control),
 960	SND_SOC_DAPM_MUX("AIF2 DACR Stereo Mux", SND_SOC_NOPM, 0, 0,
 961			 &sun8i_aif2_dac_stereo_mux_control),
 962
 963	/* AIF "DAC" Inputs */
 964	SND_SOC_DAPM_AIF_IN_E("AIF1 DA0L", "AIF1 Playback", 0,
 965			      SUN8I_AIF1_DACDAT_CTRL,
 966			      SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA, 0,
 967			      sun8i_codec_aif_event,
 968			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 969	SND_SOC_DAPM_AIF_IN("AIF1 DA0R", "AIF1 Playback", 1,
 970			    SUN8I_AIF1_DACDAT_CTRL,
 971			    SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA, 0),
 972
 973	SND_SOC_DAPM_AIF_IN_E("AIF2 DACL", "AIF2 Playback", 0,
 974			      SUN8I_AIF2_DACDAT_CTRL,
 975			      SUN8I_AIF2_DACDAT_CTRL_AIF2_DACL_ENA, 0,
 976			      sun8i_codec_aif_event,
 977			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 978	SND_SOC_DAPM_AIF_IN("AIF2 DACR", "AIF2 Playback", 1,
 979			    SUN8I_AIF2_DACDAT_CTRL,
 980			    SUN8I_AIF2_DACDAT_CTRL_AIF2_DACR_ENA, 0),
 981
 982	SND_SOC_DAPM_AIF_IN_E("AIF3 DAC", "AIF3 Playback", 0,
 983			      SND_SOC_NOPM, 0, 0,
 984			      sun8i_codec_aif_event,
 985			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 986
 987	/* ADC Inputs (connected to analog codec DAPM context) */
 988	SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 0, 0),
 989	SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0),
 990
 991	/* DAC Outputs (connected to analog codec DAPM context) */
 992	SND_SOC_DAPM_DAC("DACL", NULL, SND_SOC_NOPM, 0, 0),
 993	SND_SOC_DAPM_DAC("DACR", NULL, SND_SOC_NOPM, 0, 0),
 994
 995	/* DAC Mixers */
 996	SOC_MIXER_ARRAY("DACL Mixer", SND_SOC_NOPM, 0, 0,
 997			sun8i_dac_mixer_controls),
 998	SOC_MIXER_ARRAY("DACR Mixer", SND_SOC_NOPM, 0, 0,
 999			sun8i_dac_mixer_controls),
1000};
1001
1002static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
1003	/* Clock Routes */
1004	{ "AIF1CLK", NULL, "mod" },
1005
1006	{ "SYSCLK", NULL, "AIF1CLK" },
1007
1008	{ "CLK AIF1", NULL, "AIF1CLK" },
1009	{ "CLK AIF1", NULL, "SYSCLK" },
1010	{ "RST AIF1", NULL, "CLK AIF1" },
1011	{ "AIF1 AD0L", NULL, "RST AIF1" },
1012	{ "AIF1 AD0R", NULL, "RST AIF1" },
1013	{ "AIF1 DA0L", NULL, "RST AIF1" },
1014	{ "AIF1 DA0R", NULL, "RST AIF1" },
1015
1016	{ "CLK AIF2", NULL, "AIF2CLK" },
1017	{ "CLK AIF2", NULL, "SYSCLK" },
1018	{ "RST AIF2", NULL, "CLK AIF2" },
1019	{ "AIF2 ADCL", NULL, "RST AIF2" },
1020	{ "AIF2 ADCR", NULL, "RST AIF2" },
1021	{ "AIF2 DACL", NULL, "RST AIF2" },
1022	{ "AIF2 DACR", NULL, "RST AIF2" },
1023
1024	{ "CLK AIF3", NULL, "AIF1CLK" },
1025	{ "CLK AIF3", NULL, "SYSCLK" },
1026	{ "RST AIF3", NULL, "CLK AIF3" },
1027	{ "AIF3 ADC", NULL, "RST AIF3" },
1028	{ "AIF3 DAC", NULL, "RST AIF3" },
1029
1030	{ "CLK ADC", NULL, "SYSCLK" },
1031	{ "RST ADC", NULL, "CLK ADC" },
1032	{ "ADC", NULL, "RST ADC" },
1033	{ "ADCL", NULL, "ADC" },
1034	{ "ADCR", NULL, "ADC" },
1035
1036	{ "CLK DAC", NULL, "SYSCLK" },
1037	{ "RST DAC", NULL, "CLK DAC" },
1038	{ "DAC", NULL, "RST DAC" },
1039	{ "DACL", NULL, "DAC" },
1040	{ "DACR", NULL, "DAC" },
1041
1042	/* AIF "ADC" Output Routes */
1043	{ "AIF1 AD0L", NULL, "AIF1 AD0L Stereo Mux" },
1044	{ "AIF1 AD0R", NULL, "AIF1 AD0R Stereo Mux" },
1045
1046	{ "AIF2 ADCL", NULL, "AIF2 ADCL Stereo Mux" },
1047	{ "AIF2 ADCR", NULL, "AIF2 ADCR Stereo Mux" },
1048
1049	{ "AIF3 ADC", NULL, "AIF3 ADC Source Capture Route" },
1050
1051	/* AIF "ADC" Mono/Stereo Mux Routes */
1052	{ "AIF1 AD0L Stereo Mux", "Stereo", "AIF1 AD0L Mixer" },
1053	{ "AIF1 AD0L Stereo Mux", "Reverse Stereo", "AIF1 AD0R Mixer" },
1054	{ "AIF1 AD0L Stereo Mux", "Sum Mono", "AIF1 AD0L Mixer" },
1055	{ "AIF1 AD0L Stereo Mux", "Sum Mono", "AIF1 AD0R Mixer" },
1056	{ "AIF1 AD0L Stereo Mux", "Mix Mono", "AIF1 AD0L Mixer" },
1057	{ "AIF1 AD0L Stereo Mux", "Mix Mono", "AIF1 AD0R Mixer" },
1058
1059	{ "AIF1 AD0R Stereo Mux", "Stereo", "AIF1 AD0R Mixer" },
1060	{ "AIF1 AD0R Stereo Mux", "Reverse Stereo", "AIF1 AD0L Mixer" },
1061	{ "AIF1 AD0R Stereo Mux", "Sum Mono", "AIF1 AD0L Mixer" },
1062	{ "AIF1 AD0R Stereo Mux", "Sum Mono", "AIF1 AD0R Mixer" },
1063	{ "AIF1 AD0R Stereo Mux", "Mix Mono", "AIF1 AD0L Mixer" },
1064	{ "AIF1 AD0R Stereo Mux", "Mix Mono", "AIF1 AD0R Mixer" },
1065
1066	{ "AIF2 ADCL Stereo Mux", "Stereo", "AIF2 ADCL Mixer" },
1067	{ "AIF2 ADCL Stereo Mux", "Reverse Stereo", "AIF2 ADCR Mixer" },
1068	{ "AIF2 ADCL Stereo Mux", "Sum Mono", "AIF2 ADCL Mixer" },
1069	{ "AIF2 ADCL Stereo Mux", "Sum Mono", "AIF2 ADCR Mixer" },
1070	{ "AIF2 ADCL Stereo Mux", "Mix Mono", "AIF2 ADCL Mixer" },
1071	{ "AIF2 ADCL Stereo Mux", "Mix Mono", "AIF2 ADCR Mixer" },
1072
1073	{ "AIF2 ADCR Stereo Mux", "Stereo", "AIF2 ADCR Mixer" },
1074	{ "AIF2 ADCR Stereo Mux", "Reverse Stereo", "AIF2 ADCL Mixer" },
1075	{ "AIF2 ADCR Stereo Mux", "Sum Mono", "AIF2 ADCL Mixer" },
1076	{ "AIF2 ADCR Stereo Mux", "Sum Mono", "AIF2 ADCR Mixer" },
1077	{ "AIF2 ADCR Stereo Mux", "Mix Mono", "AIF2 ADCL Mixer" },
1078	{ "AIF2 ADCR Stereo Mux", "Mix Mono", "AIF2 ADCR Mixer" },
1079
1080	/* AIF "ADC" Output Mux Routes */
1081	{ "AIF3 ADC Source Capture Route", "AIF2 ADCL", "AIF2 ADCL Mixer" },
1082	{ "AIF3 ADC Source Capture Route", "AIF2 ADCR", "AIF2 ADCR Mixer" },
1083
1084	/* AIF "ADC" Mixer Routes */
1085	{ "AIF1 AD0L Mixer", "AIF1 Slot 0 Digital ADC Capture Switch", "AIF1 DA0L Stereo Mux" },
1086	{ "AIF1 AD0L Mixer", "AIF2 Digital ADC Capture Switch", "AIF2 DACL Source" },
1087	{ "AIF1 AD0L Mixer", "AIF1 Data Digital ADC Capture Switch", "ADCL" },
1088	{ "AIF1 AD0L Mixer", "AIF2 Inv Digital ADC Capture Switch", "AIF2 DACR Source" },
1089
1090	{ "AIF1 AD0R Mixer", "AIF1 Slot 0 Digital ADC Capture Switch", "AIF1 DA0R Stereo Mux" },
1091	{ "AIF1 AD0R Mixer", "AIF2 Digital ADC Capture Switch", "AIF2 DACR Source" },
1092	{ "AIF1 AD0R Mixer", "AIF1 Data Digital ADC Capture Switch", "ADCR" },
1093	{ "AIF1 AD0R Mixer", "AIF2 Inv Digital ADC Capture Switch", "AIF2 DACL Source" },
1094
1095	{ "AIF2 ADCL Mixer", "AIF2 ADC Mixer AIF1 DA0 Capture Switch", "AIF1 DA0L Stereo Mux" },
1096	{ "AIF2 ADCL Mixer", "AIF2 ADC Mixer AIF2 DAC Rev Capture Switch", "AIF2 DACR Source" },
1097	{ "AIF2 ADCL Mixer", "AIF2 ADC Mixer ADC Capture Switch", "ADCL" },
1098
1099	{ "AIF2 ADCR Mixer", "AIF2 ADC Mixer AIF1 DA0 Capture Switch", "AIF1 DA0R Stereo Mux" },
1100	{ "AIF2 ADCR Mixer", "AIF2 ADC Mixer AIF2 DAC Rev Capture Switch", "AIF2 DACL Source" },
1101	{ "AIF2 ADCR Mixer", "AIF2 ADC Mixer ADC Capture Switch", "ADCR" },
1102
1103	/* AIF "DAC" Input Mux Routes */
1104	{ "AIF2 DACL Source", "AIF2", "AIF2 DACL Stereo Mux" },
1105	{ "AIF2 DACL Source", "AIF3+2", "AIF3 DAC" },
1106	{ "AIF2 DACL Source", "AIF2+3", "AIF2 DACL Stereo Mux" },
1107
1108	{ "AIF2 DACR Source", "AIF2", "AIF2 DACR Stereo Mux" },
1109	{ "AIF2 DACR Source", "AIF3+2", "AIF2 DACR Stereo Mux" },
1110	{ "AIF2 DACR Source", "AIF2+3", "AIF3 DAC" },
1111
1112	/* AIF "DAC" Mono/Stereo Mux Routes */
1113	{ "AIF1 DA0L Stereo Mux", "Stereo", "AIF1 DA0L" },
1114	{ "AIF1 DA0L Stereo Mux", "Reverse Stereo", "AIF1 DA0R" },
1115	{ "AIF1 DA0L Stereo Mux", "Sum Mono", "AIF1 DA0L" },
1116	{ "AIF1 DA0L Stereo Mux", "Sum Mono", "AIF1 DA0R" },
1117	{ "AIF1 DA0L Stereo Mux", "Mix Mono", "AIF1 DA0L" },
1118	{ "AIF1 DA0L Stereo Mux", "Mix Mono", "AIF1 DA0R" },
1119
1120	{ "AIF1 DA0R Stereo Mux", "Stereo", "AIF1 DA0R" },
1121	{ "AIF1 DA0R Stereo Mux", "Reverse Stereo", "AIF1 DA0L" },
1122	{ "AIF1 DA0R Stereo Mux", "Sum Mono", "AIF1 DA0L" },
1123	{ "AIF1 DA0R Stereo Mux", "Sum Mono", "AIF1 DA0R" },
1124	{ "AIF1 DA0R Stereo Mux", "Mix Mono", "AIF1 DA0L" },
1125	{ "AIF1 DA0R Stereo Mux", "Mix Mono", "AIF1 DA0R" },
1126
1127	{ "AIF2 DACL Stereo Mux", "Stereo", "AIF2 DACL" },
1128	{ "AIF2 DACL Stereo Mux", "Reverse Stereo", "AIF2 DACR" },
1129	{ "AIF2 DACL Stereo Mux", "Sum Mono", "AIF2 DACL" },
1130	{ "AIF2 DACL Stereo Mux", "Sum Mono", "AIF2 DACR" },
1131	{ "AIF2 DACL Stereo Mux", "Mix Mono", "AIF2 DACL" },
1132	{ "AIF2 DACL Stereo Mux", "Mix Mono", "AIF2 DACR" },
1133
1134	{ "AIF2 DACR Stereo Mux", "Stereo", "AIF2 DACR" },
1135	{ "AIF2 DACR Stereo Mux", "Reverse Stereo", "AIF2 DACL" },
1136	{ "AIF2 DACR Stereo Mux", "Sum Mono", "AIF2 DACL" },
1137	{ "AIF2 DACR Stereo Mux", "Sum Mono", "AIF2 DACR" },
1138	{ "AIF2 DACR Stereo Mux", "Mix Mono", "AIF2 DACL" },
1139	{ "AIF2 DACR Stereo Mux", "Mix Mono", "AIF2 DACR" },
1140
1141	/* DAC Output Routes */
1142	{ "DACL", NULL, "DACL Mixer" },
1143	{ "DACR", NULL, "DACR Mixer" },
1144
1145	/* DAC Mixer Routes */
1146	{ "DACL Mixer", "AIF1 Slot 0 Digital DAC Playback Switch", "AIF1 DA0L Stereo Mux" },
1147	{ "DACL Mixer", "AIF2 Digital DAC Playback Switch", "AIF2 DACL Source" },
1148	{ "DACL Mixer", "ADC Digital DAC Playback Switch", "ADCL" },
1149
1150	{ "DACR Mixer", "AIF1 Slot 0 Digital DAC Playback Switch", "AIF1 DA0R Stereo Mux" },
1151	{ "DACR Mixer", "AIF2 Digital DAC Playback Switch", "AIF2 DACR Source" },
1152	{ "DACR Mixer", "ADC Digital DAC Playback Switch", "ADCR" },
1153};
1154
1155static const struct snd_soc_dapm_widget sun8i_codec_legacy_widgets[] = {
1156	/* Legacy ADC Inputs (connected to analog codec DAPM context) */
1157	SND_SOC_DAPM_ADC("AIF1 Slot 0 Left ADC", NULL, SND_SOC_NOPM, 0, 0),
1158	SND_SOC_DAPM_ADC("AIF1 Slot 0 Right ADC", NULL, SND_SOC_NOPM, 0, 0),
1159
1160	/* Legacy DAC Outputs (connected to analog codec DAPM context) */
1161	SND_SOC_DAPM_DAC("AIF1 Slot 0 Left", NULL, SND_SOC_NOPM, 0, 0),
1162	SND_SOC_DAPM_DAC("AIF1 Slot 0 Right", NULL, SND_SOC_NOPM, 0, 0),
1163};
1164
1165static const struct snd_soc_dapm_route sun8i_codec_legacy_routes[] = {
1166	/* Legacy ADC Routes */
1167	{ "ADCL", NULL, "AIF1 Slot 0 Left ADC" },
1168	{ "ADCR", NULL, "AIF1 Slot 0 Right ADC" },
1169
1170	/* Legacy DAC Routes */
1171	{ "AIF1 Slot 0 Left", NULL, "DACL" },
1172	{ "AIF1 Slot 0 Right", NULL, "DACR" },
1173};
1174
1175static int sun8i_codec_component_probe(struct snd_soc_component *component)
1176{
1177	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
1178	struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component);
1179	int ret;
1180
1181	/* Add widgets for backward compatibility with old device trees. */
1182	if (scodec->quirks->legacy_widgets) {
1183		ret = snd_soc_dapm_new_controls(dapm, sun8i_codec_legacy_widgets,
1184						ARRAY_SIZE(sun8i_codec_legacy_widgets));
1185		if (ret)
1186			return ret;
1187
1188		ret = snd_soc_dapm_add_routes(dapm, sun8i_codec_legacy_routes,
1189					      ARRAY_SIZE(sun8i_codec_legacy_routes));
1190		if (ret)
1191			return ret;
1192	}
1193
1194	/*
1195	 * AIF1CLK and AIF2CLK share a pair of clock parents: PLL_AUDIO ("mod")
1196	 * and MCLK (from the CPU DAI connected to AIF1). MCLK's parent is also
1197	 * PLL_AUDIO, so using it adds no additional flexibility. Use PLL_AUDIO
1198	 * directly to simplify the clock tree.
1199	 */
1200	regmap_update_bits(scodec->regmap, SUN8I_SYSCLK_CTL,
1201			   SUN8I_SYSCLK_CTL_AIF1CLK_SRC_MASK |
1202			   SUN8I_SYSCLK_CTL_AIF2CLK_SRC_MASK,
1203			   SUN8I_SYSCLK_CTL_AIF1CLK_SRC_PLL |
1204			   SUN8I_SYSCLK_CTL_AIF2CLK_SRC_PLL);
1205
1206	/* Use AIF1CLK as the SYSCLK parent since AIF1 is used most often. */
1207	regmap_update_bits(scodec->regmap, SUN8I_SYSCLK_CTL,
1208			   BIT(SUN8I_SYSCLK_CTL_SYSCLK_SRC),
1209			   SUN8I_SYSCLK_CTL_SYSCLK_SRC_AIF1CLK);
1210
1211	/* Program the default sample rate. */
1212	sun8i_codec_update_sample_rate(scodec);
1213
1214	return 0;
1215}
1216
1217static const struct snd_soc_component_driver sun8i_soc_component = {
 
 
1218	.dapm_widgets		= sun8i_codec_dapm_widgets,
1219	.num_dapm_widgets	= ARRAY_SIZE(sun8i_codec_dapm_widgets),
1220	.dapm_routes		= sun8i_codec_dapm_routes,
1221	.num_dapm_routes	= ARRAY_SIZE(sun8i_codec_dapm_routes),
1222	.probe			= sun8i_codec_component_probe,
1223	.idle_bias_on		= 1,
1224	.endianness		= 1,
1225	.non_legacy_dai_naming	= 1,
1226};
1227
1228static const struct regmap_config sun8i_codec_regmap_config = {
1229	.reg_bits	= 32,
1230	.reg_stride	= 4,
1231	.val_bits	= 32,
1232	.max_register	= SUN8I_DAC_MXR_SRC,
1233
1234	.cache_type	= REGCACHE_FLAT,
1235};
1236
1237static int sun8i_codec_probe(struct platform_device *pdev)
1238{
1239	struct sun8i_codec *scodec;
1240	void __iomem *base;
1241	int ret;
1242
1243	scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL);
1244	if (!scodec)
1245		return -ENOMEM;
1246
1247	scodec->clk_module = devm_clk_get(&pdev->dev, "mod");
1248	if (IS_ERR(scodec->clk_module)) {
1249		dev_err(&pdev->dev, "Failed to get the module clock\n");
1250		return PTR_ERR(scodec->clk_module);
1251	}
1252
1253	base = devm_platform_ioremap_resource(pdev, 0);
1254	if (IS_ERR(base)) {
1255		dev_err(&pdev->dev, "Failed to map the registers\n");
1256		return PTR_ERR(base);
1257	}
1258
1259	scodec->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "bus", base,
1260						   &sun8i_codec_regmap_config);
1261	if (IS_ERR(scodec->regmap)) {
1262		dev_err(&pdev->dev, "Failed to create our regmap\n");
1263		return PTR_ERR(scodec->regmap);
1264	}
1265
1266	scodec->quirks = of_device_get_match_data(&pdev->dev);
1267
1268	platform_set_drvdata(pdev, scodec);
1269
1270	pm_runtime_enable(&pdev->dev);
1271	if (!pm_runtime_enabled(&pdev->dev)) {
1272		ret = sun8i_codec_runtime_resume(&pdev->dev);
1273		if (ret)
1274			goto err_pm_disable;
1275	}
1276
1277	ret = devm_snd_soc_register_component(&pdev->dev, &sun8i_soc_component,
1278					      sun8i_codec_dais,
1279					      ARRAY_SIZE(sun8i_codec_dais));
1280	if (ret) {
1281		dev_err(&pdev->dev, "Failed to register codec\n");
1282		goto err_suspend;
1283	}
1284
1285	return ret;
1286
1287err_suspend:
1288	if (!pm_runtime_status_suspended(&pdev->dev))
1289		sun8i_codec_runtime_suspend(&pdev->dev);
1290
1291err_pm_disable:
1292	pm_runtime_disable(&pdev->dev);
1293
1294	return ret;
1295}
1296
1297static int sun8i_codec_remove(struct platform_device *pdev)
1298{
1299	pm_runtime_disable(&pdev->dev);
1300	if (!pm_runtime_status_suspended(&pdev->dev))
1301		sun8i_codec_runtime_suspend(&pdev->dev);
1302
1303	return 0;
1304}
1305
1306static const struct sun8i_codec_quirks sun8i_a33_quirks = {
1307	.legacy_widgets	= true,
1308	.lrck_inversion	= true,
1309};
1310
1311static const struct sun8i_codec_quirks sun50i_a64_quirks = {
1312};
1313
1314static const struct of_device_id sun8i_codec_of_match[] = {
1315	{ .compatible = "allwinner,sun8i-a33-codec", .data = &sun8i_a33_quirks },
1316	{ .compatible = "allwinner,sun50i-a64-codec", .data = &sun50i_a64_quirks },
1317	{}
1318};
1319MODULE_DEVICE_TABLE(of, sun8i_codec_of_match);
1320
1321static const struct dev_pm_ops sun8i_codec_pm_ops = {
1322	SET_RUNTIME_PM_OPS(sun8i_codec_runtime_suspend,
1323			   sun8i_codec_runtime_resume, NULL)
1324};
1325
1326static struct platform_driver sun8i_codec_driver = {
1327	.driver = {
1328		.name = "sun8i-codec",
1329		.of_match_table = sun8i_codec_of_match,
1330		.pm = &sun8i_codec_pm_ops,
1331	},
1332	.probe = sun8i_codec_probe,
1333	.remove = sun8i_codec_remove,
1334};
1335module_platform_driver(sun8i_codec_driver);
1336
1337MODULE_DESCRIPTION("Allwinner A33 (sun8i) codec driver");
1338MODULE_AUTHOR("Mylène Josserand <mylene.josserand@free-electrons.com>");
1339MODULE_LICENSE("GPL");
1340MODULE_ALIAS("platform:sun8i-codec");