// SPDX-License-Identifier: GPL-2.0
//
// Driver for the MAX9860 Mono Audio Voice Codec
//
// https://datasheets.maximintegrated.com/en/ds/MAX9860.pdf
//
// The driver does not support sidetone since the DVST register field is
// backwards with the mute near the maximum level instead of the minimum.
//
// Author: Peter Rosin <peda@axentia.s>
//         Copyright 2016 Axentia Technologies

#include <linux/init.h>
#include <linux/module.h>
#include <linux/clk.h>
#include <linux/kernel.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/i2c.h>
#include <linux/regulator/consumer.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/pcm_params.h>
#include <sound/tlv.h>

#include "max9860.h"

struct max9860_priv {
	struct regmap *regmap;
	struct regulator *dvddio;
	struct notifier_block dvddio_nb;
	u8 psclk;
	unsigned long pclk_rate;
	int fmt;
};

static int max9860_dvddio_event(struct notifier_block *nb,
				unsigned long event, void *data)
{
	struct max9860_priv *max9860 = container_of(nb, struct max9860_priv,
						    dvddio_nb);
	if (event & REGULATOR_EVENT_DISABLE) {
		regcache_mark_dirty(max9860->regmap);
		regcache_cache_only(max9860->regmap, true);
	}

	return 0;
}

static const struct reg_default max9860_reg_defaults[] = {
	{ MAX9860_PWRMAN,       0x00 },
	{ MAX9860_INTEN,        0x00 },
	{ MAX9860_SYSCLK,       0x00 },
	{ MAX9860_AUDIOCLKHIGH, 0x00 },
	{ MAX9860_AUDIOCLKLOW,  0x00 },
	{ MAX9860_IFC1A,        0x00 },
	{ MAX9860_IFC1B,        0x00 },
	{ MAX9860_VOICEFLTR,    0x00 },
	{ MAX9860_DACATTN,      0x00 },
	{ MAX9860_ADCLEVEL,     0x00 },
	{ MAX9860_DACGAIN,      0x00 },
	{ MAX9860_MICGAIN,      0x00 },
	{ MAX9860_MICADC,       0x00 },
	{ MAX9860_NOISEGATE,    0x00 },
};

static bool max9860_readable(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case MAX9860_INTRSTATUS ... MAX9860_MICGAIN:
	case MAX9860_MICADC ... MAX9860_PWRMAN:
	case MAX9860_REVISION:
		return true;
	}

	return false;
}

static bool max9860_writeable(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case MAX9860_INTEN ... MAX9860_MICGAIN:
	case MAX9860_MICADC ... MAX9860_PWRMAN:
		return true;
	}

	return false;
}

static bool max9860_volatile(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case MAX9860_INTRSTATUS:
	case MAX9860_MICREADBACK:
		return true;
	}

	return false;
}

static bool max9860_precious(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case MAX9860_INTRSTATUS:
		return true;
	}

	return false;
}

static const struct regmap_config max9860_regmap = {
	.reg_bits = 8,
	.val_bits = 8,

	.readable_reg = max9860_readable,
	.writeable_reg = max9860_writeable,
	.volatile_reg = max9860_volatile,
	.precious_reg = max9860_precious,

	.max_register = MAX9860_MAX_REGISTER,
	.reg_defaults = max9860_reg_defaults,
	.num_reg_defaults = ARRAY_SIZE(max9860_reg_defaults),
	.cache_type = REGCACHE_RBTREE,
};

static const DECLARE_TLV_DB_SCALE(dva_tlv, -9100, 100, 1);
static const DECLARE_TLV_DB_SCALE(dvg_tlv, 0, 600, 0);
static const DECLARE_TLV_DB_SCALE(adc_tlv, -1200, 100, 0);
static const DECLARE_TLV_DB_RANGE(pam_tlv,
	0, MAX9860_PAM_MAX - 1,             TLV_DB_SCALE_ITEM(-2000, 2000, 1),
	MAX9860_PAM_MAX, MAX9860_PAM_MAX,   TLV_DB_SCALE_ITEM(3000, 0, 0));
static const DECLARE_TLV_DB_SCALE(pgam_tlv, 0, 100, 0);
static const DECLARE_TLV_DB_SCALE(anth_tlv, -7600, 400, 1);
static const DECLARE_TLV_DB_SCALE(agcth_tlv, -1800, 100, 0);

static const char * const agchld_text[] = {
	"AGC Disabled", "50ms", "100ms", "400ms"
};

