/*
 * wm8523.c  --  WM8523 ALSA SoC Audio driver
 *
 * Copyright 2009 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/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/of_device.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 "wm8523.h"

#define WM8523_NUM_SUPPLIES 2
static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = {
	"AVDD",
	"LINEVDD",
};

#define WM8523_NUM_RATES 7

/* codec private data */
struct wm8523_priv {
	struct regmap *regmap;
	struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES];
	unsigned int sysclk;
	unsigned int rate_constraint_list[WM8523_NUM_RATES];
	struct snd_pcm_hw_constraint_list rate_constraint;
};

static const struct reg_default wm8523_reg_defaults[] = {
	{ 2, 0x0000 },     /* R2 - PSCTRL1 */
	{ 3, 0x1812 },     /* R3 - AIF_CTRL1 */
	{ 4, 0x0000 },     /* R4 - AIF_CTRL2 */
	{ 5, 0x0001 },     /* R5 - DAC_CTRL3 */
	{ 6, 0x0190 },     /* R6 - DAC_GAINL */
	{ 7, 0x0190 },     /* R7 - DAC_GAINR */
	{ 8, 0x0000 },     /* R8 - ZERO_DETECT */
};

static bool wm8523_volatile_register(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case WM8523_DEVICE_ID:
	case WM8523_REVISION:
		return true;
	default:
		return false;
	}
}

static const DECLARE_TLV_DB_SCALE(dac_tlv, -10000, 25, 0);

static const char *wm8523_zd_count_text[] = {
	"1024",
	"2048",
};

static SOC_ENUM_SINGLE_DECL(wm8523_zc_count, WM8523_ZERO_DETECT, 0,
			    wm8523_zd_count_text);

static const struct snd_kcontrol_new wm8523_controls[] = {
SOC_DOUBLE_R_TLV("Playback Volume", WM8523_DAC_GAINL, WM8523_DAC_GAINR,
		 0, 448, 0, dac_tlv),
SOC_SINGLE("ZC Switch", WM8523_DAC_CTRL3, 4, 1, 0),
SOC_SINGLE("Playback Deemphasis Switch", WM8523_AIF_CTRL1, 8, 1, 0),
SOC_DOUBLE("Playback Switch", WM8523_DAC_CTRL3, 2, 3, 1, 1),
SOC_SINGLE("Volume Ramp Up Switch", WM8523_DAC_CTRL3, 1, 1, 0),
SOC_SINGLE("Volume Ramp Down Switch", WM8523_DAC_CTRL3, 0, 1, 0),
SOC_ENUM("Zero Detect Count", wm8523_zc_count),
};

static const struct snd_soc_dapm_widget wm8523_dapm_widgets[] = {
SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_OUTPUT("LINEVOUTL"),
SND_SOC_DAPM_OUTPUT("LINEVOUTR"),
};

static const struct snd_soc_dapm_route wm8523_dapm_routes[] = {
	{ "LINEVOUTL", NULL, "DAC" },
	{ "LINEVOUTR", NULL, "DAC" },
};

static struct {
	int value;
	int ratio;
} lrclk_ratios[WM8523_NUM_RATES] = {
	{ 1, 128 },
	{ 2, 192 },
	{ 3, 256 },
	{ 4, 384 },
	{ 5, 512 },
	{ 6, 768 },
	{ 7, 1152 },
};

static struct {
	int value;
	int ratio;
} bclk_ratios[WM8523_NUM_RATES] = {
	{ 2, 32 },
	{ 3, 64 },
	{ 4, 128 },
};

static int wm8523_startup(struct snd_pcm_substream *substream,
			  struct snd_soc_dai *dai)
{
	struct snd_soc_codec *codec = dai->codec;
	struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);

	/* The set of sample rates that can be supported depends on the
	 * MCLK supplied to the CODEC - enforce this.
	 */
	if (!wm8523->sysclk) {
		dev_err(codec->dev,
			"No MCLK configured, call set_sysclk() on init\n");
		return -EINVAL;
	}

	snd_pcm_hw_constraint_list(substream->runtime, 0,
				   SNDRV_PCM_HW_PARAM_RATE,
				   &wm8523->rate_constraint);

	return 0;
}

