/*
 * max9867.c -- max9867 ALSA SoC Audio driver
 *
 * Copyright 2013-15 Maxim Integrated Products
 *
 * 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/i2c.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/tlv.h>
#include "max9867.h"

static const char *const max9867_spmode[] = {
	"Stereo Diff", "Mono Diff",
	"Stereo Cap", "Mono Cap",
	"Stereo Single", "Mono Single",
	"Stereo Single Fast", "Mono Single Fast"
};
static const char *const max9867_sidetone_text[] = {
	"None", "Left", "Right", "LeftRight", "LeftRightDiv2",
};
static const char *const max9867_filter_text[] = {"IIR", "FIR"};

static SOC_ENUM_SINGLE_DECL(max9867_filter, MAX9867_CODECFLTR, 7,
	max9867_filter_text);
static SOC_ENUM_SINGLE_DECL(max9867_spkmode, MAX9867_MODECONFIG, 0,
	max9867_spmode);
static SOC_ENUM_SINGLE_DECL(max9867_sidetone, MAX9867_DACGAIN, 6,
	max9867_sidetone_text);
static DECLARE_TLV_DB_SCALE(max9860_capture_tlv, -600, 200, 0);
static DECLARE_TLV_DB_SCALE(max9860_mic_tlv, 2000, 100, 1);
static DECLARE_TLV_DB_SCALE(max9860_adc_left_tlv, -1200, 100, 1);
static DECLARE_TLV_DB_SCALE(max9860_adc_right_tlv, -1200, 100, 1);
static const unsigned int max98088_micboost_tlv[] = {
	TLV_DB_RANGE_HEAD(2),
	0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0),
	2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
};

static const struct snd_kcontrol_new max9867_snd_controls[] = {
	SOC_DOUBLE_R("Master Playback Volume", MAX9867_LEFTVOL,
				MAX9867_RIGHTVOL, 0, 63, 1),
	SOC_DOUBLE_R_TLV("Capture Volume", MAX9867_LEFTMICGAIN,
			MAX9867_RIGHTMICGAIN,
			0, 15, 1, max9860_capture_tlv),
	SOC_DOUBLE_R_TLV("Mic Volume", MAX9867_LEFTMICGAIN,
			MAX9867_RIGHTMICGAIN, 0, 31, 1, max9860_mic_tlv),
	SOC_DOUBLE_R_TLV("Mic Boost Volume", MAX9867_LEFTMICGAIN,
			MAX9867_RIGHTMICGAIN, 5, 3, 0, max98088_micboost_tlv),
	SOC_ENUM("Digital Sidetone Src", max9867_sidetone),
	SOC_SINGLE("Sidetone Volume", MAX9867_DACGAIN, 0, 31, 1),
	SOC_SINGLE("DAC Volume", MAX9867_DACLEVEL, 4, 3, 0),
	SOC_SINGLE("DAC Attenuation", MAX9867_DACLEVEL, 0, 15, 1),
	SOC_SINGLE_TLV("ADC Left Volume", MAX9867_ADCLEVEL,
			4, 15, 1, max9860_adc_left_tlv),
	SOC_SINGLE_TLV("ADC Right Volume", MAX9867_ADCLEVEL,
			0, 15, 1, max9860_adc_right_tlv),
	SOC_ENUM("Speaker Mode", max9867_spkmode),
	SOC_SINGLE("Volume Smoothing Switch", MAX9867_MODECONFIG, 6, 1, 0),
	SOC_SINGLE("ZCD Switch", MAX9867_MODECONFIG, 5, 1, 0),
	SOC_ENUM("DSP Filter", max9867_filter),
};

static const char *const max9867_mux[] = {"None", "Mic", "Line", "Mic_Line"};

static SOC_ENUM_SINGLE_DECL(max9867_mux_enum,
	MAX9867_INPUTCONFIG, MAX9867_INPUT_SHIFT,
	max9867_mux);

static const struct snd_kcontrol_new max9867_dapm_mux_controls =
	SOC_DAPM_ENUM("Route", max9867_mux_enum);

static const struct snd_kcontrol_new max9867_left_dapm_control =
	SOC_DAPM_SINGLE("Switch", MAX9867_PWRMAN, 6, 1, 0);
static const struct snd_kcontrol_new max9867_right_dapm_control =
	SOC_DAPM_SINGLE("Switch", MAX9867_PWRMAN, 5, 1, 0);
static const struct snd_kcontrol_new max9867_line_dapm_control =
	SOC_DAPM_SINGLE("Switch", MAX9867_LEFTLINELVL, 6, 1, 1);

static const struct snd_soc_dapm_widget max9867_dapm_widgets[] = {
	SND_SOC_DAPM_AIF_IN("DAI_OUT", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
	SND_SOC_DAPM_DAC("Left DAC", NULL, MAX9867_PWRMAN, 3, 0),
	SND_SOC_DAPM_DAC("Right DAC", NULL, MAX9867_PWRMAN, 2, 0),
	SND_SOC_DAPM_MIXER("Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
	SND_SOC_DAPM_OUTPUT("HPOUT"),

	SND_SOC_DAPM_AIF_IN("DAI_IN", "HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
	SND_SOC_DAPM_ADC("Left ADC", "HiFi Capture", MAX9867_PWRMAN, 1, 0),
	SND_SOC_DAPM_ADC("Right ADC", "HiFi Capture", MAX9867_PWRMAN, 0, 0),
	SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0,
		&max9867_dapm_mux_controls),

	SND_SOC_DAPM_MIXER("Input Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
	SND_SOC_DAPM_SWITCH("Left Line", MAX9867_LEFTLINELVL, 6, 1,
		&max9867_left_dapm_control),
	SND_SOC_DAPM_SWITCH("Right Line", MAX9867_RIGTHLINELVL, 6, 1,
		&max9867_right_dapm_control),
	SND_SOC_DAPM_SWITCH("Line Mixer", SND_SOC_NOPM, 0, 0,
		&max9867_line_dapm_control),
	SND_SOC_DAPM_INPUT("LINE_IN"),
};

static const struct snd_soc_dapm_route max9867_audio_map[] = {
	{"Left DAC", NULL, "DAI_OUT"},
	{"Right DAC", NULL, "DAI_OUT"},
	{"Output Mixer", NULL, "Left DAC"},
	{"Output Mixer", NULL, "Right DAC"},
	{"HPOUT", NULL, "Output Mixer"},

	{"Left ADC", NULL, "DAI_IN"},
	{"Right ADC", NULL, "DAI_IN"},
	{"Input Mixer", NULL, "Left ADC"},
	{"Input Mixer", NULL, "Right ADC"},
	{"Input Mux", "Line", "Input Mixer"},
	{"Input Mux", "Mic", "Input Mixer"},
	{"Input Mux", "Mic_Line", "Input Mixer"},
	{"Right Line", "Switch", "Input Mux"},
	{"Left Line", "Switch", "Input Mux"},
	{"LINE_IN", NULL, "Left Line"},
	{"LINE_IN", NULL, "Right Line"},
};

enum rates {
	pcm_rate_8, pcm_rate_16, pcm_rate_24,
	pcm_rate_32, pcm_rate_44,
	pcm_rate_48, max_pcm_rate,
};

struct ni_div_rates {
	u32 mclk;
	u16 ni[max_pcm_rate];
} ni_div[] = {
	{11289600, {0x116A, 0x22D4, 0x343F, 0x45A9, 0x6000, 0x687D} },
	{12000000, {0x1062, 0x20C5, 0x3127, 0x4189, 0x5A51, 0x624E} },
	{12288000, {0x1000, 0x2000, 0x3000, 0x4000, 0x5833, 0x6000} },
	{13000000, {0x0F20, 0x1E3F, 0x2D5F, 0x3C7F, 0x535F, 0x5ABE} },
	{19200000, {0x0A3D, 0x147B, 0x1EB8, 0x28F6, 0x3873, 0x3D71} },
	{24000000, {0x1062, 0x20C5, 0x1893, 0x4189, 0x5A51, 0x624E} },
	{26000000, {0x0F20, 0x1E3F, 0x16AF, 0x3C7F, 0x535F, 0x5ABE} },
	{27000000, {0x0E90, 0x1D21, 0x15D8, 0x3A41, 0x5048, 0x5762} },
};

static inline int get_ni_value(int mclk, int rate)
{
	int i, ret = 0;

	/* find the closest rate index*/
	for (i = 0; i < ARRAY_SIZE(ni_div); i++) {
		if (ni_div[i].mclk >= mclk)
			break;
	}
	if (i == ARRAY_SIZE(ni_div))
		return -EINVAL;

	switch (rate) {
	case 8000:
		return ni_div[i].ni[pcm_rate_8];
	case 16000:
		return ni_div[i].ni[pcm_rate_16];
	case 32000:
		return ni_div[i].ni[pcm_rate_32];
	case 44100:
		return ni_div[i].ni[pcm_rate_44];
	case 48000:
		return ni_div[i].ni[pcm_rate_48];
	default:
		pr_err("%s wrong rate %d\n", __func__, rate);
		ret = -EINVAL;
	}
	return ret;
}

