From 49950d606ad7cb5a7870bb29d831fbd8c4d102a3 Mon Sep 17 00:00:00 2001 From: Xing Zheng Date: Tue, 24 Jul 2018 23:17:38 +0800 Subject: [PATCH] ASoC: rockchip: multicodecs: add support property 'rockchip,wait-card-locked' Some times, we would like to specify the order of loading sound card, and can use this property to wait other sound cards are locked. Therefore, this sound card with the property should be slave card. Change-Id: I3dcd77a527ad902a5a3c00bcce2c81cf6e782549 Signed-off-by: Xing Zheng --- sound/soc/rockchip/rockchip_multicodecs.c | 61 +++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/sound/soc/rockchip/rockchip_multicodecs.c b/sound/soc/rockchip/rockchip_multicodecs.c index e40be38cbc1b..517d081abac8 100644 --- a/sound/soc/rockchip/rockchip_multicodecs.c +++ b/sound/soc/rockchip/rockchip_multicodecs.c @@ -33,6 +33,7 @@ #define DRV_NAME "rk-multicodecs" #define MAX_CODECS 2 +#define WAIT_CARDS (SNDRV_CARDS - 1) #define DEFAULT_MCLK_FS 256 struct multicodecs_data { @@ -142,6 +143,60 @@ static int rk_multicodecs_parse_daifmt(struct device_node *node, return 0; } +static int wait_locked_card(struct device_node *np, struct device *dev) +{ + char *propname = "rockchip,wait-card-locked"; + u32 cards[WAIT_CARDS]; + int num, i; + int ret; + + ret = of_property_count_u32_elems(np, propname); + if (ret < 0) { + if (ret == -EINVAL) { + /* + * -EINVAL means the property does not exist, this is + * fine. + */ + return 0; + } + + dev_err(dev, "Property '%s' elems could not be read: %d\n", + propname, ret); + return ret; + } + + num = ret; + if (num > WAIT_CARDS) + num = WAIT_CARDS; + + ret = of_property_read_u32_array(np, propname, cards, num); + if (ret < 0) { + if (ret == -EINVAL) { + /* + * -EINVAL means the property does not exist, this is + * fine. + */ + return 0; + } + + dev_err(dev, "Property '%s' could not be read: %d\n", + propname, ret); + return ret; + } + + ret = 0; + for (i = 0; i < num; i++) { + if (!snd_card_locked(cards[i])) { + dev_warn(dev, "card: %d has not been locked, re-probe again\n", + cards[i]); + ret = -EPROBE_DEFER; + break; + } + } + + return ret; +} + static struct snd_soc_ops rk_ops = { .hw_params = rk_multicodecs_hw_params, }; @@ -160,6 +215,12 @@ static int rk_multicodecs_probe(struct platform_device *pdev) int ret = 0, i = 0, idx = 0; const char *prefix = "rockchip,"; + ret = wait_locked_card(np, &pdev->dev); + if (ret < 0) { + dev_err(&pdev->dev, "check_lock_card failed: %d\n", ret); + return ret; + } + mc_data = devm_kzalloc(&pdev->dev, sizeof(*mc_data), GFP_KERNEL); if (!mc_data) return -ENOMEM;