ASoC: simple-card-utils.c: share asoc_graph_parse_dai()

Current Audio Graph Card/Card2 implements asoc_simple_parse_dai()
on each driver, but these are same function.
This patch share it as asoc_graph_parse_dai().

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87o7lihpvy.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Kuninori Morimoto 2023-06-14 00:02:57 +00:00 committed by Mark Brown
parent fd01a15164
commit fed4be313a
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
4 changed files with 110 additions and 212 deletions

View File

@ -195,6 +195,9 @@ int asoc_simple_remove(struct platform_device *pdev);
int asoc_graph_card_probe(struct snd_soc_card *card);
int asoc_graph_is_ports0(struct device_node *port);
int asoc_graph_parse_dai(struct device_node *ep,
struct snd_soc_dai_link_component *dlc,
int *is_single_link);
#ifdef DEBUG
static inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv,

View File

@ -55,60 +55,6 @@ static const struct snd_soc_ops graph_ops = {
.hw_params = asoc_simple_hw_params,
};
static int graph_get_dai_id(struct device_node *ep)
{
struct device_node *node;
struct device_node *endpoint;
struct of_endpoint info;
int i, id;
const u32 *reg;
int ret;
/* use driver specified DAI ID if exist */
ret = snd_soc_get_dai_id(ep);
if (ret != -ENOTSUPP)
return ret;
/* use endpoint/port reg if exist */
ret = of_graph_parse_endpoint(ep, &info);
if (ret == 0) {
/*
* Because it will count port/endpoint if it doesn't have "reg".
* But, we can't judge whether it has "no reg", or "reg = <0>"
* only of_graph_parse_endpoint().
* We need to check "reg" property
*/
if (of_property_present(ep, "reg"))
return info.id;
node = of_get_parent(ep);
reg = of_get_property(node, "reg", NULL);
of_node_put(node);
if (reg)
return info.port;
}
node = of_graph_get_port_parent(ep);
/*
* Non HDMI sound case, counting port/endpoint on its DT
* is enough. Let's count it.
*/
i = 0;
id = -1;
for_each_endpoint_of_node(node, endpoint) {
if (endpoint == ep)
id = i;
i++;
}
of_node_put(node);
if (id < 0)
return -ENODEV;
return id;
}
static bool soc_component_is_pcm(struct snd_soc_dai_link_component *dlc)
{
struct snd_soc_dai *dai = snd_soc_find_dai_with_mutex(dlc);
@ -120,57 +66,6 @@ static bool soc_component_is_pcm(struct snd_soc_dai_link_component *dlc)
return false;
}
static int asoc_simple_parse_dai(struct device_node *ep,
struct snd_soc_dai_link_component *dlc,
int *is_single_link)
{
struct device_node *node;
struct of_phandle_args args;
int ret;
if (!ep)
return 0;
node = of_graph_get_port_parent(ep);
/* Get dai->name */
args.np = node;
args.args[0] = graph_get_dai_id(ep);
args.args_count = (of_graph_get_endpoint_count(node) > 1);
/*
* FIXME
*
* Here, dlc->dai_name is pointer to CPU/Codec DAI name.
* If user unbinded CPU or Codec driver, but not for Sound Card,
* dlc->dai_name is keeping unbinded CPU or Codec
* driver's pointer.
*
* If user re-bind CPU or Codec driver again, ALSA SoC will try
* to rebind Card via snd_soc_try_rebind_card(), but because of
* above reason, it might can't bind Sound Card.
* Because Sound Card is pointing to released dai_name pointer.
*
* To avoid this rebind Card issue,
* 1) It needs to alloc memory to keep dai_name eventhough
* CPU or Codec driver was unbinded, or
* 2) user need to rebind Sound Card everytime
* if he unbinded CPU or Codec.
*/
ret = snd_soc_get_dai_name(&args, &dlc->dai_name);
if (ret < 0) {
of_node_put(node);
return ret;
}
dlc->of_node = node;
if (is_single_link)
*is_single_link = of_graph_get_endpoint_count(node) == 1;
return 0;
}
static void graph_parse_convert(struct device *dev,
struct device_node *ep,
struct asoc_simple_data *adata)
@ -231,7 +126,7 @@ static int graph_parse_node(struct asoc_simple_priv *priv,
graph_parse_mclk_fs(top, ep, dai_props);
ret = asoc_simple_parse_dai(ep, dlc, cpu);
ret = asoc_graph_parse_dai(ep, dlc, cpu);
if (ret < 0)
return ret;

View File

@ -353,111 +353,6 @@ static const struct snd_soc_ops graph_ops = {
.hw_params = asoc_simple_hw_params,
};
static int graph_get_dai_id(struct device_node *ep)
{
struct device_node *node;
struct device_node *endpoint;
struct of_endpoint info;
int i, id;
const u32 *reg;
int ret;
/* use driver specified DAI ID if exist */
ret = snd_soc_get_dai_id(ep);
if (ret != -ENOTSUPP)
return ret;
/* use endpoint/port reg if exist */
ret = of_graph_parse_endpoint(ep, &info);
if (ret == 0) {
/*
* Because it will count port/endpoint if it doesn't have "reg".
* But, we can't judge whether it has "no reg", or "reg = <0>"
* only of_graph_parse_endpoint().
* We need to check "reg" property
*/
if (of_property_present(ep, "reg"))
return info.id;
node = of_get_parent(ep);
reg = of_get_property(node, "reg", NULL);
of_node_put(node);
if (reg)
return info.port;
}
node = of_graph_get_port_parent(ep);
/*
* Non HDMI sound case, counting port/endpoint on its DT
* is enough. Let's count it.
*/
i = 0;
id = -1;
for_each_endpoint_of_node(node, endpoint) {
if (endpoint == ep)
id = i;
i++;
}
of_node_put(node);
if (id < 0)
return -ENODEV;
return id;
}
static int asoc_simple_parse_dai(struct device_node *ep,
struct snd_soc_dai_link_component *dlc,
int *is_single_link)
{
struct device_node *node;
struct of_phandle_args args;
int ret;
if (!ep)
return 0;
node = of_graph_get_port_parent(ep);
/* Get dai->name */
args.np = node;
args.args[0] = graph_get_dai_id(ep);
args.args_count = (of_graph_get_endpoint_count(node) > 1);
/*
* FIXME
*
* Here, dlc->dai_name is pointer to CPU/Codec DAI name.
* If user unbinded CPU or Codec driver, but not for Sound Card,
* dlc->dai_name is keeping unbinded CPU or Codec
* driver's pointer.
*
* If user re-bind CPU or Codec driver again, ALSA SoC will try
* to rebind Card via snd_soc_try_rebind_card(), but because of
* above reason, it might can't bind Sound Card.
* Because Sound Card is pointing to released dai_name pointer.
*
* To avoid this rebind Card issue,
* 1) It needs to alloc memory to keep dai_name eventhough
* CPU or Codec driver was unbinded, or
* 2) user need to rebind Sound Card everytime
* if he unbinded CPU or Codec.
*/
ret = snd_soc_get_dai_name(&args, &dlc->dai_name);
if (ret < 0) {
of_node_put(node);
return ret;
}
dlc->of_node = node;
if (is_single_link)
*is_single_link = of_graph_get_endpoint_count(node) == 1;
return 0;
}
static void graph_parse_convert(struct device_node *ep,
struct simple_dai_props *props)
{
@ -512,7 +407,7 @@ static int __graph_parse_node(struct asoc_simple_priv *priv,
graph_parse_mclk_fs(ep, dai_props);
ret = asoc_simple_parse_dai(ep, dlc, &is_single_links);
ret = asoc_graph_parse_dai(ep, dlc, &is_single_links);
if (ret < 0)
return ret;

View File

@ -1019,6 +1019,111 @@ int asoc_graph_is_ports0(struct device_node *np)
}
EXPORT_SYMBOL_GPL(asoc_graph_is_ports0);
static int graph_get_dai_id(struct device_node *ep)
{
struct device_node *node;
struct device_node *endpoint;
struct of_endpoint info;
int i, id;
int ret;
/* use driver specified DAI ID if exist */
ret = snd_soc_get_dai_id(ep);
if (ret != -ENOTSUPP)
return ret;
/* use endpoint/port reg if exist */
ret = of_graph_parse_endpoint(ep, &info);
if (ret == 0) {
/*
* Because it will count port/endpoint if it doesn't have "reg".
* But, we can't judge whether it has "no reg", or "reg = <0>"
* only of_graph_parse_endpoint().
* We need to check "reg" property
*/
if (of_property_present(ep, "reg"))
return info.id;
node = of_get_parent(ep);
ret = of_property_present(node, "reg");
of_node_put(node);
if (ret)
return info.port;
}
node = of_graph_get_port_parent(ep);
/*
* Non HDMI sound case, counting port/endpoint on its DT
* is enough. Let's count it.
*/
i = 0;
id = -1;
for_each_endpoint_of_node(node, endpoint) {
if (endpoint == ep)
id = i;
i++;
}
of_node_put(node);
if (id < 0)
return -ENODEV;
return id;
}
int asoc_graph_parse_dai(struct device_node *ep,
struct snd_soc_dai_link_component *dlc,
int *is_single_link)
{
struct device_node *node;
struct of_phandle_args args = {};
int ret;
if (!ep)
return 0;
node = of_graph_get_port_parent(ep);
/* Get dai->name */
args.np = node;
args.args[0] = graph_get_dai_id(ep);
args.args_count = (of_graph_get_endpoint_count(node) > 1);
/*
* FIXME
*
* Here, dlc->dai_name is pointer to CPU/Codec DAI name.
* If user unbinded CPU or Codec driver, but not for Sound Card,
* dlc->dai_name is keeping unbinded CPU or Codec
* driver's pointer.
*
* If user re-bind CPU or Codec driver again, ALSA SoC will try
* to rebind Card via snd_soc_try_rebind_card(), but because of
* above reason, it might can't bind Sound Card.
* Because Sound Card is pointing to released dai_name pointer.
*
* To avoid this rebind Card issue,
* 1) It needs to alloc memory to keep dai_name eventhough
* CPU or Codec driver was unbinded, or
* 2) user need to rebind Sound Card everytime
* if he unbinded CPU or Codec.
*/
ret = snd_soc_get_dai_name(&args, &dlc->dai_name);
if (ret < 0) {
of_node_put(node);
return ret;
}
dlc->of_node = node;
if (is_single_link)
*is_single_link = of_graph_get_endpoint_count(node) == 1;
return 0;
}
EXPORT_SYMBOL_GPL(asoc_graph_parse_dai);
/* Module information */
MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
MODULE_DESCRIPTION("ALSA SoC Simple Card Utils");