/*
 * SoC audio for HP iPAQ hx4700
 *
 * Copyright (c) 2009 Philipp Zabel
 *
 *  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/timer.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/gpio.h>

#include <sound/core.h>
#include <sound/jack.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>

#include <mach/hx4700.h>
#include <asm/mach-types.h>
#include "pxa2xx-i2s.h"

#include "../codecs/ak4641.h"

static struct snd_soc_jack hs_jack;

/* Headphones jack detection DAPM pin */
static struct snd_soc_jack_pin hs_jack_pin[] = {
	{
		.pin	= "Headphone Jack",
		.mask	= SND_JACK_HEADPHONE,
	},
	{
		.pin	= "Speaker",
		/* disable speaker when hp jack is inserted */
		.mask   = SND_JACK_HEADPHONE,
		.invert	= 1,
	},
};

/* Headphones jack detection GPIO */
static struct snd_soc_jack_gpio hs_jack_gpio = {
	.gpio		= GPIO75_HX4700_EARPHONE_nDET,
	.invert		= true,
	.name		= "hp-gpio",
	.report		= SND_JACK_HEADPHONE,
	.debounce_time	= 200,
};

/*
 * iPAQ hx4700 uses I2S for capture and playback.
 */
static int hx4700_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;
	int ret = 0;

	/* set the I2S system clock as output */
	ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
			SND_SOC_CLOCK_OUT);
	if (ret < 0)
		return ret;

	/* inform codec driver about clock freq *
	 * (PXA I2S always uses divider 256)    */
	ret = snd_soc_dai_set_sysclk(codec_dai, 0, 256 * params_rate(params),
			SND_SOC_CLOCK_IN);
	if (ret < 0)
		return ret;

	return 0;
}

static struct snd_soc_ops hx4700_ops = {
	.hw_params = hx4700_hw_params,
};

static int hx4700_spk_power(struct snd_soc_dapm_widget *w,
			    struct snd_kcontrol *k, int event)
{
	gpio_set_value(GPIO107_HX4700_SPK_nSD, !!SND_SOC_DAPM_EVENT_ON(event));
	return 0;
}

static int hx4700_hp_power(struct snd_soc_dapm_widget *w,
			   struct snd_kcontrol *k, int event)
{
	gpio_set_value(GPIO92_HX4700_HP_DRIVER, !!SND_SOC_DAPM_EVENT_ON(event));
	return 0;
}

/* hx4700 machine dapm widgets */
static const struct snd_soc_dapm_widget hx4700_dapm_widgets[] = {
	SND_SOC_DAPM_HP("Headphone Jack", hx4700_hp_power),
	SND_SOC_DAPM_SPK("Speaker", hx4700_spk_power),
	SND_SOC_DAPM_MIC("Built-in Microphone", NULL),
};

/* hx4700 machine audio_map */
static const struct snd_soc_dapm_route hx4700_audio_map[] = {

	/* Headphone connected to LOUT, ROUT */
	{"Headphone Jack", NULL, "LOUT"},
	{"Headphone Jack", NULL, "ROUT"},

	/* Speaker connected to MOUT2 */
	{"Speaker", NULL, "MOUT2"},

	/* Microphone connected to MICIN */
	{"MICIN", NULL, "Built-in Microphone"},
	{"AIN", NULL, "MICOUT"},
};

/*
 * Logic for a ak4641 as connected on a HP iPAQ hx4700
 */
static int hx4700_ak4641_init(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_dapm_context *dapm = &codec->dapm;
	int err;

	/* NC codec pins */
	/* FIXME: is anything connected here? */
	snd_soc_dapm_nc_pin(dapm, "MOUT1");
	snd_soc_dapm_nc_pin(dapm, "MICEXT");
	snd_soc_dapm_nc_pin(dapm, "AUX");

	/* Jack detection API stuff */
	err = snd_soc_jack_new(codec, "Headphone Jack",
				SND_JACK_HEADPHONE, &hs_jack);
	if (err)
		return err;

	err = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pin),
					hs_jack_pin);
	if (err)
		return err;

	err = snd_soc_jack_add_gpios(&hs_jack, 1, &hs_jack_gpio);

	return err;
}

static int hx4700_card_remove(struct snd_soc_card *card)
{
	snd_soc_jack_free_gpios(&hs_jack, 1, &hs_jack_gpio);

	return 0;
}

/* hx4700 digital audio interface glue - connects codec <--> CPU */
static struct snd_soc_dai_link hx4700_dai = {
	.name = "ak4641",
	.stream_name = "AK4641",
	.cpu_dai_name = "pxa2xx-i2s",
	.codec_dai_name = "ak4641-hifi",
	.platform_name = "pxa-pcm-audio",
	.codec_name = "ak4641.0-0012",
	.init = hx4700_ak4641_init,
	.dai_fmt = SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF |
		   SND_SOC_DAIFMT_CBS_CFS,
	.ops = &hx4700_ops,
};

/* hx4700 audio machine driver */
static struct snd_soc_card snd_soc_card_hx4700 = {
	.name			= "iPAQ hx4700",
	.owner			= THIS_MODULE,
	.remove			= hx4700_card_remove,
	.dai_link		= &hx4700_dai,
	.num_links		= 1,
	.dapm_widgets		= hx4700_dapm_widgets,
	.num_dapm_widgets	= ARRAY_SIZE(hx4700_dapm_widgets),
	.dapm_routes		= hx4700_audio_map,
	.num_dapm_routes	= ARRAY_SIZE(hx4700_audio_map),
};

static struct gpio hx4700_audio_gpios[] = {
	{ GPIO107_HX4700_SPK_nSD, GPIOF_OUT_INIT_HIGH, "SPK_POWER" },
	{ GPIO92_HX4700_HP_DRIVER, GPIOF_OUT_INIT_LOW, "EP_POWER" },
};

static int hx4700_audio_probe(struct platform_device *pdev)
{
	int ret;

	if (!machine_is_h4700())
		return -ENODEV;

	ret = gpio_request_array(hx4700_audio_gpios,
				ARRAY_SIZE(hx4700_audio_gpios));
	if (ret)
		return ret;

	snd_soc_card_hx4700.dev = &pdev->dev;
	ret = snd_soc_register_card(&snd_soc_card_hx4700);
	if (ret)
		gpio_free_array(hx4700_audio_gpios,
				ARRAY_SIZE(hx4700_audio_gpios));

	return ret;
}

static int hx4700_audio_remove(struct platform_device *pdev)
{
	snd_soc_unregister_card(&snd_soc_card_hx4700);

	gpio_set_value(GPIO92_HX4700_HP_DRIVER, 0);
	gpio_set_value(GPIO107_HX4700_SPK_nSD, 0);

	gpio_free_array(hx4700_audio_gpios, ARRAY_SIZE(hx4700_audio_gpios));
	return 0;
}

static struct platform_driver hx4700_audio_driver = {
	.driver	= {
		.name = "hx4700-audio",
		.owner = THIS_MODULE,
		.pm = &snd_soc_pm_ops,
	},
	.probe	= hx4700_audio_probe,
	.remove	= hx4700_audio_remove,
};

module_platform_driver(hx4700_audio_driver);

MODULE_AUTHOR("Philipp Zabel");
MODULE_DESCRIPTION("ALSA SoC iPAQ hx4700");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:hx4700-audio");
