/*
 * mt6392-codec.c --  MT6392 ALSA SoC codec driver
 *
 * Copyright (c) 2016 MediaTek Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include "mt6392-codec.h"
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/of.h>
#include <sound/soc.h>
#include <sound/tlv.h>

/*
 * Class D: has HW Trim mode and SW Trim mode
 * Class AB: use the trim offset derived from Class D HW Trim
 *
 * The option used to choose the trim mode of Class D
 */
static int int_spk_amp_enable_get(struct snd_kcontrol *kcontrol,
				  struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct mt6392_codec_priv *codec_data =
	    snd_soc_component_get_drvdata(component);
	uint32_t reg_value = snd_soc_component_read32(codec_data->codec, SPK_CON0);
	ucontrol->value.integer.value[0] = reg_value & BIT(0) ? 1 : 0;
	return 0;
}

static int int_spk_amp_enable_put(struct snd_kcontrol *kcontrol,
				  struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct mt6392_codec_priv *codec_data =
	    snd_soc_component_get_drvdata(component);

	if (ucontrol->value.integer.value[0] == 0)
		mt6392_int_spk_turn_off(codec_data->codec);
	else
		mt6392_int_spk_turn_on(codec_data->codec);

	return 0;
}

#define USE_HW_TRIM_CLASS_D

/* Int Spk Amp Playback Volume
 * {mute, 0, 4, 5, 6, 7, 8, ..., 17} dB
 */
static const unsigned int int_spk_amp_gain_tlv[] = {
	TLV_DB_RANGE_HEAD(3),
	0,
	0,
	TLV_DB_SCALE_ITEM(0, 0, 1),
	1,
	1,
	TLV_DB_SCALE_ITEM(0, 0, 0),
	2,
	15,
	TLV_DB_SCALE_ITEM(400, 100, 0),
};

/* Audio_Speaker_PGA_gain
 * {mute, 0, 4, 5, 6, 7, 8, ..., 17} dB
 */
static const char *const int_spk_amp_gain_text[] = {
	"MUTE",
	"+0dB",
	"+4dB",
	"+5dB",
	"+6dB",
	"+7dB",
	"+8dB",
	"+9dB",
	"+10dB",
	"+11dB",
	"+12dB",
	"+13dB",
	"+14dB",
	"+15dB",
	"+16dB",
	"+17dB",
};

static const struct soc_enum int_spk_amp_gain_enum =
	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(int_spk_amp_gain_text),
		int_spk_amp_gain_text);

static int int_spk_amp_gain_get(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct mt6392_codec_priv *codec_data =
	    snd_soc_component_get_drvdata(component);
	uint32_t value = 0;

	value = codec_data->spk_amp_gain;

	ucontrol->value.integer.value[0] = value;

	return 0;
}

static int int_spk_amp_gain_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct mt6392_codec_priv *codec_data =
	    snd_soc_component_get_drvdata(component);
	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
	uint32_t value = ucontrol->value.integer.value[0];

	if (value >= e->items)
		return -EINVAL;

	snd_soc_component_update_bits(codec_data->codec, SPK_CON9, GENMASK(11, 8),
			    value << 8);

	codec_data->spk_amp_gain = value;

	dev_dbg(codec_data->codec->dev, "%s value = %u\n", __func__, value);

	return 0;
}

/* Internal speaker mode (AB/D) */
static const char *const int_spk_amp_mode_texts[] = {
	"Class D",
	"Class AB",
};

static SOC_ENUM_SINGLE_EXT_DECL(mt6392_speaker_mode_enum,
				int_spk_amp_mode_texts);

static int mt6392_spk_mode_get(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct mt6392_codec_priv *codec_data =
	    snd_soc_component_get_drvdata(component);

	ucontrol->value.integer.value[0] = codec_data->speaker_mode;
	return 0;
}

