Skip to content

Commit f2ed6b0

Browse files
mengdonglinbroonie
authored andcommitted
ASoC: Make aux_dev more like a generic component
aux_dev is mainly used by the machine driver to specify analog devices, which are registered as codecs. Making it more like a generic component can help the machine driver to use it to specify any component with topology info by name. Details: - Remove the stub 'rtd_aux' array from the soc card. - Add a list 'aux_comp_list' to store the components of aux_devs. And add a list head 'list_aux' to struct snd_soc_component, for adding such components to the above list. - Add a 'init' ops to a component for machine specific init. soc_bind_aux_dev() will set it to be aux_dev's init. And it will be called when probing the component. - soc_bind_aux_dev() will also search components by name of an aux_dev, since it may not be a codec. - Move probing of aux_devs before checking new DAI links brought by topology. - Move removal of aux_devs later than removal of links. Because topology of aux components may register DAIs and the DAI drivers will go with removal of the aux components, we want soc_remove_link_dais() to remove the DAIs at first. Signed-off-by: Mengdong Lin <[email protected]> Signed-off-by: Mark Brown <[email protected]>
1 parent 68003e6 commit f2ed6b0

File tree

2 files changed

+83
-71
lines changed

2 files changed

+83
-71
lines changed

include/sound/soc.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,7 @@ struct snd_soc_component {
787787
unsigned int registered_as_component:1;
788788

789789
struct list_head list;
790+
struct list_head list_aux; /* for auxiliary component of the card */
790791

791792
struct snd_soc_dai_driver *dai_drv;
792793
int num_dai;
@@ -830,6 +831,9 @@ struct snd_soc_component {
830831
int (*probe)(struct snd_soc_component *);
831832
void (*remove)(struct snd_soc_component *);
832833

834+
/* machine specific init */
835+
int (*init)(struct snd_soc_component *component);
836+
833837
#ifdef CONFIG_DEBUG_FS
834838
void (*init_debugfs)(struct snd_soc_component *component);
835839
const char *debugfs_prefix;
@@ -1130,8 +1134,7 @@ struct snd_soc_card {
11301134
*/
11311135
struct snd_soc_aux_dev *aux_dev;
11321136
int num_aux_devs;
1133-
struct snd_soc_pcm_runtime *rtd_aux;
1134-
int num_aux_rtd;
1137+
struct list_head aux_comp_list;
11351138

11361139
const struct snd_kcontrol_new *controls;
11371140
int num_controls;
@@ -1537,6 +1540,7 @@ static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card)
15371540
INIT_LIST_HEAD(&card->widgets);
15381541
INIT_LIST_HEAD(&card->paths);
15391542
INIT_LIST_HEAD(&card->dapm_list);
1543+
INIT_LIST_HEAD(&card->aux_comp_list);
15401544
}
15411545

15421546
static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc)

sound/soc/soc-core.c

Lines changed: 77 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,6 +1413,16 @@ static int soc_probe_component(struct snd_soc_card *card,
14131413
component->name);
14141414
}
14151415

