/*
 * 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"

/* 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 {
		debug("%s: Unknown code 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;
}
