/*
 * Copyright (C) 2012 Samsung Electronics
 * R. Chandrasekar <rcsekar@samsung.com>
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <malloc.h>
#include <common.h>
#include <asm/io.h>
#include <libfdt.h>
#include <fdtdec.h>
#include <i2c.h>
#include <i2s.h>
#include <sound.h>
#include <asm/arch/sound.h>
#include "wm8994.h"
#include "max98095.h"

/* defines */
#define SOUND_400_HZ 400
#define SOUND_BITS_IN_BYTE 8

static struct i2stx_info g_i2stx_pri;

/*
 * get_sound_i2s_values gets values for i2s parameters
 *
 * @param i2stx_info	i2s transmitter transfer param structure
 * @param blob		FDT blob if enabled else NULL
 */
static int get_sound_i2s_values(struct i2stx_info *i2s, const void *blob)
{
#ifdef CONFIG_OF_CONTROL
	int node;
	int error = 0;
	int base;

	node = fdtdec_next_compatible(blob, 0,
					COMPAT_SAMSUNG_EXYNOS5_SOUND);
	if (node <= 0) {
		debug("EXYNOS_SOUND: No node for sound in device tree\n");
		return -1;
	}

	/*
	 * Get the pre-defined sound specific values from FDT.
	 * All of these are expected to be correct otherwise
	 * wrong register values in i2s setup parameters
	 * may result in no sound play.
	 */
	base = fdtdec_get_addr(blob, node, "reg");
	if (base == FDT_ADDR_T_NONE) {
		debug("%s: Missing  i2s base\n", __func__);
		return -1;
	}
	i2s->base_address = base;

	i2s->audio_pll_clk = fdtdec_get_int(blob,
				node, "samsung,i2s-epll-clock-frequency", -1);
	error |= i2s->audio_pll_clk;
	debug("audio_pll_clk = %d\n", i2s->audio_pll_clk);
	i2s->samplingrate = fdtdec_get_int(blob,
				node, "samsung,i2s-sampling-rate", -1);
	error |= i2s->samplingrate;
	debug("samplingrate = %d\n", i2s->samplingrate);
	i2s->bitspersample = fdtdec_get_int(blob,
				node, "samsung,i2s-bits-per-sample", -1);
	error |= i2s->bitspersample;
	debug("bitspersample = %d\n", i2s->bitspersample);
	i2s->channels = fdtdec_get_int(blob,
			node, "samsung,i2s-channels", -1);
	error |= i2s->channels;
	debug("channels = %d\n", i2s->channels);
	i2s->rfs = fdtdec_get_int(blob,
				node, "samsung,i2s-lr-clk-framesize", -1);
	error |= i2s->rfs;
	debug("rfs = %d\n", i2s->rfs);
	i2s->bfs = fdtdec_get_int(blob,
				node, "samsung,i2s-bit-clk-framesize", -1);
	error |= i2s->bfs;
	debug("bfs = %d\n", i2s->bfs);
	if (error == -1) {
		debug("fail to get sound i2s node properties\n");
		return -1;
	}
#else
	i2s->base_address = samsung_get_base_i2s();
	i2s->audio_pll_clk = I2S_PLL_CLK;
	i2s->samplingrate = I2S_SAMPLING_RATE;
	i2s->bitspersample = I2S_BITS_PER_SAMPLE;
	i2s->channels = I2S_CHANNELS;
	i2s->rfs = I2S_RFS;
	i2s->bfs = I2S_BFS;
#endif
	return 0;
}

/*
 * Init codec
 *
 * @param blob          FDT blob
 * @param pi2s_tx	i2s parameters required by codec
 * @return              int value, 0 for success
 */
