cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

common.c (4298B)


      1// SPDX-License-Identifier: GPL-2.0
      2// Copyright (c) 2018, Linaro Limited.
      3// Copyright (c) 2018, The Linux Foundation. All rights reserved.
      4
      5#include <linux/module.h>
      6#include "common.h"
      7
      8int qcom_snd_parse_of(struct snd_soc_card *card)
      9{
     10	struct device_node *np;
     11	struct device_node *codec = NULL;
     12	struct device_node *platform = NULL;
     13	struct device_node *cpu = NULL;
     14	struct device *dev = card->dev;
     15	struct snd_soc_dai_link *link;
     16	struct of_phandle_args args;
     17	struct snd_soc_dai_link_component *dlc;
     18	int ret, num_links;
     19
     20	ret = snd_soc_of_parse_card_name(card, "model");
     21	if (ret == 0 && !card->name)
     22		/* Deprecated, only for compatibility with old device trees */
     23		ret = snd_soc_of_parse_card_name(card, "qcom,model");
     24	if (ret) {
     25		dev_err(dev, "Error parsing card name: %d\n", ret);
     26		return ret;
     27	}
     28
     29	if (of_property_read_bool(dev->of_node, "widgets")) {
     30		ret = snd_soc_of_parse_audio_simple_widgets(card, "widgets");
     31		if (ret)
     32			return ret;
     33	}
     34
     35	/* DAPM routes */
     36	if (of_property_read_bool(dev->of_node, "audio-routing")) {
     37		ret = snd_soc_of_parse_audio_routing(card, "audio-routing");
     38		if (ret)
     39			return ret;
     40	}
     41	/* Deprecated, only for compatibility with old device trees */
     42	if (of_property_read_bool(dev->of_node, "qcom,audio-routing")) {
     43		ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing");
     44		if (ret)
     45			return ret;
     46	}
     47
     48	ret = snd_soc_of_parse_pin_switches(card, "pin-switches");
     49	if (ret)
     50		return ret;
     51
     52	ret = snd_soc_of_parse_aux_devs(card, "aux-devs");
     53	if (ret)
     54		return ret;
     55
     56	/* Populate links */
     57	num_links = of_get_available_child_count(dev->of_node);
     58
     59	/* Allocate the DAI link array */
     60	card->dai_link = devm_kcalloc(dev, num_links, sizeof(*link), GFP_KERNEL);
     61	if (!card->dai_link)
     62		return -ENOMEM;
     63
     64	card->num_links = num_links;
     65	link = card->dai_link;
     66
     67	for_each_available_child_of_node(dev->of_node, np) {
     68		dlc = devm_kzalloc(dev, 2 * sizeof(*dlc), GFP_KERNEL);
     69		if (!dlc) {
     70			ret = -ENOMEM;
     71			goto err_put_np;
     72		}
     73
     74		link->cpus	= &dlc[0];
     75		link->platforms	= &dlc[1];
     76
     77		link->num_cpus		= 1;
     78		link->num_platforms	= 1;
     79
     80		ret = of_property_read_string(np, "link-name", &link->name);
     81		if (ret) {
     82			dev_err(card->dev, "error getting codec dai_link name\n");
     83			goto err_put_np;
     84		}
     85
     86		cpu = of_get_child_by_name(np, "cpu");
     87		platform = of_get_child_by_name(np, "platform");
     88		codec = of_get_child_by_name(np, "codec");
     89
     90		if (!cpu) {
     91			dev_err(dev, "%s: Can't find cpu DT node\n", link->name);
     92			ret = -EINVAL;
     93			goto err;
     94		}
     95
     96		ret = of_parse_phandle_with_args(cpu, "sound-dai",
     97					"#sound-dai-cells", 0, &args);
     98		if (ret) {
     99			dev_err(card->dev, "%s: error getting cpu phandle\n", link->name);
    100			goto err;
    101		}
    102		link->cpus->of_node = args.np;
    103		link->id = args.args[0];
    104
    105		ret = snd_soc_of_get_dai_name(cpu, &link->cpus->dai_name);
    106		if (ret) {
    107			dev_err_probe(card->dev, ret,
    108				      "%s: error getting cpu dai name\n", link->name);
    109			goto err;
    110		}
    111
    112		if (platform) {
    113			link->platforms->of_node = of_parse_phandle(platform,
    114					"sound-dai",
    115					0);
    116			if (!link->platforms->of_node) {
    117				dev_err(card->dev, "%s: platform dai not found\n", link->name);
    118				ret = -EINVAL;
    119				goto err;
    120			}
    121		} else {
    122			link->platforms->of_node = link->cpus->of_node;
    123		}
    124
    125		if (codec) {
    126			ret = snd_soc_of_get_dai_link_codecs(dev, codec, link);
    127			if (ret < 0) {
    128				dev_err_probe(card->dev, ret,
    129					      "%s: codec dai not found\n", link->name);
    130				goto err;
    131			}
    132
    133			if (platform) {
    134				/* DPCM backend */
    135				link->no_pcm = 1;
    136				link->ignore_pmdown_time = 1;
    137			}
    138		} else {
    139			/* DPCM frontend */
    140			dlc = devm_kzalloc(dev, sizeof(*dlc), GFP_KERNEL);
    141			if (!dlc) {
    142				ret = -ENOMEM;
    143				goto err;
    144			}
    145
    146			link->codecs	 = dlc;
    147			link->num_codecs = 1;
    148
    149			link->codecs->dai_name = "snd-soc-dummy-dai";
    150			link->codecs->name = "snd-soc-dummy";
    151			link->dynamic = 1;
    152		}
    153
    154		if (platform || !codec) {
    155			/* DPCM */
    156			snd_soc_dai_link_set_capabilities(link);
    157			link->ignore_suspend = 1;
    158			link->nonatomic = 1;
    159		}
    160
    161		link->stream_name = link->name;
    162		link++;
    163
    164		of_node_put(cpu);
    165		of_node_put(codec);
    166		of_node_put(platform);
    167	}
    168
    169	return 0;
    170err:
    171	of_node_put(cpu);
    172	of_node_put(codec);
    173	of_node_put(platform);
    174err_put_np:
    175	of_node_put(np);
    176	return ret;
    177}
    178EXPORT_SYMBOL(qcom_snd_parse_of);
    179
    180MODULE_LICENSE("GPL v2");