int asoc_simple_card_parse_dai(struct device_node *node, struct device_node **dai_of_node, const char **dai_name, const char *list_name, const char *cells_name, int *is_single_link) { struct of_phandle_args args; int ret; if (!node) return 0; /* * Get node via "sound-dai = <&phandle port>" * it will be used as xxx_of_node on soc_bind_dai_link() */ ret = of_parse_phandle_with_args(node, list_name, cells_name, 0, &args); if (ret) return ret; /* Get dai->name */ if (dai_name) { ret = snd_soc_of_get_dai_name(node, dai_name); if (ret < 0) return ret; } *dai_of_node = args.np; if (is_single_link) *is_single_link = !args.args_count; return 0; }
static int asoc_simple_card_sub_parse_of(struct device_node *np, struct asoc_simple_dai *dai, struct device_node **p_node, const char **name, int *args_count) { struct of_phandle_args args; struct clk *clk; u32 val; int ret; /* * Get node via "sound-dai = <&phandle port>" * it will be used as xxx_of_node on soc_bind_dai_link() */ ret = of_parse_phandle_with_args(np, "sound-dai", "#sound-dai-cells", 0, &args); if (ret) return ret; *p_node = args.np; if (args_count) *args_count = args.args_count; /* Get dai->name */ ret = snd_soc_of_get_dai_name(np, name); if (ret < 0) return ret; /* Parse TDM slot */ ret = snd_soc_of_parse_tdm_slot(np, &dai->slots, &dai->slot_width); if (ret) return ret; /* * Parse dai->sysclk come from "clocks = <&xxx>" * (if system has common clock) * or "system-clock-frequency = <xxx>" * or device's module clock. */ if (of_property_read_bool(np, "clocks")) { clk = of_clk_get(np, 0); if (IS_ERR(clk)) { ret = PTR_ERR(clk); return ret; } dai->sysclk = clk_get_rate(clk); } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) { dai->sysclk = val; } else { clk = of_clk_get(args.np, 0); if (!IS_ERR(clk)) dai->sysclk = clk_get_rate(clk); } return 0; }
static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card) { struct device *dev = card->dev; struct snd_soc_dai_link *link; struct device_node *np, *codec, *cpu, *node = dev->of_node; struct apq8016_sbc_data *data; int ret, num_links; ret = snd_soc_of_parse_card_name(card, "qcom,model"); if (ret) { dev_err(dev, "Error parsing card name: %d\n", ret); return ERR_PTR(ret); } /* DAPM routes */ if (of_property_read_bool(node, "qcom,audio-routing")) { ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing"); if (ret) return ERR_PTR(ret); } /* Populate links */ num_links = of_get_child_count(node); /* Allocate the private data and the DAI link array */ data = devm_kzalloc(dev, sizeof(*data) + sizeof(*link) * num_links, GFP_KERNEL); if (!data) return ERR_PTR(-ENOMEM); card->dai_link = &data->dai_link[0]; card->num_links = num_links; link = data->dai_link; for_each_child_of_node(node, np) { cpu = of_get_child_by_name(np, "cpu"); codec = of_get_child_by_name(np, "codec"); if (!cpu || !codec) { dev_err(dev, "Can't find cpu/codec DT node\n"); return ERR_PTR(-EINVAL); } link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0); if (!link->cpu_of_node) { dev_err(card->dev, "error getting cpu phandle\n"); return ERR_PTR(-EINVAL); } link->codec_of_node = of_parse_phandle(codec, "sound-dai", 0); if (!link->codec_of_node) { dev_err(card->dev, "error getting codec phandle\n"); return ERR_PTR(-EINVAL); } ret = snd_soc_of_get_dai_name(cpu, &link->cpu_dai_name); if (ret) { dev_err(card->dev, "error getting cpu dai name\n"); return ERR_PTR(ret); } ret = snd_soc_of_get_dai_name(codec, &link->codec_dai_name); if (ret) { dev_err(card->dev, "error getting codec dai name\n"); return ERR_PTR(ret); } link->platform_of_node = link->cpu_of_node; ret = of_property_read_string(np, "link-name", &link->name); if (ret) { dev_err(card->dev, "error getting codec dai_link name\n"); return ERR_PTR(ret); } link->stream_name = link->name; link->init = apq8016_sbc_dai_init; link++; }