/*
 * Renesas R-Car DVC support
 *
 * Copyright (C) 2014 Renesas Solutions Corp.
 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.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.
 */

/*
 * Playback Volume
 *	amixer set "DVC Out" 100%
 *
 * Capture Volume
 *	amixer set "DVC In" 100%
 *
 * Playback Mute
 *	amixer set "DVC Out Mute" on
 *
 * Capture Mute
 *	amixer set "DVC In Mute" on
 *
 * Volume Ramp
 *	amixer set "DVC Out Ramp Up Rate"   "0.125 dB/64 steps"
 *	amixer set "DVC Out Ramp Down Rate" "0.125 dB/512 steps"
 *	amixer set "DVC Out Ramp" on
 *	aplay xxx.wav &
 *	amixer set "DVC Out"  80%  // Volume Down
 *	amixer set "DVC Out" 100%  // Volume Up
 */

#include "rsnd.h"

#define RSND_DVC_NAME_SIZE	16

#define DVC_NAME "dvc"

struct rsnd_dvc {
	struct rsnd_mod mod;
	struct rsnd_kctrl_cfg_m volume;
	struct rsnd_kctrl_cfg_m mute;
	struct rsnd_kctrl_cfg_s ren;	/* Ramp Enable */
	struct rsnd_kctrl_cfg_s rup;	/* Ramp Rate Up */
	struct rsnd_kctrl_cfg_s rdown;	/* Ramp Rate Down */
	u32 flags;
};

#define KCTRL_INITIALIZED	(1 << 0)

#define rsnd_dvc_get(priv, id) ((struct rsnd_dvc *)(priv->dvc) + id)
#define rsnd_dvc_nr(priv) ((priv)->dvc_nr)

#define rsnd_mod_to_dvc(_mod)	\
	container_of((_mod), struct rsnd_dvc, mod)

#define for_each_rsnd_dvc(pos, priv, i)				\
	for ((i) = 0;						\
	     ((i) < rsnd_dvc_nr(priv)) &&			\
	     ((pos) = (struct rsnd_dvc *)(priv)->dvc + i);	\
	     i++)

static void rsnd_dvc_activation(struct rsnd_mod *mod)
{
	rsnd_mod_write(mod, DVC_SWRSR, 0);
	rsnd_mod_write(mod, DVC_SWRSR, 1);
}

static void rsnd_dvc_halt(struct rsnd_mod *mod)
{
	rsnd_mod_write(mod, DVC_DVUIR, 1);
	rsnd_mod_write(mod, DVC_SWRSR, 0);
}

#define rsnd_dvc_get_vrpdr(dvc) (rsnd_kctrl_vals(dvc->rup) << 8 | \
				 rsnd_kctrl_vals(dvc->rdown))
#define rsnd_dvc_get_vrdbr(dvc) (0x3ff - (rsnd_kctrl_valm(dvc->volume, 0) >> 13))

static void rsnd_dvc_volume_parameter(struct rsnd_dai_stream *io,
					      struct rsnd_mod *mod)
{
	struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
	u32 val[RSND_MAX_CHANNELS];
	int i;

	/* Enable Ramp */
	if (rsnd_kctrl_vals(dvc->ren))
		for (i = 0; i < RSND_MAX_CHANNELS; i++)
			val[i] = rsnd_kctrl_max(dvc->volume);
	else
		for (i = 0; i < RSND_MAX_CHANNELS; i++)
			val[i] = rsnd_kctrl_valm(dvc->volume, i);

	/* Enable Digital Volume */
	rsnd_mod_write(mod, DVC_VOL0R, val[0]);
	rsnd_mod_write(mod, DVC_VOL1R, val[1]);
	rsnd_mod_write(mod, DVC_VOL2R, val[2]);
	rsnd_mod_write(mod, DVC_VOL3R, val[3]);
	rsnd_mod_write(mod, DVC_VOL4R, val[4]);
	rsnd_mod_write(mod, DVC_VOL5R, val[5]);
	rsnd_mod_write(mod, DVC_VOL6R, val[6]);
	rsnd_mod_write(mod, DVC_VOL7R, val[7]);
}

