aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Reichel <sre@kernel.org>2014-04-28 10:07:22 -0400
committerMark Brown <broonie@linaro.org>2014-05-01 13:56:45 -0400
commit3ca041ed04734c1709460184f985f5451a813d69 (patch)
tree49e48b52a78cce6a918d213b53cd591229c6d1e0
parentc9eaa447e77efe77b7fa4c953bd62de8297fd6c5 (diff)
ASoC: dt: Allow Aux Codecs to be specified using DT
This patch adds support for specifying auxiliary codecs and codec configuration via device tree phandles. This change adds new fields to snd_soc_aux_dev and snd_soc_codec_conf and adds support for the changes to SoC core methods. Signed-off-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Sebastian Reichel <sre@kernel.org> Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r--include/sound/soc.h13
-rw-r--r--sound/soc/soc-core.c68
2 files changed, 54 insertions, 27 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 0b83168d8ff4..d371ae1c7279 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -931,7 +931,12 @@ struct snd_soc_dai_link {
931}; 931};
932 932
933struct snd_soc_codec_conf { 933struct snd_soc_codec_conf {
934 /*
935 * specify device either by device name, or by
936 * DT/OF node, but not both.
937 */
934 const char *dev_name; 938 const char *dev_name;
939 const struct device_node *of_node;
935 940
936 /* 941 /*
937 * optional map of kcontrol, widget and path name prefixes that are 942 * optional map of kcontrol, widget and path name prefixes that are
@@ -942,7 +947,13 @@ struct snd_soc_codec_conf {
942 947
943struct snd_soc_aux_dev { 948struct snd_soc_aux_dev {
944 const char *name; /* Codec name */ 949 const char *name; /* Codec name */
945 const char *codec_name; /* for multi-codec */ 950
951 /*
952 * specify multi-codec either by device name, or by
953 * DT/OF node, but not both.
954 */
955 const char *codec_name;
956 const struct device_node *codec_of_node;
946 957
947 /* codec/machine specific init - e.g. add machine controls */ 958 /* codec/machine specific init - e.g. add machine controls */
948 int (*init)(struct snd_soc_dapm_context *dapm); 959 int (*init)(struct snd_soc_dapm_context *dapm);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 051c006281f5..448a60748523 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1104,10 +1104,12 @@ static void soc_set_name_prefix(struct snd_soc_card *card,
1104 1104
1105 for (i = 0; i < card->num_configs; i++) { 1105 for (i = 0; i < card->num_configs; i++) {
1106 struct snd_soc_codec_conf *map = &card->codec_conf[i]; 1106 struct snd_soc_codec_conf *map = &card->codec_conf[i];
1107 if (map->dev_name && !strcmp(codec->name, map->dev_name)) { 1107 if (map->of_node && codec->dev->of_node != map->of_node)
1108 codec->name_prefix = map->name_prefix; 1108 continue;
1109 break; 1109 if (map->dev_name && strcmp(codec->name, map->dev_name))
1110 } 1110 continue;
1111 codec->name_prefix = map->name_prefix;
1112 break;
1111 } 1113 }
1112} 1114}
1113 1115
@@ -1541,52 +1543,66 @@ static void soc_unregister_ac97_dai_link(struct snd_soc_codec *codec)
1541} 1543}
1542#endif 1544#endif
1543 1545
1544static int soc_check_aux_dev(struct snd_soc_card *card, int num) 1546struct snd_soc_codec *soc_find_matching_codec(struct snd_soc_card *card, int num)
1545{ 1547{
1546 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; 1548 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
1547 struct snd_soc_codec *codec; 1549 struct snd_soc_codec *codec;
1548 1550
1549 /* find CODEC from registered CODECs*/ 1551 /* find CODEC from registered CODECs */
1550 list_for_each_entry(codec, &codec_list, list) { 1552 list_for_each_entry(codec, &codec_list, list) {
1551 if (!strcmp(codec->name, aux_dev->codec_name)) 1553 if (aux_dev->codec_of_node &&
1552 return 0; 1554 (codec->dev->of_node != aux_dev->codec_of_node))
1555 continue;
1556 if (aux_dev->codec_name && strcmp(codec->name, aux_dev->codec_name))
1557 continue;
1558 return codec;
1553 } 1559 }
1554 1560
1555 dev_err(card->dev, "ASoC: %s not registered\n", aux_dev->codec_name); 1561 return NULL;
1562}
1563
1564static int soc_check_aux_dev(struct snd_soc_card *card, int num)
1565{
1566 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
1567 const char *codecname = aux_dev->codec_name;
1568 struct snd_soc_codec *codec = soc_find_matching_codec(card, num);
1556 1569
1570 if (codec)
1571 return 0;
1572 if (aux_dev->codec_of_node)
1573 codecname = of_node_full_name(aux_dev->codec_of_node);
1574
1575 dev_err(card->dev, "ASoC: %s not registered\n", codecname);
1557 return -EPROBE_DEFER; 1576 return -EPROBE_DEFER;
1558} 1577}
1559 1578
1560static int soc_probe_aux_dev(struct snd_soc_card *card, int num) 1579static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
1561{ 1580{
1562 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; 1581 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
1563 struct snd_soc_codec *codec; 1582 const char *codecname = aux_dev->codec_name;
1564 int ret = -ENODEV; 1583 int ret = -ENODEV;
1584 struct snd_soc_codec *codec = soc_find_matching_codec(card, num);
1565 1585
1566 /* find CODEC from registered CODECs*/ 1586 if (!codec) {
1567 list_for_each_entry(codec, &codec_list, list) { 1587 if (aux_dev->codec_of_node)
1568 if (!strcmp(codec->name, aux_dev->codec_name)) { 1588 codecname = of_node_full_name(aux_dev->codec_of_node);
1569 if (codec->probed) { 1589
1570 dev_err(codec->dev, 1590 /* codec not found */
1571 "ASoC: codec already probed"); 1591 dev_err(card->dev, "ASoC: codec %s not found", codecname);
1572 ret = -EBUSY; 1592 return -EPROBE_DEFER;
1573 goto out; 1593 }
1574 } 1594
1575 goto found; 1595 if (codec->probed) {
1576 } 1596 dev_err(codec->dev, "ASoC: codec already probed");
1597 return -EBUSY;
1577 } 1598 }
1578 /* codec not found */
1579 dev_err(card->dev, "ASoC: codec %s not found", aux_dev->codec_name);
1580 return -EPROBE_DEFER;
1581 1599
1582found:
1583 ret = soc_probe_codec(card, codec); 1600 ret = soc_probe_codec(card, codec);
1584 if (ret < 0) 1601 if (ret < 0)
1585 return ret; 1602 return ret;
1586 1603
1587 ret = soc_post_component_init(card, codec, num, 1); 1604 ret = soc_post_component_init(card, codec, num, 1);
1588 1605
1589out:
1590 return ret; 1606 return ret;
1591} 1607}
1592 1608