// SPDX-License-Identifier: GPL-2.0-only
/*
 * wm8804.c  --  WM8804 S/PDIF transceiver driver
 *
 * Copyright 2010-11 Wolfson Microelectronics plc
 *
 * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/gpio/consumer.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include <sound/soc-dapm.h>

#include "wm8804.h"

#define WM8804_NUM_SUPPLIES 2
static const char *wm8804_supply_names[WM8804_NUM_SUPPLIES] = {
	"PVDD",
	"DVDD"
};

static const struct reg_default wm8804_reg_defaults[] = {
	{ 3,  0x21 },     /* R3  - PLL1 */
	{ 4,  0xFD },     /* R4  - PLL2 */
	{ 5,  0x36 },     /* R5  - PLL3 */
	{ 6,  0x07 },     /* R6  - PLL4 */
	{ 7,  0x16 },     /* R7  - PLL5 */
	{ 8,  0x18 },     /* R8  - PLL6 */
	{ 9,  0xFF },     /* R9  - SPDMODE */
	{ 10, 0x00 },     /* R10 - INTMASK */
	{ 18, 0x00 },     /* R18 - SPDTX1 */
	{ 19, 0x00 },     /* R19 - SPDTX2 */
	{ 20, 0x00 },     /* R20 - SPDTX3 */
	{ 21, 0x71 },     /* R21 - SPDTX4 */
	{ 22, 0x0B },     /* R22 - SPDTX5 */
	{ 23, 0x70 },     /* R23 - GPO0 */
	{ 24, 0x57 },     /* R24 - GPO1 */
	{ 26, 0x42 },     /* R26 - GPO2 */
	{ 27, 0x06 },     /* R27 - AIFTX */
	{ 28, 0x06 },     /* R28 - AIFRX */
	{ 29, 0x80 },     /* R29 - SPDRX1 */
	{ 30, 0x07 },     /* R30 - PWRDN */
};

struct wm8804_priv {
	struct device *dev;
	struct regmap *regmap;
	struct regulator_bulk_data supplies[WM8804_NUM_SUPPLIES];
	struct notifier_block disable_nb[WM8804_NUM_SUPPLIES];
	int mclk_div;

	struct gpio_desc *reset;

	int aif_pwr;
};

static int txsrc_put(struct snd_kcontrol *kcontrol,
		     struct snd_ctl_elem_value *ucontrol);

static int wm8804_aif_event(struct snd_soc_dapm_widget *w,
			    struct snd_kcontrol *kcontrol, int event);

/*
 * We can't use the same notifier block for more than one supply and
 * there's no way I can see to get from a callback to the caller
 * except container_of().
 */
#define WM8804_REGULATOR_EVENT(n) \
static int wm8804_regulator_event_##n(struct notifier_block *nb, \
				      unsigned long event, void *data)    \
{ \
	struct wm8804_priv *wm8804 = container_of(nb, struct wm8804_priv, \
						  disable_nb[n]); \
	if (event & REGULATOR_EVENT_DISABLE) { \
		regcache_mark_dirty(wm8804->regmap);	\
	} \
	return 0; \
}

WM8804_REGULATOR_EVENT(0)
WM8804_REGULATOR_EVENT(1)

static const char *txsrc_text[] = { "S/PDIF RX", "AIF" };
static SOC_ENUM_SINGLE_DECL(txsrc, WM8804_SPDTX4, 6, txsrc_text);

static const struct snd_kcontrol_new wm8804_tx_source_mux[] = {
	SOC_DAPM_ENUM_EXT("Input Source", txsrc,
			  snd_soc_dapm_get_enum_double, txsrc_put),
};