static int mt6392_spk_mode_put(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct mt6392_codec_priv *codec_data =
	    snd_soc_component_get_drvdata(component);
	int ret = 0;
	uint32_t mode = ucontrol->value.integer.value[0];

	switch (mode) {
	case MT6392_CLASS_D:
	case MT6392_CLASS_AB:
		codec_data->speaker_mode = ucontrol->value.integer.value[0];
		break;
	default:
		ret = -EINVAL;
		break;
	}

	return ret;
}

/* Check OC Flag */
static const char *const mt6392_speaker_oc_flag_texts[] = {
	"NoOverCurrent",
	"OverCurrent"
};

static SOC_ENUM_SINGLE_EXT_DECL(mt6392_speaker_oc_flag_enum,
				mt6392_speaker_oc_flag_texts);

static int mt6392_speaker_oc_flag_get(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct mt6392_codec_priv *codec_data =
	    snd_soc_component_get_drvdata(component);
	uint32_t reg_value = snd_soc_component_read32(codec_data->codec, SPK_CON6);

	if (codec_data->speaker_mode == MT6392_CLASS_AB)
		ucontrol->value.integer.value[0] =
		    (reg_value & BIT(15)) ? 1 : 0;
	else
		ucontrol->value.integer.value[0] =
		    (reg_value & BIT(14)) ? 1 : 0;

	return 0;
}

static const struct snd_kcontrol_new mt6392_codec_controls[] = {
	/* Internal speaker PGA gain control */
	SOC_SINGLE_BOOL_EXT("Int Spk Amp Enable", 0, int_spk_amp_enable_get,
			    int_spk_amp_enable_put),
	SOC_SINGLE_TLV("Int Spk Amp Playback Volume", SPK_CON9, 8, 15, 0,
		       int_spk_amp_gain_tlv),
	/* Audio_Speaker_PGA_gain */
	SOC_ENUM_EXT("Audio_Speaker_PGA_gain", int_spk_amp_gain_enum,
		     int_spk_amp_gain_get, int_spk_amp_gain_put),
	/* Internal speaker mode (AB/D) */
	SOC_ENUM_EXT("Int Spk Amp Mode", mt6392_speaker_mode_enum,
		     mt6392_spk_mode_get, mt6392_spk_mode_put),
	/* Check OC Flag */
	SOC_ENUM_EXT("Speaker_OC_Flag", mt6392_speaker_oc_flag_enum,
		     mt6392_speaker_oc_flag_get, NULL),
};

static void mt6392_codec_get_spk_trim_offset(struct snd_soc_component *codec)
{
	struct mt6392_codec_priv *codec_data = snd_soc_component_get_drvdata(codec);

	/* turn on spk (class D) and hw trim */
	snd_soc_component_update_bits(codec, TOP_CKPDN1_CLR, 0x000E, 0x000E);
	snd_soc_component_update_bits(codec, SPK_CON7, 0xFFFF, 0x48F4);
	snd_soc_component_update_bits(codec, SPK_CON11, 0xFFFF, 0x0055);
	snd_soc_component_update_bits(codec, SPK_CON9, 0xF0FF, 0x2018);
	snd_soc_component_update_bits(codec, SPK_CON2, 0xFFFF, 0x0414);
	snd_soc_component_update_bits(codec, SPK_CON0, 0xFFFF, 0x3409);
	usleep_range(20000, 21000);

	/* save trim offset */
	codec_data->spk_trim_offset =
	    snd_soc_component_read32(codec, SPK_CON1) & GENMASK(4, 0);

	/* turn off trim */
	snd_soc_component_update_bits(codec, SPK_CON0, 0xFFFF, 0x3401);
	snd_soc_component_update_bits(codec, SPK_CON9, 0xF0FF, 0x2000);
	usleep_range(2000, 3000);

	/* turn off spk */
	snd_soc_component_update_bits(codec, SPK_CON12, 0xFFFF, 0x0000);
	snd_soc_component_update_bits(codec, SPK_CON0, 0xFFFF, 0x3400);
	snd_soc_component_update_bits(codec, TOP_CKPDN1_CLR, 0x000E, 0x0000);
}