static SOC_ENUM_SINGLE_DECL(agchld_enum, MAX9860_MICADC,
			    MAX9860_AGCHLD_SHIFT, agchld_text);

static const char * const agcsrc_text[] = {
	"Left ADC", "Left/Right ADC"
};

static SOC_ENUM_SINGLE_DECL(agcsrc_enum, MAX9860_MICADC,
			    MAX9860_AGCSRC_SHIFT, agcsrc_text);

static const char * const agcatk_text[] = {
	"3ms", "12ms", "50ms", "200ms"
};

static SOC_ENUM_SINGLE_DECL(agcatk_enum, MAX9860_MICADC,
			    MAX9860_AGCATK_SHIFT, agcatk_text);

static const char * const agcrls_text[] = {
	"78ms", "156ms", "312ms", "625ms",
	"1.25s", "2.5s", "5s", "10s"
};

static SOC_ENUM_SINGLE_DECL(agcrls_enum, MAX9860_MICADC,
			    MAX9860_AGCRLS_SHIFT, agcrls_text);

static const char * const filter_text[] = {
	"Disabled",
	"Elliptical HP 217Hz notch (16kHz)",
	"Butterworth HP 500Hz (16kHz)",
	"Elliptical HP 217Hz notch (8kHz)",
	"Butterworth HP 500Hz (8kHz)",
	"Butterworth HP 200Hz (48kHz)"
};

static SOC_ENUM_SINGLE_DECL(avflt_enum, MAX9860_VOICEFLTR,
			    MAX9860_AVFLT_SHIFT, filter_text);

static SOC_ENUM_SINGLE_DECL(dvflt_enum, MAX9860_VOICEFLTR,
			    MAX9860_DVFLT_SHIFT, filter_text);

static const struct snd_kcontrol_new max9860_controls[] = {
SOC_SINGLE_TLV("Master Playback Volume", MAX9860_DACATTN,
	       MAX9860_DVA_SHIFT, MAX9860_DVA_MUTE, 1, dva_tlv),
SOC_SINGLE_TLV("DAC Gain Volume", MAX9860_DACGAIN,
	       MAX9860_DVG_SHIFT, MAX9860_DVG_MAX, 0, dvg_tlv),
SOC_DOUBLE_TLV("Line Capture Volume", MAX9860_ADCLEVEL,
	       MAX9860_ADCLL_SHIFT, MAX9860_ADCRL_SHIFT, MAX9860_ADCxL_MIN, 1,
	       adc_tlv),

SOC_ENUM("AGC Hold Time", agchld_enum),
SOC_ENUM("AGC/Noise Gate Source", agcsrc_enum),
SOC_ENUM("AGC Attack Time", agcatk_enum),
SOC_ENUM("AGC Release Time", agcrls_enum),

SOC_SINGLE_TLV("Noise Gate Threshold Volume", MAX9860_NOISEGATE,
	       MAX9860_ANTH_SHIFT, MAX9860_ANTH_MAX, 0, anth_tlv),
SOC_SINGLE_TLV("AGC Signal Threshold Volume", MAX9860_NOISEGATE,
	       MAX9860_AGCTH_SHIFT, MAX9860_AGCTH_MIN, 1, agcth_tlv),

SOC_SINGLE_TLV("Mic PGA Volume", MAX9860_MICGAIN,
	       MAX9860_PGAM_SHIFT, MAX9860_PGAM_MIN, 1, pgam_tlv),
SOC_SINGLE_TLV("Mic Preamp Volume", MAX9860_MICGAIN,
	       MAX9860_PAM_SHIFT, MAX9860_PAM_MAX, 0, pam_tlv),

SOC_ENUM("ADC Filter", avflt_enum),
SOC_ENUM("DAC Filter", dvflt_enum),
};

static const struct snd_soc_dapm_widget max9860_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("MICL"),
SND_SOC_DAPM_INPUT("MICR"),

SND_SOC_DAPM_ADC("ADCL", NULL, MAX9860_PWRMAN, MAX9860_ADCLEN_SHIFT, 0),
SND_SOC_DAPM_ADC("ADCR", NULL, MAX9860_PWRMAN, MAX9860_ADCREN_SHIFT, 0),

