/*
 * Arizona core driver
 *
 * Copyright 2014 CirrusLogic, Inc.
 * Copyright 2012 Wolfson Microelectronics plc
 *
 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/mfd/core.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/machine.h>
#include <linux/slab.h>

#include <linux/mfd/arizona/core.h>
#include <linux/mfd/arizona/registers.h>

#include "arizona.h"

static const char *wm5102_core_supplies[] = {
	"AVDD",
	"DBVDD1",
};

int arizona_clk32k_enable(struct arizona *arizona)
{
	int ret = 0;

	mutex_lock(&arizona->clk_lock);

	arizona->clk32k_ref++;

	if (arizona->clk32k_ref == 1) {
		switch (arizona->pdata.clk32k_src) {
		case ARIZONA_32KZ_MCLK1:
			ret = pm_runtime_get_sync(arizona->dev);
			if (ret != 0)
				goto out;
			break;
		}

		ret = regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
					 ARIZONA_CLK_32K_ENA,
					 ARIZONA_CLK_32K_ENA);
	}

out:
	if (ret != 0)
		arizona->clk32k_ref--;

	mutex_unlock(&arizona->clk_lock);

	return ret;
}
EXPORT_SYMBOL_GPL(arizona_clk32k_enable);

int arizona_clk32k_disable(struct arizona *arizona)
{
	int ret = 0;

	mutex_lock(&arizona->clk_lock);

	BUG_ON(arizona->clk32k_ref <= 0);

	arizona->clk32k_ref--;

	if (arizona->clk32k_ref == 0) {
		regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
				   ARIZONA_CLK_32K_ENA, 0);

		switch (arizona->pdata.clk32k_src) {
		case ARIZONA_32KZ_MCLK1:
			pm_runtime_put_sync(arizona->dev);
			break;
		}
	}

	mutex_unlock(&arizona->clk_lock);

	return ret;
}
EXPORT_SYMBOL_GPL(arizona_clk32k_disable);

static irqreturn_t arizona_clkgen_err(int irq, void *data)
{
	struct arizona *arizona = data;

	dev_err(arizona->dev, "CLKGEN error\n");

	return IRQ_HANDLED;
}

static irqreturn_t arizona_underclocked(int irq, void *data)
{
	struct arizona *arizona = data;
	unsigned int val;
	int ret;

	ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_8,
			  &val);
	if (ret != 0) {
		dev_err(arizona->dev, "Failed to read underclock status: %d\n",
			ret);
		return IRQ_NONE;
	}

	if (val & ARIZONA_AIF3_UNDERCLOCKED_STS)
		dev_err(arizona->dev, "AIF3 underclocked\n");
	if (val & ARIZONA_AIF2_UNDERCLOCKED_STS)
		dev_err(arizona->dev, "AIF2 underclocked\n");
	if (val & ARIZONA_AIF1_UNDERCLOCKED_STS)
		dev_err(arizona->dev, "AIF1 underclocked\n");
	if (val & ARIZONA_ISRC3_UNDERCLOCKED_STS)
		dev_err(arizona->dev, "ISRC3 underclocked\n");
	if (val & ARIZONA_ISRC2_UNDERCLOCKED_STS)
		dev_err(arizona->dev, "ISRC2 underclocked\n");
	if (val & ARIZONA_ISRC1_UNDERCLOCKED_STS)
		dev_err(arizona->dev, "ISRC1 underclocked\n");
	if (val & ARIZONA_FX_UNDERCLOCKED_STS)
		dev_err(arizona->dev, "FX underclocked\n");
	if (val & ARIZONA_ASRC_UNDERCLOCKED_STS)
		dev_err(arizona->dev, "ASRC underclocked\n");
	if (val & ARIZONA_DAC_UNDERCLOCKED_STS)
		dev_err(arizona->dev, "DAC underclocked\n");
	if (val & ARIZONA_ADC_UNDERCLOCKED_STS)
		dev_err(arizona->dev, "ADC underclocked\n");
	if (val & ARIZONA_MIXER_UNDERCLOCKED_STS)
		dev_err(arizona->dev, "Mixer dropped sample\n");

	return IRQ_HANDLED;
}

static irqreturn_t arizona_overclocked(int irq, void *data)
{
	struct arizona *arizona = data;
	unsigned int val[3];
	int ret;

	ret = regmap_bulk_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_6,
			       &val[0], 3);
	if (ret != 0) {
		dev_err(arizona->dev, "Failed to read overclock status: %d\n",
			ret);
		return IRQ_NONE;
	}

	switch (arizona->type) {
	case WM8998:
	case WM1814:
		val[0] = ((val[0] & 0x60e0) >> 1) |
			 ((val[0] & 0x1e00) >> 2) |
			 (val[0] & 0x000f);
		break;
	default:
		break;
	}

	if (val[0] & ARIZONA_PWM_OVERCLOCKED_STS)
		dev_err(arizona->dev, "PWM overclocked\n");
	if (val[0] & ARIZONA_FX_CORE_OVERCLOCKED_STS)
		dev_err(arizona->dev, "FX core overclocked\n");
	if (val[0] & ARIZONA_DAC_SYS_OVERCLOCKED_STS)
		dev_err(arizona->dev, "DAC SYS overclocked\n");
	if (val[0] & ARIZONA_DAC_WARP_OVERCLOCKED_STS)
		dev_err(arizona->dev, "DAC WARP overclocked\n");
	if (val[0] & ARIZONA_ADC_OVERCLOCKED_STS)
		dev_err(arizona->dev, "ADC overclocked\n");
	if (val[0] & ARIZONA_MIXER_OVERCLOCKED_STS)
		dev_err(arizona->dev, "Mixer overclocked\n");
	if (val[0] & ARIZONA_AIF3_SYNC_OVERCLOCKED_STS)
		dev_err(arizona->dev, "AIF3 overclocked\n");
	if (val[0] & ARIZONA_AIF2_SYNC_OVERCLOCKED_STS)
		dev_err(arizona->dev, "AIF2 overclocked\n");
	if (val[0] & ARIZONA_AIF1_SYNC_OVERCLOCKED_STS)
		dev_err(arizona->dev, "AIF1 overclocked\n");
	if (val[0] & ARIZONA_PAD_CTRL_OVERCLOCKED_STS)
		dev_err(arizona->dev, "Pad control overclocked\n");

	if (val[1] & ARIZONA_SLIMBUS_SUBSYS_OVERCLOCKED_STS)
		dev_err(arizona->dev, "Slimbus subsystem overclocked\n");
	if (val[1] & ARIZONA_SLIMBUS_ASYNC_OVERCLOCKED_STS)
		dev_err(arizona->dev, "Slimbus async overclocked\n");
	if (val[1] & ARIZONA_SLIMBUS_SYNC_OVERCLOCKED_STS)
		dev_err(arizona->dev, "Slimbus sync overclocked\n");
	if (val[1] & ARIZONA_ASRC_ASYNC_SYS_OVERCLOCKED_STS)
		dev_err(arizona->dev, "ASRC async system overclocked\n");
	if (val[1] & ARIZONA_ASRC_ASYNC_WARP_OVERCLOCKED_STS)
		dev_err(arizona->dev, "ASRC async WARP overclocked\n");
	if (val[1] & ARIZONA_ASRC_SYNC_SYS_OVERCLOCKED_STS)
		dev_err(arizona->dev, "ASRC sync system overclocked\n");
	if (val[1] & ARIZONA_ASRC_SYNC_WARP_OVERCLOCKED_STS)
		dev_err(arizona->dev, "ASRC sync WARP overclocked\n");
	if (val[1] & ARIZONA_ADSP2_1_OVERCLOCKED_STS)
		dev_err(arizona->dev, "DSP1 overclocked\n");
	if (val[1] & ARIZONA_ISRC3_OVERCLOCKED_STS)
		dev_err(arizona->dev, "ISRC3 overclocked\n");
	if (val[1] & ARIZONA_ISRC2_OVERCLOCKED_STS)
		dev_err(arizona->dev, "ISRC2 overclocked\n");
	if (val[1] & ARIZONA_ISRC1_OVERCLOCKED_STS)
		dev_err(arizona->dev, "ISRC1 overclocked\n");

	if (val[2] & ARIZONA_SPDIF_OVERCLOCKED_STS)
		dev_err(arizona->dev, "SPDIF overclocked\n");

	return IRQ_HANDLED;
}

static int arizona_poll_reg(struct arizona *arizona,
			    int timeout, unsigned int reg,
			    unsigned int mask, unsigned int target)
{
	unsigned int val = 0;
	int ret, i;

	for (i = 0; i < timeout; i++) {
		ret = regmap_read(arizona->regmap, reg, &val);
		if (ret != 0) {
			dev_err(arizona->dev, "Failed to read reg %u: %d\n",
				reg, ret);
			continue;
		}

		if ((val & mask) == target)
			return 0;

		msleep(1);
	}

	dev_err(arizona->dev, "Polling reg %u timed out: %x\n", reg, val);
	return -ETIMEDOUT;
}

static int arizona_wait_for_boot(struct arizona *arizona)
{
	int ret;

	/*
	 * We can't use an interrupt as we need to runtime resume to do so,
	 * we won't race with the interrupt handler as it'll be blocked on
	 * runtime resume.
	 */
	switch (arizona->type) {
	case WM5102:
	case WM8997:
	case WM1814:
	case WM8998:
	case WM5110:
	case WM8280:
	case WM1831:
	case CS47L24:
		ret = arizona_poll_reg(arizona, 5,
				       ARIZONA_INTERRUPT_RAW_STATUS_5,
				       ARIZONA_BOOT_DONE_STS,
				       ARIZONA_BOOT_DONE_STS);
		if (!ret)
			regmap_write(arizona->regmap,
				     ARIZONA_INTERRUPT_STATUS_5,
				     ARIZONA_BOOT_DONE_STS);
		break;
	default:
		ret = arizona_poll_reg(arizona, 5, CLEARWATER_IRQ1_RAW_STATUS_1,
				       CLEARWATER_BOOT_DONE_STS1,
				       CLEARWATER_BOOT_DONE_STS1);

		if (!ret)
			regmap_write(arizona->regmap, CLEARWATER_IRQ1_STATUS_1,
				     CLEARWATER_BOOT_DONE_EINT1);
		break;
	}

	pm_runtime_mark_last_busy(arizona->dev);

	return ret;
}