static int max9867_dai_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 max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);
	unsigned int ni_h, ni_l;
	int value;

	value = get_ni_value(max9867->sysclk, params_rate(params));
	if (value < 0)
		return value;

	ni_h = (0xFF00 & value) >> 8;
	ni_l = 0x00FF & value;
	/* set up the ni value */
	regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKHIGH,
		MAX9867_NI_HIGH_MASK, ni_h);
	regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKLOW,
		MAX9867_NI_LOW_MASK, ni_l);
	if (!max9867->master) {
		/*
		 * digital pll locks on to any externally supplied LRCLK signal
		 * and also enable rapid lock mode.
		 */
		regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKLOW,
			MAX9867_RAPID_LOCK, MAX9867_RAPID_LOCK);
		regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKHIGH,
			MAX9867_PLL, MAX9867_PLL);
	} else {
		unsigned long int bclk_rate, pclk_bclk_ratio;
		int bclk_value;

		bclk_rate = params_rate(params) * 2 * params_width(params);
		pclk_bclk_ratio = max9867->pclk/bclk_rate;
		switch (params_width(params)) {
		case 8:
		case 16:
			switch (pclk_bclk_ratio) {
			case 2:
				bclk_value = MAX9867_IFC1B_PCLK_2;
				break;
			case 4:
				bclk_value = MAX9867_IFC1B_PCLK_4;
				break;
			case 8:
				bclk_value = MAX9867_IFC1B_PCLK_8;
				break;
			case 16:
				bclk_value = MAX9867_IFC1B_PCLK_16;
				break;
			default:
				dev_err(codec->dev,
					"unsupported sampling rate\n");
				return -EINVAL;
			}
			break;
		case 24:
			bclk_value = MAX9867_IFC1B_24BIT;
			break;
		case 32:
			bclk_value = MAX9867_IFC1B_32BIT;
			break;
		default:
			dev_err(codec->dev, "unsupported sampling rate\n");
			return -EINVAL;
		}
		regmap_update_bits(max9867->regmap, MAX9867_IFC1B,
			MAX9867_IFC1B_BCLK_MASK, bclk_value);
	}
	return 0;
}