static const struct snd_soc_dapm_widget wm8804_dapm_widgets[] = {
SND_SOC_DAPM_OUTPUT("SPDIF Out"),
SND_SOC_DAPM_INPUT("SPDIF In"),

SND_SOC_DAPM_PGA("SPDIFTX", WM8804_PWRDN, 2, 1, NULL, 0),
SND_SOC_DAPM_PGA("SPDIFRX", WM8804_PWRDN, 1, 1, NULL, 0),

SND_SOC_DAPM_MUX("Tx Source", SND_SOC_NOPM, 6, 0, wm8804_tx_source_mux),

SND_SOC_DAPM_AIF_OUT_E("AIFTX", NULL, 0, SND_SOC_NOPM, 0, 0, wm8804_aif_event,
		       SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_AIF_IN_E("AIFRX", NULL, 0, SND_SOC_NOPM, 0, 0, wm8804_aif_event,
		      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
};

static const struct snd_soc_dapm_route wm8804_dapm_routes[] = {
	{ "AIFRX", NULL, "Playback" },
	{ "Tx Source", "AIF", "AIFRX" },

	{ "SPDIFRX", NULL, "SPDIF In" },
	{ "Tx Source", "S/PDIF RX", "SPDIFRX" },

	{ "SPDIFTX", NULL, "Tx Source" },
	{ "SPDIF Out", NULL, "SPDIFTX" },

	{ "AIFTX", NULL, "SPDIFRX" },
	{ "Capture", NULL, "AIFTX" },
};

static int wm8804_aif_event(struct snd_soc_dapm_widget *w,
			    struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
	struct wm8804_priv *wm8804 = snd_soc_component_get_drvdata(component);

	switch (event) {
	case SND_SOC_DAPM_POST_PMU:
		/* power up the aif */
		if (!wm8804->aif_pwr)
			snd_soc_component_update_bits(component, WM8804_PWRDN, 0x10, 0x0);
		wm8804->aif_pwr++;
		break;
	case SND_SOC_DAPM_POST_PMD:
		/* power down only both paths are disabled */
		wm8804->aif_pwr--;
		if (!wm8804->aif_pwr)
			snd_soc_component_update_bits(component, WM8804_PWRDN, 0x10, 0x10);
		break;
	}

	return 0;
}

static int txsrc_put(struct snd_kcontrol *kcontrol,
		     struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
	unsigned int val = ucontrol->value.enumerated.item[0] << e->shift_l;
	unsigned int mask = 1 << e->shift_l;
	unsigned int txpwr;

	if (val != 0 && val != mask)
		return -EINVAL;

	snd_soc_dapm_mutex_lock(dapm);

	if (snd_soc_component_test_bits(component, e->reg, mask, val)) {
		/* save the current power state of the transmitter */
		txpwr = snd_soc_component_read(component, WM8804_PWRDN) & 0x4;

		/* power down the transmitter */
		snd_soc_component_update_bits(component, WM8804_PWRDN, 0x4, 0x4);

		/* set the tx source */
		snd_soc_component_update_bits(component, e->reg, mask, val);

		/* restore the transmitter's configuration */
		snd_soc_component_update_bits(component, WM8804_PWRDN, 0x4, txpwr);
	}

	snd_soc_dapm_mutex_unlock(dapm);

	return 0;
}

static bool wm8804_volatile(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case WM8804_RST_DEVID1:
	case WM8804_DEVID2:
	case WM8804_DEVREV:
	case WM8804_INTSTAT:
	case WM8804_SPDSTAT:
	case WM8804_RXCHAN1:
	case WM8804_RXCHAN2:
	case WM8804_RXCHAN3:
	case WM8804_RXCHAN4:
	case WM8804_RXCHAN5:
		return true;
	default:
		return false;
	}
}

static int wm8804_soft_reset(struct wm8804_priv *wm8804)
{
	return regmap_write(wm8804->regmap, WM8804_RST_DEVID1, 0x0);
}

static int wm8804_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
	struct snd_soc_component *component;
	u16 format, master, bcp, lrp;

	component = dai->component;

	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
		format = 0x2;
		break;
	case SND_SOC_DAIFMT_RIGHT_J:
		format = 0x0;
		break;
	case SND_SOC_DAIFMT_LEFT_J:
		format = 0x1;
		break;
	case SND_SOC_DAIFMT_DSP_A:
	case SND_SOC_DAIFMT_DSP_B:
		format = 0x3;
		break;
	default:
		dev_err(dai->dev, "Unknown dai format\n");
		return -EINVAL;
	}

	/* set data format */
	snd_soc_component_update_bits(component, WM8804_AIFTX, 0x3, format);
	snd_soc_component_update_bits(component, WM8804_AIFRX, 0x3, format);

	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBM_CFM:
		master = 1;
		break;
	case SND_SOC_DAIFMT_CBS_CFS:
		master = 0;
		break;
	default:
		dev_err(dai->dev, "Unknown master/slave configuration\n");
		return -EINVAL;
	}

	/* set master/slave mode */
	snd_soc_component_update_bits(component, WM8804_AIFRX, 0x40, master << 6);

	bcp = lrp = 0;
	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
	case SND_SOC_DAIFMT_NB_NF:
		break;
	case SND_SOC_DAIFMT_IB_IF:
		bcp = lrp = 1;
		break;
	case SND_SOC_DAIFMT_IB_NF:
		bcp = 1;
		break;
	case SND_SOC_DAIFMT_NB_IF:
		lrp = 1;
		break;
	default:
		dev_err(dai->dev, "Unknown polarity configuration\n");
		return -EINVAL;
	}

	/* set frame inversion */
	snd_soc_component_update_bits(component, WM8804_AIFTX, 0x10 | 0x20,
			    (bcp << 4) | (lrp << 5));
	snd_soc_component_update_bits(component, WM8804_AIFRX, 0x10 | 0x20,
			    (bcp << 4) | (lrp << 5));
	return 0;
}