static inline void arizona_enable_reset(struct arizona *arizona)
{
	if (arizona->pdata.reset)
		gpio_set_value_cansleep(arizona->pdata.reset, 0);
}

static void arizona_disable_reset(struct arizona *arizona)
{
	if (arizona->pdata.reset) {
		switch (arizona->type) {
		case WM5110:
		case WM8280:
			msleep(5);
			break;
		default:
			break;
		}

		gpio_set_value_cansleep(arizona->pdata.reset, 1);
		msleep(1);
	}
}

struct arizona_sysclk_state {
	unsigned int fll;
	unsigned int sysclk;
};

static int arizona_enable_freerun_sysclk(struct arizona *arizona,
					 struct arizona_sysclk_state *state)
{
	int ret, err;
	return 0;
	/* Cache existing FLL and SYSCLK settings */
	ret = regmap_read(arizona->regmap, ARIZONA_FLL1_CONTROL_1, &state->fll);
	if (ret) {
		dev_err(arizona->dev, "Failed to cache FLL settings: %d\n",
			ret);
		return ret;
	}
	ret = regmap_read(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1,
			  &state->sysclk);
	if (ret) {
		dev_err(arizona->dev, "Failed to cache SYSCLK settings: %d\n",
			ret);
		return ret;
	}

	/* Start up SYSCLK using the FLL in free running mode */
	ret = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1,
			ARIZONA_FLL1_ENA | ARIZONA_FLL1_FREERUN);
	if (ret) {
		dev_err(arizona->dev,
			"Failed to start FLL in freerunning mode: %d\n",
			ret);
		return ret;
	}
	ret = arizona_poll_reg(arizona, 25, ARIZONA_INTERRUPT_RAW_STATUS_5,
			       ARIZONA_FLL1_CLOCK_OK_STS,
			       ARIZONA_FLL1_CLOCK_OK_STS);
	if (ret) {
		ret = -ETIMEDOUT;
		goto err_fll;
	}

	ret = regmap_write(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, 0x0144);
	if (ret) {
		dev_err(arizona->dev, "Failed to start SYSCLK: %d\n", ret);
		goto err_fll;
	}

	return 0;

err_fll:
	err = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1, state->fll);
	if (err)
		dev_err(arizona->dev,
			"Failed to re-apply old FLL settings: %d\n", err);

	return ret;
}

static int arizona_disable_freerun_sysclk(struct arizona *arizona,
					  struct arizona_sysclk_state *state)
{
	int ret;
	return 0;
	ret = regmap_write(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1,
			   state->sysclk);
	if (ret) {
		dev_err(arizona->dev,
			"Failed to re-apply old SYSCLK settings: %d\n", ret);
		return ret;
	}

	ret = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1, state->fll);
	if (ret) {
		dev_err(arizona->dev,
			"Failed to re-apply old FLL settings: %d\n", ret);
		return ret;
	}

	return 0;
}

static int wm5102_apply_hardware_patch(struct arizona *arizona)
{
	return 0;
/*	struct arizona_sysclk_state state;
	int err, ret;

	ret = arizona_enable_freerun_sysclk(arizona, &state);
	if (ret)
		return ret;

	// Start the write sequencer and wait for it to finish
	ret = regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_0,
			ARIZONA_WSEQ_ENA | ARIZONA_WSEQ_START | 160);
	if (ret) {
		dev_err(arizona->dev, "Failed to start write sequencer: %d\n",
			ret);
		goto err;
	}

	ret = arizona_poll_reg(arizona, 5, ARIZONA_WRITE_SEQUENCER_CTRL_1,
			       ARIZONA_WSEQ_BUSY, 0);
	if (ret) {
		regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_0,
			     ARIZONA_WSEQ_ABORT);
		ret = -ETIMEDOUT;
	}

err:
	err = arizona_disable_freerun_sysclk(arizona, &state);

	return ret ?: err;*/
}

/*
 * Register patch to some of the CODECs internal write sequences
 * to ensure a clean exit from the low power sleep state.
 */
static const struct reg_sequence wm5110_sleep_patch[] = {
	{ 0x337A, 0xC100 },
	{ 0x337B, 0x0041 },
	{ 0x3300, 0xA210 },
	{ 0x3301, 0x050C },
};

static int wm5110_apply_sleep_patch(struct arizona *arizona)
{
	struct arizona_sysclk_state state;
	int err, ret;

	ret = arizona_enable_freerun_sysclk(arizona, &state);
	if (ret)
		return ret;

	ret = regmap_multi_reg_write_bypassed(arizona->regmap,
					      wm5110_sleep_patch,
					      ARRAY_SIZE(wm5110_sleep_patch));

	err = arizona_disable_freerun_sysclk(arizona, &state);

	if (ret)
		return ret;
	else
		return err;
}

static int wm5102_clear_write_sequencer(struct arizona *arizona)
{
	int ret;
	return 0;
	ret = regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_3,
			   0x0);
	if (ret) {
		dev_err(arizona->dev,
			"Failed to clear write sequencer state: %d\n", ret);
		return ret;
	}

	arizona_enable_reset(arizona);
	regulator_disable(arizona->dcvdd);

	msleep(20);

	ret = regulator_enable(arizona->dcvdd);
	if (ret) {
		dev_err(arizona->dev, "Failed to re-enable DCVDD: %d\n", ret);
		return ret;
	}
	arizona_disable_reset(arizona);

	return 0;
}

static int arizona_soft_reset(struct arizona *arizona)
{
	int ret;
	return 0;
	ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0);
	if (ret != 0) {
		dev_err(arizona->dev, "Failed to reset device: %d\n", ret);
		goto err;
	}
	msleep(1);

err:
	return ret;
}

#ifdef CONFIG_PM_RUNTIME
static int arizona_dcvdd_notify(struct notifier_block *nb,
				unsigned long action, void *data)
{
	struct arizona *arizona = container_of(nb, struct arizona,
					       dcvdd_notifier);

	dev_dbg(arizona->dev, "DCVDD notify %lx\n", action);

	if (action & REGULATOR_EVENT_DISABLE)
		msleep(20);

	return NOTIFY_DONE;
}

