/*
 * ASoC driver for TI DAVINCI EVM platform
 *
 * Author:      Vladimir Barinov, <vbarinov@ru.mvista.com>
 * Copyright:   (C) 2007 MontaVista Software, Inc., <source@mvista.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.
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>

#include <asm/mach-types.h>
#include <asm/dma.h>
#include <asm/arch/hardware.h>

#include "../codecs/tlv320aic3x.h"
#include "davinci-pcm.h"
#include "davinci-i2s.h"

#define EVM_CODEC_CLOCK 22579200

static int evm_hw_params(struct snd_pcm_substream *substream,
			 struct snd_pcm_hw_params *params)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai;
	struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai;
	int ret = 0;

	/* set codec DAI configuration */
	ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
					 SND_SOC_DAIFMT_CBM_CFM);
	if (ret < 0)
		return ret;

	/* set cpu DAI configuration */
	ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_CBM_CFM |
				       SND_SOC_DAIFMT_IB_NF);
	if (ret < 0)
		return ret;

	/* set the codec system clock */
	ret = codec_dai->dai_ops.set_sysclk(codec_dai, 0, EVM_CODEC_CLOCK,
					    SND_SOC_CLOCK_OUT);
	if (ret < 0)
		return ret;

	return 0;
}

static struct snd_soc_ops evm_ops = {
	.hw_params = evm_hw_params,
};

/* davinci-evm machine dapm widgets */
static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
	SND_SOC_DAPM_HP("Headphone Jack", NULL),
	SND_SOC_DAPM_LINE("Line Out", NULL),
	SND_SOC_DAPM_MIC("Mic Jack", NULL),
	SND_SOC_DAPM_LINE("Line In", NULL),
};

/* davinci-evm machine audio_mapnections to the codec pins */
static const char *audio_map[][3] = {
	/* Headphone connected to HPLOUT, HPROUT */
	{"Headphone Jack", NULL, "HPLOUT"},
	{"Headphone Jack", NULL, "HPROUT"},

	/* Line Out connected to LLOUT, RLOUT */
	{"Line Out", NULL, "LLOUT"},
	{"Line Out", NULL, "RLOUT"},

	/* Mic connected to (MIC3L | MIC3R) */
	{"MIC3L", NULL, "Mic Bias 2V"},
	{"MIC3R", NULL, "Mic Bias 2V"},
	{"Mic Bias 2V", NULL, "Mic Jack"},

	/* Line In connected to (LINE1L | LINE2L), (LINE1R | LINE2R) */
	{"LINE1L", NULL, "Line In"},
	{"LINE2L", NULL, "Line In"},
	{"LINE1R", NULL, "Line In"},
	{"LINE2R", NULL, "Line In"},

	{NULL, NULL, NULL},
};

/* Logic for a aic3x as connected on a davinci-evm */
static int evm_aic3x_init(struct snd_soc_codec *codec)
{
	int i;

	/* Add davinci-evm specific widgets */
	for (i = 0; i < ARRAY_SIZE(aic3x_dapm_widgets); i++)
		snd_soc_dapm_new_control(codec, &aic3x_dapm_widgets[i]);

	/* Set up davinci-evm specific audio path audio_map */
	for (i = 0; audio_map[i][0] != NULL; i++)
		snd_soc_dapm_connect_input(codec, audio_map[i][0],
					   audio_map[i][1], audio_map[i][2]);

	/* not connected */
	snd_soc_dapm_set_endpoint(codec, "MONO_LOUT", 0);
	snd_soc_dapm_set_endpoint(codec, "HPLCOM", 0);
	snd_soc_dapm_set_endpoint(codec, "HPRCOM", 0);

	/* always connected */
	snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 1);
	snd_soc_dapm_set_endpoint(codec, "Line Out", 1);
	snd_soc_dapm_set_endpoint(codec, "Mic Jack", 1);
	snd_soc_dapm_set_endpoint(codec, "Line In", 1);

	snd_soc_dapm_sync_endpoints(codec);

	return 0;
}

/* davinci-evm digital audio interface glue - connects codec <--> CPU */
static struct snd_soc_dai_link evm_dai = {
	.name = "TLV320AIC3X",
	.stream_name = "AIC3X",
	.cpu_dai = &davinci_i2s_dai,
	.codec_dai = &aic3x_dai,
	.init = evm_aic3x_init,
	.ops = &evm_ops,
};

/* davinci-evm audio machine driver */
static struct snd_soc_machine snd_soc_machine_evm = {
	.name = "DaVinci EVM",
	.dai_link = &evm_dai,
	.num_links = 1,
};

/* evm audio private data */
static struct aic3x_setup_data evm_aic3x_setup = {
	.i2c_address = 0x1b,
};

/* evm audio subsystem */
static struct snd_soc_device evm_snd_devdata = {
	.machine = &snd_soc_machine_evm,
	.platform = &davinci_soc_platform,
	.codec_dev = &soc_codec_dev_aic3x,
	.codec_data = &evm_aic3x_setup,
};

static struct resource evm_snd_resources[] = {
	{
		.start = DAVINCI_MCBSP_BASE,
		.end = DAVINCI_MCBSP_BASE + SZ_8K - 1,
		.flags = IORESOURCE_MEM,
	},
};

static struct evm_snd_platform_data evm_snd_data = {
	.tx_dma_ch	= DM644X_DMACH_MCBSP_TX,
	.rx_dma_ch	= DM644X_DMACH_MCBSP_RX,
};

static struct platform_device *evm_snd_device;

static int __init evm_init(void)
{
	int ret;

	evm_snd_device = platform_device_alloc("soc-audio", 0);
	if (!evm_snd_device)
		return -ENOMEM;

	platform_set_drvdata(evm_snd_device, &evm_snd_devdata);
	evm_snd_devdata.dev = &evm_snd_device->dev;
	evm_snd_device->dev.platform_data = &evm_snd_data;

	ret = platform_device_add_resources(evm_snd_device, evm_snd_resources,
					    ARRAY_SIZE(evm_snd_resources));
	if (ret) {
		platform_device_put(evm_snd_device);
		return ret;
	}

	ret = platform_device_add(evm_snd_device);
	if (ret)
		platform_device_put(evm_snd_device);

	return ret;
}

static void __exit evm_exit(void)
{
	platform_device_unregister(evm_snd_device);
}

module_init(evm_init);
module_exit(evm_exit);

MODULE_AUTHOR("Vladimir Barinov");
MODULE_DESCRIPTION("TI DAVINCI EVM ASoC driver");
MODULE_LICENSE("GPL");
