// SPDX-License-Identifier: GPL-2.0
/*
 * mtk-soundcard-driver.c  --  MediaTek soundcard driver common
 *
 * Copyright (c) 2022 MediaTek Inc.
 * Author: Trevor Wu <trevor.wu@mediatek.com>
 */

#include <linux/module.h>
#include <linux/of.h>
#include <sound/soc.h>

#include "mtk-soundcard-driver.h"

static int set_card_codec_info(struct snd_soc_card *card,
			       struct device_node *sub_node,
			       struct snd_soc_dai_link *dai_link)
{
	struct device *dev = card->dev;
	struct device_node *codec_node;
	int ret;

	codec_node = of_get_child_by_name(sub_node, "codec");
	if (!codec_node) {
		dev_dbg(dev, "%s no specified codec\n", dai_link->name);
		return 0;
	}

	/* set card codec info */
	ret = snd_soc_of_get_dai_link_codecs(dev, codec_node, dai_link);

	of_node_put(codec_node);

	if (ret < 0)
		return dev_err_probe(dev, ret, "%s: codec dai not found\n",
				     dai_link->name);

	return 0;
}

static int set_dailink_daifmt(struct snd_soc_card *card,
			      struct device_node *sub_node,
			      struct snd_soc_dai_link *dai_link)
{
	unsigned int daifmt;
	const char *str;
	int ret;
	struct {
		char *name;
		unsigned int val;
	} of_clk_table[] = {
		{ "cpu",	SND_SOC_DAIFMT_CBC_CFC },
		{ "codec",	SND_SOC_DAIFMT_CBP_CFP },
	};

	daifmt = snd_soc_daifmt_parse_format(sub_node, NULL);
	if (daifmt) {
		dai_link->dai_fmt &= SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK;
		dai_link->dai_fmt |= daifmt;
	}

	/*
	 * check "mediatek,clk-provider = xxx"
	 * SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK area
	 */
	ret = of_property_read_string(sub_node, "mediatek,clk-provider", &str);
	if (ret == 0) {
		int i;

		for (i = 0; i < ARRAY_SIZE(of_clk_table); i++) {
			if (strcmp(str, of_clk_table[i].name) == 0) {
				dai_link->dai_fmt &= ~SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK;
				dai_link->dai_fmt |= of_clk_table[i].val;
				break;
			}
		}
	}

	return 0;
}

int parse_dai_link_info(struct snd_soc_card *card)
{
	struct device *dev = card->dev;
	struct device_node *sub_node;
	struct snd_soc_dai_link *dai_link;
	const char *dai_link_name;
	int ret, i;

	/* Loop over all the dai link sub nodes */
	for_each_available_child_of_node(dev->of_node, sub_node) {
		if (of_property_read_string(sub_node, "link-name",
					    &dai_link_name)) {
			of_node_put(sub_node);
			return -EINVAL;
		}

		for_each_card_prelinks(card, i, dai_link) {
			if (!strcmp(dai_link_name, dai_link->name))
				break;
		}

		if (i >= card->num_links) {
			of_node_put(sub_node);
			return -EINVAL;
		}

		ret = set_card_codec_info(card, sub_node, dai_link);
		if (ret < 0) {
			of_node_put(sub_node);
			return ret;
		}

		ret = set_dailink_daifmt(card, sub_node, dai_link);
		if (ret < 0) {
			of_node_put(sub_node);
			return ret;
		}
	}

	return 0;
}
EXPORT_SYMBOL_GPL(parse_dai_link_info);

void clean_card_reference(struct snd_soc_card *card)
{
	struct snd_soc_dai_link *dai_link;
	int i;

	/* release codec reference gotten by set_card_codec_info */
	for_each_card_prelinks(card, i, dai_link)
		snd_soc_of_put_dai_link_codecs(dai_link);
}
EXPORT_SYMBOL_GPL(clean_card_reference);