static int wm8804_hw_params(struct snd_pcm_substream *substream,
			    struct snd_pcm_hw_params *params,
			    struct snd_soc_dai *dai)
{
	struct snd_soc_component *component;
	u16 blen;

	component = dai->component;

	switch (params_width(params)) {
	case 16:
		blen = 0x0;
		break;
	case 20:
		blen = 0x1;
		break;
	case 24:
		blen = 0x2;
		break;
	default:
		dev_err(dai->dev, "Unsupported word length: %u\n",
			params_width(params));
		return -EINVAL;
	}

	/* set word length */
	snd_soc_component_update_bits(component, WM8804_AIFTX, 0xc, blen << 2);
	snd_soc_component_update_bits(component, WM8804_AIFRX, 0xc, blen << 2);

	return 0;
}

struct pll_div {
	u32 prescale:1;
	u32 mclkdiv:1;
	u32 freqmode:2;
	u32 n:4;
	u32 k:22;
};

/* PLL rate to output rate divisions */
static struct {
	unsigned int div;
	unsigned int freqmode;
	unsigned int mclkdiv;
} post_table[] = {
	{  2,  0, 0 },
	{  4,  0, 1 },
	{  4,  1, 0 },
	{  8,  1, 1 },
	{  8,  2, 0 },
	{ 16,  2, 1 },
	{ 12,  3, 0 },
	{ 24,  3, 1 }
};

