/*
 * ASoC machine driver for Snow boards
 *
 * 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.
 *
 * 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.
 */

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>

#include <sound/soc.h>

#include "i2s.h"

#define FIN_PLL_RATE		24000000

static struct snd_soc_dai_link snow_dai[] = {
	{
		.name = "Primary",
		.stream_name = "Primary",
		.codec_dai_name = "HiFi",
		.dai_fmt = SND_SOC_DAIFMT_I2S |
				SND_SOC_DAIFMT_NB_NF |
				SND_SOC_DAIFMT_CBS_CFS,
	},
};

static int snow_late_probe(struct snd_soc_card *card)
{
	struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
	struct snd_soc_dai *cpu_dai = card->rtd[0].cpu_dai;
	int ret;

	/* Set the MCLK rate for the codec */
	ret = snd_soc_dai_set_sysclk(codec_dai, 0,
					FIN_PLL_RATE, SND_SOC_CLOCK_IN);
	if (ret < 0)
		return ret;

	/* Select I2S Bus clock to set RCLK and BCLK */
	ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_RCLKSRC_0,
					0, SND_SOC_CLOCK_IN);
	if (ret < 0)
		return ret;

	return 0;
}

static struct snd_soc_card snow_snd = {
	.name = "Snow-I2S",
	.owner = THIS_MODULE,
	.dai_link = snow_dai,
	.num_links = ARRAY_SIZE(snow_dai),

	.late_probe = snow_late_probe,
};

static int snow_probe(struct platform_device *pdev)
{
	struct snd_soc_card *card = &snow_snd;
	struct device_node *i2s_node, *codec_node;
	int i, ret;

	i2s_node = of_parse_phandle(pdev->dev.of_node,
				    "samsung,i2s-controller", 0);
	if (!i2s_node) {
		dev_err(&pdev->dev,
			"Property 'i2s-controller' missing or invalid\n");
		return -EINVAL;
	}

	codec_node = of_parse_phandle(pdev->dev.of_node,
				      "samsung,audio-codec", 0);
	if (!codec_node) {
		dev_err(&pdev->dev,
			"Property 'audio-codec' missing or invalid\n");
		return -EINVAL;
	}

	for (i = 0; i < ARRAY_SIZE(snow_dai); i++) {
		snow_dai[i].codec_of_node = codec_node;
		snow_dai[i].cpu_of_node = i2s_node;
		snow_dai[i].platform_of_node = i2s_node;
	}

	card->dev = &pdev->dev;

	/* Update card-name if provided through DT, else use default name */
	snd_soc_of_parse_card_name(card, "samsung,model");

	ret = devm_snd_soc_register_card(&pdev->dev, card);
	if (ret) {
		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
		return ret;
	}

	return ret;
}

static const struct of_device_id snow_of_match[] = {
	{ .compatible = "google,snow-audio-max98090", },
	{ .compatible = "google,snow-audio-max98091", },
	{ .compatible = "google,snow-audio-max98095", },
	{},
};
MODULE_DEVICE_TABLE(of, snow_of_match);

static struct platform_driver snow_driver = {
	.driver = {
		.name = "snow-audio",
		.pm = &snd_soc_pm_ops,
		.of_match_table = snow_of_match,
	},
	.probe = snow_probe,
};

module_platform_driver(snow_driver);

MODULE_DESCRIPTION("ALSA SoC Audio machine driver for Snow");
MODULE_LICENSE("GPL");