static int max9867_prepare(struct snd_pcm_substream *substream,
			 struct snd_soc_dai *dai)
{
	struct snd_soc_codec *codec = dai->codec;
	struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);

	regmap_update_bits(max9867->regmap, MAX9867_PWRMAN,
		MAX9867_SHTDOWN_MASK, MAX9867_SHTDOWN_MASK);
	return 0;
}

static int max9867_mute(struct snd_soc_dai *dai, int mute)
{
	struct snd_soc_codec *codec = dai->codec;
	struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);

	if (mute)
		regmap_update_bits(max9867->regmap, MAX9867_DACLEVEL,
			MAX9867_DAC_MUTE_MASK, MAX9867_DAC_MUTE_MASK);
	else
		regmap_update_bits(max9867->regmap, MAX9867_DACLEVEL,
			MAX9867_DAC_MUTE_MASK, 0);
	return 0;
}

static int max9867_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 max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);
	int value = 0;

	/* Set the prescaler based on the master clock frequency*/
	if (freq >= 10000000 && freq <= 20000000) {
		value |= MAX9867_PSCLK_10_20;
		max9867->pclk =  freq;
	} else if (freq >= 20000000 && freq <= 40000000) {
		value |= MAX9867_PSCLK_20_40;
		max9867->pclk =  freq/2;
	} else if (freq >= 40000000 && freq <= 60000000) {
		value |= MAX9867_PSCLK_40_60;
		max9867->pclk =  freq/4;
	} else {
		pr_err("bad clock frequency %d", freq);
		return -EINVAL;
	}
	value = value << MAX9867_PSCLK_SHIFT;
	max9867->sysclk = freq;
	/* exact integer mode is not supported */
	value &= ~MAX9867_FREQ_MASK;
	regmap_update_bits(max9867->regmap, MAX9867_SYSCLK,
			MAX9867_PSCLK_MASK, value);
	return 0;
}