#define FIXED_PLL_SIZE ((1ULL << 22) * 10)
static int pll_factors(struct pll_div *pll_div, unsigned int target,
		       unsigned int source, unsigned int mclk_div)
{
	u64 Kpart;
	unsigned long int K, Ndiv, Nmod, tmp;
	int i;

	/*
	 * Scale the output frequency up; the PLL should run in the
	 * region of 90-100MHz.
	 */
	for (i = 0; i < ARRAY_SIZE(post_table); i++) {
		tmp = target * post_table[i].div;
		if ((tmp >= 90000000 && tmp <= 100000000) &&
		    (mclk_div == post_table[i].mclkdiv)) {
			pll_div->freqmode = post_table[i].freqmode;
			pll_div->mclkdiv = post_table[i].mclkdiv;
			target *= post_table[i].div;
			break;
		}
	}

	if (i == ARRAY_SIZE(post_table)) {
		pr_err("%s: Unable to scale output frequency: %uHz\n",
		       __func__, target);
		return -EINVAL;
	}

	pll_div->prescale = 0;
	Ndiv = target / source;
	if (Ndiv < 5) {
		source >>= 1;
		pll_div->prescale = 1;
		Ndiv = target / source;
	}

	if (Ndiv < 5 || Ndiv > 13) {
		pr_err("%s: WM8804 N value is not within the recommended range: %lu\n",
		       __func__, Ndiv);
		return -EINVAL;
	}
	pll_div->n = Ndiv;

	Nmod = target % source;
	Kpart = FIXED_PLL_SIZE * (u64)Nmod;

	do_div(Kpart, source);

	K = Kpart & 0xffffffff;
	if ((K % 10) >= 5)
		K += 5;
	K /= 10;
	pll_div->k = K;

	return 0;
}

static int wm8804_set_pll(struct snd_soc_dai *dai, int pll_id,
			  int source, unsigned int freq_in,
			  unsigned int freq_out)
{
	struct snd_soc_component *component = dai->component;
	struct wm8804_priv *wm8804 = snd_soc_component_get_drvdata(component);
	bool change;

	if (!freq_in || !freq_out) {
		/* disable the PLL */
		regmap_update_bits_check(wm8804->regmap, WM8804_PWRDN,
					 0x1, 0x1, &change);
		if (change)
			pm_runtime_put(wm8804->dev);
	} else {
		int ret;
		struct pll_div pll_div;

		ret = pll_factors(&pll_div, freq_out, freq_in,
				  wm8804->mclk_div);
		if (ret)
			return ret;

		/* power down the PLL before reprogramming it */
		regmap_update_bits_check(wm8804->regmap, WM8804_PWRDN,
					 0x1, 0x1, &change);
		if (!change)
			pm_runtime_get_sync(wm8804->dev);

		/* set PLLN and PRESCALE */
		snd_soc_component_update_bits(component, WM8804_PLL4, 0xf | 0x10,
				    pll_div.n | (pll_div.prescale << 4));
		/* set mclkdiv and freqmode */
		snd_soc_component_update_bits(component, WM8804_PLL5, 0x3 | 0x8,
				    pll_div.freqmode | (pll_div.mclkdiv << 3));
		/* set PLLK */
		snd_soc_component_write(component, WM8804_PLL1, pll_div.k & 0xff);
		snd_soc_component_write(component, WM8804_PLL2, (pll_div.k >> 8) & 0xff);
		snd_soc_component_write(component, WM8804_PLL3, pll_div.k >> 16);

		/* power up the PLL */
		snd_soc_component_update_bits(component, WM8804_PWRDN, 0x1, 0);
	}

	return 0;
}

static int wm8804_set_sysclk(struct snd_soc_dai *dai,
			     int clk_id, unsigned int freq, int dir)
{
	struct snd_soc_component *component;

	component = dai->component;

	switch (clk_id) {
	case WM8804_TX_CLKSRC_MCLK:
		if ((freq >= 10000000 && freq <= 14400000)
				|| (freq >= 16280000 && freq <= 27000000))
			snd_soc_component_update_bits(component, WM8804_PLL6, 0x80, 0x80);
		else {
			dev_err(dai->dev, "OSCCLOCK is not within the "
				"recommended range: %uHz\n", freq);
			return -EINVAL;
		}
		break;
	case WM8804_TX_CLKSRC_PLL:
		snd_soc_component_update_bits(component, WM8804_PLL6, 0x80, 0);
		break;
	case WM8804_CLKOUT_SRC_CLK1:
		snd_soc_component_update_bits(component, WM8804_PLL6, 0x8, 0);
		break;
	case WM8804_CLKOUT_SRC_OSCCLK:
		snd_soc_component_update_bits(component, WM8804_PLL6, 0x8, 0x8);
		break;
	default:
		dev_err(dai->dev, "Unknown clock source: %d\n", clk_id);
		return -EINVAL;
	}

	return 0;
}