static int arizona_runtime_resume(struct device *dev)
{
	struct arizona *arizona = dev_get_drvdata(dev);
	int ret;
	unsigned int offset, num_gpios = 0;

	dev_dbg(arizona->dev, "Leaving AoD mode\n");

	switch (arizona->type) {
	case WM5110:
	case WM8280:
		if (arizona->rev == 3)
			arizona_enable_reset(arizona);
		break;
	case WM5102:
	case WM8997:
	case WM8998:
	case WM1814:
	case WM1831:
	case CS47L24:
		break;
	default:
		if (arizona->external_dcvdd)
			arizona_enable_reset(arizona);
		break;
	};

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

	regcache_cache_only(arizona->regmap, false);
	if (arizona->regmap_32bit)
		regcache_cache_only(arizona->regmap_32bit, false);

	switch (arizona->type) {
	case WM5102:
		if (arizona->external_dcvdd) {
			ret = regmap_update_bits(arizona->regmap,
						 ARIZONA_ISOLATION_CONTROL,
						 ARIZONA_ISOLATE_DCVDD1, 0);
			if (ret != 0) {
				dev_err(arizona->dev,
					"Failed to connect DCVDD: %d\n", ret);
				goto err;
			}
		}

		ret = wm5102_patch(arizona);
		if (ret != 0) {
			dev_err(arizona->dev, "Failed to apply patch: %d\n",
				ret);
			goto err;
		}

		ret = wm5102_apply_hardware_patch(arizona);
		if (ret) {
			dev_err(arizona->dev,
				"Failed to apply hardware patch: %d\n",
				ret);
			goto err;
		}
		break;
	case WM5110:
	case WM8280:
		if (arizona->rev == 3) {
			if (!arizona->pdata.reset) {
				ret = arizona_soft_reset(arizona);
				if (ret != 0)
					goto err;
			} else {
				arizona_disable_reset(arizona);
			}
		}

		ret = arizona_wait_for_boot(arizona);
		if (ret)
			goto err;

		if (arizona->external_dcvdd) {
			ret = regmap_update_bits(arizona->regmap,
						 ARIZONA_ISOLATION_CONTROL,
						 ARIZONA_ISOLATE_DCVDD1, 0);
			if (ret) {
				dev_err(arizona->dev,
					"Failed to connect DCVDD: %d\n", ret);
				goto err;
			}
		} else {
			/*
			 * As this is only called for the internal regulator
			 * (where we know voltage ranges available) it is ok
			 * to request an exact range.
			 */
			ret = regulator_set_voltage(arizona->dcvdd,
						    1200000, 1200000);
			if (ret < 0) {
				dev_err(arizona->dev,
					"Failed to set resume voltage: %d\n",
					ret);
				goto err;
			}
		}
		break;
	case WM8997:
	case WM8998:
	case WM1814:
		ret = arizona_wait_for_boot(arizona);
		if (ret != 0) {
			goto err;
		}

		if (arizona->external_dcvdd) {
			ret = regmap_update_bits(arizona->regmap,
						 ARIZONA_ISOLATION_CONTROL,
						 ARIZONA_ISOLATE_DCVDD1, 0);
			if (ret != 0) {
				dev_err(arizona->dev,
					"Failed to connect DCVDD: %d\n", ret);
				goto err;
			}
		}
		break;
	case WM1831:
	case CS47L24:
		ret = arizona_wait_for_boot(arizona);
		if (ret != 0) {
			goto err;
		}
		break;
	default:
		if (arizona->external_dcvdd)
			arizona_disable_reset(arizona);

		ret = arizona_wait_for_boot(arizona);
		if (ret != 0) {
			goto err;
		}

		mutex_lock(&arizona->reg_setting_lock);
		regmap_write(arizona->regmap, 0x80, 0x3);
		ret = regcache_sync_region(arizona->regmap, CLEARWATER_CP_MODE,
					   CLEARWATER_CP_MODE);
		regmap_write(arizona->regmap, 0x80, 0x0);
		mutex_unlock(&arizona->reg_setting_lock);

		if (ret != 0) {
			dev_err(arizona->dev, "Failed to restore keyed cache\n");
			goto err;
		}
		break;
	}

	switch (arizona->type) {
	case WM8285:
	case WM1840:
		num_gpios = CLEARWATER_NUM_GPIOS;
		break;
	case CS47L35:
		num_gpios = MARLEY_NUM_GPIOS;
		break;
	case CS47L90:
	case CS47L91:
		num_gpios = MOON_NUM_GPIOS;
		break;
	case CS47L15:
		num_gpios = CS47L15_NUM_GPIOS;
		break;
	default:
		break;
	}


	ret = regcache_sync(arizona->regmap);
	if (ret != 0) {
		dev_err(arizona->dev,
			"Failed to restore 16-bit register cache\n");
		goto err;
	}

	if (arizona->regmap_32bit) {
		ret = regcache_sync(arizona->regmap_32bit);
		if (ret != 0) {
			dev_err(arizona->dev,
				"Failed to restore 32-bit register cache\n");
			goto err;
		}
	}

	return 0;

err:
	regcache_cache_only(arizona->regmap, true);
	if (arizona->regmap_32bit)
		regcache_cache_only(arizona->regmap_32bit, true);
	regulator_disable(arizona->dcvdd);
	return ret;
}

static int arizona_runtime_suspend(struct device *dev)
{
	struct arizona *arizona = dev_get_drvdata(dev);
	int ret;

	dev_dbg(arizona->dev, "Entering AoD mode\n");

	if (arizona->external_dcvdd) {
		switch (arizona->type) {
		case WM5102:
		case WM5110:
		case WM8997:
		case WM8280:
		case WM8998:
		case WM1814:
			ret = regmap_update_bits(arizona->regmap,
						 ARIZONA_ISOLATION_CONTROL,
						 ARIZONA_ISOLATE_DCVDD1,
						 ARIZONA_ISOLATE_DCVDD1);
			if (ret != 0) {
				dev_err(arizona->dev, "Failed to isolate DCVDD: %d\n",
					ret);
				return ret;
			}
			break;
		default:
			break;
		}
	} else {
		switch (arizona->type) {
		case WM5110:
		case WM8280:
			/*
			 * As this is only called for the internal regulator
			 * (where we know voltage ranges available) it is ok
			 * to request an exact range.
			 */
			ret = regulator_set_voltage(arizona->dcvdd,
						    1175000,
						    1175000);
			if (ret < 0) {
				dev_err(arizona->dev,
					"Failed to set suspend voltage: %d\n",
					ret);
				return ret;
			}
			break;
		default:
			break;
		}
	}

	regcache_cache_only(arizona->regmap, true);
	regcache_mark_dirty(arizona->regmap);
	if (arizona->regmap_32bit) {
		regcache_cache_only(arizona->regmap_32bit, true);
		regcache_mark_dirty(arizona->regmap_32bit);
	}
	regulator_disable(arizona->dcvdd);

	return 0;
}
#else
static inline int arizona_dcvdd_notify(struct notifier_block *nb,
				       unsigned long action, void *data)
{
	return 0;
}
#endif

#ifdef CONFIG_PM_SLEEP
static int arizona_suspend_noirq(struct device *dev)
{
	struct arizona *arizona = dev_get_drvdata(dev);

	dev_dbg(arizona->dev, "Late suspend, reenabling IRQ\n");

	if (arizona->irq_sem) {
		enable_irq(arizona->irq);
		arizona->irq_sem = 0;
	}

	return 0;
}

static int arizona_suspend(struct device *dev)
{
	struct arizona *arizona = dev_get_drvdata(dev);

	dev_dbg(arizona->dev, "Early suspend, disabling IRQ\n");

	disable_irq(arizona->irq);
	arizona->irq_sem = 1;

	return 0;
}

static int arizona_resume_noirq(struct device *dev)
{
	struct arizona *arizona = dev_get_drvdata(dev);

	dev_dbg(arizona->dev, "Early resume, disabling IRQ\n");
	disable_irq(arizona->irq);

	arizona->irq_sem = 1;

	return 0;
}

static int arizona_resume(struct device *dev)
{
	struct arizona *arizona = dev_get_drvdata(dev);

	dev_dbg(arizona->dev, "Late resume, reenabling IRQ\n");
	if (arizona->irq_sem) {
		enable_irq(arizona->irq);
		arizona->irq_sem = 0;
	}

	return 0;
}
#endif

const struct dev_pm_ops arizona_pm_ops = {
	SET_RUNTIME_PM_OPS(arizona_runtime_suspend,
			   arizona_runtime_resume,
			   NULL)
	SET_SYSTEM_SLEEP_PM_OPS(arizona_suspend, arizona_resume)
#ifdef CONFIG_PM_SLEEP
	.suspend_noirq = arizona_suspend_noirq,
	.resume_noirq = arizona_resume_noirq,
#endif
};
EXPORT_SYMBOL_GPL(arizona_pm_ops);

#ifdef CONFIG_OF
unsigned long arizona_of_get_type(struct device *dev)
{
	const struct of_device_id *id = of_match_device(arizona_of_match, dev);

	if (id)
		return (unsigned long)id->data;
	else
		return 0;
}
EXPORT_SYMBOL_GPL(arizona_of_get_type);

int arizona_of_get_named_gpio(struct arizona *arizona, const char *prop,
			      bool mandatory)
{
	int gpio;

	gpio = of_get_named_gpio(arizona->dev->of_node, prop, 0);
	if (gpio < 0) {
		if (mandatory)
			dev_err(arizona->dev,
				"Mandatory DT gpio %s missing/malformed: %d\n",
				prop, gpio);

		gpio = 0;
	}

	return gpio;
}
EXPORT_SYMBOL_GPL(arizona_of_get_named_gpio);

int arizona_of_read_u32_array(struct arizona *arizona,
			      const char *prop, bool mandatory,
			      u32 *data, size_t num)
{
	int ret;

	ret = of_property_read_u32_array(arizona->dev->of_node, prop,
					 data, num);

	if (ret >= 0)
		return 0;

	switch (ret) {
	case -EINVAL:
		if (mandatory)
			dev_err(arizona->dev,
				"Mandatory DT property %s is missing\n",
				prop);
		break;
	default:
		dev_err(arizona->dev,
			"DT property %s is malformed: %d\n",
			prop, ret);
	}

	return ret;
}
EXPORT_SYMBOL_GPL(arizona_of_read_u32_array);

int arizona_of_read_u32(struct arizona *arizona,
			       const char* prop, bool mandatory,
			       u32 *data)
{
	return arizona_of_read_u32_array(arizona, prop, mandatory, data, 1);
}
EXPORT_SYMBOL_GPL(arizona_of_read_u32);

