/*
 * 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 SNDRV_CTL_TLVD_DECLARE_DB_RANGE(max98088_micboost_tlv,
	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,
	.component_driver = {
		.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");