static int wm8804_set_clkdiv(struct snd_soc_dai *dai,
			     int div_id, int div)
{
	struct snd_soc_component *component;
	struct wm8804_priv *wm8804;

	component = dai->component;
	switch (div_id) {
	case WM8804_CLKOUT_DIV:
		snd_soc_component_update_bits(component, WM8804_PLL5, 0x30,
				    (div & 0x3) << 4);
		break;
	case WM8804_MCLK_DIV:
		wm8804 = snd_soc_component_get_drvdata(component);
		wm8804->mclk_div = div;
		break;
	default:
		dev_err(dai->dev, "Unknown clock divider: %d\n", div_id);
		return -EINVAL;
	}
	return 0;
}

static const struct snd_soc_dai_ops wm8804_dai_ops = {
	.hw_params = wm8804_hw_params,
	.set_fmt = wm8804_set_fmt,
	.set_sysclk = wm8804_set_sysclk,
	.set_clkdiv = wm8804_set_clkdiv,
	.set_pll = wm8804_set_pll
};

#define WM8804_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
			SNDRV_PCM_FMTBIT_S24_LE)

#define WM8804_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
		      SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \
		      SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \
		      SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000)

static struct snd_soc_dai_driver wm8804_dai = {
	.name = "wm8804-spdif",
	.playback = {
		.stream_name = "Playback",
		.channels_min = 2,
		.channels_max = 2,
		.rates = WM8804_RATES,
		.formats = WM8804_FORMATS,
	},
	.capture = {
		.stream_name = "Capture",
		.channels_min = 2,
		.channels_max = 2,
		.rates = WM8804_RATES,
		.formats = WM8804_FORMATS,
	},
	.ops = &wm8804_dai_ops,
	.symmetric_rate = 1
};

static const struct snd_soc_component_driver soc_component_dev_wm8804 = {
	.dapm_widgets		= wm8804_dapm_widgets,
	.num_dapm_widgets	= ARRAY_SIZE(wm8804_dapm_widgets),
	.dapm_routes		= wm8804_dapm_routes,
	.num_dapm_routes	= ARRAY_SIZE(wm8804_dapm_routes),
	.use_pmdown_time	= 1,
	.endianness		= 1,
};

const struct regmap_config wm8804_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,

	.max_register = WM8804_MAX_REGISTER,
	.volatile_reg = wm8804_volatile,

	.cache_type = REGCACHE_MAPLE,
	.reg_defaults = wm8804_reg_defaults,
	.num_reg_defaults = ARRAY_SIZE(wm8804_reg_defaults),
};
EXPORT_SYMBOL_GPL(wm8804_regmap_config);