static int arizona_of_get_max_channels(struct arizona *arizona,
				       const char *prop)
{
	struct arizona_pdata *pdata = &arizona->pdata;
	struct device_node *np = arizona->dev->of_node;
	struct property *tempprop;
	const __be32 *cur;
	u32 val;
	int i;

	i = 0;
	of_property_for_each_u32(np, prop, tempprop, cur, val) {
		if (i == ARRAY_SIZE(pdata->max_channels_clocked))
			break;

		pdata->max_channels_clocked[i++] = val;
	}

	return 0;
}

static int arizona_of_get_inmode(struct arizona *arizona,
					const char *prop)
{
	struct arizona_pdata *pdata = &arizona->pdata;
	struct device_node *np = arizona->dev->of_node;
	struct property *tempprop;
	const __be32 *cur;
	u32 val;
	int i;

	i = 0;
	of_property_for_each_u32(np, prop, tempprop, cur, val) {
		if (i == ARRAY_SIZE(pdata->inmode))
			break;

		pdata->inmode[i++] = val;
	}

	return 0;
}

static int arizona_of_get_lrclk_adv(struct arizona *arizona,
					const char *prop)
{
	struct arizona_pdata *pdata = &arizona->pdata;
	struct device_node *np = arizona->dev->of_node;
	struct property *tempprop;
	const __be32 *cur;
	u32 val;
	int i;

	i = 0;
	of_property_for_each_u32(np, prop, tempprop, cur, val) {
		if (i == ARRAY_SIZE(pdata->lrclk_adv))
			break;

		pdata->lrclk_adv[i++] = val;
	}

	return 0;
}

static int arizona_of_get_dmicref(struct arizona *arizona,
					const char *prop)
{
	struct arizona_pdata *pdata = &arizona->pdata;
	struct device_node *np = arizona->dev->of_node;
	struct property *tempprop;
	const __be32 *cur;
	u32 val;
	int i;

	i = 0;
	of_property_for_each_u32(np, prop, tempprop, cur, val) {
		if (i == ARRAY_SIZE(pdata->dmic_ref))
			break;

		pdata->dmic_ref[i++] = val;
	}

	return 0;
}

static int arizona_of_get_dmic_clksrc(struct arizona *arizona,
					const char *prop)
{
	struct arizona_pdata *pdata = &arizona->pdata;
	struct device_node *np = arizona->dev->of_node;
	struct property *tempprop;
	const __be32 *cur;
	u32 val;
	int i;

	i = 0;
	of_property_for_each_u32(np, prop, tempprop, cur, val) {
		if (i == ARRAY_SIZE(pdata->dmic_clksrc))
			break;

		pdata->dmic_clksrc[i++] = val;
	}

	return 0;
}

static int arizona_of_get_gpio_defaults(struct arizona *arizona,
					const char *prop)
{
	struct arizona_pdata *pdata = &arizona->pdata;
	struct device_node *np = arizona->dev->of_node;
	struct property *tempprop;
	const __be32 *cur;
	u32 val;
	int i;

	i = 0;
	of_property_for_each_u32(np, prop, tempprop, cur, val) {
		if (i == ARRAY_SIZE(pdata->gpio_defaults))
			break;

		pdata->gpio_defaults[i++] = val;
	}

	/*
	 * All values are literal except out of range values
	 * which are chip default, translate into platform
	 * data which uses 0 as chip default and out of range
	 * as zero.
	 */
	while (i > 0) {
		--i;
		if (pdata->gpio_defaults[i] > 0xffff)
			pdata->gpio_defaults[i] = 0;
		else if (pdata->gpio_defaults[i] == 0)
			pdata->gpio_defaults[i] = 0x10000;
	}

	return 0;
}

static int arizona_of_get_u32_num_groups(struct arizona *arizona,
					const char *prop,
					int group_size)
{
	int len_prop;
	int num_groups;

	if (!of_get_property(arizona->dev->of_node, prop, &len_prop))
		return -EINVAL;

	num_groups =  len_prop / (group_size * sizeof(u32));

	if (num_groups * group_size * sizeof(u32) != len_prop) {
		dev_err(arizona->dev,
			"DT property %s is malformed: %d\n",
			prop, -EOVERFLOW);
		return -EOVERFLOW;
	}

	return num_groups;
}

static int arizona_of_get_micd_ranges(struct arizona *arizona,
				      const char *prop)
{
	int nranges;
	int i, j;
	int ret = 0;
	u32 value;
	struct arizona_micd_range *micd_ranges;

	nranges = arizona_of_get_u32_num_groups(arizona, prop, 2);
	if (nranges < 0)
		return nranges;

	micd_ranges = devm_kzalloc(arizona->dev,
				   nranges * sizeof(struct arizona_micd_range),
				   GFP_KERNEL);

	for (i = 0, j = 0; i < nranges; ++i) {
		ret = of_property_read_u32_index(arizona->dev->of_node,
						 prop, j++, &value);
		if (ret < 0)
			goto error;
		micd_ranges[i].max = value;

		ret = of_property_read_u32_index(arizona->dev->of_node,
						 prop, j++, &value);
		if (ret < 0)
			goto error;
		micd_ranges[i].key = value;
	}

	arizona->pdata.micd_ranges = micd_ranges;
	arizona->pdata.num_micd_ranges = nranges;

	return ret;

error:
	devm_kfree(arizona->dev, micd_ranges);
	dev_err(arizona->dev, "DT property %s is malformed: %d\n", prop, ret);
	return ret;
}

static int arizona_of_get_micd_configs(struct arizona *arizona,
				       const char *prop)
{
	int nconfigs;
	int i, j, group_size;
	int ret = 0;
	u32 value;
	struct arizona_micd_config *micd_configs;

	switch (arizona->type) {
	case WM5102:
	case WM5110:
	case WM8997:
	case WM8280:
	case WM8998:
	case WM1814:
	case WM8285:
	case WM1840:
	case WM1831:
	case CS47L24:
	case CS47L35:
		group_size = 3;
		break;
	default:
		group_size = 4;
		break;
	}

	nconfigs = arizona_of_get_u32_num_groups(arizona, prop, group_size);
	if (nconfigs < 0)
		return nconfigs;

	micd_configs = devm_kzalloc(arizona->dev,
				    nconfigs *
				    sizeof(struct arizona_micd_config),
				    GFP_KERNEL);

	for (i = 0, j = 0; i < nconfigs; ++i) {
		ret = of_property_read_u32_index(arizona->dev->of_node,
						 prop, j++, &value);
		if (ret < 0)
			goto error;
		micd_configs[i].src = value;

		if (group_size == 4) {
			ret = of_property_read_u32_index(arizona->dev->of_node,
							 prop, j++, &value);
			if (ret < 0)
				goto error;
			micd_configs[i].gnd = value;
		}

		ret = of_property_read_u32_index(arizona->dev->of_node,
						 prop, j++, &value);
		if (ret < 0)
			goto error;
		micd_configs[i].bias = value;

		ret = of_property_read_u32_index(arizona->dev->of_node,
						 prop, j++, &value);
		if (ret < 0)
			goto error;
		micd_configs[i].gpio = value;
	}

	arizona->pdata.micd_configs = micd_configs;
	arizona->pdata.num_micd_configs = nconfigs;

	return ret;

error:
	devm_kfree(arizona->dev, micd_configs);
	dev_err(arizona->dev, "DT property %s is malformed: %d\n", prop, ret);

	return ret;
}

static int arizona_of_get_micbias(struct arizona *arizona,
				  const char *prop, int index,
				  int num_micbias_outputs)
{
	int ret, i;
	int j = 0;
	u32 micbias_config[4 + ARIZONA_MAX_CHILD_MICBIAS] = {0};

	ret = arizona_of_read_u32_array(arizona, prop, false,
					micbias_config,
					4 + num_micbias_outputs);

	if (ret >= 0) {
		arizona->pdata.micbias[index].mV = micbias_config[j++];
		arizona->pdata.micbias[index].ext_cap = micbias_config[j++];
		for (i = 0; i < num_micbias_outputs; i++)
			arizona->pdata.micbias[index].discharge[i] =
				micbias_config[j++];
		arizona->pdata.micbias[index].soft_start = micbias_config[j++];
		arizona->pdata.micbias[index].bypass = micbias_config[j++];
	}

	return ret;
}

