diff options
author | Sebastian Reichel <sre@kernel.org> | 2014-04-28 10:07:22 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-05-01 13:56:45 -0400 |
commit | 3ca041ed04734c1709460184f985f5451a813d69 (patch) | |
tree | 49e48b52a78cce6a918d213b53cd591229c6d1e0 | |
parent | c9eaa447e77efe77b7fa4c953bd62de8297fd6c5 (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.h | 13 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 68 |
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 | ||
933 | struct snd_soc_codec_conf { | 933 | struct 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 | ||
943 | struct snd_soc_aux_dev { | 948 | struct 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 | ||
1544 | static int soc_check_aux_dev(struct snd_soc_card *card, int num) | 1546 | struct 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 | |||
1564 | static 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 | ||
1560 | static int soc_probe_aux_dev(struct snd_soc_card *card, int num) | 1579 | static 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 | ||
1582 | found: | ||
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 | ||
1589 | out: | ||
1590 | return ret; | 1606 | return ret; |
1591 | } | 1607 | } |
1592 | 1608 | ||