static void mt6392_int_spk_on_with_trim(struct snd_soc_component *codec)
{
#if defined(USE_HW_TRIM_CLASS_D)
	/* turn on spk (class D) and hw trim */
	snd_soc_component_update_bits(codec, TOP_CKPDN1_CLR, 0x000E, 0x000E);
	snd_soc_component_update_bits(codec, SPK_CON7, 0xFFFF, 0x48F4);
	snd_soc_component_update_bits(codec, SPK_CON11, 0xFFFF, 0x0055);
	snd_soc_component_update_bits(codec, SPK_CON9, 0xF0FF, 0x2018);
	snd_soc_component_update_bits(codec, SPK_CON2, 0xFFFF, 0x0414);
	snd_soc_component_update_bits(codec, SPK_CON0, 0xFFFF, 0x3409);
	usleep_range(20000, 21000);

	/* turn off trim */
	snd_soc_component_update_bits(codec, SPK_CON0, 0xFFFF, 0x3401);
	snd_soc_component_update_bits(codec, SPK_CON9, 0xF0FF, 0x2000);
#else
	struct mt6392_codec_priv *codec_data = snd_soc_component_get_drvdata(codec);

	/* turn on spk (class D) */
	snd_soc_component_update_bits(codec, TOP_CKPDN1_CLR, 0x000E, 0x000E);
	snd_soc_component_update_bits(codec, SPK_CON7, 0xFFFF, 0x48F4);
	snd_soc_component_update_bits(codec, SPK_CON2, 0xFFFF, 0x0414);
	snd_soc_component_update_bits(codec, SPK_CON0, 0xFFFF, 0x3001);
	snd_soc_component_update_bits(codec, SPK_CON9, 0xF0FF, 0x2000);

	/* enable sw trim */
	snd_soc_component_update_bits(codec, SPK_CON12, 0xFFFF, 0x0009);
	snd_soc_component_update_bits(codec, SPK_CON12, 0xFFFF, 0x0001);
	snd_soc_component_update_bits(codec, SPK_CON12, 0xFFFF, 0x0283);
	snd_soc_component_update_bits(codec, SPK_CON12, 0xFFFF, 0x0281);
	snd_soc_component_update_bits(codec, SPK_CON12, 0xFFFF, 0x2A81);
	snd_soc_component_update_bits(codec, SPK_CON1, 0xFFFF, 0x6000);
	/* class D and class AB use the same trim offset value */
	snd_soc_component_update_bits(codec, SPK_CON1, GENMASK(12, 8),
			    (codec_data->spk_trim_offset << 8));

	/* trim stop */
	snd_soc_component_update_bits(codec, SPK_CON12, 0xFFFF, 0xAA81);
#endif
	usleep_range(2000, 3000);
}

int mt6392_int_spk_turn_on(struct snd_soc_component *codec)
{
	struct mt6392_codec_priv *codec_data = snd_soc_component_get_drvdata(codec);
	int ret = 0;

	dev_dbg(codec->dev, "%s\n", __func__);

	switch (codec_data->speaker_mode) {
	case MT6392_CLASS_D:
		mt6392_int_spk_on_with_trim(codec);
		break;
	case MT6392_CLASS_AB:
		snd_soc_component_update_bits(codec, TOP_CKPDN1_CLR, 0x000E, 0x000E);
		snd_soc_component_update_bits(codec, SPK_CON7, 0xFFFF, 0x48F4);
		snd_soc_component_update_bits(codec, SPK_CON2, 0xFFFF, 0x0414);
		snd_soc_component_update_bits(codec, SPK_CON0, 0xFFFF, 0x3005);
		snd_soc_component_update_bits(codec, SPK_CON9, 0xF0FF, 0x2000);
		snd_soc_component_update_bits(codec, SPK_CON1, 0xFFFF, 0x6000);
		/* class D and class AB use the same trim offset value */
		snd_soc_component_update_bits(codec, SPK_CON1, GENMASK(12, 8),
				    (codec_data->spk_trim_offset << 8));
		usleep_range(2000, 3000);
		break;
	default:
		ret = -EINVAL;
		break;
	}

	return ret;
}