static int arizona_of_get_core_pdata(struct arizona *arizona)
{
	struct arizona_pdata *pdata = &arizona->pdata;
	u32 out_mono[ARIZONA_MAX_OUTPUT];
	int i, num_micbias_outputs;

	switch (arizona->type) {
	case WM5102:
	case WM5110:
	case WM8997:
	case WM8280:
	case WM8998:
	case WM1814:
	case WM8285:
	case WM1840:
	case WM1831:
	case CS47L24:
		num_micbias_outputs = 1;
		break;
	case CS47L15:
		num_micbias_outputs = CS47L15_NUM_CHILD_MICBIAS;
		break;
	case CS47L35:
		num_micbias_outputs = MARLEY_NUM_CHILD_MICBIAS;
		break;
	default:
		num_micbias_outputs = MOON_NUM_CHILD_MICBIAS;
		break;
	}

	memset(&out_mono, 0, sizeof(out_mono));

	pdata->reset = arizona_of_get_named_gpio(arizona, "wlf,reset", true);

	arizona_of_read_s32(arizona, "wlf,clk32k-src", false,
			    &pdata->clk32k_src);

	arizona_of_get_micd_ranges(arizona, "wlf,micd-ranges");
	arizona_of_get_micd_configs(arizona, "wlf,micd-configs");

	arizona_of_get_micbias(arizona, "wlf,micbias1", 0, num_micbias_outputs);
	arizona_of_get_micbias(arizona, "wlf,micbias2", 1, num_micbias_outputs);
	arizona_of_get_micbias(arizona, "wlf,micbias3", 2, num_micbias_outputs);
	arizona_of_get_micbias(arizona, "wlf,micbias4", 3, num_micbias_outputs);

	arizona_of_get_gpio_defaults(arizona, "wlf,gpio-defaults");

	arizona_of_get_max_channels(arizona, "wlf,max-channels-clocked");

	arizona_of_get_dmicref(arizona, "wlf,dmic-ref");

	arizona_of_get_inmode(arizona, "wlf,inmode");

	arizona_of_get_dmic_clksrc(arizona, "wlf,dmic-clksrc");

	arizona_of_read_u32_array(arizona, "wlf,out-mono", false,
				  out_mono, ARRAY_SIZE(out_mono));
	for (i = 0; i < ARRAY_SIZE(out_mono); ++i)
		pdata->out_mono[i] = !!out_mono[i];

	arizona_of_read_u32(arizona, "wlf,wm5102t-output-pwr", false,
				&pdata->wm5102t_output_pwr);

	arizona_of_read_s32(arizona, "wlf,hpdet-ext-res", false,
				&pdata->hpdet_ext_res);

	pdata->rev_specific_fw = of_property_read_bool(arizona->dev->of_node,
						       "wlf,rev-specific-fw");

	arizona_of_get_lrclk_adv(arizona, "wlf,aif-lrclk-advance");

	return 0;
}

const struct of_device_id arizona_of_match[] = {
	{ .compatible = "wlf,wm5102", .data = (void *)WM5102 },
	{ .compatible = "wlf,wm8280", .data = (void *)WM8280 },
	{ .compatible = "wlf,wm5110", .data = (void *)WM5110 },
	{ .compatible = "wlf,wm8997", .data = (void *)WM8997 },
	{ .compatible = "wlf,wm8998", .data = (void *)WM8998 },
	{ .compatible = "wlf,wm1814", .data = (void *)WM1814 },
	{ .compatible = "wlf,wm8285", .data = (void *)WM8285 },
	{ .compatible = "wlf,wm1840", .data = (void *)WM1840 },
	{ .compatible = "wlf,wm1831", .data = (void *)WM1831 },
	{ .compatible = "cirrus,cs47l15", .data = (void *)CS47L15 },
	{ .compatible = "cirrus,cs47l24", .data = (void *)CS47L24 },
	{ .compatible = "cirrus,cs47l35", .data = (void *)CS47L35 },
	{ .compatible = "cirrus,cs47l85", .data = (void *)WM8285 },
	{ .compatible = "cirrus,cs47l90", .data = (void *)CS47L90 },
	{ .compatible = "cirrus,cs47l91", .data = (void *)CS47L91 },
	{},
};
EXPORT_SYMBOL_GPL(arizona_of_match);
#else
static inline int arizona_of_get_core_pdata(struct arizona *arizona)
{
	return 0;
}
#endif

static struct mfd_cell early_devs[] = {
	{ .name = "arizona-ldo1" },
};

static struct mfd_cell wm5102_devs[] = {
	{ .name = "arizona-micsupp" },
	{ .name = "arizona-extcon" },
	{ .name = "arizona-gpio" },
	{ .name = "arizona-haptics" },
	{ .name = "arizona-pwm" },
	{ .name = "wm5102-codec" },
};

static struct mfd_cell florida_devs[] = {
	{ .name = "arizona-micsupp" },
	{ .name = "arizona-extcon" },
	{ .name = "arizona-gpio" },
	{ .name = "arizona-haptics" },
	{ .name = "arizona-pwm" },
	{ .name = "florida-codec" },
};

static struct mfd_cell largo_devs[] = {
	{ .name = "arizona-gpio" },
	{ .name = "arizona-haptics" },
	{ .name = "arizona-pwm" },
	{ .name = "largo-codec" },
};

static struct mfd_cell wm8997_devs[] = {
	{ .name = "arizona-micsupp" },
	{ .name = "arizona-extcon" },
	{ .name = "arizona-gpio" },
	{ .name = "arizona-haptics" },
	{ .name = "arizona-pwm" },
	{ .name = "wm8997-codec" },
};

static struct mfd_cell vegas_devs[] = {
	{ .name = "arizona-micsupp" },
	{ .name = "arizona-extcon" },
	{ .name = "arizona-gpio" },
	{ .name = "arizona-haptics" },
	{ .name = "arizona-pwm" },
	{ .name = "vegas-codec" },
};

static struct mfd_cell clearwater_devs[] = {
	{ .name = "arizona-micsupp" },
	{ .name = "arizona-extcon" },
	{ .name = "arizona-gpio" },
	{ .name = "arizona-haptics" },
	{ .name = "arizona-pwm" },
	{ .name = "clearwater-codec" },
};

static struct mfd_cell marley_devs[] = {
	{ .name = "arizona-micsupp" },
	{ .name = "arizona-extcon" },
	{ .name = "arizona-gpio" },
	{ .name = "arizona-haptics" },
	{ .name = "arizona-pwm" },
	{ .name = "marley-codec" },
};

static struct mfd_cell moon_devs[] = {
	{ .name = "arizona-micsupp" },
	{ .name = "arizona-extcon" },
	{ .name = "arizona-gpio" },
	{ .name = "arizona-haptics" },
	{ .name = "arizona-pwm" },
	{ .name = "moon-codec" },
};

static struct mfd_cell cs47l15_devs[] = {
	{ .name = "arizona-extcon" },
	{ .name = "arizona-gpio" },
	{ .name = "arizona-haptics" },
	{ .name = "arizona-pwm" },
	{ .name = "cs47l15-codec" },
};

static const struct {
	unsigned int enable;
	unsigned int conf_reg;
	unsigned int vol_reg;
	unsigned int adc_reg;
} arizona_florida_channel_defs[] = {
	{
		ARIZONA_IN1R_ENA, ARIZONA_IN1L_CONTROL,
		ARIZONA_ADC_DIGITAL_VOLUME_1R, ARIZONA_ADC_VCO_CAL_5
	},
	{
		ARIZONA_IN1L_ENA, ARIZONA_IN1L_CONTROL,
		ARIZONA_ADC_DIGITAL_VOLUME_1L, ARIZONA_ADC_VCO_CAL_4
	},
	{
		ARIZONA_IN2R_ENA, ARIZONA_IN2L_CONTROL,
		ARIZONA_ADC_DIGITAL_VOLUME_2R, ARIZONA_ADC_VCO_CAL_7
	},
	{
		ARIZONA_IN2L_ENA, ARIZONA_IN2L_CONTROL,
		ARIZONA_ADC_DIGITAL_VOLUME_2L, ARIZONA_ADC_VCO_CAL_6
	},
	{
		ARIZONA_IN3R_ENA, ARIZONA_IN3L_CONTROL,
		ARIZONA_ADC_DIGITAL_VOLUME_3R, ARIZONA_ADC_VCO_CAL_9
	},
	{
		ARIZONA_IN3L_ENA, ARIZONA_IN3L_CONTROL,
		ARIZONA_ADC_DIGITAL_VOLUME_3L, ARIZONA_ADC_VCO_CAL_8
	},
};

void arizona_florida_mute_analog(struct arizona* arizona,
				 unsigned int mute)
{
	unsigned int val, chans;
	int i;

	regmap_read(arizona->regmap, ARIZONA_INPUT_ENABLES_STATUS, &chans);

	for (i = 0; i < ARRAY_SIZE(arizona_florida_channel_defs); ++i) {
		if (!(chans & arizona_florida_channel_defs[i].enable))
			continue;

		/* Check for analogue input */
		regmap_read(arizona->regmap,
			    arizona_florida_channel_defs[i].conf_reg,
			    &val);
		if (val & 0x0400)
			continue;

		regmap_update_bits(arizona->regmap,
				   arizona_florida_channel_defs[i].vol_reg,
				   ARIZONA_IN1L_MUTE,
				   mute);
	}
}
EXPORT_SYMBOL_GPL(arizona_florida_mute_analog);

