// SPDX-License-Identifier: GPL-2.0-only
/*
 * linux/sound/soc/pxa/z2.c
 *
 * SoC Audio driver for Aeronix Zipit Z2
 *
 * Copyright (C) 2009 Ken McGuire <kenm@desertweyr.com>
 * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com>
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>

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

#include <asm/mach-types.h>
#include <mach/hardware.h>
#include <mach/audio.h>
#include <mach/z2.h>

#include "../codecs/wm8750.h"
#include "pxa2xx-i2s.h"

static struct snd_soc_card snd_soc_z2;

static int z2_hw_params(struct snd_pcm_substream *substream,
	struct snd_pcm_hw_params *params)
{
	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
	unsigned int clk = 0;
	int ret = 0;

	switch (params_rate(params)) {
	case 8000:
	case 16000:
	case 48000:
	case 96000:
		clk = 12288000;
		break;
	case 11025:
	case 22050:
	case 44100:
		clk = 11289600;
		break;
	}

	/* set the codec system clock for DAC and ADC */
	ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk,
		SND_SOC_CLOCK_IN);
	if (ret < 0)
		return ret;

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

	return 0;
}

static struct snd_soc_jack hs_jack;

/* Headset jack detection DAPM pins */
static struct snd_soc_jack_pin hs_jack_pins[] = {
	{
		.pin	= "Mic Jack",
		.mask	= SND_JACK_MICROPHONE,
	},
	{
		.pin	= "Headphone Jack",
		.mask	= SND_JACK_HEADPHONE,
	},
	{
		.pin    = "Ext Spk",
		.mask   = SND_JACK_HEADPHONE,
		.invert = 1
	},
};

/* Headset jack detection gpios */
static struct snd_soc_jack_gpio hs_jack_gpios[] = {
	{
		.gpio		= GPIO37_ZIPITZ2_HEADSET_DETECT,
		.name		= "hsdet-gpio",
		.report		= SND_JACK_HEADSET,
		.debounce_time	= 200,
		.invert		= 1,
	},
};

/* z2 machine dapm widgets */
static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = {
	SND_SOC_DAPM_HP("Headphone Jack", NULL),
	SND_SOC_DAPM_MIC("Mic Jack", NULL),
	SND_SOC_DAPM_SPK("Ext Spk", NULL),

	/* headset is a mic and mono headphone */
	SND_SOC_DAPM_HP("Headset Jack", NULL),
};

/* Z2 machine audio_map */
static const struct snd_soc_dapm_route z2_audio_map[] = {

	/* headphone connected to LOUT1, ROUT1 */
	{"Headphone Jack", NULL, "LOUT1"},
	{"Headphone Jack", NULL, "ROUT1"},

	/* ext speaker connected to LOUT2, ROUT2  */
	{"Ext Spk", NULL, "ROUT2"},
	{"Ext Spk", NULL, "LOUT2"},

	/* mic is connected to R input 2 - with bias */
	{"RINPUT2", NULL, "Mic Bias"},
	{"Mic Bias", NULL, "Mic Jack"},
};

/*
 * Logic for a wm8750 as connected on a Z2 Device
 */
static int z2_wm8750_init(struct snd_soc_pcm_runtime *rtd)
{
	int ret;

	/* Jack detection API stuff */
	ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", SND_JACK_HEADSET,
				    &hs_jack, hs_jack_pins,
				    ARRAY_SIZE(hs_jack_pins));
	if (ret)
		goto err;

	ret = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios),
				hs_jack_gpios);
	if (ret)
		goto err;

	return 0;

err:
	return ret;
}

static const struct snd_soc_ops z2_ops = {
	.hw_params = z2_hw_params,
};

/* z2 digital audio interface glue - connects codec <--> CPU */
SND_SOC_DAILINK_DEFS(wm8750,
	DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-i2s")),
	DAILINK_COMP_ARRAY(COMP_CODEC("wm8750.0-001b", "wm8750-hifi")),
	DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));

static struct snd_soc_dai_link z2_dai = {
	.name		= "wm8750",
	.stream_name	= "WM8750",
	.init		= z2_wm8750_init,
	.dai_fmt	= SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
			  SND_SOC_DAIFMT_CBS_CFS,
	.ops		= &z2_ops,
	SND_SOC_DAILINK_REG(wm8750),
};

/* z2 audio machine driver */
static struct snd_soc_card snd_soc_z2 = {
	.name		= "Z2",
	.owner		= THIS_MODULE,
	.dai_link	= &z2_dai,
	.num_links	= 1,

	.dapm_widgets = wm8750_dapm_widgets,
	.num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets),
	.dapm_routes = z2_audio_map,
	.num_dapm_routes = ARRAY_SIZE(z2_audio_map),
	.fully_routed = true,
};

static struct platform_device *z2_snd_device;

static int __init z2_init(void)
{
	int ret;

	if (!machine_is_zipit2())
		return -ENODEV;

	z2_snd_device = platform_device_alloc("soc-audio", -1);
	if (!z2_snd_device)
		return -ENOMEM;

	platform_set_drvdata(z2_snd_device, &snd_soc_z2);
	ret = platform_device_add(z2_snd_device);

	if (ret)
		platform_device_put(z2_snd_device);

	return ret;
}

static void __exit z2_exit(void)
{
	platform_device_unregister(z2_snd_device);
}

module_init(z2_init);
module_exit(z2_exit);

MODULE_AUTHOR("Ken McGuire <kenm@desertweyr.com>, "
		"Marek Vasut <marek.vasut@gmail.com>");
MODULE_DESCRIPTION("ALSA SoC ZipitZ2");
MODULE_LICENSE("GPL");
