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

adau1701.c (22236B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Driver for ADAU1701 SigmaDSP processor
      4 *
      5 * Copyright 2011 Analog Devices Inc.
      6 * Author: Lars-Peter Clausen <lars@metafoo.de>
      7 *	based on an inital version by Cliff Cai <cliff.cai@analog.com>
      8 */
      9
     10#include <linux/module.h>
     11#include <linux/init.h>
     12#include <linux/i2c.h>
     13#include <linux/delay.h>
     14#include <linux/slab.h>
     15#include <linux/of.h>
     16#include <linux/of_device.h>
     17#include <linux/gpio/consumer.h>
     18#include <linux/regulator/consumer.h>
     19#include <linux/regmap.h>
     20#include <sound/core.h>
     21#include <sound/pcm.h>
     22#include <sound/pcm_params.h>
     23#include <sound/soc.h>
     24
     25#include <asm/unaligned.h>
     26
     27#include "sigmadsp.h"
     28#include "adau1701.h"
     29
     30#define ADAU1701_SAFELOAD_DATA(i) (0x0810 + (i))
     31#define ADAU1701_SAFELOAD_ADDR(i) (0x0815 + (i))
     32
     33#define ADAU1701_DSPCTRL	0x081c
     34#define ADAU1701_SEROCTL	0x081e
     35#define ADAU1701_SERICTL	0x081f
     36
     37#define ADAU1701_AUXNPOW	0x0822
     38#define ADAU1701_PINCONF_0	0x0820
     39#define ADAU1701_PINCONF_1	0x0821
     40#define ADAU1701_AUXNPOW	0x0822
     41
     42#define ADAU1701_OSCIPOW	0x0826
     43#define ADAU1701_DACSET		0x0827
     44
     45#define ADAU1701_MAX_REGISTER	0x0828
     46
     47#define ADAU1701_DSPCTRL_CR		(1 << 2)
     48#define ADAU1701_DSPCTRL_DAM		(1 << 3)
     49#define ADAU1701_DSPCTRL_ADM		(1 << 4)
     50#define ADAU1701_DSPCTRL_IST		(1 << 5)
     51#define ADAU1701_DSPCTRL_SR_48		0x00
     52#define ADAU1701_DSPCTRL_SR_96		0x01
     53#define ADAU1701_DSPCTRL_SR_192		0x02
     54#define ADAU1701_DSPCTRL_SR_MASK	0x03
     55
     56#define ADAU1701_SEROCTL_INV_LRCLK	0x2000
     57#define ADAU1701_SEROCTL_INV_BCLK	0x1000
     58#define ADAU1701_SEROCTL_MASTER		0x0800
     59
     60#define ADAU1701_SEROCTL_OBF16		0x0000
     61#define ADAU1701_SEROCTL_OBF8		0x0200
     62#define ADAU1701_SEROCTL_OBF4		0x0400
     63#define ADAU1701_SEROCTL_OBF2		0x0600
     64#define ADAU1701_SEROCTL_OBF_MASK	0x0600
     65
     66#define ADAU1701_SEROCTL_OLF1024	0x0000
     67#define ADAU1701_SEROCTL_OLF512		0x0080
     68#define ADAU1701_SEROCTL_OLF256		0x0100
     69#define ADAU1701_SEROCTL_OLF_MASK	0x0180
     70
     71#define ADAU1701_SEROCTL_MSB_DEALY1	0x0000
     72#define ADAU1701_SEROCTL_MSB_DEALY0	0x0004
     73#define ADAU1701_SEROCTL_MSB_DEALY8	0x0008
     74#define ADAU1701_SEROCTL_MSB_DEALY12	0x000c
     75#define ADAU1701_SEROCTL_MSB_DEALY16	0x0010
     76#define ADAU1701_SEROCTL_MSB_DEALY_MASK	0x001c
     77
     78#define ADAU1701_SEROCTL_WORD_LEN_24	0x0000
     79#define ADAU1701_SEROCTL_WORD_LEN_20	0x0001
     80#define ADAU1701_SEROCTL_WORD_LEN_16	0x0002
     81#define ADAU1701_SEROCTL_WORD_LEN_MASK	0x0003
     82
     83#define ADAU1701_AUXNPOW_VBPD		0x40
     84#define ADAU1701_AUXNPOW_VRPD		0x20
     85
     86#define ADAU1701_SERICTL_I2S		0
     87#define ADAU1701_SERICTL_LEFTJ		1
     88#define ADAU1701_SERICTL_TDM		2
     89#define ADAU1701_SERICTL_RIGHTJ_24	3
     90#define ADAU1701_SERICTL_RIGHTJ_20	4
     91#define ADAU1701_SERICTL_RIGHTJ_18	5
     92#define ADAU1701_SERICTL_RIGHTJ_16	6
     93#define ADAU1701_SERICTL_MODE_MASK	7
     94#define ADAU1701_SERICTL_INV_BCLK	BIT(3)
     95#define ADAU1701_SERICTL_INV_LRCLK	BIT(4)
     96
     97#define ADAU1701_OSCIPOW_OPD		0x04
     98#define ADAU1701_DACSET_DACINIT		1
     99
    100#define ADAU1707_CLKDIV_UNSET		(-1U)
    101
    102#define ADAU1701_FIRMWARE "adau1701.bin"
    103
    104static const char * const supply_names[] = {
    105	"dvdd", "avdd"
    106};
    107
    108struct adau1701 {
    109	struct gpio_desc  *gpio_nreset;
    110	struct gpio_descs *gpio_pll_mode;
    111	unsigned int dai_fmt;
    112	unsigned int pll_clkdiv;
    113	unsigned int sysclk;
    114	struct regmap *regmap;
    115	struct i2c_client *client;
    116	u8 pin_config[12];
    117
    118	struct sigmadsp *sigmadsp;
    119	struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
    120};
    121
    122static const struct snd_kcontrol_new adau1701_controls[] = {
    123	SOC_SINGLE("Master Capture Switch", ADAU1701_DSPCTRL, 4, 1, 0),
    124};
    125
    126static const struct snd_soc_dapm_widget adau1701_dapm_widgets[] = {
    127	SND_SOC_DAPM_DAC("DAC0", "Playback", ADAU1701_AUXNPOW, 3, 1),
    128	SND_SOC_DAPM_DAC("DAC1", "Playback", ADAU1701_AUXNPOW, 2, 1),
    129	SND_SOC_DAPM_DAC("DAC2", "Playback", ADAU1701_AUXNPOW, 1, 1),
    130	SND_SOC_DAPM_DAC("DAC3", "Playback", ADAU1701_AUXNPOW, 0, 1),
    131	SND_SOC_DAPM_ADC("ADC", "Capture", ADAU1701_AUXNPOW, 7, 1),
    132
    133	SND_SOC_DAPM_OUTPUT("OUT0"),
    134	SND_SOC_DAPM_OUTPUT("OUT1"),
    135	SND_SOC_DAPM_OUTPUT("OUT2"),
    136	SND_SOC_DAPM_OUTPUT("OUT3"),
    137	SND_SOC_DAPM_INPUT("IN0"),
    138	SND_SOC_DAPM_INPUT("IN1"),
    139};
    140
    141static const struct snd_soc_dapm_route adau1701_dapm_routes[] = {
    142	{ "OUT0", NULL, "DAC0" },
    143	{ "OUT1", NULL, "DAC1" },
    144	{ "OUT2", NULL, "DAC2" },
    145	{ "OUT3", NULL, "DAC3" },
    146
    147	{ "ADC", NULL, "IN0" },
    148	{ "ADC", NULL, "IN1" },
    149};
    150
    151static unsigned int adau1701_register_size(struct device *dev,
    152		unsigned int reg)
    153{
    154	switch (reg) {
    155	case ADAU1701_PINCONF_0:
    156	case ADAU1701_PINCONF_1:
    157		return 3;
    158	case ADAU1701_DSPCTRL:
    159	case ADAU1701_SEROCTL:
    160	case ADAU1701_AUXNPOW:
    161	case ADAU1701_OSCIPOW:
    162	case ADAU1701_DACSET:
    163		return 2;
    164	case ADAU1701_SERICTL:
    165		return 1;
    166	}
    167
    168	dev_err(dev, "Unsupported register address: %d\n", reg);
    169	return 0;
    170}
    171
    172static bool adau1701_volatile_reg(struct device *dev, unsigned int reg)
    173{
    174	switch (reg) {
    175	case ADAU1701_DACSET:
    176	case ADAU1701_DSPCTRL:
    177		return true;
    178	default:
    179		return false;
    180	}
    181}
    182
    183static int adau1701_reg_write(void *context, unsigned int reg,
    184			      unsigned int value)
    185{
    186	struct i2c_client *client = context;
    187	unsigned int i;
    188	unsigned int size;
    189	uint8_t buf[5];
    190	int ret;
    191
    192	size = adau1701_register_size(&client->dev, reg);
    193	if (size == 0)
    194		return -EINVAL;
    195
    196	buf[0] = reg >> 8;
    197	buf[1] = reg & 0xff;
    198
    199	for (i = size + 1; i >= 2; --i) {
    200		buf[i] = value;
    201		value >>= 8;
    202	}
    203
    204	ret = i2c_master_send(client, buf, size + 2);
    205	if (ret == size + 2)
    206		return 0;
    207	else if (ret < 0)
    208		return ret;
    209	else
    210		return -EIO;
    211}
    212
    213static int adau1701_reg_read(void *context, unsigned int reg,
    214			     unsigned int *value)
    215{
    216	int ret;
    217	unsigned int i;
    218	unsigned int size;
    219	uint8_t send_buf[2], recv_buf[3];
    220	struct i2c_client *client = context;
    221	struct i2c_msg msgs[2];
    222
    223	size = adau1701_register_size(&client->dev, reg);
    224	if (size == 0)
    225		return -EINVAL;
    226
    227	send_buf[0] = reg >> 8;
    228	send_buf[1] = reg & 0xff;
    229
    230	msgs[0].addr = client->addr;
    231	msgs[0].len = sizeof(send_buf);
    232	msgs[0].buf = send_buf;
    233	msgs[0].flags = 0;
    234
    235	msgs[1].addr = client->addr;
    236	msgs[1].len = size;
    237	msgs[1].buf = recv_buf;
    238	msgs[1].flags = I2C_M_RD;
    239
    240	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
    241	if (ret < 0)
    242		return ret;
    243	else if (ret != ARRAY_SIZE(msgs))
    244		return -EIO;
    245
    246	*value = 0;
    247
    248	for (i = 0; i < size; i++) {
    249		*value <<= 8;
    250		*value |= recv_buf[i];
    251	}
    252
    253	return 0;
    254}
    255
    256static int adau1701_safeload(struct sigmadsp *sigmadsp, unsigned int addr,
    257	const uint8_t bytes[], size_t len)
    258{
    259	struct i2c_client *client = to_i2c_client(sigmadsp->dev);
    260	struct adau1701 *adau1701 = i2c_get_clientdata(client);
    261	unsigned int val;
    262	unsigned int i;
    263	uint8_t buf[10];
    264	int ret;
    265
    266	ret = regmap_read(adau1701->regmap, ADAU1701_DSPCTRL, &val);
    267	if (ret)
    268		return ret;
    269
    270	if (val & ADAU1701_DSPCTRL_IST)
    271		msleep(50);
    272
    273	for (i = 0; i < len / 4; i++) {
    274		put_unaligned_le16(ADAU1701_SAFELOAD_DATA(i), buf);
    275		buf[2] = 0x00;
    276		memcpy(buf + 3, bytes + i * 4, 4);
    277		ret = i2c_master_send(client, buf, 7);
    278		if (ret < 0)
    279			return ret;
    280		else if (ret != 7)
    281			return -EIO;
    282
    283		put_unaligned_le16(ADAU1701_SAFELOAD_ADDR(i), buf);
    284		put_unaligned_le16(addr + i, buf + 2);
    285		ret = i2c_master_send(client, buf, 4);
    286		if (ret < 0)
    287			return ret;
    288		else if (ret != 4)
    289			return -EIO;
    290	}
    291
    292	return regmap_update_bits(adau1701->regmap, ADAU1701_DSPCTRL,
    293		ADAU1701_DSPCTRL_IST, ADAU1701_DSPCTRL_IST);
    294}
    295
    296static const struct sigmadsp_ops adau1701_sigmadsp_ops = {
    297	.safeload = adau1701_safeload,
    298};
    299
    300static int adau1701_reset(struct snd_soc_component *component, unsigned int clkdiv,
    301	unsigned int rate)
    302{
    303	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
    304	int ret;
    305
    306	DECLARE_BITMAP(values, 2);
    307	sigmadsp_reset(adau1701->sigmadsp);
    308
    309	if (clkdiv != ADAU1707_CLKDIV_UNSET && adau1701->gpio_pll_mode) {
    310		switch (clkdiv) {
    311		case 64:
    312			__assign_bit(0, values, 0);
    313			__assign_bit(1, values, 0);
    314			break;
    315		case 256:
    316			__assign_bit(0, values, 0);
    317			__assign_bit(1, values, 1);
    318			break;
    319		case 384:
    320			__assign_bit(0, values, 1);
    321			__assign_bit(1, values, 0);
    322			break;
    323		case 0: /* fallback */
    324		case 512:
    325			__assign_bit(0, values, 1);
    326			__assign_bit(1, values, 1);
    327			break;
    328		}
    329		gpiod_set_array_value_cansleep(adau1701->gpio_pll_mode->ndescs,
    330				adau1701->gpio_pll_mode->desc, adau1701->gpio_pll_mode->info,
    331				values);
    332	}
    333
    334	adau1701->pll_clkdiv = clkdiv;
    335
    336	if (adau1701->gpio_nreset) {
    337		gpiod_set_value_cansleep(adau1701->gpio_nreset, 0);
    338		/* minimum reset time is 20ns */
    339		udelay(1);
    340		gpiod_set_value_cansleep(adau1701->gpio_nreset, 1);
    341		/* power-up time may be as long as 85ms */
    342		mdelay(85);
    343	}
    344
    345	/*
    346	 * Postpone the firmware download to a point in time when we
    347	 * know the correct PLL setup
    348	 */
    349	if (clkdiv != ADAU1707_CLKDIV_UNSET) {
    350		ret = sigmadsp_setup(adau1701->sigmadsp, rate);
    351		if (ret) {
    352			dev_warn(component->dev, "Failed to load firmware\n");
    353			return ret;
    354		}
    355	}
    356
    357	regmap_write(adau1701->regmap, ADAU1701_DACSET, ADAU1701_DACSET_DACINIT);
    358	regmap_write(adau1701->regmap, ADAU1701_DSPCTRL, ADAU1701_DSPCTRL_CR);
    359
    360	regcache_mark_dirty(adau1701->regmap);
    361	regcache_sync(adau1701->regmap);
    362
    363	return 0;
    364}
    365
    366static int adau1701_set_capture_pcm_format(struct snd_soc_component *component,
    367					   struct snd_pcm_hw_params *params)
    368{
    369	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
    370	unsigned int mask = ADAU1701_SEROCTL_WORD_LEN_MASK;
    371	unsigned int val;
    372
    373	switch (params_width(params)) {
    374	case 16:
    375		val = ADAU1701_SEROCTL_WORD_LEN_16;
    376		break;
    377	case 20:
    378		val = ADAU1701_SEROCTL_WORD_LEN_20;
    379		break;
    380	case 24:
    381		val = ADAU1701_SEROCTL_WORD_LEN_24;
    382		break;
    383	default:
    384		return -EINVAL;
    385	}
    386
    387	if (adau1701->dai_fmt == SND_SOC_DAIFMT_RIGHT_J) {
    388		switch (params_width(params)) {
    389		case 16:
    390			val |= ADAU1701_SEROCTL_MSB_DEALY16;
    391			break;
    392		case 20:
    393			val |= ADAU1701_SEROCTL_MSB_DEALY12;
    394			break;
    395		case 24:
    396			val |= ADAU1701_SEROCTL_MSB_DEALY8;
    397			break;
    398		}
    399		mask |= ADAU1701_SEROCTL_MSB_DEALY_MASK;
    400	}
    401
    402	regmap_update_bits(adau1701->regmap, ADAU1701_SEROCTL, mask, val);
    403
    404	return 0;
    405}
    406
    407static int adau1701_set_playback_pcm_format(struct snd_soc_component *component,
    408					    struct snd_pcm_hw_params *params)
    409{
    410	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
    411	unsigned int val;
    412
    413	if (adau1701->dai_fmt != SND_SOC_DAIFMT_RIGHT_J)
    414		return 0;
    415
    416	switch (params_width(params)) {
    417	case 16:
    418		val = ADAU1701_SERICTL_RIGHTJ_16;
    419		break;
    420	case 20:
    421		val = ADAU1701_SERICTL_RIGHTJ_20;
    422		break;
    423	case 24:
    424		val = ADAU1701_SERICTL_RIGHTJ_24;
    425		break;
    426	default:
    427		return -EINVAL;
    428	}
    429
    430	regmap_update_bits(adau1701->regmap, ADAU1701_SERICTL,
    431		ADAU1701_SERICTL_MODE_MASK, val);
    432
    433	return 0;
    434}
    435
    436static int adau1701_hw_params(struct snd_pcm_substream *substream,
    437		struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
    438{
    439	struct snd_soc_component *component = dai->component;
    440	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
    441	unsigned int clkdiv = adau1701->sysclk / params_rate(params);
    442	unsigned int val;
    443	int ret;
    444
    445	/*
    446	 * If the mclk/lrclk ratio changes, the chip needs updated PLL
    447	 * mode GPIO settings, and a full reset cycle, including a new
    448	 * firmware upload.
    449	 */
    450	if (clkdiv != adau1701->pll_clkdiv) {
    451		ret = adau1701_reset(component, clkdiv, params_rate(params));
    452		if (ret < 0)
    453			return ret;
    454	}
    455
    456	switch (params_rate(params)) {
    457	case 192000:
    458		val = ADAU1701_DSPCTRL_SR_192;
    459		break;
    460	case 96000:
    461		val = ADAU1701_DSPCTRL_SR_96;
    462		break;
    463	case 48000:
    464		val = ADAU1701_DSPCTRL_SR_48;
    465		break;
    466	default:
    467		return -EINVAL;
    468	}
    469
    470	regmap_update_bits(adau1701->regmap, ADAU1701_DSPCTRL,
    471		ADAU1701_DSPCTRL_SR_MASK, val);
    472
    473	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
    474		return adau1701_set_playback_pcm_format(component, params);
    475	else
    476		return adau1701_set_capture_pcm_format(component, params);
    477}
    478
    479static int adau1701_set_dai_fmt(struct snd_soc_dai *codec_dai,
    480		unsigned int fmt)
    481{
    482	struct snd_soc_component *component = codec_dai->component;
    483	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
    484	unsigned int serictl = 0x00, seroctl = 0x00;
    485	bool invert_lrclk;
    486
    487	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
    488	case SND_SOC_DAIFMT_CBP_CFP:
    489		/* master, 64-bits per sample, 1 frame per sample */
    490		seroctl |= ADAU1701_SEROCTL_MASTER | ADAU1701_SEROCTL_OBF16
    491				| ADAU1701_SEROCTL_OLF1024;
    492		break;
    493	case SND_SOC_DAIFMT_CBC_CFC:
    494		break;
    495	default:
    496		return -EINVAL;
    497	}
    498
    499	/* clock inversion */
    500	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
    501	case SND_SOC_DAIFMT_NB_NF:
    502		invert_lrclk = false;
    503		break;
    504	case SND_SOC_DAIFMT_NB_IF:
    505		invert_lrclk = true;
    506		break;
    507	case SND_SOC_DAIFMT_IB_NF:
    508		invert_lrclk = false;
    509		serictl |= ADAU1701_SERICTL_INV_BCLK;
    510		seroctl |= ADAU1701_SEROCTL_INV_BCLK;
    511		break;
    512	case SND_SOC_DAIFMT_IB_IF:
    513		invert_lrclk = true;
    514		serictl |= ADAU1701_SERICTL_INV_BCLK;
    515		seroctl |= ADAU1701_SEROCTL_INV_BCLK;
    516		break;
    517	default:
    518		return -EINVAL;
    519	}
    520
    521	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
    522	case SND_SOC_DAIFMT_I2S:
    523		break;
    524	case SND_SOC_DAIFMT_LEFT_J:
    525		serictl |= ADAU1701_SERICTL_LEFTJ;
    526		seroctl |= ADAU1701_SEROCTL_MSB_DEALY0;
    527		invert_lrclk = !invert_lrclk;
    528		break;
    529	case SND_SOC_DAIFMT_RIGHT_J:
    530		serictl |= ADAU1701_SERICTL_RIGHTJ_24;
    531		seroctl |= ADAU1701_SEROCTL_MSB_DEALY8;
    532		invert_lrclk = !invert_lrclk;
    533		break;
    534	default:
    535		return -EINVAL;
    536	}
    537
    538	if (invert_lrclk) {
    539		seroctl |= ADAU1701_SEROCTL_INV_LRCLK;
    540		serictl |= ADAU1701_SERICTL_INV_LRCLK;
    541	}
    542
    543	adau1701->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
    544
    545	regmap_write(adau1701->regmap, ADAU1701_SERICTL, serictl);
    546	regmap_update_bits(adau1701->regmap, ADAU1701_SEROCTL,
    547		~ADAU1701_SEROCTL_WORD_LEN_MASK, seroctl);
    548
    549	return 0;
    550}
    551
    552static int adau1701_set_bias_level(struct snd_soc_component *component,
    553		enum snd_soc_bias_level level)
    554{
    555	unsigned int mask = ADAU1701_AUXNPOW_VBPD | ADAU1701_AUXNPOW_VRPD;
    556	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
    557
    558	switch (level) {
    559	case SND_SOC_BIAS_ON:
    560		break;
    561	case SND_SOC_BIAS_PREPARE:
    562		break;
    563	case SND_SOC_BIAS_STANDBY:
    564		/* Enable VREF and VREF buffer */
    565		regmap_update_bits(adau1701->regmap,
    566				   ADAU1701_AUXNPOW, mask, 0x00);
    567		break;
    568	case SND_SOC_BIAS_OFF:
    569		/* Disable VREF and VREF buffer */
    570		regmap_update_bits(adau1701->regmap,
    571				   ADAU1701_AUXNPOW, mask, mask);
    572		break;
    573	}
    574
    575	return 0;
    576}
    577
    578static int adau1701_mute_stream(struct snd_soc_dai *dai, int mute, int direction)
    579{
    580	struct snd_soc_component *component = dai->component;
    581	unsigned int mask = ADAU1701_DSPCTRL_DAM;
    582	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
    583	unsigned int val;
    584
    585	if (mute)
    586		val = 0;
    587	else
    588		val = mask;
    589
    590	regmap_update_bits(adau1701->regmap, ADAU1701_DSPCTRL, mask, val);
    591
    592	return 0;
    593}
    594
    595static int adau1701_set_sysclk(struct snd_soc_component *component, int clk_id,
    596	int source, unsigned int freq, int dir)
    597{
    598	unsigned int val;
    599	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
    600
    601	switch (clk_id) {
    602	case ADAU1701_CLK_SRC_OSC:
    603		val = 0x0;
    604		break;
    605	case ADAU1701_CLK_SRC_MCLK:
    606		val = ADAU1701_OSCIPOW_OPD;
    607		break;
    608	default:
    609		return -EINVAL;
    610	}
    611
    612	regmap_update_bits(adau1701->regmap, ADAU1701_OSCIPOW,
    613			   ADAU1701_OSCIPOW_OPD, val);
    614	adau1701->sysclk = freq;
    615
    616	return 0;
    617}
    618
    619static int adau1701_startup(struct snd_pcm_substream *substream,
    620	struct snd_soc_dai *dai)
    621{
    622	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(dai->component);
    623
    624	return sigmadsp_restrict_params(adau1701->sigmadsp, substream);
    625}
    626
    627#define ADAU1701_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | \
    628	SNDRV_PCM_RATE_192000)
    629
    630#define ADAU1701_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
    631	SNDRV_PCM_FMTBIT_S24_LE)
    632
    633static const struct snd_soc_dai_ops adau1701_dai_ops = {
    634	.set_fmt	= adau1701_set_dai_fmt,
    635	.hw_params	= adau1701_hw_params,
    636	.mute_stream	= adau1701_mute_stream,
    637	.startup	= adau1701_startup,
    638	.no_capture_mute = 1,
    639};
    640
    641static struct snd_soc_dai_driver adau1701_dai = {
    642	.name = "adau1701",
    643	.playback = {
    644		.stream_name = "Playback",
    645		.channels_min = 2,
    646		.channels_max = 8,
    647		.rates = ADAU1701_RATES,
    648		.formats = ADAU1701_FORMATS,
    649	},
    650	.capture = {
    651		.stream_name = "Capture",
    652		.channels_min = 2,
    653		.channels_max = 8,
    654		.rates = ADAU1701_RATES,
    655		.formats = ADAU1701_FORMATS,
    656	},
    657	.ops = &adau1701_dai_ops,
    658	.symmetric_rate = 1,
    659};
    660
    661#ifdef CONFIG_OF
    662static const struct of_device_id adau1701_dt_ids[] = {
    663	{ .compatible = "adi,adau1701", },
    664	{ }
    665};
    666MODULE_DEVICE_TABLE(of, adau1701_dt_ids);
    667#endif
    668
    669static int adau1701_probe(struct snd_soc_component *component)
    670{
    671	int i, ret;
    672	unsigned int val;
    673	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
    674
    675	ret = sigmadsp_attach(adau1701->sigmadsp, component);
    676	if (ret)
    677		return ret;
    678
    679	ret = regulator_bulk_enable(ARRAY_SIZE(adau1701->supplies),
    680				    adau1701->supplies);
    681	if (ret < 0) {
    682		dev_err(component->dev, "Failed to enable regulators: %d\n", ret);
    683		return ret;
    684	}
    685
    686	/*
    687	 * Let the pll_clkdiv variable default to something that won't happen
    688	 * at runtime. That way, we can postpone the firmware download from
    689	 * adau1701_reset() to a point in time when we know the correct PLL
    690	 * mode parameters.
    691	 */
    692	adau1701->pll_clkdiv = ADAU1707_CLKDIV_UNSET;
    693
    694	/* initalize with pre-configured pll mode settings */
    695	ret = adau1701_reset(component, adau1701->pll_clkdiv, 0);
    696	if (ret < 0)
    697		goto exit_regulators_disable;
    698
    699	/* set up pin config */
    700	val = 0;
    701	for (i = 0; i < 6; i++)
    702		val |= adau1701->pin_config[i] << (i * 4);
    703
    704	regmap_write(adau1701->regmap, ADAU1701_PINCONF_0, val);
    705
    706	val = 0;
    707	for (i = 0; i < 6; i++)
    708		val |= adau1701->pin_config[i + 6] << (i * 4);
    709
    710	regmap_write(adau1701->regmap, ADAU1701_PINCONF_1, val);
    711
    712	return 0;
    713
    714exit_regulators_disable:
    715
    716	regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies), adau1701->supplies);
    717	return ret;
    718}
    719
    720static void adau1701_remove(struct snd_soc_component *component)
    721{
    722	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
    723
    724	if (adau1701->gpio_nreset)
    725		gpiod_set_value_cansleep(adau1701->gpio_nreset, 0);
    726
    727	regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies), adau1701->supplies);
    728}
    729
    730#ifdef CONFIG_PM
    731static int adau1701_suspend(struct snd_soc_component *component)
    732{
    733	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
    734
    735	regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies),
    736			       adau1701->supplies);
    737
    738	return 0;
    739}
    740
    741static int adau1701_resume(struct snd_soc_component *component)
    742{
    743	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
    744	int ret;
    745
    746        ret = regulator_bulk_enable(ARRAY_SIZE(adau1701->supplies),
    747				    adau1701->supplies);
    748	if (ret < 0) {
    749		dev_err(component->dev, "Failed to enable regulators: %d\n", ret);
    750		return ret;
    751	}
    752
    753	return adau1701_reset(component, adau1701->pll_clkdiv, 0);
    754}
    755#else
    756#define adau1701_resume 	NULL
    757#define adau1701_suspend 	NULL
    758#endif /* CONFIG_PM */
    759
    760static const struct snd_soc_component_driver adau1701_component_drv = {
    761	.probe			= adau1701_probe,
    762	.remove			= adau1701_remove,
    763	.resume			= adau1701_resume,
    764	.suspend		= adau1701_suspend,
    765	.set_bias_level		= adau1701_set_bias_level,
    766	.controls		= adau1701_controls,
    767	.num_controls		= ARRAY_SIZE(adau1701_controls),
    768	.dapm_widgets		= adau1701_dapm_widgets,
    769	.num_dapm_widgets	= ARRAY_SIZE(adau1701_dapm_widgets),
    770	.dapm_routes		= adau1701_dapm_routes,
    771	.num_dapm_routes	= ARRAY_SIZE(adau1701_dapm_routes),
    772	.set_sysclk		= adau1701_set_sysclk,
    773	.use_pmdown_time	= 1,
    774	.endianness		= 1,
    775	.non_legacy_dai_naming	= 1,
    776};
    777
    778static const struct regmap_config adau1701_regmap = {
    779	.reg_bits		= 16,
    780	.val_bits		= 32,
    781	.max_register		= ADAU1701_MAX_REGISTER,
    782	.cache_type		= REGCACHE_RBTREE,
    783	.volatile_reg		= adau1701_volatile_reg,
    784	.reg_write		= adau1701_reg_write,
    785	.reg_read		= adau1701_reg_read,
    786};
    787
    788static int adau1701_i2c_probe(struct i2c_client *client)
    789{
    790	struct adau1701 *adau1701;
    791	struct device *dev = &client->dev;
    792	int ret, i;
    793
    794	adau1701 = devm_kzalloc(dev, sizeof(*adau1701), GFP_KERNEL);
    795	if (!adau1701)
    796		return -ENOMEM;
    797
    798	for (i = 0; i < ARRAY_SIZE(supply_names); i++)
    799		adau1701->supplies[i].supply = supply_names[i];
    800
    801	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(adau1701->supplies),
    802			adau1701->supplies);
    803	if (ret < 0) {
    804		dev_err(dev, "Failed to get regulators: %d\n", ret);
    805		return ret;
    806	}
    807
    808	ret = regulator_bulk_enable(ARRAY_SIZE(adau1701->supplies),
    809			adau1701->supplies);
    810	if (ret < 0) {
    811		dev_err(dev, "Failed to enable regulators: %d\n", ret);
    812		return ret;
    813	}
    814
    815	adau1701->client = client;
    816	adau1701->regmap = devm_regmap_init(dev, NULL, client,
    817					    &adau1701_regmap);
    818	if (IS_ERR(adau1701->regmap)) {
    819		ret = PTR_ERR(adau1701->regmap);
    820		goto exit_regulators_disable;
    821	}
    822
    823
    824	if (dev->of_node) {
    825		of_property_read_u32(dev->of_node, "adi,pll-clkdiv",
    826				     &adau1701->pll_clkdiv);
    827
    828		of_property_read_u8_array(dev->of_node, "adi,pin-config",
    829					  adau1701->pin_config,
    830					  ARRAY_SIZE(adau1701->pin_config));
    831	}
    832
    833	adau1701->gpio_nreset = devm_gpiod_get_optional(dev, "reset", GPIOD_IN);
    834
    835	if (IS_ERR(adau1701->gpio_nreset)) {
    836		ret = PTR_ERR(adau1701->gpio_nreset);
    837		goto exit_regulators_disable;
    838	}
    839
    840	adau1701->gpio_pll_mode = devm_gpiod_get_array_optional(dev, "adi,pll-mode", GPIOD_OUT_LOW);
    841
    842	if (IS_ERR(adau1701->gpio_pll_mode)) {
    843		ret = PTR_ERR(adau1701->gpio_pll_mode);
    844		goto exit_regulators_disable;
    845	}
    846
    847	i2c_set_clientdata(client, adau1701);
    848
    849	adau1701->sigmadsp = devm_sigmadsp_init_i2c(client,
    850		&adau1701_sigmadsp_ops, ADAU1701_FIRMWARE);
    851	if (IS_ERR(adau1701->sigmadsp)) {
    852		ret = PTR_ERR(adau1701->sigmadsp);
    853		goto exit_regulators_disable;
    854	}
    855
    856	ret = devm_snd_soc_register_component(&client->dev,
    857			&adau1701_component_drv,
    858			&adau1701_dai, 1);
    859
    860exit_regulators_disable:
    861
    862	regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies), adau1701->supplies);
    863	return ret;
    864}
    865
    866static const struct i2c_device_id adau1701_i2c_id[] = {
    867	{ "adau1401", 0 },
    868	{ "adau1401a", 0 },
    869	{ "adau1701", 0 },
    870	{ "adau1702", 0 },
    871	{ }
    872};
    873MODULE_DEVICE_TABLE(i2c, adau1701_i2c_id);
    874
    875static struct i2c_driver adau1701_i2c_driver = {
    876	.driver = {
    877		.name	= "adau1701",
    878		.of_match_table	= of_match_ptr(adau1701_dt_ids),
    879	},
    880	.probe_new	= adau1701_i2c_probe,
    881	.id_table	= adau1701_i2c_id,
    882};
    883
    884module_i2c_driver(adau1701_i2c_driver);
    885
    886MODULE_DESCRIPTION("ASoC ADAU1701 SigmaDSP driver");
    887MODULE_AUTHOR("Cliff Cai <cliff.cai@analog.com>");
    888MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
    889MODULE_LICENSE("GPL");