File Index
Files and directories
Sign in
FILE

adau1977.c

File preview with syntax highlighting.

linux-6.19.14/sound/soc/codecs/adau1977.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * ADAU1977/ADAU1978/ADAU1979 driver
   4 *
   5 * Copyright 2014 Analog Devices Inc.
   6 *  Author: Lars-Peter Clausen <lars@metafoo.de>
   7 */
   8
   9#include <linux/delay.h>
  10#include <linux/device.h>
  11#include <linux/gpio/consumer.h>
  12#include <linux/i2c.h>
  13#include <linux/init.h>
  14#include <linux/module.h>
  15#include <linux/regmap.h>
  16#include <linux/regulator/consumer.h>
  17#include <linux/slab.h>
  18
  19#include <sound/core.h>
  20#include <sound/initval.h>
  21#include <sound/pcm.h>
  22#include <sound/pcm_params.h>
  23#include <sound/soc.h>
  24#include <sound/tlv.h>
  25
  26#include <dt-bindings/sound/adi,adau1977.h>
  27
  28#include "adau1977.h"
  29
  30#define ADAU1977_REG_POWER		0x00
  31#define ADAU1977_REG_PLL		0x01
  32#define ADAU1977_REG_BOOST		0x02
  33#define ADAU1977_REG_MICBIAS		0x03
  34#define ADAU1977_REG_BLOCK_POWER_SAI	0x04
  35#define ADAU1977_REG_SAI_CTRL0		0x05
  36#define ADAU1977_REG_SAI_CTRL1		0x06
  37#define ADAU1977_REG_CMAP12		0x07
  38#define ADAU1977_REG_CMAP34		0x08
  39#define ADAU1977_REG_SAI_OVERTEMP	0x09
  40#define ADAU1977_REG_POST_ADC_GAIN(x)	(0x0a + (x))
  41#define ADAU1977_REG_MISC_CONTROL	0x0e
  42#define ADAU1977_REG_DIAG_CONTROL	0x10
  43#define ADAU1977_REG_STATUS(x)		(0x11 + (x))
  44#define ADAU1977_REG_DIAG_IRQ1		0x15
  45#define ADAU1977_REG_DIAG_IRQ2		0x16
  46#define ADAU1977_REG_ADJUST1		0x17
  47#define ADAU1977_REG_ADJUST2		0x18
  48#define ADAU1977_REG_ADC_CLIP		0x19
  49#define ADAU1977_REG_DC_HPF_CAL		0x1a
  50
  51#define ADAU1977_POWER_RESET			BIT(7)
  52#define ADAU1977_POWER_PWUP			BIT(0)
  53
  54#define ADAU1977_PLL_CLK_S			BIT(4)
  55#define ADAU1977_PLL_MCS_MASK			0x7
  56
  57#define ADAU1977_MICBIAS_MB_VOLTS_MASK		0xf0
  58#define ADAU1977_MICBIAS_MB_VOLTS_OFFSET	4
  59
  60#define ADAU1977_BLOCK_POWER_SAI_LR_POL		BIT(7)
  61#define ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE	BIT(6)
  62#define ADAU1977_BLOCK_POWER_SAI_LDO_EN		BIT(5)
  63
  64#define ADAU1977_SAI_CTRL0_FMT_MASK		(0x3 << 6)
  65#define ADAU1977_SAI_CTRL0_FMT_I2S		(0x0 << 6)
  66#define ADAU1977_SAI_CTRL0_FMT_LJ		(0x1 << 6)
  67#define ADAU1977_SAI_CTRL0_FMT_RJ_24BIT		(0x2 << 6)
  68#define ADAU1977_SAI_CTRL0_FMT_RJ_16BIT		(0x3 << 6)
  69
  70#define ADAU1977_SAI_CTRL0_SAI_MASK		(0x7 << 3)
  71#define ADAU1977_SAI_CTRL0_SAI_I2S		(0x0 << 3)
  72#define ADAU1977_SAI_CTRL0_SAI_TDM_2		(0x1 << 3)
  73#define ADAU1977_SAI_CTRL0_SAI_TDM_4		(0x2 << 3)
  74#define ADAU1977_SAI_CTRL0_SAI_TDM_8		(0x3 << 3)
  75#define ADAU1977_SAI_CTRL0_SAI_TDM_16		(0x4 << 3)
  76
  77#define ADAU1977_SAI_CTRL0_FS_MASK		(0x7)
  78#define ADAU1977_SAI_CTRL0_FS_8000_12000	(0x0)
  79#define ADAU1977_SAI_CTRL0_FS_16000_24000	(0x1)
  80#define ADAU1977_SAI_CTRL0_FS_32000_48000	(0x2)
  81#define ADAU1977_SAI_CTRL0_FS_64000_96000	(0x3)
  82#define ADAU1977_SAI_CTRL0_FS_128000_192000	(0x4)
  83
  84#define ADAU1977_SAI_CTRL1_SLOT_WIDTH_MASK	(0x3 << 5)
  85#define ADAU1977_SAI_CTRL1_SLOT_WIDTH_32	(0x0 << 5)
  86#define ADAU1977_SAI_CTRL1_SLOT_WIDTH_24	(0x1 << 5)
  87#define ADAU1977_SAI_CTRL1_SLOT_WIDTH_16	(0x2 << 5)
  88#define ADAU1977_SAI_CTRL1_DATA_WIDTH_MASK	(0x1 << 4)
  89#define ADAU1977_SAI_CTRL1_DATA_WIDTH_16BIT	(0x1 << 4)
  90#define ADAU1977_SAI_CTRL1_DATA_WIDTH_24BIT	(0x0 << 4)
  91#define ADAU1977_SAI_CTRL1_LRCLK_PULSE		BIT(3)
  92#define ADAU1977_SAI_CTRL1_MSB			BIT(2)
  93#define ADAU1977_SAI_CTRL1_BCLKRATE_16		(0x1 << 1)
  94#define ADAU1977_SAI_CTRL1_BCLKRATE_32		(0x0 << 1)
  95#define ADAU1977_SAI_CTRL1_BCLKRATE_MASK	(0x1 << 1)
  96#define ADAU1977_SAI_CTRL1_MASTER		BIT(0)
  97
  98#define ADAU1977_SAI_OVERTEMP_DRV_C(x)		BIT(4 + (x))
  99#define ADAU1977_SAI_OVERTEMP_DRV_HIZ		BIT(3)
 100
 101#define ADAU1977_MISC_CONTROL_SUM_MODE_MASK	(0x3 << 6)
 102#define ADAU1977_MISC_CONTROL_SUM_MODE_1CH	(0x2 << 6)
 103#define ADAU1977_MISC_CONTROL_SUM_MODE_2CH	(0x1 << 6)
 104#define ADAU1977_MISC_CONTROL_SUM_MODE_4CH	(0x0 << 6)
 105#define ADAU1977_MISC_CONTROL_MMUTE		BIT(4)
 106#define ADAU1977_MISC_CONTROL_DC_CAL		BIT(0)
 107
 108#define ADAU1977_CHAN_MAP_SECOND_SLOT_OFFSET	4
 109#define ADAU1977_CHAN_MAP_FIRST_SLOT_OFFSET	0
 110
 111struct adau1977 {
 112	struct regmap *regmap;
 113	bool right_j;
 114	unsigned int sysclk;
 115	enum adau1977_sysclk_src sysclk_src;
 116	struct gpio_desc *reset_gpio;
 117	enum adau1977_type type;
 118
 119	struct regulator *avdd_reg;
 120	struct regulator *dvdd_reg;
 121
 122	struct snd_pcm_hw_constraint_list constraints;
 123
 124	struct device *dev;
 125	void (*switch_mode)(struct device *dev);
 126
 127	unsigned int max_clock_provider_fs;
 128	unsigned int slot_width;
 129	bool enabled;
 130	bool clock_provider;
 131};
 132
 133static const struct reg_default adau1977_reg_defaults[] = {
 134	{ 0x00, 0x00 },
 135	{ 0x01, 0x41 },
 136	{ 0x02, 0x4a },
 137	{ 0x03, 0x7d },
 138	{ 0x04, 0x3d },
 139	{ 0x05, 0x02 },
 140	{ 0x06, 0x00 },
 141	{ 0x07, 0x10 },
 142	{ 0x08, 0x32 },
 143	{ 0x09, 0xf0 },
 144	{ 0x0a, 0xa0 },
 145	{ 0x0b, 0xa0 },
 146	{ 0x0c, 0xa0 },
 147	{ 0x0d, 0xa0 },
 148	{ 0x0e, 0x02 },
 149	{ 0x10, 0x0f },
 150	{ 0x15, 0x20 },
 151	{ 0x16, 0x00 },
 152	{ 0x17, 0x00 },
 153	{ 0x18, 0x00 },
 154	{ 0x1a, 0x00 },
 155};
 156
 157static const DECLARE_TLV_DB_MINMAX_MUTE(adau1977_adc_gain, -3562, 6000);
 158
 159static const struct snd_soc_dapm_widget adau1977_micbias_dapm_widgets[] = {
 160	SND_SOC_DAPM_SUPPLY("MICBIAS", ADAU1977_REG_MICBIAS,
 161		3, 0, NULL, 0)
 162};
 163
 164static const struct snd_soc_dapm_widget adau1977_dapm_widgets[] = {
 165	SND_SOC_DAPM_SUPPLY("Vref", ADAU1977_REG_BLOCK_POWER_SAI,
 166		4, 0, NULL, 0),
 167
 168	SND_SOC_DAPM_ADC("ADC1", "Capture", ADAU1977_REG_BLOCK_POWER_SAI, 0, 0),
 169	SND_SOC_DAPM_ADC("ADC2", "Capture", ADAU1977_REG_BLOCK_POWER_SAI, 1, 0),
 170	SND_SOC_DAPM_ADC("ADC3", "Capture", ADAU1977_REG_BLOCK_POWER_SAI, 2, 0),
 171	SND_SOC_DAPM_ADC("ADC4", "Capture", ADAU1977_REG_BLOCK_POWER_SAI, 3, 0),
 172
 173	SND_SOC_DAPM_INPUT("AIN1"),
 174	SND_SOC_DAPM_INPUT("AIN2"),
 175	SND_SOC_DAPM_INPUT("AIN3"),
 176	SND_SOC_DAPM_INPUT("AIN4"),
 177
 178	SND_SOC_DAPM_OUTPUT("VREF"),
 179};
 180
 181static const struct snd_soc_dapm_route adau1977_dapm_routes[] = {
 182	{ "ADC1", NULL, "AIN1" },
 183	{ "ADC2", NULL, "AIN2" },
 184	{ "ADC3", NULL, "AIN3" },
 185	{ "ADC4", NULL, "AIN4" },
 186
 187	{ "ADC1", NULL, "Vref" },
 188	{ "ADC2", NULL, "Vref" },
 189	{ "ADC3", NULL, "Vref" },
 190	{ "ADC4", NULL, "Vref" },
 191
 192	{ "VREF", NULL, "Vref" },
 193};
 194
 195#define ADAU1977_VOLUME(x) \
 196	SOC_SINGLE_TLV("ADC" #x " Capture Volume", \
 197		ADAU1977_REG_POST_ADC_GAIN((x) - 1), \
 198		0, 255, 1, adau1977_adc_gain)
 199
 200#define ADAU1977_HPF_SWITCH(x) \
 201	SOC_SINGLE("ADC" #x " Highpass-Filter Capture Switch", \
 202		ADAU1977_REG_DC_HPF_CAL, (x) - 1, 1, 0)
 203
 204#define ADAU1977_DC_SUB_SWITCH(x) \
 205	SOC_SINGLE("ADC" #x " DC Subtraction Capture Switch", \
 206		ADAU1977_REG_DC_HPF_CAL, (x) + 3, 1, 0)
 207
 208static const struct snd_kcontrol_new adau1977_snd_controls[] = {
 209	ADAU1977_VOLUME(1),
 210	ADAU1977_VOLUME(2),
 211	ADAU1977_VOLUME(3),
 212	ADAU1977_VOLUME(4),
 213
 214	ADAU1977_HPF_SWITCH(1),
 215	ADAU1977_HPF_SWITCH(2),
 216	ADAU1977_HPF_SWITCH(3),
 217	ADAU1977_HPF_SWITCH(4),
 218
 219	ADAU1977_DC_SUB_SWITCH(1),
 220	ADAU1977_DC_SUB_SWITCH(2),
 221	ADAU1977_DC_SUB_SWITCH(3),
 222	ADAU1977_DC_SUB_SWITCH(4),
 223};
 224
 225static int adau1977_reset(struct adau1977 *adau1977)
 226{
 227	int ret;
 228
 229	/*
 230	 * The reset bit is obviously volatile, but we need to be able to cache
 231	 * the other bits in the register, so we can't just mark the whole
 232	 * register as volatile. Since this is the only place where we'll ever
 233	 * touch the reset bit just bypass the cache for this operation.
 234	 */
 235	regcache_cache_bypass(adau1977->regmap, true);
 236	ret = regmap_write(adau1977->regmap, ADAU1977_REG_POWER,
 237			ADAU1977_POWER_RESET);
 238	regcache_cache_bypass(adau1977->regmap, false);
 239
 240	return ret;
 241}
 242
 243/*
 244 * Returns the appropriate setting for ths FS field in the CTRL0 register
 245 * depending on the rate.
 246 */
 247static int adau1977_lookup_fs(unsigned int rate)
 248{
 249	if (rate >= 8000 && rate <= 12000)
 250		return ADAU1977_SAI_CTRL0_FS_8000_12000;
 251	else if (rate >= 16000 && rate <= 24000)
 252		return ADAU1977_SAI_CTRL0_FS_16000_24000;
 253	else if (rate >= 32000 && rate <= 48000)
 254		return ADAU1977_SAI_CTRL0_FS_32000_48000;
 255	else if (rate >= 64000 && rate <= 96000)
 256		return ADAU1977_SAI_CTRL0_FS_64000_96000;
 257	else if (rate >= 128000 && rate <= 192000)
 258		return ADAU1977_SAI_CTRL0_FS_128000_192000;
 259	else
 260		return -EINVAL;
 261}
 262
 263static int adau1977_lookup_mcs(struct adau1977 *adau1977, unsigned int rate,
 264	unsigned int fs)
 265{
 266	unsigned int mcs;
 267
 268	/*
 269	 * rate = sysclk / (512 * mcs_lut[mcs]) * 2**fs
 270	 * => mcs_lut[mcs] = sysclk / (512 * rate) * 2**fs
 271	 * => mcs_lut[mcs] = sysclk / ((512 / 2**fs) * rate)
 272	 */
 273
 274	rate *= 512 >> fs;
 275
 276	if (adau1977->sysclk % rate != 0)
 277		return -EINVAL;
 278
 279	mcs = adau1977->sysclk / rate;
 280
 281	/* The factors configured by MCS are 1, 2, 3, 4, 6 */
 282	if (mcs < 1 || mcs > 6 || mcs == 5)
 283		return -EINVAL;
 284
 285	mcs = mcs - 1;
 286	if (mcs == 5)
 287		mcs = 4;
 288
 289	return mcs;
 290}
 291
 292static int adau1977_hw_params(struct snd_pcm_substream *substream,
 293	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 294{
 295	struct snd_soc_component *component = dai->component;
 296	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component);
 297	unsigned int rate = params_rate(params);
 298	unsigned int slot_width;
 299	unsigned int ctrl0, ctrl0_mask;
 300	unsigned int ctrl1;
 301	int mcs, fs;
 302	int ret;
 303
 304	fs = adau1977_lookup_fs(rate);
 305	if (fs < 0)
 306		return fs;
 307
 308	if (adau1977->sysclk_src == ADAU1977_SYSCLK_SRC_MCLK) {
 309		mcs = adau1977_lookup_mcs(adau1977, rate, fs);
 310		if (mcs < 0)
 311			return mcs;
 312	} else {
 313		mcs = 0;
 314	}
 315
 316	ctrl0_mask = ADAU1977_SAI_CTRL0_FS_MASK;
 317	ctrl0 = fs;
 318
 319	if (adau1977->right_j) {
 320		switch (params_width(params)) {
 321		case 16:
 322			ctrl0 |= ADAU1977_SAI_CTRL0_FMT_RJ_16BIT;
 323			break;
 324		case 24:
 325			ctrl0 |= ADAU1977_SAI_CTRL0_FMT_RJ_24BIT;
 326			break;
 327		default:
 328			return -EINVAL;
 329		}
 330		ctrl0_mask |= ADAU1977_SAI_CTRL0_FMT_MASK;
 331	}
 332
 333	if (adau1977->clock_provider) {
 334		switch (params_width(params)) {
 335		case 16:
 336			ctrl1 = ADAU1977_SAI_CTRL1_DATA_WIDTH_16BIT;
 337			slot_width = 16;
 338			break;
 339		case 24:
 340		case 32:
 341			ctrl1 = ADAU1977_SAI_CTRL1_DATA_WIDTH_24BIT;
 342			slot_width = 32;
 343			break;
 344		default:
 345			return -EINVAL;
 346		}
 347
 348		/* In TDM mode there is a fixed slot width */
 349		if (adau1977->slot_width)
 350			slot_width = adau1977->slot_width;
 351
 352		if (slot_width == 16)
 353			ctrl1 |= ADAU1977_SAI_CTRL1_BCLKRATE_16;
 354		else
 355			ctrl1 |= ADAU1977_SAI_CTRL1_BCLKRATE_32;
 356
 357		ret = regmap_update_bits(adau1977->regmap,
 358			ADAU1977_REG_SAI_CTRL1,
 359			ADAU1977_SAI_CTRL1_DATA_WIDTH_MASK |
 360			ADAU1977_SAI_CTRL1_BCLKRATE_MASK,
 361			ctrl1);
 362		if (ret < 0)
 363			return ret;
 364	}
 365
 366	ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0,
 367				ctrl0_mask, ctrl0);
 368	if (ret < 0)
 369		return ret;
 370
 371	return regmap_update_bits(adau1977->regmap, ADAU1977_REG_PLL,
 372				ADAU1977_PLL_MCS_MASK, mcs);
 373}
 374
 375static int adau1977_power_disable(struct adau1977 *adau1977)
 376{
 377	int ret = 0;
 378
 379	if (!adau1977->enabled)
 380		return 0;
 381
 382	ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_POWER,
 383		ADAU1977_POWER_PWUP, 0);
 384	if (ret)
 385		return ret;
 386
 387	regcache_mark_dirty(adau1977->regmap);
 388
 389	gpiod_set_value_cansleep(adau1977->reset_gpio, 0);
 390
 391	regcache_cache_only(adau1977->regmap, true);
 392
 393	regulator_disable(adau1977->avdd_reg);
 394	if (adau1977->dvdd_reg)
 395		regulator_disable(adau1977->dvdd_reg);
 396
 397	adau1977->enabled = false;
 398
 399	return 0;
 400}
 401
 402static int adau1977_power_enable(struct adau1977 *adau1977)
 403{
 404	unsigned int val;
 405	int ret = 0;
 406
 407	if (adau1977->enabled)
 408		return 0;
 409
 410	ret = regulator_enable(adau1977->avdd_reg);
 411	if (ret)
 412		return ret;
 413
 414	if (adau1977->dvdd_reg) {
 415		ret = regulator_enable(adau1977->dvdd_reg);
 416		if (ret)
 417			goto err_disable_avdd;
 418	}
 419
 420	gpiod_set_value_cansleep(adau1977->reset_gpio, 1);
 421
 422	regcache_cache_only(adau1977->regmap, false);
 423
 424	if (adau1977->switch_mode)
 425		adau1977->switch_mode(adau1977->dev);
 426
 427	ret = adau1977_reset(adau1977);
 428	if (ret)
 429		goto err_disable_dvdd;
 430
 431	ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_POWER,
 432		ADAU1977_POWER_PWUP, ADAU1977_POWER_PWUP);
 433	if (ret)
 434		goto err_disable_dvdd;
 435
 436	ret = regcache_sync(adau1977->regmap);
 437	if (ret)
 438		goto err_disable_dvdd;
 439
 440	/*
 441	 * The PLL register is not affected by the software reset. It is
 442	 * possible that the value of the register was changed to the
 443	 * default value while we were in cache only mode. In this case
 444	 * regcache_sync will skip over it and we have to manually sync
 445	 * it.
 446	 */
 447	ret = regmap_read(adau1977->regmap, ADAU1977_REG_PLL, &val);
 448	if (ret)
 449		goto err_disable_dvdd;
 450
 451	if (val == 0x41) {
 452		regcache_cache_bypass(adau1977->regmap, true);
 453		ret = regmap_write(adau1977->regmap, ADAU1977_REG_PLL,
 454			0x41);
 455		if (ret)
 456			goto err_disable_dvdd;
 457		regcache_cache_bypass(adau1977->regmap, false);
 458	}
 459
 460	adau1977->enabled = true;
 461
 462	return ret;
 463
 464err_disable_dvdd:
 465	if (adau1977->dvdd_reg)
 466		regulator_disable(adau1977->dvdd_reg);
 467err_disable_avdd:
 468		regulator_disable(adau1977->avdd_reg);
 469	return ret;
 470}
 471
 472static int adau1977_set_bias_level(struct snd_soc_component *component,
 473	enum snd_soc_bias_level level)
 474{
 475	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component);
 476	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
 477	int ret = 0;
 478
 479	switch (level) {
 480	case SND_SOC_BIAS_ON:
 481		break;
 482	case SND_SOC_BIAS_PREPARE:
 483		break;
 484	case SND_SOC_BIAS_STANDBY:
 485		if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF)
 486			ret = adau1977_power_enable(adau1977);
 487		break;
 488	case SND_SOC_BIAS_OFF:
 489		ret = adau1977_power_disable(adau1977);
 490		break;
 491	}
 492
 493	return ret;
 494}
 495
 496static int adau1977_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 497	unsigned int rx_mask, int slots, int width)
 498{
 499	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
 500	unsigned int ctrl0, ctrl1, drv;
 501	unsigned int slot[4];
 502	unsigned int i;
 503	int ret;
 504
 505	if (slots == 0) {
 506		/* 0 = No fixed slot width */
 507		adau1977->slot_width = 0;
 508		adau1977->max_clock_provider_fs = 192000;
 509		return regmap_update_bits(adau1977->regmap,
 510			ADAU1977_REG_SAI_CTRL0, ADAU1977_SAI_CTRL0_SAI_MASK,
 511			ADAU1977_SAI_CTRL0_SAI_I2S);
 512	}
 513
 514	if (rx_mask == 0 || tx_mask != 0)
 515		return -EINVAL;
 516
 517	drv = 0;
 518	for (i = 0; i < 4; i++) {
 519		slot[i] = __ffs(rx_mask);
 520		drv |= ADAU1977_SAI_OVERTEMP_DRV_C(i);
 521		rx_mask &= ~(1 << slot[i]);
 522		if (slot[i] >= slots)
 523			return -EINVAL;
 524		if (rx_mask == 0)
 525			break;
 526	}
 527
 528	if (rx_mask != 0)
 529		return -EINVAL;
 530
 531	switch (width) {
 532	case 16:
 533		ctrl1 = ADAU1977_SAI_CTRL1_SLOT_WIDTH_16;
 534		break;
 535	case 24:
 536		/* We can only generate 16 bit or 32 bit wide slots */
 537		if (adau1977->clock_provider)
 538			return -EINVAL;
 539		ctrl1 = ADAU1977_SAI_CTRL1_SLOT_WIDTH_24;
 540		break;
 541	case 32:
 542		ctrl1 = ADAU1977_SAI_CTRL1_SLOT_WIDTH_32;
 543		break;
 544	default:
 545		return -EINVAL;
 546	}
 547
 548	switch (slots) {
 549	case 2:
 550		ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_2;
 551		break;
 552	case 4:
 553		ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_4;
 554		break;
 555	case 8:
 556		ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_8;
 557		break;
 558	case 16:
 559		ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_16;
 560		break;
 561	default:
 562		return -EINVAL;
 563	}
 564
 565	ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_OVERTEMP,
 566		ADAU1977_SAI_OVERTEMP_DRV_C(0) |
 567		ADAU1977_SAI_OVERTEMP_DRV_C(1) |
 568		ADAU1977_SAI_OVERTEMP_DRV_C(2) |
 569		ADAU1977_SAI_OVERTEMP_DRV_C(3), drv);
 570	if (ret)
 571		return ret;
 572
 573	ret = regmap_write(adau1977->regmap, ADAU1977_REG_CMAP12,
 574		(slot[1] << ADAU1977_CHAN_MAP_SECOND_SLOT_OFFSET) |
 575		(slot[0] << ADAU1977_CHAN_MAP_FIRST_SLOT_OFFSET));
 576	if (ret)
 577		return ret;
 578
 579	ret = regmap_write(adau1977->regmap, ADAU1977_REG_CMAP34,
 580		(slot[3] << ADAU1977_CHAN_MAP_SECOND_SLOT_OFFSET) |
 581		(slot[2] << ADAU1977_CHAN_MAP_FIRST_SLOT_OFFSET));
 582	if (ret)
 583		return ret;
 584
 585	ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0,
 586		ADAU1977_SAI_CTRL0_SAI_MASK, ctrl0);
 587	if (ret)
 588		return ret;
 589
 590	ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL1,
 591		ADAU1977_SAI_CTRL1_SLOT_WIDTH_MASK, ctrl1);
 592	if (ret)
 593		return ret;
 594
 595	adau1977->slot_width = width;
 596
 597	/* In clock provider mode the maximum bitclock is 24.576 MHz */
 598	adau1977->max_clock_provider_fs = min(192000, 24576000 / width / slots);
 599
 600	return 0;
 601}
 602
 603static int adau1977_mute(struct snd_soc_dai *dai, int mute, int stream)
 604{
 605	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
 606	unsigned int val;
 607
 608	if (mute)
 609		val = ADAU1977_MISC_CONTROL_MMUTE;
 610	else
 611		val = 0;
 612
 613	return regmap_update_bits(adau1977->regmap, ADAU1977_REG_MISC_CONTROL,
 614			ADAU1977_MISC_CONTROL_MMUTE, val);
 615}
 616
 617static int adau1977_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 618{
 619	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
 620	unsigned int ctrl0 = 0, ctrl1 = 0, block_power = 0;
 621	bool invert_lrclk;
 622	int ret;
 623
 624	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
 625	case SND_SOC_DAIFMT_CBC_CFC:
 626		adau1977->clock_provider = false;
 627		break;
 628	case SND_SOC_DAIFMT_CBP_CFP:
 629		ctrl1 |= ADAU1977_SAI_CTRL1_MASTER;
 630		adau1977->clock_provider = true;
 631		break;
 632	default:
 633		return -EINVAL;
 634	}
 635
 636	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 637	case SND_SOC_DAIFMT_NB_NF:
 638		invert_lrclk = false;
 639		break;
 640	case SND_SOC_DAIFMT_IB_NF:
 641		block_power |= ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE;
 642		invert_lrclk = false;
 643		break;
 644	case SND_SOC_DAIFMT_NB_IF:
 645		invert_lrclk = true;
 646		break;
 647	case SND_SOC_DAIFMT_IB_IF:
 648		block_power |= ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE;
 649		invert_lrclk = true;
 650		break;
 651	default:
 652		return -EINVAL;
 653	}
 654
 655	adau1977->right_j = false;
 656	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 657	case SND_SOC_DAIFMT_I2S:
 658		ctrl0 |= ADAU1977_SAI_CTRL0_FMT_I2S;
 659		break;
 660	case SND_SOC_DAIFMT_LEFT_J:
 661		ctrl0 |= ADAU1977_SAI_CTRL0_FMT_LJ;
 662		invert_lrclk = !invert_lrclk;
 663		break;
 664	case SND_SOC_DAIFMT_RIGHT_J:
 665		ctrl0 |= ADAU1977_SAI_CTRL0_FMT_RJ_24BIT;
 666		adau1977->right_j = true;
 667		invert_lrclk = !invert_lrclk;
 668		break;
 669	case SND_SOC_DAIFMT_DSP_A:
 670		ctrl1 |= ADAU1977_SAI_CTRL1_LRCLK_PULSE;
 671		ctrl0 |= ADAU1977_SAI_CTRL0_FMT_I2S;
 672		invert_lrclk = false;
 673		break;
 674	case SND_SOC_DAIFMT_DSP_B:
 675		ctrl1 |= ADAU1977_SAI_CTRL1_LRCLK_PULSE;
 676		ctrl0 |= ADAU1977_SAI_CTRL0_FMT_LJ;
 677		invert_lrclk = false;
 678		break;
 679	default:
 680		return -EINVAL;
 681	}
 682
 683	if (invert_lrclk)
 684		block_power |= ADAU1977_BLOCK_POWER_SAI_LR_POL;
 685
 686	ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_BLOCK_POWER_SAI,
 687		ADAU1977_BLOCK_POWER_SAI_LR_POL |
 688		ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE, block_power);
 689	if (ret)
 690		return ret;
 691
 692	ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0,
 693		ADAU1977_SAI_CTRL0_FMT_MASK,
 694		ctrl0);
 695	if (ret)
 696		return ret;
 697
 698	return regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL1,
 699		ADAU1977_SAI_CTRL1_MASTER | ADAU1977_SAI_CTRL1_LRCLK_PULSE,
 700		ctrl1);
 701}
 702
 703static int adau1977_startup(struct snd_pcm_substream *substream,
 704	struct snd_soc_dai *dai)
 705{
 706	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
 707	u64 formats = 0;
 708
 709	if (adau1977->slot_width == 16)
 710		formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE;
 711	else if (adau1977->right_j || adau1977->slot_width == 24)
 712		formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
 713			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE;
 714
 715	snd_pcm_hw_constraint_list(substream->runtime, 0,
 716		SNDRV_PCM_HW_PARAM_RATE, &adau1977->constraints);
 717
 718	if (adau1977->clock_provider)
 719		snd_pcm_hw_constraint_minmax(substream->runtime,
 720			SNDRV_PCM_HW_PARAM_RATE, 8000,
 721					     adau1977->max_clock_provider_fs);
 722
 723	if (formats != 0)
 724		snd_pcm_hw_constraint_mask64(substream->runtime,
 725			SNDRV_PCM_HW_PARAM_FORMAT, formats);
 726
 727	return 0;
 728}
 729
 730static int adau1977_set_tristate(struct snd_soc_dai *dai, int tristate)
 731{
 732	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
 733	unsigned int val;
 734
 735	if (tristate)
 736		val = ADAU1977_SAI_OVERTEMP_DRV_HIZ;
 737	else
 738		val = 0;
 739
 740	return regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_OVERTEMP,
 741		ADAU1977_SAI_OVERTEMP_DRV_HIZ, val);
 742}
 743
 744static const struct snd_soc_dai_ops adau1977_dai_ops = {
 745	.startup	= adau1977_startup,
 746	.hw_params	= adau1977_hw_params,
 747	.mute_stream	= adau1977_mute,
 748	.set_fmt	= adau1977_set_dai_fmt,
 749	.set_tdm_slot	= adau1977_set_tdm_slot,
 750	.set_tristate	= adau1977_set_tristate,
 751};
 752
 753static struct snd_soc_dai_driver adau1977_dai = {
 754	.name = "adau1977-hifi",
 755	.capture = {
 756		.stream_name = "Capture",
 757		.channels_min = 1,
 758		.channels_max = 4,
 759		.rates = SNDRV_PCM_RATE_KNOT,
 760		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
 761		    SNDRV_PCM_FMTBIT_S32_LE,
 762		.sig_bits = 24,
 763	},
 764	.ops = &adau1977_dai_ops,
 765};
 766
 767static const unsigned int adau1977_rates[] = {
 768	8000, 16000, 32000, 64000, 128000,
 769	11025, 22050, 44100, 88200, 172400,
 770	12000, 24000, 48000, 96000, 192000,
 771};
 772
 773#define ADAU1977_RATE_CONSTRAINT_MASK_32000 0x001f
 774#define ADAU1977_RATE_CONSTRAINT_MASK_44100 0x03e0
 775#define ADAU1977_RATE_CONSTRAINT_MASK_48000 0x7c00
 776/* All rates >= 32000 */
 777#define ADAU1977_RATE_CONSTRAINT_MASK_LRCLK 0x739c
 778
 779static bool adau1977_check_sysclk(unsigned int mclk, unsigned int base_freq)
 780{
 781	unsigned int mcs;
 782
 783	if (mclk % (base_freq * 128) != 0)
 784		return false;
 785
 786	mcs = mclk / (128 * base_freq);
 787	if (mcs < 1 || mcs > 6 || mcs == 5)
 788		return false;
 789
 790	return true;
 791}
 792
 793static int adau1977_set_sysclk(struct snd_soc_component *component,
 794	int clk_id, int source, unsigned int freq, int dir)
 795{
 796	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component);
 797	unsigned int mask = 0;
 798	unsigned int clk_src;
 799	int ret;
 800
 801	if (dir != SND_SOC_CLOCK_IN)
 802		return -EINVAL;
 803
 804	if (clk_id != ADAU1977_SYSCLK)
 805		return -EINVAL;
 806
 807	switch (source) {
 808	case ADAU1977_SYSCLK_SRC_MCLK:
 809		clk_src = 0;
 810		break;
 811	case ADAU1977_SYSCLK_SRC_LRCLK:
 812		clk_src = ADAU1977_PLL_CLK_S;
 813		break;
 814	default:
 815		return -EINVAL;
 816	}
 817
 818	if (freq != 0 && source == ADAU1977_SYSCLK_SRC_MCLK) {
 819		if (freq < 4000000 || freq > 36864000)
 820			return -EINVAL;
 821
 822		if (adau1977_check_sysclk(freq, 32000))
 823			mask |= ADAU1977_RATE_CONSTRAINT_MASK_32000;
 824		if (adau1977_check_sysclk(freq, 44100))
 825			mask |= ADAU1977_RATE_CONSTRAINT_MASK_44100;
 826		if (adau1977_check_sysclk(freq, 48000))
 827			mask |= ADAU1977_RATE_CONSTRAINT_MASK_48000;
 828
 829		if (mask == 0)
 830			return -EINVAL;
 831	} else if (source == ADAU1977_SYSCLK_SRC_LRCLK) {
 832		mask = ADAU1977_RATE_CONSTRAINT_MASK_LRCLK;
 833	}
 834
 835	ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_PLL,
 836		ADAU1977_PLL_CLK_S, clk_src);
 837	if (ret)
 838		return ret;
 839
 840	adau1977->constraints.mask = mask;
 841	adau1977->sysclk_src = source;
 842	adau1977->sysclk = freq;
 843
 844	return 0;
 845}
 846
 847static int adau1977_component_probe(struct snd_soc_component *component)
 848{
 849	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
 850	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component);
 851	int ret;
 852
 853	switch (adau1977->type) {
 854	case ADAU1977:
 855		ret = snd_soc_dapm_new_controls(dapm,
 856			adau1977_micbias_dapm_widgets,
 857			ARRAY_SIZE(adau1977_micbias_dapm_widgets));
 858		if (ret < 0)
 859			return ret;
 860		break;
 861	default:
 862		break;
 863	}
 864
 865	return 0;
 866}
 867
 868static const struct snd_soc_component_driver adau1977_component_driver = {
 869	.probe			= adau1977_component_probe,
 870	.set_bias_level		= adau1977_set_bias_level,
 871	.set_sysclk		= adau1977_set_sysclk,
 872	.controls		= adau1977_snd_controls,
 873	.num_controls		= ARRAY_SIZE(adau1977_snd_controls),
 874	.dapm_widgets		= adau1977_dapm_widgets,
 875	.num_dapm_widgets	= ARRAY_SIZE(adau1977_dapm_widgets),
 876	.dapm_routes		= adau1977_dapm_routes,
 877	.num_dapm_routes	= ARRAY_SIZE(adau1977_dapm_routes),
 878	.use_pmdown_time	= 1,
 879	.endianness		= 1,
 880};
 881
 882static int adau1977_setup_micbias(struct adau1977 *adau1977)
 883{
 884	unsigned int micbias;
 885
 886	if (device_property_read_u32(adau1977->dev, "adi,micbias", &micbias))
 887		micbias = ADAU1977_MICBIAS_8V5;
 888
 889	if (micbias > ADAU1977_MICBIAS_9V0) {
 890		dev_err(adau1977->dev, "Invalid value for 'adi,micbias'\n");
 891		return -EINVAL;
 892	}
 893
 894	return regmap_update_bits(adau1977->regmap, ADAU1977_REG_MICBIAS,
 895		ADAU1977_MICBIAS_MB_VOLTS_MASK,
 896		micbias << ADAU1977_MICBIAS_MB_VOLTS_OFFSET);
 897}
 898
 899int adau1977_probe(struct device *dev, struct regmap *regmap,
 900	enum adau1977_type type, void (*switch_mode)(struct device *dev))
 901{
 902	unsigned int power_off_mask;
 903	struct adau1977 *adau1977;
 904	int ret;
 905
 906	if (IS_ERR(regmap))
 907		return PTR_ERR(regmap);
 908
 909	adau1977 = devm_kzalloc(dev, sizeof(*adau1977), GFP_KERNEL);
 910	if (adau1977 == NULL)
 911		return -ENOMEM;
 912
 913	adau1977->dev = dev;
 914	adau1977->type = type;
 915	adau1977->regmap = regmap;
 916	adau1977->switch_mode = switch_mode;
 917	adau1977->max_clock_provider_fs = 192000;
 918
 919	adau1977->constraints.list = adau1977_rates;
 920	adau1977->constraints.count = ARRAY_SIZE(adau1977_rates);
 921
 922	adau1977->avdd_reg = devm_regulator_get(dev, "AVDD");
 923	if (IS_ERR(adau1977->avdd_reg))
 924		return PTR_ERR(adau1977->avdd_reg);
 925
 926	adau1977->dvdd_reg = devm_regulator_get_optional(dev, "DVDD");
 927	if (IS_ERR(adau1977->dvdd_reg)) {
 928		if (PTR_ERR(adau1977->dvdd_reg) != -ENODEV)
 929			return PTR_ERR(adau1977->dvdd_reg);
 930		adau1977->dvdd_reg = NULL;
 931	}
 932
 933	adau1977->reset_gpio = devm_gpiod_get_optional(dev, "reset",
 934						       GPIOD_OUT_LOW);
 935	if (IS_ERR(adau1977->reset_gpio))
 936		return PTR_ERR(adau1977->reset_gpio);
 937
 938	dev_set_drvdata(dev, adau1977);
 939
 940	if (adau1977->reset_gpio)
 941		ndelay(100);
 942
 943	ret = adau1977_power_enable(adau1977);
 944	if (ret)
 945		return ret;
 946
 947	if (type == ADAU1977) {
 948		ret = adau1977_setup_micbias(adau1977);
 949		if (ret)
 950			goto err_poweroff;
 951	}
 952
 953	if (adau1977->dvdd_reg)
 954		power_off_mask = ~0;
 955	else
 956		power_off_mask = (unsigned int)~ADAU1977_BLOCK_POWER_SAI_LDO_EN;
 957
 958	ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_BLOCK_POWER_SAI,
 959				power_off_mask, 0x00);
 960	if (ret)
 961		goto err_poweroff;
 962
 963	ret = adau1977_power_disable(adau1977);
 964	if (ret)
 965		return ret;
 966
 967	return devm_snd_soc_register_component(dev, &adau1977_component_driver,
 968			&adau1977_dai, 1);
 969
 970err_poweroff:
 971	adau1977_power_disable(adau1977);
 972	return ret;
 973
 974}
 975EXPORT_SYMBOL_GPL(adau1977_probe);
 976
 977static bool adau1977_register_volatile(struct device *dev, unsigned int reg)
 978{
 979	switch (reg) {
 980	case ADAU1977_REG_STATUS(0):
 981	case ADAU1977_REG_STATUS(1):
 982	case ADAU1977_REG_STATUS(2):
 983	case ADAU1977_REG_STATUS(3):
 984	case ADAU1977_REG_ADC_CLIP:
 985		return true;
 986	}
 987
 988	return false;
 989}
 990
 991const struct regmap_config adau1977_regmap_config = {
 992	.max_register = ADAU1977_REG_DC_HPF_CAL,
 993	.volatile_reg = adau1977_register_volatile,
 994
 995	.cache_type = REGCACHE_MAPLE,
 996	.reg_defaults = adau1977_reg_defaults,
 997	.num_reg_defaults = ARRAY_SIZE(adau1977_reg_defaults),
 998};
 999EXPORT_SYMBOL_GPL(adau1977_regmap_config);
1000
1001MODULE_DESCRIPTION("ASoC ADAU1977/ADAU1978/ADAU1979 driver");
1002MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
1003MODULE_LICENSE("GPL");
~/ Read-only file preview.