static int max9867_dai_set_fmt(struct snd_soc_dai *codec_dai,
		unsigned int fmt)
{
	struct snd_soc_codec *codec = codec_dai->codec;
	struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);
	u8 iface1A = 0, iface1B = 0;
	int ret;

	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBM_CFM:
		max9867->master = 1;
		iface1A |= MAX9867_MASTER;
		break;
	case SND_SOC_DAIFMT_CBS_CFS:
		max9867->master = 0;
		iface1A &= ~MAX9867_MASTER;
		break;
	default:
		return -EINVAL;
	}

	/* for i2s compatible mode */
	iface1A |= MAX9867_I2S_DLY;
	/* SDOUT goes to hiz state after all data is transferred */
	iface1A |= MAX9867_SDOUT_HIZ;

	/* Clock inversion bits, BCI and WCI */
	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
	case SND_SOC_DAIFMT_NB_NF:
		break;
	case SND_SOC_DAIFMT_IB_IF:
		iface1A |= MAX9867_WCI_MODE | MAX9867_BCI_MODE;
		break;
	case SND_SOC_DAIFMT_IB_NF:
		iface1A |= MAX9867_BCI_MODE;
		break;
	case SND_SOC_DAIFMT_NB_IF:
		iface1A |= MAX9867_WCI_MODE;
		break;
	default:
		return -EINVAL;
	}

	ret = regmap_write(max9867->regmap, MAX9867_IFC1A, iface1A);
	ret = regmap_write(max9867->regmap, MAX9867_IFC1B, iface1B);
	return 0;
}

static struct snd_soc_dai_ops max9867_dai_ops = {
	.set_fmt = max9867_dai_set_fmt,
	.set_sysclk	= max9867_set_dai_sysclk,
	.prepare	= max9867_prepare,
	.digital_mute	= max9867_mute,
	.hw_params = max9867_dai_hw_params,
};

#define MAX9867_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
	SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
#define MAX9867_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)

static struct snd_soc_dai_driver max9867_dai[] = {
	{
	.name = "max9867-aif1",
	.playback = {
		.stream_name = "HiFi Playback",
		.channels_min = 1,
		.channels_max = 2,
		.rates = MAX9867_RATES,
		.formats = MAX9867_FORMATS,
	},
	.capture = {
		.stream_name = "HiFi Capture",
		.channels_min = 1,
		.channels_max = 2,
		.rates = MAX9867_RATES,
		.formats = MAX9867_FORMATS,
	},
	.ops = &max9867_dai_ops,
	}
};

#ifdef CONFIG_PM_SLEEP
static int max9867_suspend(struct device *dev)
{
	struct max9867_priv *max9867 = dev_get_drvdata(dev);

	/* Drop down to power saving mode when system is suspended */
	regmap_update_bits(max9867->regmap, MAX9867_PWRMAN,
		MAX9867_SHTDOWN_MASK, ~MAX9867_SHTDOWN_MASK);
	return 0;
}

static int max9867_resume(struct device *dev)
{
	struct max9867_priv *max9867 = dev_get_drvdata(dev);

	regmap_update_bits(max9867->regmap, MAX9867_PWRMAN,
		MAX9867_SHTDOWN_MASK, MAX9867_SHTDOWN_MASK);
	return 0;
}
#endif

static int max9867_probe(struct snd_soc_codec *codec)
{
	struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);

	dev_dbg(codec->dev, "max98090_probe\n");
	max9867->codec = codec;
	return 0;
}