SND_SOC_DAPM_AIF_OUT("AIFOUTL", "Capture", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_OUT("AIFOUTR", "Capture", 1, SND_SOC_NOPM, 0, 0),

SND_SOC_DAPM_AIF_IN("AIFINL", "Playback", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_IN("AIFINR", "Playback", 1, SND_SOC_NOPM, 0, 0),

SND_SOC_DAPM_DAC("DAC", NULL, MAX9860_PWRMAN, MAX9860_DACEN_SHIFT, 0),

SND_SOC_DAPM_OUTPUT("OUT"),

SND_SOC_DAPM_SUPPLY("Supply", SND_SOC_NOPM, 0, 0,
		    NULL, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_REGULATOR_SUPPLY("AVDD", 0, 0),
SND_SOC_DAPM_REGULATOR_SUPPLY("DVDD", 0, 0),
SND_SOC_DAPM_CLOCK_SUPPLY("mclk"),
};

static const struct snd_soc_dapm_route max9860_dapm_routes[] = {
	{ "ADCL", NULL, "MICL" },
	{ "ADCR", NULL, "MICR" },
	{ "AIFOUTL", NULL, "ADCL" },
	{ "AIFOUTR", NULL, "ADCR" },

	{ "DAC", NULL, "AIFINL" },
	{ "DAC", NULL, "AIFINR" },
	{ "OUT", NULL, "DAC" },

	{ "Supply", NULL, "AVDD" },
	{ "Supply", NULL, "DVDD" },
	{ "Supply", NULL, "mclk" },

	{ "DAC", NULL, "Supply" },
	{ "ADCL", NULL, "Supply" },
	{ "ADCR", NULL, "Supply" },
};

static int max9860_hw_params(struct snd_pcm_substream *substream,
			     struct snd_pcm_hw_params *params,
			     struct snd_soc_dai *dai)
{
	struct snd_soc_component *component = dai->component;
	struct max9860_priv *max9860 = snd_soc_component_get_drvdata(component);
	u8 master;
	u8 ifc1a = 0;
	u8 ifc1b = 0;
	u8 sysclk = 0;
	unsigned long n;
	int ret;

	dev_dbg(component->dev, "hw_params %u Hz, %u channels\n",
		params_rate(params),
		params_channels(params));

	if (params_channels(params) == 2)
		ifc1b |= MAX9860_ST;

	switch (max9860->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
	case SND_SOC_DAIFMT_CBC_CFC:
		master = 0;
		break;
	case SND_SOC_DAIFMT_CBP_CFP:
		master = MAX9860_MASTER;
		break;
	default:
		return -EINVAL;
	}
	ifc1a |= master;

	if (master) {
		if (params_width(params) * params_channels(params) > 48)
			ifc1b |= MAX9860_BSEL_64X;
		else
			ifc1b |= MAX9860_BSEL_48X;
	}

	switch (max9860->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
		ifc1a |= MAX9860_DDLY;
		ifc1b |= MAX9860_ADLY;
		break;
	case SND_SOC_DAIFMT_LEFT_J:
		ifc1a |= MAX9860_WCI;
		break;
	case SND_SOC_DAIFMT_DSP_A:
		if (params_width(params) != 16) {
			dev_err(component->dev,
				"DSP_A works for 16 bits per sample only.\n");
			return -EINVAL;
		}
		ifc1a |= MAX9860_DDLY | MAX9860_WCI | MAX9860_HIZ | MAX9860_TDM;
		ifc1b |= MAX9860_ADLY;
		break;
	case SND_SOC_DAIFMT_DSP_B:
		if (params_width(params) != 16) {
			dev_err(component->dev,
				"DSP_B works for 16 bits per sample only.\n");
			return -EINVAL;
		}
		ifc1a |= MAX9860_WCI | MAX9860_HIZ | MAX9860_TDM;
		break;
	default:
		return -EINVAL;
	}

	switch (max9860->fmt & SND_SOC_DAIFMT_INV_MASK) {
	case SND_SOC_DAIFMT_NB_NF:
		break;
	case SND_SOC_DAIFMT_NB_IF:
		switch (max9860->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
		case SND_SOC_DAIFMT_DSP_A:
		case SND_SOC_DAIFMT_DSP_B:
			return -EINVAL;
		}
		ifc1a ^= MAX9860_WCI;
		break;
	case SND_SOC_DAIFMT_IB_IF:
		switch (max9860->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
		case SND_SOC_DAIFMT_DSP_A:
		case SND_SOC_DAIFMT_DSP_B:
			return -EINVAL;
		}
		ifc1a ^= MAX9860_WCI;
		fallthrough;
	case SND_SOC_DAIFMT_IB_NF:
		ifc1a ^= MAX9860_DBCI;
		ifc1b ^= MAX9860_ABCI;
		break;
	default:
		return -EINVAL;
	}

	dev_dbg(component->dev, "IFC1A  %02x\n", ifc1a);
	ret = regmap_write(max9860->regmap, MAX9860_IFC1A, ifc1a);
	if (ret) {
		dev_err(component->dev, "Failed to set IFC1A: %d\n", ret);
		return ret;
	}
	dev_dbg(component->dev, "IFC1B  %02x\n", ifc1b);
	ret = regmap_write(max9860->regmap, MAX9860_IFC1B, ifc1b);
	if (ret) {
		dev_err(component->dev, "Failed to set IFC1B: %d\n", ret);
		return ret;
	}

	/*
	 * Check if Integer Clock Mode is possible, but avoid it in slave mode
	 * since we then do not know if lrclk is derived from pclk and the
	 * datasheet mentions that the frequencies have to match exactly in
	 * order for this to work.
	 */
	if (params_rate(params) == 8000 || params_rate(params) == 16000) {
		if (master) {
			switch (max9860->pclk_rate) {
			case 12000000:
				sysclk = MAX9860_FREQ_12MHZ;
				break;
			case 13000000:
				sysclk = MAX9860_FREQ_13MHZ;
				break;
			case 19200000:
				sysclk = MAX9860_FREQ_19_2MHZ;
				break;
			default:
				/*
				 * Integer Clock Mode not possible. Leave
				 * sysclk at zero and fall through to the
				 * code below for PLL mode.
				 */
				break;
			}

			if (sysclk && params_rate(params) == 16000)
				sysclk |= MAX9860_16KHZ;
		}
	}

	/*
	 * Largest possible n:
	 *    65536 * 96 * 48kHz / 10MHz -> 30199
	 * Smallest possible n:
	 *    65536 * 96 *  8kHz / 20MHz -> 2517
	 * Both fit nicely in the available 15 bits, no need to apply any mask.
	 */
	n = DIV_ROUND_CLOSEST_ULL(65536ULL * 96 * params_rate(params),
				  max9860->pclk_rate);

	if (!sysclk) {
		/* PLL mode */
		if (params_rate(params) > 24000)
			sysclk |= MAX9860_16KHZ;

		if (!master)
			n |= 1; /* trigger rapid pll lock mode */
	}

	sysclk |= max9860->psclk;
	dev_dbg(component->dev, "SYSCLK %02x\n", sysclk);
	ret = regmap_write(max9860->regmap,
			   MAX9860_SYSCLK, sysclk);
	if (ret) {
		dev_err(component->dev, "Failed to set SYSCLK: %d\n", ret);
		return ret;
	}
	dev_dbg(component->dev, "N %lu\n", n);
	ret = regmap_write(max9860->regmap,
			   MAX9860_AUDIOCLKHIGH, n >> 8);
	if (ret) {
		dev_err(component->dev, "Failed to set NHI: %d\n", ret);
		return ret;
	}
	ret = regmap_write(max9860->regmap,
			   MAX9860_AUDIOCLKLOW, n & 0xff);
	if (ret) {
		dev_err(component->dev, "Failed to set NLO: %d\n", ret);
		return ret;
	}

	if (!master) {
		dev_dbg(component->dev, "Enable PLL\n");
		ret = regmap_update_bits(max9860->regmap, MAX9860_AUDIOCLKHIGH,
					 MAX9860_PLL, MAX9860_PLL);
		if (ret) {
			dev_err(component->dev, "Failed to enable PLL: %d\n",
				ret);
			return ret;
		}
	}

	return 0;
}

static int max9860_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
	struct snd_soc_component *component = dai->component;
	struct max9860_priv *max9860 = snd_soc_component_get_drvdata(component);

	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
	case SND_SOC_DAIFMT_CBP_CFP:
	case SND_SOC_DAIFMT_CBC_CFC:
		max9860->fmt = fmt;
		return 0;

	default:
		return -EINVAL;
	}
}

