/*
 * raumfeld_audio.c  --  SoC audio for Raumfeld audio devices
 *
 * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
 *
 * based on code from:
 *
 *    Wolfson Microelectronics PLC.
 *    Openedhand Ltd.
 *    Liam Girdwood <lrg@slimlogic.co.uk>
 *    Richard Purdie <richard@openedhand.com>
 *
 * 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.
 */

#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <sound/pcm.h>
#include <sound/soc.h>

#include <asm/mach-types.h>

#include "pxa-ssp.h"

#define GPIO_SPDIF_RESET	(38)
#define GPIO_MCLK_RESET		(111)
#define GPIO_CODEC_RESET	(120)

static struct i2c_client *max9486_client;
static struct i2c_board_info max9486_hwmon_info = {
	I2C_BOARD_INFO("max9485", 0x63),
};

#define MAX9485_MCLK_FREQ_112896 0x22
#define MAX9485_MCLK_FREQ_122880 0x23
#define MAX9485_MCLK_FREQ_225792 0x32
#define MAX9485_MCLK_FREQ_245760 0x33

static void set_max9485_clk(char clk)
{
	i2c_master_send(max9486_client, &clk, 1);
}

static void raumfeld_enable_audio(bool en)
{
	if (en) {
		gpio_set_value(GPIO_MCLK_RESET, 1);

		/* wait some time to let the clocks become stable */
		msleep(100);

		gpio_set_value(GPIO_SPDIF_RESET, 1);
		gpio_set_value(GPIO_CODEC_RESET, 1);
	} else {
		gpio_set_value(GPIO_MCLK_RESET, 0);
		gpio_set_value(GPIO_SPDIF_RESET, 0);
		gpio_set_value(GPIO_CODEC_RESET, 0);
	}
}

/* CS4270 */
static int raumfeld_cs4270_startup(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *codec_dai = rtd->codec_dai;

	/* set freq to 0 to enable all possible codec sample rates */
	return snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0);
}

static void raumfeld_cs4270_shutdown(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *codec_dai = rtd->codec_dai;

	/* set freq to 0 to enable all possible codec sample rates */
	snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0);
}

static int raumfeld_cs4270_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_dai *codec_dai = rtd->codec_dai;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
	unsigned int clk = 0;
	int ret = 0;

	switch (params_rate(params)) {
	case 44100:
		set_max9485_clk(MAX9485_MCLK_FREQ_112896);
		clk = 11289600;
		break;
	case 48000:
		set_max9485_clk(MAX9485_MCLK_FREQ_122880);
		clk = 12288000;
		break;
	case 88200:
		set_max9485_clk(MAX9485_MCLK_FREQ_225792);
		clk = 22579200;
		break;
	case 96000:
		set_max9485_clk(MAX9485_MCLK_FREQ_245760);
		clk = 24576000;
		break;
	default:
		return -EINVAL;
	}

	ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk, 0);
	if (ret < 0)
		return ret;

	/* setup the CPU DAI */
	ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, clk);
	if (ret < 0)
		return ret;

	ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_DIV_SCR, 4);
	if (ret < 0)
		return ret;

	ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, clk, 1);
	if (ret < 0)
		return ret;

	return 0;
}

static struct snd_soc_ops raumfeld_cs4270_ops = {
	.startup = raumfeld_cs4270_startup,
	.shutdown = raumfeld_cs4270_shutdown,
	.hw_params = raumfeld_cs4270_hw_params,
};

static int raumfeld_analog_suspend(struct snd_soc_card *card)
{
	raumfeld_enable_audio(false);
	return 0;
}

static int raumfeld_analog_resume(struct snd_soc_card *card)
{
	raumfeld_enable_audio(true);
	return 0;
}

/* AK4104 */

static int raumfeld_ak4104_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_dai *cpu_dai = rtd->cpu_dai;
	int ret = 0, clk = 0;

	switch (params_rate(params)) {
	case 44100:
		set_max9485_clk(MAX9485_MCLK_FREQ_112896);
		clk = 11289600;
		break;
	case 48000:
		set_max9485_clk(MAX9485_MCLK_FREQ_122880);
		clk = 12288000;
		break;
	case 88200:
		set_max9485_clk(MAX9485_MCLK_FREQ_225792);
		clk = 22579200;
		break;
	case 96000:
		set_max9485_clk(MAX9485_MCLK_FREQ_245760);
		clk = 24576000;
		break;
	default:
		return -EINVAL;
	}

	/* setup the CPU DAI */
	ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, clk);
	if (ret < 0)
		return ret;

	ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_DIV_SCR, 4);
	if (ret < 0)
		return ret;

	ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, clk, 1);
	if (ret < 0)
		return ret;

	return 0;
}