static bool arizona_florida_get_input_state(struct arizona* arizona)
{
	unsigned int val, chans;
	int count, i, j;

	regmap_read(arizona->regmap, ARIZONA_INPUT_ENABLES_STATUS, &chans);

	for (i = 0; i < ARRAY_SIZE(arizona_florida_channel_defs); ++i) {
		if (!(chans & arizona_florida_channel_defs[i].enable))
			continue;

		/* Check for analogue input */
		regmap_read(arizona->regmap,
			    arizona_florida_channel_defs[i].conf_reg,
			    &val);
		if (val & 0x0400)
			continue;

		count = 0;

		for (j = 0; j < 4; ++j) {
			regmap_read(arizona->regmap,
				    arizona_florida_channel_defs[i].adc_reg,
				    &val);
			val &= ARIZONA_ADC1L_COUNT_RD_MASK;
			val >>= ARIZONA_ADC1L_COUNT_RD_SHIFT;

			dev_dbg(arizona->dev, "ADC Count: %d\n", val);

			if (val > 78 || val < 54)
				count++;
		}

		if (count == j)
			return true;
	}

	return false;
}

void arizona_florida_clear_input(struct arizona *arizona)
{
return;
	mutex_lock(&arizona->reg_setting_lock);
	regmap_write(arizona->regmap, 0x80, 0x3);

	if (arizona_florida_get_input_state(arizona)) {
		arizona_florida_mute_analog(arizona, ARIZONA_IN1L_MUTE);

		regmap_write(arizona->regmap, 0x3A6, 0x5555);
		regmap_write(arizona->regmap, 0x3A5, 0x3);
		msleep(10);
		regmap_write(arizona->regmap, 0x3A5, 0x0);

		if (arizona_florida_get_input_state(arizona)) {
			regmap_write(arizona->regmap, 0x3A6, 0xAAAA);
			regmap_write(arizona->regmap, 0x3A5, 0x5);
			msleep(10);
			regmap_write(arizona->regmap, 0x3A5, 0x0);
		}

		regmap_write(arizona->regmap, 0x3A6, 0x0);

		msleep(5);

		arizona_florida_mute_analog(arizona, 0);
	}

	regmap_write(arizona->regmap, 0x80, 0x0);
	mutex_unlock(&arizona->reg_setting_lock);
}
EXPORT_SYMBOL_GPL(arizona_florida_clear_input);

int arizona_get_num_micbias(struct arizona *arizona,
	unsigned int *micbiases, unsigned int *child_micbiases)
{
	unsigned int num_micbiases, num_child_micbiases;

	if (!arizona)
		return -EINVAL;

	switch (arizona->type) {
	case WM5102:
	case WM5110:
	case WM8997:
	case WM8280:
	case WM8998:
	case WM1814:
		num_micbiases = WM5102_NUM_MICBIAS;
		num_child_micbiases = 0;
		break;
	case WM1831:
	case CS47L24:
		num_micbiases = LARGO_NUM_MICBIAS;
		num_child_micbiases = 0;
		break;
	case WM8285:
	case WM1840:
		num_micbiases = CLEARWATER_NUM_MICBIAS;
		num_child_micbiases = 0;
		break;
	case CS47L15:
		num_micbiases = CS47L15_NUM_MICBIAS;
		num_child_micbiases = CS47L15_NUM_CHILD_MICBIAS;
		break;
	case CS47L35:
		num_micbiases = MARLEY_NUM_MICBIAS;
		num_child_micbiases = MARLEY_NUM_CHILD_MICBIAS;
		break;
	default:
		num_micbiases = MOON_NUM_MICBIAS;
		num_child_micbiases = MOON_NUM_CHILD_MICBIAS;
		break;
	}

	if (micbiases)
		*micbiases = num_micbiases;
	if (child_micbiases)
		*child_micbiases = num_child_micbiases;

	return 0;
}
EXPORT_SYMBOL_GPL(arizona_get_num_micbias);