EXPORT_SYMBOL_GPL(mt6392_int_spk_turn_on);

int mt6392_int_spk_turn_off(struct snd_soc_component *codec)
{
	struct mt6392_codec_priv *codec_data = snd_soc_component_get_drvdata(codec);
	int ret = 0;

	dev_dbg(codec->dev, "%s\n", __func__);

	switch (codec_data->speaker_mode) {
	case MT6392_CLASS_D:
		snd_soc_component_update_bits(codec, SPK_CON12, 0xFFFF, 0x0000);
		snd_soc_component_update_bits(codec, SPK_CON0, 0xFFFF, 0x3400);
		snd_soc_component_update_bits(codec, TOP_CKPDN1_CLR, 0x000E, 0x0000);
		break;
	case MT6392_CLASS_AB:
		snd_soc_component_update_bits(codec, SPK_CON0, 0xFFFF, 0x3404);
		snd_soc_component_update_bits(codec, TOP_CKPDN1_CLR, 0x000E, 0x0000);
		break;
	default:
		ret = -EINVAL;
		break;
	}

	return ret;
}

EXPORT_SYMBOL_GPL(mt6392_int_spk_turn_off);

static int mt6392_int_spk_amp_wevent(struct snd_soc_dapm_widget *w,
				     struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm);

	dev_dbg(codec->dev, "%s, event %d\n", __func__, event);

	switch (event) {
	case SND_SOC_DAPM_POST_PMU:
		mt6392_int_spk_turn_on(codec);
		break;
	case SND_SOC_DAPM_PRE_PMD:
		mt6392_int_spk_turn_off(codec);
		break;
	default:
		break;
	}

	return 0;
}

static const struct snd_soc_dapm_widget mt6392_codec_dapm_widgets[] = {
	SND_SOC_DAPM_SPK("Int Spk Amp", mt6392_int_spk_amp_wevent),
};

#ifdef CONFIG_DEBUG_FS
struct mt6392_codec_reg_attr {
	uint32_t offset;
	char *name;
};

#define DUMP_REG_ENTRY(reg)                                                    \
	{                                                                      \
		reg, #reg                                                      \
	}

static const struct mt6392_codec_reg_attr mt6392_codec_dump_reg_list[] = {
	DUMP_REG_ENTRY(SPK_CON0),
	DUMP_REG_ENTRY(SPK_CON1),
	DUMP_REG_ENTRY(SPK_CON2),
	DUMP_REG_ENTRY(SPK_CON3),
	DUMP_REG_ENTRY(SPK_CON4),
	DUMP_REG_ENTRY(SPK_CON5),
	DUMP_REG_ENTRY(SPK_CON6),
	DUMP_REG_ENTRY(SPK_CON7),
	DUMP_REG_ENTRY(SPK_CON8),
	DUMP_REG_ENTRY(SPK_CON9),
	DUMP_REG_ENTRY(SPK_CON10),
	DUMP_REG_ENTRY(SPK_CON11),
	DUMP_REG_ENTRY(SPK_CON12),
};