static int wm8523_hw_params(struct snd_pcm_substream *substream,
			    struct snd_pcm_hw_params *params,
			    struct snd_soc_dai *dai)
{
	struct snd_soc_codec *codec = dai->codec;
	struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
	int i;
	u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1);
	u16 aifctrl2 = snd_soc_read(codec, WM8523_AIF_CTRL2);

	/* Find a supported LRCLK ratio */
	for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) {
		if (wm8523->sysclk / params_rate(params) ==
		    lrclk_ratios[i].ratio)
			break;
	}

	/* Should never happen, should be handled by constraints */
	if (i == ARRAY_SIZE(lrclk_ratios)) {
		dev_err(codec->dev, "MCLK/fs ratio %d unsupported\n",
			wm8523->sysclk / params_rate(params));
		return -EINVAL;
	}

	aifctrl2 &= ~WM8523_SR_MASK;
	aifctrl2 |= lrclk_ratios[i].value;

	if (aifctrl1 & WM8523_AIF_MSTR) {
		/* Find a fs->bclk ratio */
		for (i = 0; i < ARRAY_SIZE(bclk_ratios); i++)
			if (params_width(params) * 2 <= bclk_ratios[i].ratio)
				break;

		if (i == ARRAY_SIZE(bclk_ratios)) {
			dev_err(codec->dev,
				"No matching BCLK/fs ratio for word length %d\n",
				params_width(params));
			return -EINVAL;
		}

		aifctrl2 &= ~WM8523_BCLKDIV_MASK;
		aifctrl2 |= bclk_ratios[i].value << WM8523_BCLKDIV_SHIFT;
	}

	aifctrl1 &= ~WM8523_WL_MASK;
	switch (params_width(params)) {
	case 16:
		break;
	case 20:
		aifctrl1 |= 0x8;
		break;
	case 24:
		aifctrl1 |= 0x10;
		break;
	case 32:
		aifctrl1 |= 0x18;
		break;
	}

	snd_soc_write(codec, WM8523_AIF_CTRL1, aifctrl1);
	snd_soc_write(codec, WM8523_AIF_CTRL2, aifctrl2);

	return 0;
}

static int wm8523_set_dai_sysclk(struct snd_soc_dai *codec_dai,
		int clk_id, unsigned int freq, int dir)
{
	struct snd_soc_codec *codec = codec_dai->codec;
	struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
	unsigned int val;
	int i;

	wm8523->sysclk = freq;

	wm8523->rate_constraint.count = 0;
	for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) {
		val = freq / lrclk_ratios[i].ratio;
		/* Check that it's a standard rate since core can't
		 * cope with others and having the odd rates confuses
		 * constraint matching.
		 */
		switch (val) {
		case 8000:
		case 11025:
		case 16000:
		case 22050:
		case 32000:
		case 44100:
		case 48000:
		case 64000:
		case 88200:
		case 96000:
		case 176400:
		case 192000:
			dev_dbg(codec->dev, "Supported sample rate: %dHz\n",
				val);
			wm8523->rate_constraint_list[i] = val;
			wm8523->rate_constraint.count++;
			break;
		default:
			dev_dbg(codec->dev, "Skipping sample rate: %dHz\n",
				val);
		}
	}

	/* Need at least one supported rate... */
	if (wm8523->rate_constraint.count == 0)
		return -EINVAL;

	return 0;
}


