Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
   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.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 void 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
1359static const struct sun8i_codec_quirks sun8i_a33_quirks = {
1360	.legacy_widgets	= true,
1361	.lrck_inversion	= true,
1362};
1363
1364static const struct sun8i_codec_quirks sun50i_a64_quirks = {
1365};
1366
1367static const struct of_device_id sun8i_codec_of_match[] = {
1368	{ .compatible = "allwinner,sun8i-a33-codec", .data = &sun8i_a33_quirks },
1369	{ .compatible = "allwinner,sun50i-a64-codec", .data = &sun50i_a64_quirks },
1370	{}
1371};
1372MODULE_DEVICE_TABLE(of, sun8i_codec_of_match);
1373
1374static const struct dev_pm_ops sun8i_codec_pm_ops = {
1375	SET_RUNTIME_PM_OPS(sun8i_codec_runtime_suspend,
1376			   sun8i_codec_runtime_resume, NULL)
1377};
1378
1379static struct platform_driver sun8i_codec_driver = {
1380	.driver = {
1381		.name = "sun8i-codec",
1382		.of_match_table = sun8i_codec_of_match,
1383		.pm = &sun8i_codec_pm_ops,
1384	},
1385	.probe = sun8i_codec_probe,
1386	.remove_new = sun8i_codec_remove,
1387};
1388module_platform_driver(sun8i_codec_driver);
1389
1390MODULE_DESCRIPTION("Allwinner A33 (sun8i) codec driver");
1391MODULE_AUTHOR("Mylène Josserand <mylene.josserand@free-electrons.com>");
1392MODULE_LICENSE("GPL");
1393MODULE_ALIAS("platform:sun8i-codec");