static ssize_t mt6392_codec_debug_read(struct file *file,
				       char __user * user_buf, size_t count,
				       loff_t * pos)
{
	struct mt6392_codec_priv *codec_data = file->private_data;
	ssize_t ret, i;
	char *buf;
	int n = 0;

	if (*pos < 0 || !count)
		return -EINVAL;

	buf = kmalloc(count, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	for (i = 0; i < ARRAY_SIZE(mt6392_codec_dump_reg_list); i++) {
		n += scnprintf(buf + n, count - n, "%s = 0x%x\n",
			       mt6392_codec_dump_reg_list[i].name,
			       snd_soc_component_read32(codec_data->codec,
					    mt6392_codec_dump_reg_list[i].
					    offset));
	}

	ret = simple_read_from_buffer(user_buf, count, pos, buf, n);

	kfree(buf);

	return ret;
}

static const struct file_operations mt6392_codec_debug_ops = {
	.open = simple_open,
	.read = mt6392_codec_debug_read,
	.llseek = default_llseek,
};
#endif

static void mt6392_codec_init_regs(struct mt6392_codec_priv *codec_data)
{
	struct snd_soc_component *codec = codec_data->codec;

	dev_dbg(codec->dev, "%s\n", __func__);

	/* default PGA gain: 12dB */
	codec_data->spk_amp_gain = 0xA;
	snd_soc_component_update_bits(codec, SPK_CON9, GENMASK(11, 8),
			    (codec_data->spk_amp_gain) << 8);
}

static int mt6392_codec_parse_dt(struct snd_soc_component *codec)
{
	struct mt6392_codec_priv *codec_data = snd_soc_component_get_drvdata(codec);
	struct device *dev = codec->dev;
	int ret = 0;

	ret = of_property_read_u32(dev->of_node, "mediatek,speaker-mode",
				   &codec_data->speaker_mode);
	if (ret) {
		dev_warn(dev, "%s fail to read speaker-mode in node %s\n",
			 __func__, dev->of_node->full_name);
		codec_data->speaker_mode = MT6392_CLASS_D;
	} else if (codec_data->speaker_mode != MT6392_CLASS_D &&
		   codec_data->speaker_mode != MT6392_CLASS_AB) {
		codec_data->speaker_mode = MT6392_CLASS_D;
	}

	return ret;
}

/* FIXME:
 * attached to the mt8167 codec for now
 * there is no dev for mt6392, thus use the dev from mt8167 codec
 * need to parse the dt from mt6392 itself
 * and detach it into a standalone codec driver
 */
int mt6392_codec_probe(struct snd_soc_component *codec)
{
	struct mt6392_codec_priv *codec_data = snd_soc_component_get_drvdata(codec);
	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec);
	int ret = 0;

	ret = snd_soc_add_component_controls(codec, mt6392_codec_controls,
					 ARRAY_SIZE(mt6392_codec_controls));
	if (ret < 0)
		goto error_probe;

	ret = snd_soc_dapm_new_controls(dapm, mt6392_codec_dapm_widgets,
					ARRAY_SIZE(mt6392_codec_dapm_widgets));
	if (ret < 0)
		goto error_probe;

	codec_data->codec = codec;

	mt6392_codec_parse_dt(codec);

	mt6392_codec_init_regs(codec_data);

	mt6392_codec_get_spk_trim_offset(codec);

#ifdef CONFIG_DEBUG_FS
	codec_data->debugfs = debugfs_create_file("mt6392_codec_regs",
						  S_IFREG | S_IRUGO, NULL,
						  codec_data,
						  &mt6392_codec_debug_ops);
#endif
error_probe:
	return ret;
}

EXPORT_SYMBOL_GPL(mt6392_codec_probe);

int mt6392_codec_remove(struct snd_soc_component *codec)
{
#ifdef CONFIG_DEBUG_FS
	struct mt6392_codec_priv *codec_data = snd_soc_component_get_drvdata(codec);
	debugfs_remove(codec_data->debugfs);
#endif
	dev_dbg(codec->dev, "%s\n", __func__);
	return 0;
}

EXPORT_SYMBOL_GPL(mt6392_codec_remove);

MODULE_DESCRIPTION("Mediatek ALSA SoC AFE MT6392 Codec Driver");
MODULE_LICENSE("GPL v2");