int wm8804_probe(struct device *dev, struct regmap *regmap)
{
	struct wm8804_priv *wm8804;
	unsigned int id1, id2;
	int i, ret;

	wm8804 = devm_kzalloc(dev, sizeof(*wm8804), GFP_KERNEL);
	if (!wm8804)
		return -ENOMEM;

	dev_set_drvdata(dev, wm8804);

	wm8804->dev = dev;
	wm8804->regmap = regmap;

	wm8804->reset = devm_gpiod_get_optional(dev, "wlf,reset",
						GPIOD_OUT_LOW);
	if (IS_ERR(wm8804->reset)) {
		ret = PTR_ERR(wm8804->reset);
		dev_err(dev, "Failed to get reset line: %d\n", ret);
		return ret;
	}

	for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++)
		wm8804->supplies[i].supply = wm8804_supply_names[i];

	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(wm8804->supplies),
				      wm8804->supplies);
	if (ret) {
		dev_err(dev, "Failed to request supplies: %d\n", ret);
		return ret;
	}

	wm8804->disable_nb[0].notifier_call = wm8804_regulator_event_0;
	wm8804->disable_nb[1].notifier_call = wm8804_regulator_event_1;

	/* This should really be moved into the regulator core */
	for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++) {
		struct regulator *regulator = wm8804->supplies[i].consumer;

		ret = devm_regulator_register_notifier(regulator,
						       &wm8804->disable_nb[i]);
		if (ret != 0) {
			dev_err(dev,
				"Failed to register regulator notifier: %d\n",
				ret);
			return ret;
		}
	}

	ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies),
				    wm8804->supplies);
	if (ret) {
		dev_err(dev, "Failed to enable supplies: %d\n", ret);
		return ret;
	}

	gpiod_set_value_cansleep(wm8804->reset, 1);

	ret = regmap_read(regmap, WM8804_RST_DEVID1, &id1);
	if (ret < 0) {
		dev_err(dev, "Failed to read device ID: %d\n", ret);
		goto err_reg_enable;
	}

	ret = regmap_read(regmap, WM8804_DEVID2, &id2);
	if (ret < 0) {
		dev_err(dev, "Failed to read device ID: %d\n", ret);
		goto err_reg_enable;
	}

	id2 = (id2 << 8) | id1;

	if (id2 != 0x8805) {
		dev_err(dev, "Invalid device ID: %#x\n", id2);
		ret = -EINVAL;
		goto err_reg_enable;
	}

	ret = regmap_read(regmap, WM8804_DEVREV, &id1);
	if (ret < 0) {
		dev_err(dev, "Failed to read device revision: %d\n",
			ret);
		goto err_reg_enable;
	}
	dev_info(dev, "revision %c\n", id1 + 'A');

	if (!wm8804->reset) {
		ret = wm8804_soft_reset(wm8804);
		if (ret < 0) {
			dev_err(dev, "Failed to issue reset: %d\n", ret);
			goto err_reg_enable;
		}
	}

	ret = devm_snd_soc_register_component(dev, &soc_component_dev_wm8804,
				     &wm8804_dai, 1);
	if (ret < 0) {
		dev_err(dev, "Failed to register CODEC: %d\n", ret);
		goto err_reg_enable;
	}

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

	return 0;

err_reg_enable:
	regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies), wm8804->supplies);
	return ret;
}
EXPORT_SYMBOL_GPL(wm8804_probe);

void wm8804_remove(struct device *dev)
{
	pm_runtime_disable(dev);
}
EXPORT_SYMBOL_GPL(wm8804_remove);

#if IS_ENABLED(CONFIG_PM)
static int wm8804_runtime_resume(struct device *dev)
{
	struct wm8804_priv *wm8804 = dev_get_drvdata(dev);
	int ret;

	ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies),
				    wm8804->supplies);
	if (ret) {
		dev_err(wm8804->dev, "Failed to enable supplies: %d\n", ret);
		return ret;
	}

	regcache_sync(wm8804->regmap);

	/* Power up OSCCLK */
	regmap_update_bits(wm8804->regmap, WM8804_PWRDN, 0x8, 0x0);

	return 0;
}

static int wm8804_runtime_suspend(struct device *dev)
{
	struct wm8804_priv *wm8804 = dev_get_drvdata(dev);

	/* Power down OSCCLK */
	regmap_update_bits(wm8804->regmap, WM8804_PWRDN, 0x8, 0x8);

	regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies),
			       wm8804->supplies);

	return 0;
}
#endif

const struct dev_pm_ops wm8804_pm = {
	SET_RUNTIME_PM_OPS(wm8804_runtime_suspend, wm8804_runtime_resume, NULL)
};
EXPORT_SYMBOL_GPL(wm8804_pm);

MODULE_DESCRIPTION("ASoC WM8804 driver");
MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");
MODULE_LICENSE("GPL");