static const struct snd_soc_dai_ops max9860_dai_ops = {
	.hw_params = max9860_hw_params,
	.set_fmt = max9860_set_fmt,
};

static struct snd_soc_dai_driver max9860_dai = {
	.name = "max9860-hifi",
	.playback = {
		.stream_name = "Playback",
		.channels_min = 1,
		.channels_max = 2,
		.rates = SNDRV_PCM_RATE_CONTINUOUS,
		.rate_min = 8000,
		.rate_max = 48000,
		.formats = SNDRV_PCM_FMTBIT_S16_LE |
			   SNDRV_PCM_FMTBIT_S24_LE |
			   SNDRV_PCM_FMTBIT_S32_LE,
	},
	.capture = {
		.stream_name = "Capture",
		.channels_min = 1,
		.channels_max = 2,
		.rates = SNDRV_PCM_RATE_CONTINUOUS,
		.rate_min = 8000,
		.rate_max = 48000,
		.formats = SNDRV_PCM_FMTBIT_S16_LE |
			   SNDRV_PCM_FMTBIT_S24_LE |
			   SNDRV_PCM_FMTBIT_S32_LE,
	},
	.ops = &max9860_dai_ops,
	.symmetric_rate = 1,
};

static int max9860_set_bias_level(struct snd_soc_component *component,
				  enum snd_soc_bias_level level)
{
	struct max9860_priv *max9860 = dev_get_drvdata(component->dev);
	int ret;