static struct snd_soc_ops raumfeld_ak4104_ops = {
	.hw_params = raumfeld_ak4104_hw_params,
};

#define DAI_LINK_CS4270		\
{							\
	.name		= "CS4270",			\
	.stream_name	= "CS4270",			\
	.cpu_dai_name	= "pxa-ssp-dai.0",		\
	.platform_name	= "pxa-pcm-audio",		\
	.codec_dai_name	= "cs4270-hifi",		\
	.codec_name	= "cs4270.0-0048",	\
	.dai_fmt	= SND_SOC_DAIFMT_I2S |		\
			  SND_SOC_DAIFMT_NB_NF |        \
			  SND_SOC_DAIFMT_CBS_CFS,       \
	.ops		= &raumfeld_cs4270_ops,		\
}

#define DAI_LINK_AK4104		\
{							\
	.name		= "ak4104",			\
	.stream_name	= "Playback",			\
	.cpu_dai_name	= "pxa-ssp-dai.1",		\
	.codec_dai_name	= "ak4104-hifi",		\
	.platform_name	= "pxa-pcm-audio",		\
	.dai_fmt	= SND_SOC_DAIFMT_I2S |		\
			  SND_SOC_DAIFMT_NB_NF |	\
			  SND_SOC_DAIFMT_CBS_CFS,       \
	.ops		= &raumfeld_ak4104_ops,		\
	.codec_name	= "spi0.0",			\
}

static struct snd_soc_dai_link snd_soc_raumfeld_connector_dai[] =
{
	DAI_LINK_CS4270,
	DAI_LINK_AK4104,
};

static struct snd_soc_dai_link snd_soc_raumfeld_speaker_dai[] =
{
	DAI_LINK_CS4270,
};

static struct snd_soc_card snd_soc_raumfeld_connector = {
	.name		= "Raumfeld Connector",
	.owner		= THIS_MODULE,
	.dai_link	= snd_soc_raumfeld_connector_dai,
	.num_links	= ARRAY_SIZE(snd_soc_raumfeld_connector_dai),
	.suspend_post	= raumfeld_analog_suspend,
	.resume_pre	= raumfeld_analog_resume,
};

static struct snd_soc_card snd_soc_raumfeld_speaker = {
	.name		= "Raumfeld Speaker",
	.owner		= THIS_MODULE,
	.dai_link	= snd_soc_raumfeld_speaker_dai,
	.num_links	= ARRAY_SIZE(snd_soc_raumfeld_speaker_dai),
	.suspend_post	= raumfeld_analog_suspend,
	.resume_pre	= raumfeld_analog_resume,
};

static struct platform_device *raumfeld_audio_device;

static int __init raumfeld_audio_init(void)
{
	int ret;

	if (!machine_is_raumfeld_speaker() &&
	    !machine_is_raumfeld_connector())
		return 0;

	max9486_client = i2c_new_device(i2c_get_adapter(0),
					&max9486_hwmon_info);

	if (!max9486_client)
		return -ENOMEM;

	set_max9485_clk(MAX9485_MCLK_FREQ_122880);

	/* Register analog device */
	raumfeld_audio_device = platform_device_alloc("soc-audio", 0);
	if (!raumfeld_audio_device)
		return -ENOMEM;

	if (machine_is_raumfeld_speaker())
		platform_set_drvdata(raumfeld_audio_device,
				     &snd_soc_raumfeld_speaker);

	if (machine_is_raumfeld_connector())
		platform_set_drvdata(raumfeld_audio_device,
				     &snd_soc_raumfeld_connector);

	ret = platform_device_add(raumfeld_audio_device);
	if (ret < 0) {
		platform_device_put(raumfeld_audio_device);
		return ret;
	}

	raumfeld_enable_audio(true);
	return 0;
}

static void __exit raumfeld_audio_exit(void)
{
	raumfeld_enable_audio(false);

	platform_device_unregister(raumfeld_audio_device);

	i2c_unregister_device(max9486_client);

	gpio_free(GPIO_MCLK_RESET);
	gpio_free(GPIO_CODEC_RESET);
	gpio_free(GPIO_SPDIF_RESET);
}

module_init(raumfeld_audio_init);
module_exit(raumfeld_audio_exit);

/* Module information */
MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
MODULE_DESCRIPTION("Raumfeld audio SoC");
MODULE_LICENSE("GPL");