static int wm8523_set_dai_fmt(struct snd_soc_dai *codec_dai,
		unsigned int fmt)
{
	struct snd_soc_codec *codec = codec_dai->codec;
	u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1);

	aifctrl1 &= ~(WM8523_BCLK_INV_MASK | WM8523_LRCLK_INV_MASK |
		      WM8523_FMT_MASK | WM8523_AIF_MSTR_MASK);

	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBM_CFM:
		aifctrl1 |= WM8523_AIF_MSTR;
		break;
	case SND_SOC_DAIFMT_CBS_CFS:
		break;
	default:
		return -EINVAL;
	}

	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
		aifctrl1 |= 0x0002;
		break;
	case SND_SOC_DAIFMT_RIGHT_J:
		break;
	case SND_SOC_DAIFMT_LEFT_J:
		aifctrl1 |= 0x0001;
		break;
	case SND_SOC_DAIFMT_DSP_A:
		aifctrl1 |= 0x0003;
		break;
	case SND_SOC_DAIFMT_DSP_B:
		aifctrl1 |= 0x0023;
		break;
	default:
		return -EINVAL;
	}

	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
	case SND_SOC_DAIFMT_NB_NF:
		break;
	case SND_SOC_DAIFMT_IB_IF:
		aifctrl1 |= WM8523_BCLK_INV | WM8523_LRCLK_INV;
		break;
	case SND_SOC_DAIFMT_IB_NF:
		aifctrl1 |= WM8523_BCLK_INV;
		break;
	case SND_SOC_DAIFMT_NB_IF:
		aifctrl1 |= WM8523_LRCLK_INV;
		break;
	default:
		return -EINVAL;
	}

	snd_soc_write(codec, WM8523_AIF_CTRL1, aifctrl1);

	return 0;
}

static int wm8523_set_bias_level(struct snd_soc_codec *codec,
				 enum snd_soc_bias_level level)
{
	struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
	int ret;

	switch (level) {
	case SND_SOC_BIAS_ON:
		break;

	case SND_SOC_BIAS_PREPARE:
		/* Full power on */
		snd_soc_update_bits(codec, WM8523_PSCTRL1,
				    WM8523_SYS_ENA_MASK, 3);
		break;

	case SND_SOC_BIAS_STANDBY:
		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
			ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
						    wm8523->supplies);
			if (ret != 0) {
				dev_err(codec->dev,
					"Failed to enable supplies: %d\n",
					ret);
				return ret;
			}

			/* Sync back default/cached values */
			regcache_sync(wm8523->regmap);

			/* Initial power up */
			snd_soc_update_bits(codec, WM8523_PSCTRL1,
					    WM8523_SYS_ENA_MASK, 1);

			msleep(100);
		}

		/* Power up to mute */
		snd_soc_update_bits(codec, WM8523_PSCTRL1,
				    WM8523_SYS_ENA_MASK, 2);

		break;

	case SND_SOC_BIAS_OFF:
		/* The chip runs through the power down sequence for us. */
		snd_soc_update_bits(codec, WM8523_PSCTRL1,
				    WM8523_SYS_ENA_MASK, 0);
		msleep(100);

		regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies),
				       wm8523->supplies);
		break;
	}
	return 0;
}

#define WM8523_RATES SNDRV_PCM_RATE_8000_192000

#define WM8523_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)

static const struct snd_soc_dai_ops wm8523_dai_ops = {
	.startup	= wm8523_startup,
	.hw_params	= wm8523_hw_params,
	.set_sysclk	= wm8523_set_dai_sysclk,
	.set_fmt	= wm8523_set_dai_fmt,
};

static struct snd_soc_dai_driver wm8523_dai = {
	.name = "wm8523-hifi",
	.playback = {
		.stream_name = "Playback",
		.channels_min = 2,  /* Mono modes not yet supported */
		.channels_max = 2,
		.rates = WM8523_RATES,
		.formats = WM8523_FORMATS,
	},
	.ops = &wm8523_dai_ops,
};

static int wm8523_probe(struct snd_soc_codec *codec)
{
	struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);

	wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0];
	wm8523->rate_constraint.count =
		ARRAY_SIZE(wm8523->rate_constraint_list);

	/* Change some default settings - latch VU and enable ZC */
	snd_soc_update_bits(codec, WM8523_DAC_GAINR,
			    WM8523_DACR_VU, WM8523_DACR_VU);
	snd_soc_update_bits(codec, WM8523_DAC_CTRL3, WM8523_ZC, WM8523_ZC);

	return 0;
}

static struct snd_soc_codec_driver soc_codec_dev_wm8523 = {
	.probe =	wm8523_probe,
	.set_bias_level = wm8523_set_bias_level,
	.suspend_bias_off = true,