static void rsnd_dvc_volume_init(struct rsnd_dai_stream *io,
				 struct rsnd_mod *mod)
{
	struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
	u32 adinr = 0;
	u32 dvucr = 0;
	u32 vrctr = 0;
	u32 vrpdr = 0;
	u32 vrdbr = 0;

	adinr = rsnd_get_adinr_bit(mod, io) |
		rsnd_runtime_channel_after_ctu(io);

	/* Enable Digital Volume, Zero Cross Mute Mode */
	dvucr |= 0x101;

	/* Enable Ramp */
	if (rsnd_kctrl_vals(dvc->ren)) {
		dvucr |= 0x10;

		/*
		 * FIXME !!
		 * use scale-downed Digital Volume
		 * as Volume Ramp
		 * 7F FFFF -> 3FF
		 */
		vrctr = 0xff;
		vrpdr = rsnd_dvc_get_vrpdr(dvc);
		vrdbr = rsnd_dvc_get_vrdbr(dvc);
	}

	/* Initialize operation */
	rsnd_mod_write(mod, DVC_DVUIR, 1);

	/* General Information */
	rsnd_mod_write(mod, DVC_ADINR, adinr);
	rsnd_mod_write(mod, DVC_DVUCR, dvucr);

	/* Volume Ramp Parameter */
	rsnd_mod_write(mod, DVC_VRCTR, vrctr);
	rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
	rsnd_mod_write(mod, DVC_VRDBR, vrdbr);

	/* Digital Volume Function Parameter */
	rsnd_dvc_volume_parameter(io, mod);

	/* cancel operation */
	rsnd_mod_write(mod, DVC_DVUIR, 0);
}

static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io,
				   struct rsnd_mod *mod)
{
	struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
	u32 zcmcr = 0;
	u32 vrpdr = 0;
	u32 vrdbr = 0;
	int i;

	for (i = 0; i < rsnd_kctrl_size(dvc->mute); i++)
		zcmcr |= (!!rsnd_kctrl_valm(dvc->mute, i)) << i;

	if (rsnd_kctrl_vals(dvc->ren)) {
		vrpdr = rsnd_dvc_get_vrpdr(dvc);
		vrdbr = rsnd_dvc_get_vrdbr(dvc);
	}

	/* Disable DVC Register access */
	rsnd_mod_write(mod, DVC_DVUER, 0);

	/* Zero Cross Mute Function */
	rsnd_mod_write(mod, DVC_ZCMCR, zcmcr);

	/* Volume Ramp Function */
	rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
	rsnd_mod_write(mod, DVC_VRDBR, vrdbr);
	/* add DVC_VRWTR here */

	/* Digital Volume Function Parameter */
	rsnd_dvc_volume_parameter(io, mod);

	/* Enable DVC Register access */
	rsnd_mod_write(mod, DVC_DVUER, 1);
}

static int rsnd_dvc_probe_(struct rsnd_mod *mod,
			   struct rsnd_dai_stream *io,
			   struct rsnd_priv *priv)
{
	return rsnd_cmd_attach(io, rsnd_mod_id(mod));
}

static int rsnd_dvc_init(struct rsnd_mod *mod,
			 struct rsnd_dai_stream *io,
			 struct rsnd_priv *priv)
{
	rsnd_mod_power_on(mod);

	rsnd_dvc_activation(mod);

	rsnd_dvc_volume_init(io, mod);

	rsnd_dvc_volume_update(io, mod);

	return 0;
}

static int rsnd_dvc_quit(struct rsnd_mod *mod,
			 struct rsnd_dai_stream *io,
			 struct rsnd_priv *priv)
{
	rsnd_dvc_halt(mod);

	rsnd_mod_power_off(mod);

	return 0;
}

static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
			    struct rsnd_dai_stream *io,
			    struct snd_soc_pcm_runtime *rtd)
{
	struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
	struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
	int is_play = rsnd_io_is_play(io);
	int channels = rsnd_rdai_channels_get(rdai);
	int ret;

	if (rsnd_flags_has(dvc, KCTRL_INITIALIZED))
		return 0;

	/* Volume */
	ret = rsnd_kctrl_new_m(mod, io, rtd,
			is_play ?
			"DVC Out Playback Volume" : "DVC In Capture Volume",
			rsnd_kctrl_accept_anytime,
			rsnd_dvc_volume_update,
			&dvc->volume, channels,
			0x00800000 - 1);
	if (ret < 0)
		return ret;