static int codec_init(const void *blob, struct i2stx_info *pi2s_tx)
{
	int ret;
	const char *codectype;
#ifdef CONFIG_OF_CONTROL
	int node;

	/* Get the node from FDT for sound */
	node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS5_SOUND);
	if (node <= 0) {
		debug("EXYNOS_SOUND: No node for sound in device tree\n");
		debug("node = %d\n", node);
		return -1;
	}

	/*
	 * Get the pre-defined sound codec specific values from FDT.
	 * All of these are expected to be correct otherwise sound
	 * can not be played
	 */
	codectype = fdt_getprop(blob, node, "samsung,codec-type", NULL);
	debug("device = %s\n", codectype);
#else
	codectype =  AUDIO_CODEC;
#endif
	if (!strcmp(codectype, "wm8994")) {
		/* Check the codec type and initialise the same */
		ret = wm8994_init(blob, WM8994_AIF2,
			pi2s_tx->samplingrate,
			(pi2s_tx->samplingrate * (pi2s_tx->rfs)),
			pi2s_tx->bitspersample, pi2s_tx->channels);
	} else if (!strcmp(codectype, "max98095")) {
		ret = max98095_init(blob, pi2s_tx->samplingrate,
				(pi2s_tx->samplingrate * (pi2s_tx->rfs)),
				pi2s_tx->bitspersample);
	} else {
		debug("%s: Unknown codec type %s\n", __func__, codectype);
		return -1;
	}

	if (ret) {
		debug("%s: Codec init failed\n", __func__);
		return -1;
	}

	return 0;
}

int sound_init(const void *blob)
{
	int ret;
	struct i2stx_info *pi2s_tx = &g_i2stx_pri;

	/* Get the I2S Values */
	if (get_sound_i2s_values(pi2s_tx, blob) < 0) {
		debug(" FDT I2S values failed\n");
		return -1;
	}

	if (codec_init(blob, pi2s_tx) < 0) {
		debug(" Codec init failed\n");
		return -1;
	}

	ret = i2s_tx_init(pi2s_tx);
	if (ret) {
		debug("%s: Failed to init i2c transmit: ret=%d\n", __func__,
		      ret);
		return ret;
	}


	return ret;
}

/*
 * Generates square wave sound data for 1 second
 *
 * @param data          data buffer pointer
 * @param size          size of the buffer
 * @param freq          frequency of the wave
 */
static void sound_prepare_buffer(unsigned short *data, int size, uint32_t freq)
{
	const int sample = 48000;
	const unsigned short amplitude = 16000; /* between 1 and 32767 */
	const int period = freq ? sample / freq : 0;
	const int half = period / 2;

	assert(freq);

	/* Make sure we don't overflow our buffer */
	if (size % 2)
		size--;

	while (size) {
		int i;
		for (i = 0; size && i < half; i++) {
			size -= 2;
			*data++ = amplitude;
			*data++ = amplitude;
		}
		for (i = 0; size && i < period - half; i++) {
			size -= 2;
			*data++ = -amplitude;
			*data++ = -amplitude;
		}
	}
}

int sound_play(uint32_t msec, uint32_t frequency)
{
	unsigned int *data;
	unsigned long data_size;
	unsigned int ret = 0;

	/*Buffer length computation */
	data_size = g_i2stx_pri.samplingrate * g_i2stx_pri.channels;
	data_size *= (g_i2stx_pri.bitspersample / SOUND_BITS_IN_BYTE);
	data = malloc(data_size);

	if (data == NULL) {
		debug("%s: malloc failed\n", __func__);
		return -1;
	}

	sound_prepare_buffer((unsigned short *)data,
				data_size / sizeof(unsigned short), frequency);

	while (msec >= 1000) {
		ret = i2s_transfer_tx_data(&g_i2stx_pri, data,
					   (data_size / sizeof(int)));
		msec -= 1000;
	}
	if (msec) {
		unsigned long size =
			(data_size * msec) / (sizeof(int) * 1000);

		ret = i2s_transfer_tx_data(&g_i2stx_pri, data, size);
	}

	free(data);

	return ret;
}