int arizona_dev_init(struct arizona *arizona)
{
	struct device *dev = arizona->dev;
	const char *type_name = "Unknown";
	unsigned int reg, val, mask;
	int (*apply_patch)(struct arizona *) = NULL;
	int ret, i, max_inputs, j;
	unsigned int max_micbias = 0, num_child_micbias = 0;
	unsigned int num_dmic_clksrc = 0;



	dev_set_drvdata(arizona->dev, arizona);
	mutex_init(&arizona->clk_lock);
	mutex_init(&arizona->reg_setting_lock);
	mutex_init(&arizona->rate_lock);
	mutex_init(&arizona->dspclk_ena_lock);

	if (dev_get_platdata(arizona->dev))
		memcpy(&arizona->pdata, dev_get_platdata(arizona->dev),
		       sizeof(arizona->pdata));
	else
		arizona_of_get_core_pdata(arizona);

	regcache_cache_only(arizona->regmap, true);
	if (arizona->regmap_32bit)
		regcache_cache_only(arizona->regmap_32bit, true);

	switch (arizona->type) {
	case WM5102:
	case WM5110:
	case WM8280:
	case WM8997:
	case WM8998:
	case WM1814:
	case WM8285:
	case WM1840:
	case WM1831:
	case CS47L15:
	case CS47L24:
	case CS47L35:
	case CS47L90:
	case CS47L91:
		for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++)
			arizona->core_supplies[i].supply = wm5102_core_supplies[i];
		arizona->num_core_supplies = ARRAY_SIZE(wm5102_core_supplies);
		break;
	default:
		dev_err(arizona->dev, "Unknown device type %d\n",
			arizona->type);
		return -EINVAL;
	}

	/* Mark DCVDD as external, LDO1 driver will clear if internal */
	arizona->external_dcvdd = true;

	switch (arizona->type) {
	case WM1831:
	case CS47L15:
	case CS47L24:
	case CS47L35:
	case CS47L90:
	case CS47L91:
		break;
	default:
		ret = mfd_add_devices(arizona->dev, -1, early_devs,
				      ARRAY_SIZE(early_devs), NULL, 0, NULL);
		if (ret != 0) {
			dev_err(dev, "Failed to add early children: %d\n", ret);
			return ret;
		}
		break;
	}

	ret = devm_regulator_bulk_get(dev, arizona->num_core_supplies,
				      arizona->core_supplies);
	if (ret != 0) {
		dev_err(dev, "Failed to request core supplies: %d\n",
			ret);
		goto err_early;
	}

	/**
	 * Don't use devres here because the only device we have to get
	 * against is the MFD device and DCVDD will likely be supplied by
	 * one of its children. Meaning that the regulator will be
	 * destroyed by the time devres calls regulator put.
	 */
	arizona->dcvdd = regulator_get(arizona->dev, "DCVDD");
	if (IS_ERR(arizona->dcvdd)) {
		ret = PTR_ERR(arizona->dcvdd);
		dev_err(dev, "Failed to request DCVDD: %d\n", ret);
		goto err_early;
	}

	arizona->dcvdd_notifier.notifier_call = arizona_dcvdd_notify;
	ret = regulator_register_notifier(arizona->dcvdd,
					  &arizona->dcvdd_notifier);
	if (ret < 0) {
		dev_err(dev, "Failed to register DCVDD notifier %d\n", ret);
		goto err_dcvdd;
	}

	if (arizona->pdata.reset) {
		/* Start out with /RESET low to put the chip into reset */
		ret = devm_gpio_request_one(arizona->dev, arizona->pdata.reset,
					    GPIOF_DIR_OUT | GPIOF_INIT_LOW,
					    "cirrus,reset");
		if (ret != 0) {
			dev_err(dev, "Failed to request /RESET: %d, gpio: %d, flags: %d, label: %s\n", ret, arizona->pdata.reset, GPIOF_DIR_OUT | GPIOF_INIT_LOW, "cirrus,reset");
			goto err_notifier;
		}
	}

	/* Ensure period of reset asserted before we apply the supplies */
	msleep(20);

	ret = regulator_bulk_enable(arizona->num_core_supplies,
				    arizona->core_supplies);
	if (ret != 0) {
		dev_err(dev, "Failed to enable core supplies: %d\n",
			ret);
		goto err_notifier;
	}

	ret = regulator_enable(arizona->dcvdd);
	if (ret != 0) {
		dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
		goto err_enable;
	}

	arizona_disable_reset(arizona);

	regcache_cache_only(arizona->regmap, false);
	if (arizona->regmap_32bit)
		regcache_cache_only(arizona->regmap_32bit, false);

	/* Verify that this is a chip we know about */
	ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg);
	if (ret != 0) {
		dev_err(dev, "Failed to read ID register: %d\n", ret);
		goto err_reset;
	}

	switch (reg) {
	case 0x5102:
	case 0x5110:
	case 0x6349:
	case 0x6363:
	case 0x8997:
	case 0x6338:
	case 0x6360:
	case 0x6364:
	case 0x6370:
		break;
	default:
		dev_err(arizona->dev, "Unknown device ID: %x\n", reg);
		goto err_reset;
	}

	/* If we have a /RESET GPIO we'll already be reset */
	if (!arizona->pdata.reset) {
		ret = arizona_soft_reset(arizona);
		if (ret != 0)
			goto err_reset;
	}

	/* Ensure device startup is complete */
	switch (arizona->type) {
	case WM5102:
		ret = regmap_read(arizona->regmap,
				  ARIZONA_WRITE_SEQUENCER_CTRL_3, &val);
		if (ret) {
			dev_err(dev,
				"Failed to check write sequencer state: %d\n",
				ret);
		} else if (val & 0x01) {
			ret = wm5102_clear_write_sequencer(arizona);
			if (ret)
				return ret;
		}
		break;
	default:
		break;
	}

	ret = arizona_wait_for_boot(arizona);
	if (ret) {
		dev_err(arizona->dev, "Device failed initial boot: %d\n", ret);
		goto err_reset;
	}

	/* Read the device ID information & do device specific stuff */
	ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg);
	if (ret != 0) {
		dev_err(dev, "Failed to read ID register: %d\n", ret);
		goto err_reset;
	}

	ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION,
			  &arizona->rev);
	if (ret != 0) {
		dev_err(dev, "Failed to read revision register: %d\n", ret);
		goto err_reset;
	}
	arizona->rev &= ARIZONA_DEVICE_REVISION_MASK;

	switch (reg) {
#ifdef CONFIG_MFD_WM5102
	case 0x5102:
		type_name = "WM5102";
		if (arizona->type != WM5102) {
			dev_err(arizona->dev, "WM5102 registered as %d\n",
				arizona->type);
			arizona->type = WM5102;
		}
		apply_patch = wm5102_patch;
		arizona->rev &= 0x7;
		break;
#endif
#ifdef CONFIG_MFD_FLORIDA
	case 0x5110:
		switch (arizona->type) {
		case WM8280:
			if (arizona->rev >= 0x5)
				type_name = "WM8281";
			else
				type_name = "WM8280";
			break;

		case WM5110:
			type_name = "WM5110";
			break;

		default:
			dev_err(arizona->dev, "Florida codec registered as %d\n",
				arizona->type);
			arizona->type = WM8280;
			type_name = "Florida";
			break;
		}
		apply_patch = florida_patch;
		break;
#endif
#ifdef CONFIG_MFD_LARGO
	case 0x6363:
		switch (arizona->type) {
		case CS47L24:
			type_name = "CS47L24";
			break;

		case WM1831:
			type_name = "WM1831";
			break;

		default:
			dev_err(arizona->dev, "Largo codec registered as %d\n",
				arizona->type);
			arizona->type = CS47L24;
			type_name = "Largo";
			break;
		}
		apply_patch = largo_patch;
		break;
#endif
#ifdef CONFIG_MFD_WM8997
	case 0x8997:
		type_name = "WM8997";
		if (arizona->type != WM8997) {
			dev_err(arizona->dev, "WM8997 registered as %d\n",
				arizona->type);
			arizona->type = WM8997;
		}
		apply_patch = wm8997_patch;
		break;
#endif
#ifdef CONFIG_MFD_VEGAS
	case 0x6349:
		switch (arizona->type) {
		case WM8998:
			type_name = "WM8998";
			break;

		case WM1814:
			type_name = "WM1814";
			break;

		default:
			dev_err(arizona->dev,
				"Unknown Vegas codec registered as WM8998\n");
			arizona->type = WM8998;
		}

		apply_patch = vegas_patch;
		break;
#endif
#ifdef CONFIG_MFD_CLEARWATER
	case 0x6338:
		switch (arizona->type) {
		case WM8285:
			type_name = "CS47L85";
			break;

		case WM1840:
			type_name = "WM1840";
			break;

		default:
			dev_err(arizona->dev,
				"Unknown Clearwater codec registered as CS47L85\n");
			arizona->type = WM8285;
		}

		apply_patch = clearwater_patch;
		break;
#endif
#ifdef CONFIG_MFD_MARLEY
	case 0x6360:
		switch (arizona->type) {
		case CS47L35:
			type_name = "CS47L35";
			break;

		default:
			dev_err(arizona->dev,
			   "Unknown Marley codec registered as CS47L35\n");
			arizona->type = CS47L35;
		}

		apply_patch = marley_patch;
		break;
#endif
#ifdef CONFIG_MFD_MOON
	case 0x6364:
		switch (arizona->type) {
		case CS47L90:
			type_name = "CS47L90";
			break;
		case CS47L91:
			type_name = "CS47L91";
			break;
		default:
			dev_err(arizona->dev,
				"Unknown Moon codec registered as CS47L90\n");
			arizona->type = CS47L90;
		}

		apply_patch = moon_patch;
		break;
#endif
#ifdef CONFIG_MFD_CS47L15
	case 0x6370:
		switch (arizona->type) {
		case CS47L15:
			type_name = "CS47L15";
			break;
		default:
			arizona->type = CS47L15;
			dev_err(arizona->dev,
				"CS47L15 codec registered as %d\n",
				arizona->type);
			break;
		}

		apply_patch = cs47l15_patch;
		break;
#endif
	default:
		dev_err(arizona->dev, "Unknown device ID %x\n", reg);
		goto err_reset;
	}

	dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A');

	if (apply_patch) {
		ret = apply_patch(arizona);
		if (ret != 0) {
			dev_err(arizona->dev, "Failed to apply patch: %d\n",
				ret);
			goto err_reset;
		}

		switch (arizona->type) {
		case WM5102:
			ret = wm5102_apply_hardware_patch(arizona);
			if (ret) {
				dev_err(arizona->dev,
					"Failed to apply hardware patch: %d\n",
					ret);
				goto err_reset;
			}
			break;
		case WM5110:
		case WM8280:
			ret = wm5110_apply_sleep_patch(arizona);
			if (ret) {
				dev_err(arizona->dev,
					"Failed to apply sleep patch: %d\n",
					ret);
				goto err_reset;
			}
			break;
		default:
			break;
		}
	}

	switch (arizona->type) {
	case WM5102:
	case WM5110:
	case WM8280:
	case WM8997:
	case WM8998:
	case WM1814:
	case WM1831:
	case CS47L24:

		break;
	default:

		break;
	}

	/* Chip default */
	if (!arizona->pdata.clk32k_src)
		arizona->pdata.clk32k_src = ARIZONA_32KZ_MCLK2;

	switch (arizona->pdata.clk32k_src) {
	case ARIZONA_32KZ_MCLK1:
	case ARIZONA_32KZ_MCLK2:
		regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
				   ARIZONA_CLK_32K_SRC_MASK,
				   arizona->pdata.clk32k_src - 1);
		arizona_clk32k_enable(arizona);
		break;
	case ARIZONA_32KZ_NONE:
		regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
				   ARIZONA_CLK_32K_SRC_MASK, 2);
		break;
	default:
		dev_err(arizona->dev, "Invalid 32kHz clock source: %d\n",
			arizona->pdata.clk32k_src);
		ret = -EINVAL;
		goto err_reset;
	}

	arizona_get_num_micbias(arizona, &max_micbias, &num_child_micbias);

	for (i = 0; i < max_micbias; i++) {
		if (!arizona->pdata.micbias[i].mV &&
		    !arizona->pdata.micbias[i].bypass)
			continue;

		/* Apply default for bypass mode */
		if (!arizona->pdata.micbias[i].mV)
			arizona->pdata.micbias[i].mV = 2800;

		val = (arizona->pdata.micbias[i].mV - 1500) / 100;

		mask = ARIZONA_MICB1_LVL_MASK | ARIZONA_MICB1_EXT_CAP |
			ARIZONA_MICB1_BYPASS | ARIZONA_MICB1_RATE;

		val <<= ARIZONA_MICB1_LVL_SHIFT;

		if (arizona->pdata.micbias[i].ext_cap)
			val |= ARIZONA_MICB1_EXT_CAP;

		if (num_child_micbias == 0) {
			mask |= ARIZONA_MICB1_DISCH;
			if (arizona->pdata.micbias[i].discharge[0])
				val |= ARIZONA_MICB1_DISCH;
		}

		if (arizona->pdata.micbias[i].soft_start)
			val |= ARIZONA_MICB1_RATE;

		if (arizona->pdata.micbias[i].bypass)
			val |= ARIZONA_MICB1_BYPASS;

		regmap_update_bits(arizona->regmap,
			ARIZONA_MIC_BIAS_CTRL_1 + i,
			mask, val);

		if (num_child_micbias) {
			val = 0;
			mask = 0;
			for (j = 0; j < num_child_micbias; j++) {
				mask |= (ARIZONA_MICB1A_DISCH << j*4);
				if (arizona->pdata.micbias[i].discharge[j])
					val |= (ARIZONA_MICB1A_DISCH << j*4);
			}
			regmap_update_bits(arizona->regmap,
				ARIZONA_MIC_BIAS_CTRL_5 + i*2,
				mask, val);
		}
	}

	switch (arizona->type) {
	case WM5102:
	case WM5110:
	case WM8280:
		/* These arizona chips have 4 inputs and
		settings for INxL and INxR are same*/
		max_inputs = 4;
		break;
	case WM8997:
	case WM1831:
	case CS47L24:
	case WM8998:
	case WM1814:
	case CS47L35:
		max_inputs = 2;
		break;
	case WM8285:
	case WM1840:
		/* DMIC Ref for IN4-6 is fixed for WM8285/1840 and
		settings for INxL and INxR are different*/
		max_inputs = 3;
		break;
	case CS47L15:
		max_inputs = 2;
		break;
	default:
		/*DMIC Ref for IN3-5 is fixed for CS47L90 and
		settings for INxL and INxR are different*/
		max_inputs = 2;
		/* For CS47L90/91 dmic clk src can be set same as
		pdm speaker clock this is used when pdm speaker
		feedsback IV data via pdm input */
		num_dmic_clksrc = 5;
		break;
	}

	for (i = 0; i < num_dmic_clksrc; i++) {
		regmap_update_bits(arizona->regmap,
			   ARIZONA_IN1R_CONTROL + (i * 8),
			   MOON_IN1_DMICCLK_SRC_MASK,
			   (arizona->pdata.dmic_clksrc[i])
				<< MOON_IN1_DMICCLK_SRC_SHIFT);
	}

	for (i = 0; i < max_inputs; i++) {
		switch (arizona->type) {
		case WM5102:
		case WM5110:
		case WM8997:
		case WM8280:
		case WM1831:
		case CS47L24:
			val = arizona->pdata.dmic_ref[i]
				<< ARIZONA_IN1_DMIC_SUP_SHIFT;
			val |= (arizona->pdata.inmode[i] & 2)
				<< (ARIZONA_IN1_MODE_SHIFT - 1);
			val |= (arizona->pdata.inmode[i] & 1)
				<< ARIZONA_IN1_SINGLE_ENDED_SHIFT;
			mask = ARIZONA_IN1_DMIC_SUP_MASK |
					ARIZONA_IN1_MODE_MASK |
					ARIZONA_IN1_SINGLE_ENDED_MASK;
			break;
		case WM8998:
		case WM1814:
		case CS47L15:
		case CS47L35:
			val = arizona->pdata.dmic_ref[i]
				<< ARIZONA_IN1_DMIC_SUP_SHIFT;
			val |= (arizona->pdata.inmode[i] & 2)
				<< (ARIZONA_IN1_MODE_SHIFT - 1);
			mask = ARIZONA_IN1_DMIC_SUP_MASK |
					ARIZONA_IN1_MODE_MASK;
			regmap_update_bits(arizona->regmap,
				   ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 8),
				   ARIZONA_IN1L_SRC_SE_MASK,
				   (arizona->pdata.inmode[i] & 1)
					<< ARIZONA_IN1L_SRC_SE_SHIFT);
			regmap_update_bits(arizona->regmap,
				   ARIZONA_ADC_DIGITAL_VOLUME_1R + (i * 8),
				   ARIZONA_IN1R_SRC_SE_MASK,
				   (arizona->pdata.inmode[i] & 1)
					<< ARIZONA_IN1R_SRC_SE_SHIFT);
			break;
		default:
			val = arizona->pdata.dmic_ref[i]
				<< ARIZONA_IN1_DMIC_SUP_SHIFT;
			val |= (arizona->pdata.inmode[2*i] & 2)
				<< (ARIZONA_IN1_MODE_SHIFT - 1);
			mask = ARIZONA_IN1_DMIC_SUP_MASK |
					ARIZONA_IN1_MODE_MASK;
			regmap_update_bits(arizona->regmap,
				   ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 8),
				   ARIZONA_IN1L_SRC_SE_MASK,
				   (arizona->pdata.inmode[2*i] & 1)
					<< ARIZONA_IN1L_SRC_SE_SHIFT);
			regmap_update_bits(arizona->regmap,
				   ARIZONA_ADC_DIGITAL_VOLUME_1R + (i * 8),
				   ARIZONA_IN1R_SRC_SE_MASK,
				   (arizona->pdata.inmode[(2*i) + 1] & 1)
					<< ARIZONA_IN1R_SRC_SE_SHIFT);
			break;
		}

		regmap_update_bits(arizona->regmap,
				   ARIZONA_IN1L_CONTROL + (i * 8), mask, val);
	}

	for (i = 0; i < ARIZONA_MAX_OUTPUT; i++) {
		/* Default is 0 so noop with defaults */
		if (arizona->pdata.out_mono[i])
			val = ARIZONA_OUT1_MONO;
		else
			val = 0;

		regmap_update_bits(arizona->regmap,
				   ARIZONA_OUTPUT_PATH_CONFIG_1L + (i * 8),
				   ARIZONA_OUT1_MONO, val);
	}

	for (i = 0; i < ARIZONA_MAX_PDM_SPK; i++) {
		if (arizona->pdata.spk_mute[i])
			regmap_update_bits(arizona->regmap,
					   ARIZONA_PDM_SPK1_CTRL_1 + (i * 2),
					   ARIZONA_SPK1_MUTE_ENDIAN_MASK |
					   ARIZONA_SPK1_MUTE_SEQ1_MASK,
					   arizona->pdata.spk_mute[i]);

		if (arizona->pdata.spk_fmt[i])
			regmap_update_bits(arizona->regmap,
					   ARIZONA_PDM_SPK1_CTRL_2 + (i * 2),
					   ARIZONA_SPK1_FMT_MASK,
					   arizona->pdata.spk_fmt[i]);
	}

	pm_runtime_set_active(arizona->dev);
	pm_runtime_enable(arizona->dev);

	/* Set up for interrupts */
	ret = arizona_irq_init(arizona);
	if (ret != 0)
		goto err_reset;

	pm_runtime_set_autosuspend_delay(arizona->dev, 100);
	pm_runtime_use_autosuspend(arizona->dev);

	arizona_request_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, "CLKGEN error",
			    arizona_clkgen_err, arizona);
	arizona_request_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, "Overclocked",
			    arizona_overclocked, arizona);
	arizona_request_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, "Underclocked",
			    arizona_underclocked, arizona);

	/**
	 * Give us a sane default for the headphone impedance in case the
	 * extcon driver is not used
	 */
	arizona->hp_impedance_x100 = 3200;

	switch (arizona->type) {
	case WM5102:
		ret = mfd_add_devices(arizona->dev, -1, wm5102_devs,
				      ARRAY_SIZE(wm5102_devs), NULL, 0, NULL);
		break;
	case WM8280:
	case WM5110:
		ret = mfd_add_devices(arizona->dev, -1, florida_devs,
				      ARRAY_SIZE(florida_devs), NULL, 0, NULL);
		break;
	case WM1831:
	case CS47L24:
		ret = mfd_add_devices(arizona->dev, -1, largo_devs,
				      ARRAY_SIZE(largo_devs), NULL, 0, NULL);
		break;
	case WM8997:
		ret = mfd_add_devices(arizona->dev, -1, wm8997_devs,
				      ARRAY_SIZE(wm8997_devs), NULL, 0, NULL);
		break;
	case WM8998:
	case WM1814:
		ret = mfd_add_devices(arizona->dev, -1, vegas_devs,
				      ARRAY_SIZE(vegas_devs), NULL, 0, NULL);
		break;
	case WM8285:
	case WM1840:
		ret = mfd_add_devices(arizona->dev, -1, clearwater_devs,
				      ARRAY_SIZE(clearwater_devs), NULL, 0, NULL);
		break;
	case CS47L15:
		ret = mfd_add_devices(arizona->dev, -1, cs47l15_devs,
				      ARRAY_SIZE(cs47l15_devs), NULL, 0, NULL);
		break;
	case CS47L35:
		ret = mfd_add_devices(arizona->dev, -1, marley_devs,
				      ARRAY_SIZE(marley_devs), NULL, 0, NULL);
		break;
	case CS47L90:
	case CS47L91:
		ret = mfd_add_devices(arizona->dev, -1, moon_devs,
				      ARRAY_SIZE(moon_devs), NULL, 0, NULL);
		break;
	}

	if (ret != 0) {
		dev_err(arizona->dev, "Failed to add subdevices: %d\n", ret);
		goto err_irq;
	}



	return 0;