	/* Mute */
	ret = rsnd_kctrl_new_m(mod, io, rtd,
			is_play ?
			"DVC Out Mute Switch" : "DVC In Mute Switch",
			rsnd_kctrl_accept_anytime,
			rsnd_dvc_volume_update,
			&dvc->mute, channels,
			1);
	if (ret < 0)
		return ret;

	/* Ramp */
	ret = rsnd_kctrl_new_s(mod, io, rtd,
			is_play ?
			"DVC Out Ramp Switch" : "DVC In Ramp Switch",
			rsnd_kctrl_accept_anytime,
			rsnd_dvc_volume_update,
			&dvc->ren, 1);
	if (ret < 0)
		return ret;

	ret = rsnd_kctrl_new_e(mod, io, rtd,
			is_play ?
			"DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate",
			rsnd_kctrl_accept_anytime,
			rsnd_dvc_volume_update,
			&dvc->rup,
			volume_ramp_rate,
			VOLUME_RAMP_MAX_DVC);
	if (ret < 0)
		return ret;

	ret = rsnd_kctrl_new_e(mod, io, rtd,
			is_play ?
			"DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate",
			rsnd_kctrl_accept_anytime,
			rsnd_dvc_volume_update,
			&dvc->rdown,
			volume_ramp_rate,
			VOLUME_RAMP_MAX_DVC);

	if (ret < 0)
		return ret;

	rsnd_flags_set(dvc, KCTRL_INITIALIZED);

	return 0;
}

static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_dai_stream *io,
					 struct rsnd_mod *mod)
{
	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);

	return rsnd_dma_request_channel(rsnd_dvc_of_node(priv),
					mod, "tx");
}

static struct rsnd_mod_ops rsnd_dvc_ops = {
	.name		= DVC_NAME,
	.dma_req	= rsnd_dvc_dma_req,
	.probe		= rsnd_dvc_probe_,
	.init		= rsnd_dvc_init,
	.quit		= rsnd_dvc_quit,
	.pcm_new	= rsnd_dvc_pcm_new,
};

struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id)
{
	if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv)))
		id = 0;

	return rsnd_mod_get(rsnd_dvc_get(priv, id));
}

int rsnd_dvc_probe(struct rsnd_priv *priv)
{
	struct device_node *node;
	struct device_node *np;
	struct device *dev = rsnd_priv_to_dev(priv);
	struct rsnd_dvc *dvc;
	struct clk *clk;
	char name[RSND_DVC_NAME_SIZE];
	int i, nr, ret;

	/* This driver doesn't support Gen1 at this point */
	if (rsnd_is_gen1(priv))
		return 0;

	node = rsnd_dvc_of_node(priv);
	if (!node)
		return 0; /* not used is not error */

	nr = of_get_child_count(node);
	if (!nr) {
		ret = -EINVAL;
		goto rsnd_dvc_probe_done;
	}

	dvc	= devm_kzalloc(dev, sizeof(*dvc) * nr, GFP_KERNEL);
	if (!dvc) {
		ret = -ENOMEM;
		goto rsnd_dvc_probe_done;
	}

	priv->dvc_nr	= nr;
	priv->dvc	= dvc;

	i = 0;
	ret = 0;
	for_each_child_of_node(node, np) {
		dvc = rsnd_dvc_get(priv, i);

		snprintf(name, RSND_DVC_NAME_SIZE, "%s.%d",
			 DVC_NAME, i);

		clk = devm_clk_get(dev, name);
		if (IS_ERR(clk)) {
			ret = PTR_ERR(clk);
			of_node_put(np);
			goto rsnd_dvc_probe_done;
		}

		ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops,
				    clk, rsnd_mod_get_status, RSND_MOD_DVC, i);
		if (ret) {
			of_node_put(np);
			goto rsnd_dvc_probe_done;
		}

		i++;
	}

rsnd_dvc_probe_done:
	of_node_put(node);

	return ret;
}

void rsnd_dvc_remove(struct rsnd_priv *priv)
{
	struct rsnd_dvc *dvc;
	int i;

	for_each_rsnd_dvc(dvc, priv, i) {
		rsnd_mod_quit(rsnd_mod_get(dvc));
	}
}