	switch (level) {
	case SND_SOC_BIAS_ON:
	case SND_SOC_BIAS_PREPARE:
		break;

	case SND_SOC_BIAS_STANDBY:
		ret = regmap_update_bits(max9860->regmap, MAX9860_PWRMAN,
					 MAX9860_SHDN, MAX9860_SHDN);
		if (ret) {
			dev_err(component->dev, "Failed to remove SHDN: %d\n",
				ret);
			return ret;
		}
		break;

	case SND_SOC_BIAS_OFF:
		ret = regmap_update_bits(max9860->regmap, MAX9860_PWRMAN,
					 MAX9860_SHDN, 0);
		if (ret) {
			dev_err(component->dev, "Failed to request SHDN: %d\n",
				ret);
			return ret;
		}
		break;
	}

	return 0;
}

static const struct snd_soc_component_driver max9860_component_driver = {
	.set_bias_level		= max9860_set_bias_level,
	.controls		= max9860_controls,
	.num_controls		= ARRAY_SIZE(max9860_controls),
	.dapm_widgets		= max9860_dapm_widgets,
	.num_dapm_widgets	= ARRAY_SIZE(max9860_dapm_widgets),
	.dapm_routes		= max9860_dapm_routes,
	.num_dapm_routes	= ARRAY_SIZE(max9860_dapm_routes),
	.use_pmdown_time	= 1,
	.endianness		= 1,
};

static int max9860_suspend(struct device *dev)
{
	struct max9860_priv *max9860 = dev_get_drvdata(dev);
	int ret;

	ret = regmap_update_bits(max9860->regmap, MAX9860_SYSCLK,
				 MAX9860_PSCLK, MAX9860_PSCLK_OFF);
	if (ret) {
		dev_err(dev, "Failed to disable clock: %d\n", ret);
		return ret;
	}

	regulator_disable(max9860->dvddio);

	return 0;
}

static int max9860_resume(struct device *dev)
{
	struct max9860_priv *max9860 = dev_get_drvdata(dev);
	int ret;

	ret = regulator_enable(max9860->dvddio);
	if (ret) {
		dev_err(dev, "Failed to enable DVDDIO: %d\n", ret);
		return ret;
	}

	regcache_cache_only(max9860->regmap, false);
	ret = regcache_sync(max9860->regmap);
	if (ret) {
		dev_err(dev, "Failed to sync cache: %d\n", ret);
		return ret;
	}

	ret = regmap_update_bits(max9860->regmap, MAX9860_SYSCLK,
				 MAX9860_PSCLK, max9860->psclk);
	if (ret) {
		dev_err(dev, "Failed to enable clock: %d\n", ret);
		return ret;
	}

	return 0;
}

static const struct dev_pm_ops max9860_pm_ops = {
	RUNTIME_PM_OPS(max9860_suspend, max9860_resume, NULL)
};