err_irq:
	arizona_irq_exit(arizona);
err_reset:
	arizona_enable_reset(arizona);
	regulator_disable(arizona->dcvdd);
err_enable:
	regulator_bulk_disable(arizona->num_core_supplies,
			       arizona->core_supplies);
err_notifier:
	regulator_unregister_notifier(arizona->dcvdd, &arizona->dcvdd_notifier);
err_dcvdd:
	regulator_put(arizona->dcvdd);
err_early:
	mfd_remove_devices(dev);
	return ret;
}
EXPORT_SYMBOL_GPL(arizona_dev_init);

int arizona_dev_exit(struct arizona *arizona)
{
	pm_runtime_disable(arizona->dev);
	disable_irq(arizona->irq);

	regulator_disable(arizona->dcvdd);
	regulator_unregister_notifier(arizona->dcvdd, &arizona->dcvdd_notifier);
	regulator_put(arizona->dcvdd);

	mfd_remove_devices(arizona->dev);
	arizona_free_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, arizona);
	arizona_free_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, arizona);
	arizona_free_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, arizona);
	arizona_irq_exit(arizona);
	arizona_enable_reset(arizona);

	regulator_bulk_disable(arizona->num_core_supplies,
			       arizona->core_supplies);
	return 0;
}
EXPORT_SYMBOL_GPL(arizona_dev_exit);
