cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

adau1977.c (25765B)


      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	int ret = 0;
    477
    478	switch (level) {
    479	case SND_SOC_BIAS_ON:
    480		break;
    481	case SND_SOC_BIAS_PREPARE:
    482		break;
    483	case SND_SOC_BIAS_STANDBY:
    484		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
    485			ret = adau1977_power_enable(adau1977);
    486		break;
    487	case SND_SOC_BIAS_OFF:
    488		ret = adau1977_power_disable(adau1977);
    489		break;
    490	}
    491
    492	return ret;
    493}
    494
    495static int adau1977_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
    496	unsigned int rx_mask, int slots, int width)
    497{
    498	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
    499	unsigned int ctrl0, ctrl1, drv;
    500	unsigned int slot[4];
    501	unsigned int i;
    502	int ret;
    503
    504	if (slots == 0) {
    505		/* 0 = No fixed slot width */
    506		adau1977->slot_width = 0;
    507		adau1977->max_clock_provider_fs = 192000;
    508		return regmap_update_bits(adau1977->regmap,
    509			ADAU1977_REG_SAI_CTRL0, ADAU1977_SAI_CTRL0_SAI_MASK,
    510			ADAU1977_SAI_CTRL0_SAI_I2S);
    511	}
    512
    513	if (rx_mask == 0 || tx_mask != 0)
    514		return -EINVAL;
    515
    516	drv = 0;
    517	for (i = 0; i < 4; i++) {
    518		slot[i] = __ffs(rx_mask);
    519		drv |= ADAU1977_SAI_OVERTEMP_DRV_C(i);
    520		rx_mask &= ~(1 << slot[i]);
    521		if (slot[i] >= slots)
    522			return -EINVAL;
    523		if (rx_mask == 0)
    524			break;
    525	}
    526
    527	if (rx_mask != 0)
    528		return -EINVAL;
    529
    530	switch (width) {
    531	case 16:
    532		ctrl1 = ADAU1977_SAI_CTRL1_SLOT_WIDTH_16;
    533		break;
    534	case 24:
    535		/* We can only generate 16 bit or 32 bit wide slots */
    536		if (adau1977->clock_provider)
    537			return -EINVAL;
    538		ctrl1 = ADAU1977_SAI_CTRL1_SLOT_WIDTH_24;
    539		break;
    540	case 32:
    541		ctrl1 = ADAU1977_SAI_CTRL1_SLOT_WIDTH_32;
    542		break;
    543	default:
    544		return -EINVAL;
    545	}
    546
    547	switch (slots) {
    548	case 2:
    549		ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_2;
    550		break;
    551	case 4:
    552		ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_4;
    553		break;
    554	case 8:
    555		ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_8;
    556		break;
    557	case 16:
    558		ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_16;
    559		break;
    560	default:
    561		return -EINVAL;
    562	}
    563
    564	ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_OVERTEMP,
    565		ADAU1977_SAI_OVERTEMP_DRV_C(0) |
    566		ADAU1977_SAI_OVERTEMP_DRV_C(1) |
    567		ADAU1977_SAI_OVERTEMP_DRV_C(2) |
    568		ADAU1977_SAI_OVERTEMP_DRV_C(3), drv);
    569	if (ret)
    570		return ret;
    571
    572	ret = regmap_write(adau1977->regmap, ADAU1977_REG_CMAP12,
    573		(slot[1] << ADAU1977_CHAN_MAP_SECOND_SLOT_OFFSET) |
    574		(slot[0] << ADAU1977_CHAN_MAP_FIRST_SLOT_OFFSET));
    575	if (ret)
    576		return ret;
    577
    578	ret = regmap_write(adau1977->regmap, ADAU1977_REG_CMAP34,
    579		(slot[3] << ADAU1977_CHAN_MAP_SECOND_SLOT_OFFSET) |
    580		(slot[2] << ADAU1977_CHAN_MAP_FIRST_SLOT_OFFSET));
    581	if (ret)
    582		return ret;
    583
    584	ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0,
    585		ADAU1977_SAI_CTRL0_SAI_MASK, ctrl0);
    586	if (ret)
    587		return ret;
    588
    589	ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL1,
    590		ADAU1977_SAI_CTRL1_SLOT_WIDTH_MASK, ctrl1);
    591	if (ret)
    592		return ret;
    593
    594	adau1977->slot_width = width;
    595
    596	/* In clock provider mode the maximum bitclock is 24.576 MHz */
    597	adau1977->max_clock_provider_fs = min(192000, 24576000 / width / slots);
    598
    599	return 0;
    600}
    601
    602static int adau1977_mute(struct snd_soc_dai *dai, int mute, int stream)
    603{
    604	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
    605	unsigned int val;
    606
    607	if (mute)
    608		val = ADAU1977_MISC_CONTROL_MMUTE;
    609	else
    610		val = 0;
    611
    612	return regmap_update_bits(adau1977->regmap, ADAU1977_REG_MISC_CONTROL,
    613			ADAU1977_MISC_CONTROL_MMUTE, val);
    614}
    615
    616static int adau1977_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
    617{
    618	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
    619	unsigned int ctrl0 = 0, ctrl1 = 0, block_power = 0;
    620	bool invert_lrclk;
    621	int ret;
    622
    623	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
    624	case SND_SOC_DAIFMT_CBC_CFC:
    625		adau1977->clock_provider = false;
    626		break;
    627	case SND_SOC_DAIFMT_CBP_CFP:
    628		ctrl1 |= ADAU1977_SAI_CTRL1_MASTER;
    629		adau1977->clock_provider = true;
    630		break;
    631	default:
    632		return -EINVAL;
    633	}
    634
    635	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
    636	case SND_SOC_DAIFMT_NB_NF:
    637		invert_lrclk = false;
    638		break;
    639	case SND_SOC_DAIFMT_IB_NF:
    640		block_power |= ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE;
    641		invert_lrclk = false;
    642		break;
    643	case SND_SOC_DAIFMT_NB_IF:
    644		invert_lrclk = true;
    645		break;
    646	case SND_SOC_DAIFMT_IB_IF:
    647		block_power |= ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE;
    648		invert_lrclk = true;
    649		break;
    650	default:
    651		return -EINVAL;
    652	}
    653
    654	adau1977->right_j = false;
    655	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
    656	case SND_SOC_DAIFMT_I2S:
    657		ctrl0 |= ADAU1977_SAI_CTRL0_FMT_I2S;
    658		break;
    659	case SND_SOC_DAIFMT_LEFT_J:
    660		ctrl0 |= ADAU1977_SAI_CTRL0_FMT_LJ;
    661		invert_lrclk = !invert_lrclk;
    662		break;
    663	case SND_SOC_DAIFMT_RIGHT_J:
    664		ctrl0 |= ADAU1977_SAI_CTRL0_FMT_RJ_24BIT;
    665		adau1977->right_j = true;
    666		invert_lrclk = !invert_lrclk;
    667		break;
    668	case SND_SOC_DAIFMT_DSP_A:
    669		ctrl1 |= ADAU1977_SAI_CTRL1_LRCLK_PULSE;
    670		ctrl0 |= ADAU1977_SAI_CTRL0_FMT_I2S;
    671		invert_lrclk = false;
    672		break;
    673	case SND_SOC_DAIFMT_DSP_B:
    674		ctrl1 |= ADAU1977_SAI_CTRL1_LRCLK_PULSE;
    675		ctrl0 |= ADAU1977_SAI_CTRL0_FMT_LJ;
    676		invert_lrclk = false;
    677		break;
    678	default:
    679		return -EINVAL;
    680	}
    681
    682	if (invert_lrclk)
    683		block_power |= ADAU1977_BLOCK_POWER_SAI_LR_POL;
    684
    685	ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_BLOCK_POWER_SAI,
    686		ADAU1977_BLOCK_POWER_SAI_LR_POL |
    687		ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE, block_power);
    688	if (ret)
    689		return ret;
    690
    691	ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0,
    692		ADAU1977_SAI_CTRL0_FMT_MASK,
    693		ctrl0);
    694	if (ret)
    695		return ret;
    696
    697	return regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL1,
    698		ADAU1977_SAI_CTRL1_MASTER | ADAU1977_SAI_CTRL1_LRCLK_PULSE,
    699		ctrl1);
    700}
    701
    702static int adau1977_startup(struct snd_pcm_substream *substream,
    703	struct snd_soc_dai *dai)
    704{
    705	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
    706	u64 formats = 0;
    707
    708	if (adau1977->slot_width == 16)
    709		formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE;
    710	else if (adau1977->right_j || adau1977->slot_width == 24)
    711		formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
    712			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE;
    713
    714	snd_pcm_hw_constraint_list(substream->runtime, 0,
    715		SNDRV_PCM_HW_PARAM_RATE, &adau1977->constraints);
    716
    717	if (adau1977->clock_provider)
    718		snd_pcm_hw_constraint_minmax(substream->runtime,
    719			SNDRV_PCM_HW_PARAM_RATE, 8000,
    720					     adau1977->max_clock_provider_fs);
    721
    722	if (formats != 0)
    723		snd_pcm_hw_constraint_mask64(substream->runtime,
    724			SNDRV_PCM_HW_PARAM_FORMAT, formats);
    725
    726	return 0;
    727}
    728
    729static int adau1977_set_tristate(struct snd_soc_dai *dai, int tristate)
    730{
    731	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
    732	unsigned int val;
    733
    734	if (tristate)
    735		val = ADAU1977_SAI_OVERTEMP_DRV_HIZ;
    736	else
    737		val = 0;
    738
    739	return regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_OVERTEMP,
    740		ADAU1977_SAI_OVERTEMP_DRV_HIZ, val);
    741}
    742
    743static const struct snd_soc_dai_ops adau1977_dai_ops = {
    744	.startup	= adau1977_startup,
    745	.hw_params	= adau1977_hw_params,
    746	.mute_stream	= adau1977_mute,
    747	.set_fmt	= adau1977_set_dai_fmt,
    748	.set_tdm_slot	= adau1977_set_tdm_slot,
    749	.set_tristate	= adau1977_set_tristate,
    750};
    751
    752static struct snd_soc_dai_driver adau1977_dai = {
    753	.name = "adau1977-hifi",
    754	.capture = {
    755		.stream_name = "Capture",
    756		.channels_min = 1,
    757		.channels_max = 4,
    758		.rates = SNDRV_PCM_RATE_KNOT,
    759		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
    760		    SNDRV_PCM_FMTBIT_S32_LE,
    761		.sig_bits = 24,
    762	},
    763	.ops = &adau1977_dai_ops,
    764};
    765
    766static const unsigned int adau1977_rates[] = {
    767	8000, 16000, 32000, 64000, 128000,
    768	11025, 22050, 44100, 88200, 172400,
    769	12000, 24000, 48000, 96000, 192000,
    770};
    771
    772#define ADAU1977_RATE_CONSTRAINT_MASK_32000 0x001f
    773#define ADAU1977_RATE_CONSTRAINT_MASK_44100 0x03e0
    774#define ADAU1977_RATE_CONSTRAINT_MASK_48000 0x7c00
    775/* All rates >= 32000 */
    776#define ADAU1977_RATE_CONSTRAINT_MASK_LRCLK 0x739c
    777
    778static bool adau1977_check_sysclk(unsigned int mclk, unsigned int base_freq)
    779{
    780	unsigned int mcs;
    781
    782	if (mclk % (base_freq * 128) != 0)
    783		return false;
    784
    785	mcs = mclk / (128 * base_freq);
    786	if (mcs < 1 || mcs > 6 || mcs == 5)
    787		return false;
    788
    789	return true;
    790}
    791
    792static int adau1977_set_sysclk(struct snd_soc_component *component,
    793	int clk_id, int source, unsigned int freq, int dir)
    794{
    795	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component);
    796	unsigned int mask = 0;
    797	unsigned int clk_src;
    798	unsigned int ret;
    799
    800	if (dir != SND_SOC_CLOCK_IN)
    801		return -EINVAL;
    802
    803	if (clk_id != ADAU1977_SYSCLK)
    804		return -EINVAL;
    805
    806	switch (source) {
    807	case ADAU1977_SYSCLK_SRC_MCLK:
    808		clk_src = 0;
    809		break;
    810	case ADAU1977_SYSCLK_SRC_LRCLK:
    811		clk_src = ADAU1977_PLL_CLK_S;
    812		break;
    813	default:
    814		return -EINVAL;
    815	}
    816
    817	if (freq != 0 && source == ADAU1977_SYSCLK_SRC_MCLK) {
    818		if (freq < 4000000 || freq > 36864000)
    819			return -EINVAL;
    820
    821		if (adau1977_check_sysclk(freq, 32000))
    822			mask |= ADAU1977_RATE_CONSTRAINT_MASK_32000;
    823		if (adau1977_check_sysclk(freq, 44100))
    824			mask |= ADAU1977_RATE_CONSTRAINT_MASK_44100;
    825		if (adau1977_check_sysclk(freq, 48000))
    826			mask |= ADAU1977_RATE_CONSTRAINT_MASK_48000;
    827
    828		if (mask == 0)
    829			return -EINVAL;
    830	} else if (source == ADAU1977_SYSCLK_SRC_LRCLK) {
    831		mask = ADAU1977_RATE_CONSTRAINT_MASK_LRCLK;
    832	}
    833
    834	ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_PLL,
    835		ADAU1977_PLL_CLK_S, clk_src);
    836	if (ret)
    837		return ret;
    838
    839	adau1977->constraints.mask = mask;
    840	adau1977->sysclk_src = source;
    841	adau1977->sysclk = freq;
    842
    843	return 0;
    844}
    845
    846static int adau1977_component_probe(struct snd_soc_component *component)
    847{
    848	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
    849	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component);
    850	int ret;
    851
    852	switch (adau1977->type) {
    853	case ADAU1977:
    854		ret = snd_soc_dapm_new_controls(dapm,
    855			adau1977_micbias_dapm_widgets,
    856			ARRAY_SIZE(adau1977_micbias_dapm_widgets));
    857		if (ret < 0)
    858			return ret;
    859		break;
    860	default:
    861		break;
    862	}
    863
    864	return 0;
    865}
    866
    867static const struct snd_soc_component_driver adau1977_component_driver = {
    868	.probe			= adau1977_component_probe,
    869	.set_bias_level		= adau1977_set_bias_level,
    870	.set_sysclk		= adau1977_set_sysclk,
    871	.controls		= adau1977_snd_controls,
    872	.num_controls		= ARRAY_SIZE(adau1977_snd_controls),
    873	.dapm_widgets		= adau1977_dapm_widgets,
    874	.num_dapm_widgets	= ARRAY_SIZE(adau1977_dapm_widgets),
    875	.dapm_routes		= adau1977_dapm_routes,
    876	.num_dapm_routes	= ARRAY_SIZE(adau1977_dapm_routes),
    877	.use_pmdown_time	= 1,
    878	.endianness		= 1,
    879	.non_legacy_dai_naming	= 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_RBTREE,
    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");