static int max9860_probe(struct i2c_client *i2c)
{
	struct device *dev = &i2c->dev;
	struct max9860_priv *max9860;
	int ret;
	struct clk *mclk;
	unsigned long mclk_rate;
	int i;
	int intr;

	max9860 = devm_kzalloc(dev, sizeof(struct max9860_priv), GFP_KERNEL);
	if (!max9860)
		return -ENOMEM;

	max9860->dvddio = devm_regulator_get(dev, "DVDDIO");
	if (IS_ERR(max9860->dvddio))
		return dev_err_probe(dev, PTR_ERR(max9860->dvddio),
				     "Failed to get DVDDIO supply\n");

	max9860->dvddio_nb.notifier_call = max9860_dvddio_event;

	ret = devm_regulator_register_notifier(max9860->dvddio,
					       &max9860->dvddio_nb);
	if (ret)
		dev_err(dev, "Failed to register DVDDIO notifier: %d\n", ret);

	ret = regulator_enable(max9860->dvddio);
	if (ret != 0) {
		dev_err(dev, "Failed to enable DVDDIO: %d\n", ret);
		return ret;
	}

	max9860->regmap = devm_regmap_init_i2c(i2c, &max9860_regmap);
	if (IS_ERR(max9860->regmap)) {
		ret = PTR_ERR(max9860->regmap);
		goto err_regulator;
	}

	dev_set_drvdata(dev, max9860);

	/*
	 * mclk has to be in the 10MHz to 60MHz range.
	 * psclk is used to scale mclk into pclk so that
	 * pclk is in the 10MHz to 20MHz range.
	 */
	mclk = clk_get(dev, "mclk");

	if (IS_ERR(mclk)) {
		ret = PTR_ERR(mclk);
		dev_err_probe(dev, ret, "Failed to get MCLK\n");
		goto err_regulator;
	}

	mclk_rate = clk_get_rate(mclk);
	clk_put(mclk);

	if (mclk_rate > 60000000 || mclk_rate < 10000000) {
		dev_err(dev, "Bad mclk %luHz (needs 10MHz - 60MHz)\n",
			mclk_rate);
		ret = -EINVAL;
		goto err_regulator;
	}
	if (mclk_rate >= 40000000)
		max9860->psclk = 3;
	else if (mclk_rate >= 20000000)
		max9860->psclk = 2;
	else
		max9860->psclk = 1;
	max9860->pclk_rate = mclk_rate >> (max9860->psclk - 1);
	max9860->psclk <<= MAX9860_PSCLK_SHIFT;
	dev_dbg(dev, "mclk %lu pclk %lu\n", mclk_rate, max9860->pclk_rate);

	regcache_cache_bypass(max9860->regmap, true);
	for (i = 0; i < max9860_regmap.num_reg_defaults; ++i) {
		ret = regmap_write(max9860->regmap,
				   max9860_regmap.reg_defaults[i].reg,
				   max9860_regmap.reg_defaults[i].def);
		if (ret) {
			dev_err(dev, "Failed to initialize register %u: %d\n",
				max9860_regmap.reg_defaults[i].reg, ret);
			goto err_regulator;
		}
	}
	regcache_cache_bypass(max9860->regmap, false);

	ret = regmap_read(max9860->regmap, MAX9860_INTRSTATUS, &intr);
	if (ret) {
		dev_err(dev, "Failed to clear INTRSTATUS: %d\n", ret);
		goto err_regulator;
	}

	pm_runtime_set_active(dev);
	pm_runtime_enable(dev);
	pm_runtime_idle(dev);

	ret = devm_snd_soc_register_component(dev, &max9860_component_driver,
					      &max9860_dai, 1);
	if (ret) {
		dev_err(dev, "Failed to register CODEC: %d\n", ret);
		goto err_pm;
	}

	return 0;

err_pm:
	pm_runtime_disable(dev);
err_regulator:
	regulator_disable(max9860->dvddio);
	return ret;
}

static void max9860_remove(struct i2c_client *i2c)
{
	struct device *dev = &i2c->dev;
	struct max9860_priv *max9860 = dev_get_drvdata(dev);

	pm_runtime_disable(dev);
	regulator_disable(max9860->dvddio);
}

static const struct i2c_device_id max9860_i2c_id[] = {
	{ "max9860", },
	{ }
};
MODULE_DEVICE_TABLE(i2c, max9860_i2c_id);

static const struct of_device_id max9860_of_match[] = {
	{ .compatible = "maxim,max9860", },
	{ }
};
MODULE_DEVICE_TABLE(of, max9860_of_match);

static struct i2c_driver max9860_i2c_driver = {
	.probe          = max9860_probe,
	.remove         = max9860_remove,
	.id_table       = max9860_i2c_id,
	.driver         = {
		.name           = "max9860",
		.of_match_table = max9860_of_match,
		.pm             = pm_ptr(&max9860_pm_ops),
	},
};

module_i2c_driver(max9860_i2c_driver);

MODULE_DESCRIPTION("ASoC MAX9860 Mono Audio Voice Codec driver");
MODULE_AUTHOR("Peter Rosin <peda@axentia.se>");
MODULE_LICENSE("GPL v2");