	.controls = wm8523_controls,
	.num_controls = ARRAY_SIZE(wm8523_controls),
	.dapm_widgets = wm8523_dapm_widgets,
	.num_dapm_widgets = ARRAY_SIZE(wm8523_dapm_widgets),
	.dapm_routes = wm8523_dapm_routes,
	.num_dapm_routes = ARRAY_SIZE(wm8523_dapm_routes),
};

static const struct of_device_id wm8523_of_match[] = {
	{ .compatible = "wlf,wm8523" },
	{ },
};
MODULE_DEVICE_TABLE(of, wm8523_of_match);

static const struct regmap_config wm8523_regmap = {
	.reg_bits = 8,
	.val_bits = 16,
	.max_register = WM8523_ZERO_DETECT,

	.reg_defaults = wm8523_reg_defaults,
	.num_reg_defaults = ARRAY_SIZE(wm8523_reg_defaults),
	.cache_type = REGCACHE_RBTREE,

	.volatile_reg = wm8523_volatile_register,
};

#if IS_ENABLED(CONFIG_I2C)
static int wm8523_i2c_probe(struct i2c_client *i2c,
			    const struct i2c_device_id *id)
{
	struct wm8523_priv *wm8523;
	unsigned int val;
	int ret, i;

	wm8523 = devm_kzalloc(&i2c->dev, sizeof(struct wm8523_priv),
			      GFP_KERNEL);
	if (wm8523 == NULL)
		return -ENOMEM;

	wm8523->regmap = devm_regmap_init_i2c(i2c, &wm8523_regmap);
	if (IS_ERR(wm8523->regmap)) {
		ret = PTR_ERR(wm8523->regmap);
		dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret);
		return ret;
	}

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

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

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

	ret = regmap_read(wm8523->regmap, WM8523_DEVICE_ID, &val);
	if (ret < 0) {
		dev_err(&i2c->dev, "Failed to read ID register\n");
		goto err_enable;
	}
	if (val != 0x8523) {
		dev_err(&i2c->dev, "Device is not a WM8523, ID is %x\n", ret);
		ret = -EINVAL;
		goto err_enable;
	}

	ret = regmap_read(wm8523->regmap, WM8523_REVISION, &val);
	if (ret < 0) {
		dev_err(&i2c->dev, "Failed to read revision register\n");
		goto err_enable;
	}
	dev_info(&i2c->dev, "revision %c\n",
		 (val & WM8523_CHIP_REV_MASK) + 'A');

	ret = regmap_write(wm8523->regmap, WM8523_DEVICE_ID, 0x8523);
	if (ret != 0) {
		dev_err(&i2c->dev, "Failed to reset device: %d\n", ret);
		goto err_enable;
	}

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

	i2c_set_clientdata(i2c, wm8523);

	ret =  snd_soc_register_codec(&i2c->dev,
			&soc_codec_dev_wm8523, &wm8523_dai, 1);

	return ret;

err_enable:
	regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
	return ret;
}

static int wm8523_i2c_remove(struct i2c_client *client)
{
	snd_soc_unregister_codec(&client->dev);
	return 0;
}

static const struct i2c_device_id wm8523_i2c_id[] = {
	{ "wm8523", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, wm8523_i2c_id);

static struct i2c_driver wm8523_i2c_driver = {
	.driver = {
		.name = "wm8523",
		.of_match_table = wm8523_of_match,
	},
	.probe =    wm8523_i2c_probe,
	.remove =   wm8523_i2c_remove,
	.id_table = wm8523_i2c_id,
};
#endif

static int __init wm8523_modinit(void)
{
	int ret;
#if IS_ENABLED(CONFIG_I2C)
	ret = i2c_add_driver(&wm8523_i2c_driver);
	if (ret != 0) {
		printk(KERN_ERR "Failed to register WM8523 I2C driver: %d\n",
		       ret);
	}
#endif
	return 0;
}
module_init(wm8523_modinit);

static void __exit wm8523_exit(void)
{
#if IS_ENABLED(CONFIG_I2C)
	i2c_del_driver(&wm8523_i2c_driver);
#endif
}
module_exit(wm8523_exit);

MODULE_DESCRIPTION("ASoC WM8523 driver");
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
MODULE_LICENSE("GPL");