1416+
/* machine specific init */
1417+
if (component->init) {
1418+
ret = component->init(component);
1419+
if (ret < 0) {
1420+
dev_err(component->dev,
1421+
"Failed to do machine specific init %d\n", ret);
1422+
goto err_probe;
1423+
}
1424+
}
1425+
14161426
if (component->controls)
14171427
snd_soc_add_component_controls(component, component->controls,
14181428
component->num_controls);
@@ -1657,65 +1667,81 @@ static int soc_probe_link_dais(struct snd_soc_card *card,
16571667

16581668
static int soc_bind_aux_dev(struct snd_soc_card *card, int num)
16591669
{
1660-
struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
16611670
struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
1662-
const char *name = aux_dev->codec_name;
1663-
1664-
rtd->component = soc_find_component(aux_dev->codec_of_node, name);
1665-
if (!rtd->component) {
1666-
if (aux_dev->codec_of_node)
1667-
name = of_node_full_name(aux_dev->codec_of_node);
1668-
1669-
dev_err(card->dev, "ASoC: %s not registered\n", name);
1670-
return -EPROBE_DEFER;
1671+
struct snd_soc_component *component;
1672+
const char *name;
1673+
struct device_node *codec_of_node;
1674+
1675+
if (aux_dev->codec_of_node || aux_dev->codec_name) {
1676+
/* codecs, usually analog devices */
1677+
name = aux_dev->codec_name;
1678+
codec_of_node = aux_dev->codec_of_node;
1679+
component = soc_find_component(codec_of_node, name);
1680+
if (!component) {
1681+
if (codec_of_node)
1682+
name = of_node_full_name(codec_of_node);
1683+
goto err_defer;
1684+
}
1685+
} else if (aux_dev->name) {
1686+
/* generic components */
1687+
name = aux_dev->name;
1688+
component = soc_find_component(NULL, name);
1689+
if (!component)
1690+
goto err_defer;
1691+
} else {
1692+
dev_err(card->dev, "ASoC: Invalid auxiliary device\n");
1693+
return -EINVAL;
16711694
}
16721695

1673-
/*
1674-
* Some places still reference rtd->codec, so we have to keep that
1675-
* initialized if the component is a CODEC. Once all those references
1676-
* have been removed, this code can be removed as well.
1677-
*/
1678-
rtd->codec = rtd->component->codec;
1679-
1696+
component->init = aux_dev->init;
1697+
list_add(&component->list_aux, &card->aux_comp_list);
16801698
return 0;
1699+
1700+
err_defer:
1701+
dev_err(card->dev, "ASoC: %s not registered\n", name);
1702+
return -EPROBE_DEFER;
16811703
}
16821704

1683-
static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
1705+
static int soc_probe_aux_devices(struct snd_soc_card *card)
16841706
{
1685-
struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
1686-
struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
1707+
struct snd_soc_component *comp;
1708+
int order;
16871709
int ret;
16881710

1689-
ret = soc_probe_component(card, rtd->component);
1690-
if (ret < 0)
1691-
return ret;
1692-
1693-
/* do machine specific initialization */
1694-
if (aux_dev->init) {
1695-
ret = aux_dev->init(rtd->component);
1696-
if (ret < 0) {
1697-
dev_err(card->dev, "ASoC: failed to init %s: %d\n",
1698-
aux_dev->name, ret);
1699-
return ret;
1711+
for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
1712+
order++) {
1713+
list_for_each_entry(comp, &card->aux_comp_list, list_aux) {
1714+
if (comp->driver->probe_order == order) {
1715+
ret = soc_probe_component(card, comp);
1716+
if (ret < 0) {
1717+
dev_err(card->dev,
1718+
"ASoC: failed to probe aux component %s %d\n",
1719+
comp->name, ret);
1720+
return ret;
1721+
}
1722+
}
17001723
}
17011724
}
17021725

1703-
return soc_post_component_init(rtd, aux_dev->name);
1726+
return 0;
17041727
}
17051728

1706-
static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
1729+
static void soc_remove_aux_devices(struct snd_soc_card *card)
17071730
{
1708-
struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
1709-
struct snd_soc_component *component = rtd->component;
1731+
struct snd_soc_component *comp, *_comp;
1732+
int order;
17101733

1711-
/* unregister the rtd device */
1712-
if (rtd->dev_registered) {
1713-
device_unregister(rtd->dev);
1714-
rtd->dev_registered = 0;
1734+
for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
1735+
order++) {
1736+
list_for_each_entry_safe(comp, _comp,
1737+
&card->aux_comp_list, list_aux) {
1738+
if (comp->driver->remove_order == order) {
1739+
soc_remove_component(comp);
1740+
/* remove it from the card's aux_comp_list */
1741+
list_del(&comp->list_aux);
1742+
}
1743+
}
17151744
}
1716-
1717-
if (component)
1718-
soc_remove_component(component);
17191745
}
17201746

17211747
static int snd_soc_init_codec_cache(struct snd_soc_codec *codec)
@@ -1894,6 +1920,11 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
18941920
}
18951921
}
18961922

1923+
/* probe auxiliary components */
1924+
ret = soc_probe_aux_devices(card);
1925+
if (ret < 0)
1926+
goto probe_dai_err;
1927+
18971928
/* Find new DAI links added during probing components and bind them.
18981929
* Components with topology may bring new DAIs and DAI links.
18991930
*/
@@ -1923,16 +1954,6 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
19231954
}
19241955
}
19251956

1926-
for (i = 0; i < card->num_aux_devs; i++) {
1927-
ret = soc_probe_aux_dev(card, i);
1928-
if (ret < 0) {
1929-
dev_err(card->dev,
1930-
"ASoC: failed to add auxiliary devices %d\n",
1931-
ret);
1932-
goto probe_aux_dev_err;
1933-
}
1934-
}
1935-
19361957
snd_soc_dapm_link_dai_widgets(card);
19371958
snd_soc_dapm_connect_dai_link_widgets(card);
19381959

@@ -1992,8 +2013,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
19922013
return 0;
19932014

19942015
probe_aux_dev_err:
1995-
for (i = 0; i < card->num_aux_devs; i++)
1996-
soc_remove_aux_dev(card, i);
2016+
soc_remove_aux_devices(card);
19972017

19982018
probe_dai_err:
19992019
soc_remove_dai_links(card);
@@ -2039,20 +2059,18 @@ static int soc_probe(struct platform_device *pdev)
20392059
static int soc_cleanup_card_resources(struct snd_soc_card *card)
20402060
{
20412061
struct snd_soc_pcm_runtime *rtd;
2042-
int i;
20432062

20442063
/* make sure any delayed work runs */
20452064
list_for_each_entry(rtd, &card->rtd_list, list)
20462065
flush_delayed_work(&rtd->delayed_work);
20472066

2048-
/* remove auxiliary devices */
2049-
for (i = 0; i < card->num_aux_devs; i++)
2050-
soc_remove_aux_dev(card, i);
2051-
20522067
/* remove and free each DAI */
20532068
soc_remove_dai_links(card);
20542069
soc_remove_pcm_runtimes(card);
20552070

2071+
/* remove auxiliary devices */
2072+
soc_remove_aux_devices(card);
2073+
20562074
soc_cleanup_card_debugfs(card);
20572075

20582076
/* remove the card */
@@ -2608,16 +2626,6 @@ int snd_soc_register_card(struct snd_soc_card *card)
26082626
INIT_LIST_HEAD(&card->rtd_list);
26092627
card->num_rtd = 0;
26102628

2611-
card->rtd_aux = devm_kzalloc(card->dev,
2612-
sizeof(struct snd_soc_pcm_runtime) *
2613-
card->num_aux_devs,
2614-
GFP_KERNEL);
2615-
if (card->rtd_aux == NULL)
2616-
return -ENOMEM;
2617-
2618-
for (i = 0; i < card->num_aux_devs; i++)
2619-
card->rtd_aux[i].card = card;
2620-
26212629
INIT_LIST_HEAD(&card->dapm_dirty);
26222630
INIT_LIST_HEAD(&card->dobj_list);
26232631
card->instantiated = 0;

0 commit comments

Comments
 (0)