static struct snd_soc_codec_driver max9867_codec = {
	.probe = max9867_probe,
	.controls = max9867_snd_controls,
	.num_controls = ARRAY_SIZE(max9867_snd_controls),
	.dapm_routes = max9867_audio_map,
	.num_dapm_routes = ARRAY_SIZE(max9867_audio_map),
	.dapm_widgets = max9867_dapm_widgets,
	.num_dapm_widgets = ARRAY_SIZE(max9867_dapm_widgets),
};

static bool max9867_volatile_register(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case MAX9867_STATUS:
	case MAX9867_JACKSTATUS:
	case MAX9867_AUXHIGH:
	case MAX9867_AUXLOW:
		return true;
	default:
		return false;
	}
}

static const struct reg_default max9867_reg[] = {
	{ 0x04, 0x00 },
	{ 0x05, 0x00 },
	{ 0x06, 0x00 },
	{ 0x07, 0x00 },
	{ 0x08, 0x00 },
	{ 0x09, 0x00 },
	{ 0x0A, 0x00 },
	{ 0x0B, 0x00 },
	{ 0x0C, 0x00 },
	{ 0x0D, 0x00 },
	{ 0x0E, 0x00 },
	{ 0x0F, 0x00 },
	{ 0x10, 0x00 },
	{ 0x11, 0x00 },
	{ 0x12, 0x00 },
	{ 0x13, 0x00 },
	{ 0x14, 0x00 },
	{ 0x15, 0x00 },
	{ 0x16, 0x00 },
	{ 0x17, 0x00 },
};

static const struct regmap_config max9867_regmap = {
	.reg_bits	= 8,
	.val_bits	= 8,
	.max_register	= MAX9867_REVISION,
	.reg_defaults	= max9867_reg,
	.num_reg_defaults = ARRAY_SIZE(max9867_reg),
	.volatile_reg	= max9867_volatile_register,
	.cache_type	= REGCACHE_RBTREE,
};

static int max9867_i2c_probe(struct i2c_client *i2c,
		const struct i2c_device_id *id)
{
	struct max9867_priv *max9867;
	int ret = 0, reg;

	max9867 = devm_kzalloc(&i2c->dev,
			sizeof(*max9867), GFP_KERNEL);
	if (!max9867)
		return -ENOMEM;

	i2c_set_clientdata(i2c, max9867);
	max9867->regmap = devm_regmap_init_i2c(i2c, &max9867_regmap);
	if (IS_ERR(max9867->regmap)) {
		ret = PTR_ERR(max9867->regmap);
		dev_err(&i2c->dev,
				"Failed to allocate regmap: %d\n", ret);
		return ret;
	}
	ret = regmap_read(max9867->regmap,
			MAX9867_REVISION, &reg);
	if (ret < 0) {
		dev_err(&i2c->dev, "Failed to read: %d\n", ret);
		return ret;
	}
	dev_info(&i2c->dev, "device revision: %x\n", reg);
	ret = snd_soc_register_codec(&i2c->dev, &max9867_codec,
			max9867_dai, ARRAY_SIZE(max9867_dai));
	if (ret < 0) {
		dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
		return ret;
	}
	return ret;
}

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

static const struct i2c_device_id max9867_i2c_id[] = {
	{ "max9867", 0 },
	{ }
};

static const struct of_device_id max9867_of_match[] = {
	{ .compatible = "maxim,max9867", },
	{ }
};

MODULE_DEVICE_TABLE(i2c, max9867_i2c_id);

static const struct dev_pm_ops max9867_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(max9867_suspend, max9867_resume)
};

static struct i2c_driver max9867_i2c_driver = {
	.driver = {
		.name = "max9867",
		.of_match_table = of_match_ptr(max9867_of_match),
		.pm = &max9867_pm_ops,
	},
	.probe  = max9867_i2c_probe,
	.remove = max9867_i2c_remove,
	.id_table = max9867_i2c_id,
};

module_i2c_driver(max9867_i2c_driver);

MODULE_AUTHOR("anish kumar <yesanishhere@gmail.com>");
MODULE_DESCRIPTION("ALSA SoC MAX9867 driver");
MODULE_LICENSE("GPL");
