Exemplo n.º 1
0
/* Logic for a aic3x as connected on a davinci-evm */
static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_card *card = rtd->card;
	struct device_node *np = card->dev->of_node;
	int ret;

	/* Add davinci-evm specific widgets */
	snd_soc_dapm_new_controls(&card->dapm, aic3x_dapm_widgets,
				  ARRAY_SIZE(aic3x_dapm_widgets));

	if (np) {
		ret = snd_soc_of_parse_audio_routing(card, "ti,audio-routing");
		if (ret)
			return ret;
	} else {
		/* Set up davinci-evm specific audio path audio_map */
		snd_soc_dapm_add_routes(&card->dapm, audio_map,
					ARRAY_SIZE(audio_map));
	}

	/* not connected */
	snd_soc_dapm_nc_pin(&card->dapm, "MONO_LOUT");
	snd_soc_dapm_nc_pin(&card->dapm, "HPLCOM");
	snd_soc_dapm_nc_pin(&card->dapm, "HPRCOM");

	return 0;
}
Exemplo n.º 2
0
static int aml_m8_audio_probe(struct platform_device *pdev)
{
    //struct device_node *np = pdev->dev.of_node;
    struct snd_soc_card *card = &aml_snd_soc_card;
    struct aml_audio_private_data *p_aml_audio;
    int ret = 0;

    printk(KERN_DEBUG "enter %s\n", __func__);

#ifdef CONFIG_USE_OF
    p_aml_audio = devm_kzalloc(&pdev->dev,
            sizeof(struct aml_audio_private_data), GFP_KERNEL);
    if (!p_aml_audio) {
        dev_err(&pdev->dev, "Can't allocate aml_audio_private_data\n");
        ret = -ENOMEM;
        goto err;
    }

    card->dev = &pdev->dev;
    platform_set_drvdata(pdev, card);
    snd_soc_card_set_drvdata(card, p_aml_audio);
    if (!(pdev->dev.of_node)) {
        dev_err(&pdev->dev, "Must be instantiated using device tree\n");
        ret = -EINVAL;
        goto err;
    }

    ret = snd_soc_of_parse_card_name(card, "aml,sound_card");
    if (ret)
        goto err;

    ret = of_property_read_string_index(pdev->dev.of_node, "aml,codec_dai",
            0, &aml_codec_dai_link[0].codec_dai_name);
    if (ret)
        goto err;

    ret = snd_soc_of_parse_audio_routing(card, "aml,audio-routing");
    if (ret)
      goto err;

//  aml_codec_dai_link[0].codec_of_node = of_parse_phandle(
//          pdev->dev.of_node, "aml,audio-codec", 0);

    ret = snd_soc_register_card(card);
    if (ret) {
        dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
            ret);
        goto err;
    }

    aml_m8_pinmux_init(card);


    return 0;
#endif

err:
    kfree(p_aml_audio);
    return ret;
}
Exemplo n.º 3
0
/* Logic for a aic3x as connected on a davinci-evm */
static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_dapm_context *dapm = &codec->dapm;
	struct device_node *np = codec->card->dev->of_node;
	int ret;

	/* Add davinci-evm specific widgets */
	snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
				  ARRAY_SIZE(aic3x_dapm_widgets));

	if (np) {
		ret = snd_soc_of_parse_audio_routing(codec->card,
							"ti,audio-routing");
		if (ret)
			return ret;
	} else {
		/* Set up davinci-evm specific audio path audio_map */
		snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
	}

	/* not connected */
	snd_soc_dapm_disable_pin(dapm, "MONO_LOUT");
	snd_soc_dapm_disable_pin(dapm, "HPLCOM");
	snd_soc_dapm_disable_pin(dapm, "HPRCOM");

	/* always connected */
	snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
	snd_soc_dapm_enable_pin(dapm, "Line Out");
	snd_soc_dapm_enable_pin(dapm, "Mic Jack");
	snd_soc_dapm_enable_pin(dapm, "Line In");

	return 0;
}
Exemplo n.º 4
0
static __devinit int msm8x10_asoc_machine_probe(struct platform_device *pdev)
{
	struct snd_soc_card *card = &snd_soc_card_msm8x10;
	int ret;

	dev_dbg(&pdev->dev, "%s\n", __func__);
	if (!pdev->dev.of_node) {
		dev_err(&pdev->dev, "No platform supplied from device tree\n");
		return -EINVAL;
	}

	card->dev = &pdev->dev;
	platform_set_drvdata(pdev, card);

	ret = snd_soc_of_parse_card_name(card, "qcom,model");
	if (ret)
		goto err;

	ret = snd_soc_of_parse_audio_routing(card,
			"qcom,audio-routing");
	if (ret)
		goto err;

	mutex_init(&cdc_mclk_mutex);
	pcbcr = ioremap(MSM8X10_DINO_LPASS_DIGCODEC_CBCR, 4);
	if (!pcbcr) {
		ret = -ENOMEM;
		goto err1;
	}
	prcgr = ioremap(MSM8X10_DINO_LPASS_DIGCODEC_CMD_RCGR, 4);
	if (!prcgr) {
		ret = -ENOMEM;
		goto err1;
	}
	atomic_set(&mclk_rsc_ref, 0);
	mbhc_cfg.gpio_level_insert = of_property_read_bool(pdev->dev.of_node,
						"qcom,headset-jack-type-NC");

	spdev = pdev;

	ret = snd_soc_register_card(card);
	if (ret == -EPROBE_DEFER)
		goto err1;
	else if (ret) {
		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
			ret);
		goto err1;
	}
	return 0;
err1:
	mutex_destroy(&cdc_mclk_mutex);
	if (pcbcr)
		iounmap(pcbcr);
	if (prcgr)
		iounmap(prcgr);
err:
	return ret;
}
Exemplo n.º 5
0
static int odroidx2_audio_probe(struct platform_device *pdev)
{
    struct device_node *snd_node = pdev->dev.of_node;
    struct snd_soc_card *card = &odroidx2;
    struct device_node *i2s_node, *codec_node;
    struct odroidx2_drv_data *dd;
    const struct of_device_id *of_id;
    int ret;

    of_id = of_match_node(odroidx2_audio_of_match, snd_node);
    dd = (struct odroidx2_drv_data *)of_id->data;

    card->num_dapm_widgets = dd->num_dapm_widgets;
    card->dapm_widgets = dd->dapm_widgets;

    card->dev = &pdev->dev;

    ret = snd_soc_of_parse_card_name(card, "samsung,model");
    if (ret < 0)
        return ret;

    ret = snd_soc_of_parse_audio_routing(card, "samsung,audio-routing");
    if (ret < 0)
        return ret;

    codec_node = of_parse_phandle(snd_node, "samsung,audio-codec", 0);
    if (!codec_node) {
        dev_err(&pdev->dev,
                "Failed parsing samsung,i2s-codec property\n");
        return -EINVAL;
    }

    i2s_node = of_parse_phandle(snd_node, "samsung,i2s-controller", 0);
    if (!i2s_node) {
        dev_err(&pdev->dev,
                "Failed parsing samsung,i2s-controller property\n");
        ret = -EINVAL;
        goto err_put_codec_n;
    }

    odroidx2_dai[0].codec_of_node = codec_node;
    odroidx2_dai[0].cpu_of_node = i2s_node;
    odroidx2_dai[0].platform_of_node = i2s_node;

    ret = snd_soc_register_card(card);
    if (ret) {
        dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
                ret);
        goto err_put_i2s_n;
    }
    return 0;

err_put_i2s_n:
    of_node_put(i2s_node);
err_put_codec_n:
    of_node_put(codec_node);
    return ret;
}
Exemplo n.º 6
0
static int msm8x16_asoc_machine_probe(struct platform_device *pdev)
{
	struct snd_soc_card *card;
	const char *card_dev_id = "qcom,msm-snd-card-id";
	int ret, id;

	ret = of_property_read_u32(pdev->dev.of_node, card_dev_id, &id);
	if (ret) {
		dev_err(&pdev->dev,
			"%s: missing %s in dt node\n", __func__, card_dev_id);
		return ret;
	}

	pdev->id = id;
	dev_set_name(&pdev->dev, "%s.%d", "msm-snd-card", id);

	dev_dbg(&pdev->dev, "%s: dev name %s, id:%d\n", __func__,
		 dev_name(&pdev->dev), pdev->id);

	dev_dbg(&pdev->dev, "%s-card:%d\n", __func__, pdev->id);
	if (!pdev->dev.of_node) {
		dev_err(&pdev->dev, "No platform supplied from device tree\n");
		return -EINVAL;
	}

	if (pdev->id >= MAX_SND_CARDS) {
		dev_err(&pdev->dev, "Sound Card parsed is wrong\n");
		return -EINVAL;
	}
	card = &bear_cards[pdev->id];

	card->dev = &pdev->dev;
	platform_set_drvdata(pdev, card);

	ret = snd_soc_of_parse_card_name(card, "qcom,model");
	if (ret)
		goto err;

	ret = snd_soc_of_parse_audio_routing(card,
			"qcom,audio-routing");
	if (ret)
		goto err;

	ret = snd_soc_register_card(card);
	if (ret) {
		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
			ret);
		goto err;
	}
	mutex_init(&cdc_mclk_mutex);
	atomic_set(&mclk_rsc_ref, 0);
	return 0;
err:
	return ret;
}
Exemplo n.º 7
0
static int asoc_simple_card_parse_of(struct device_node *node,
				     struct simple_card_data *priv)
{
	struct device *dev = simple_priv_to_dev(priv);
	enum of_gpio_flags flags;
	u32 val;
	int ret;

	if (!node)
		return -EINVAL;

	/* Parse the card name from DT */
	snd_soc_of_parse_card_name(&priv->snd_card, "simple-audio-card,name");

	/* The off-codec widgets */
	if (of_property_read_bool(node, "simple-audio-card,widgets")) {
		ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card,
					"simple-audio-card,widgets");
		if (ret)
			return ret;
	}

	/* DAPM routes */
	if (of_property_read_bool(node, "simple-audio-card,routing")) {
		ret = snd_soc_of_parse_audio_routing(&priv->snd_card,
					"simple-audio-card,routing");
		if (ret)
			return ret;
	}

	/* Factor to mclk, used in hw_params() */
	ret = of_property_read_u32(node, "simple-audio-card,mclk-fs", &val);
	if (ret == 0)
		priv->mclk_fs = val;

	dev_dbg(dev, "New simple-card: %s\n", priv->snd_card.name ?
		priv->snd_card.name : "");

	/* Single/Muti DAI link(s) & New style of DT node */
	if (of_get_child_by_name(node, "simple-audio-card,dai-link")) {
		struct device_node *np = NULL;
		int i = 0;

		for_each_child_of_node(node, np) {
			dev_dbg(dev, "\tlink %d:\n", i);
			ret = asoc_simple_card_dai_link_of(np, priv,
							   i, false);
			if (ret < 0) {
				of_node_put(np);
				return ret;
			}
			i++;
		}
	} else {
Exemplo n.º 8
0
static int asoc_simple_card_parse_of(struct device_node *node,
				     struct simple_card_data *priv)
{
	struct device *dev = simple_priv_to_dev(priv);
	struct device_node *dai_link;
	int ret;

	if (!node)
		return -EINVAL;

	dai_link = of_get_child_by_name(node, PREFIX "dai-link");

	/* The off-codec widgets */
	if (of_property_read_bool(node, PREFIX "widgets")) {
		ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card,
					PREFIX "widgets");
		if (ret)
			goto card_parse_end;
	}

	/* DAPM routes */
	if (of_property_read_bool(node, PREFIX "routing")) {
		ret = snd_soc_of_parse_audio_routing(&priv->snd_card,
					PREFIX "routing");
		if (ret)
			goto card_parse_end;
	}

	/* Factor to mclk, used in hw_params() */
	of_property_read_u32(node, PREFIX "mclk-fs", &priv->mclk_fs);

	/* Single/Muti DAI link(s) & New style of DT node */
	if (dai_link) {
		struct device_node *np = NULL;
		int i = 0;

		for_each_child_of_node(node, np) {
			dev_dbg(dev, "\tlink %d:\n", i);
			ret = asoc_simple_card_dai_link_of(np, priv,
							   i, false);
			if (ret < 0) {
				of_node_put(np);
				goto card_parse_end;
			}
			i++;
		}
	} else {
Exemplo n.º 9
0
static int atmel_asoc_wm8904_dt_init(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct device_node *codec_np, *cpu_np;
	struct snd_soc_card *card = &atmel_asoc_wm8904_card;
	struct snd_soc_dai_link *dailink = &atmel_asoc_wm8904_dailink;
	int ret;

	if (!np) {
		dev_err(&pdev->dev, "only device tree supported\n");
		return -EINVAL;
	}

	ret = snd_soc_of_parse_card_name(card, "atmel,model");
	if (ret) {
		dev_err(&pdev->dev, "failed to parse card name\n");
		return ret;
	}

	ret = snd_soc_of_parse_audio_routing(card, "atmel,audio-routing");
	if (ret) {
		dev_err(&pdev->dev, "failed to parse audio routing\n");
		return ret;
	}

	cpu_np = of_parse_phandle(np, "atmel,ssc-controller", 0);
	if (!cpu_np) {
		dev_err(&pdev->dev, "failed to get dai and pcm info\n");
		ret = -EINVAL;
		return ret;
	}
	dailink->cpu_of_node = cpu_np;
	dailink->platform_of_node = cpu_np;
	of_node_put(cpu_np);

	codec_np = of_parse_phandle(np, "atmel,audio-codec", 0);
	if (!codec_np) {
		dev_err(&pdev->dev, "failed to get codec info\n");
		ret = -EINVAL;
		return ret;
	}
	dailink->codec_of_node = codec_np;
	of_node_put(codec_np);

	return 0;
}
Exemplo n.º 10
0
int asoc_simple_card_of_parse_routing(struct snd_soc_card *card,
				      char *prefix,
				      int optional)
{
	struct device_node *node = card->dev->of_node;
	char prop[128];

	if (!prefix)
		prefix = "";

	snprintf(prop, sizeof(prop), "%s%s", prefix, "routing");

	if (!of_property_read_bool(node, prop)) {
		if (optional)
			return 0;
		return -EINVAL;
	}

	return snd_soc_of_parse_audio_routing(card, prop);
}
Exemplo n.º 11
0
static int tegra_wm9712_driver_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct snd_soc_card *card = &snd_soc_tegra_wm9712;
	struct tegra_wm9712 *machine;
	int ret;

	machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm9712),
			       GFP_KERNEL);
	if (!machine) {
		dev_err(&pdev->dev, "Can't allocate tegra_wm9712 struct\n");
		return -ENOMEM;
	}

	card->dev = &pdev->dev;
	platform_set_drvdata(pdev, card);
	snd_soc_card_set_drvdata(card, machine);

	machine->codec = platform_device_alloc("wm9712-codec", -1);
	if (!machine->codec) {
		dev_err(&pdev->dev, "Can't allocate wm9712 platform device\n");
		return -ENOMEM;
	}

	ret = platform_device_add(machine->codec);
	if (ret)
		goto codec_put;

	ret = snd_soc_of_parse_card_name(card, "nvidia,model");
	if (ret)
		goto codec_unregister;

	ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing");
	if (ret)
		goto codec_unregister;

	tegra_wm9712_dai.cpu_of_node = of_parse_phandle(np,
				       "nvidia,ac97-controller", 0);
	if (!tegra_wm9712_dai.cpu_of_node) {
		dev_err(&pdev->dev,
			"Property 'nvidia,ac97-controller' missing or invalid\n");
		ret = -EINVAL;
		goto codec_unregister;
	}

	tegra_wm9712_dai.platform_of_node = tegra_wm9712_dai.cpu_of_node;

	ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
	if (ret)
		goto codec_unregister;

	ret = tegra_asoc_utils_set_ac97_rate(&machine->util_data);
	if (ret)
		goto asoc_utils_fini;

	ret = snd_soc_register_card(card);
	if (ret) {
		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
			ret);
		goto asoc_utils_fini;
	}

	return 0;

asoc_utils_fini:
	tegra_asoc_utils_fini(&machine->util_data);
codec_unregister:
	platform_device_del(machine->codec);
codec_put:
	platform_device_put(machine->codec);
	return ret;
}
Exemplo n.º 12
0
static int at91sam9g20ek_audio_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct device_node *codec_np, *cpu_np;
	struct clk *pllb;
	struct snd_soc_card *card = &snd_soc_at91sam9g20ek;
	int ret;

	if (!np) {
		return -ENODEV;
	}

	ret = atmel_ssc_set_audio(0);
	if (ret) {
		dev_err(&pdev->dev, "ssc channel is not valid\n");
		return -EINVAL;
	}

	/*
	 * Codec MCLK is supplied by PCK0 - set it up.
	 */
	mclk = clk_get(NULL, "pck0");
	if (IS_ERR(mclk)) {
		printk(KERN_ERR "ASoC: Failed to get MCLK\n");
		ret = PTR_ERR(mclk);
		goto err;
	}

	pllb = clk_get(NULL, "pllb");
	if (IS_ERR(pllb)) {
		printk(KERN_ERR "ASoC: Failed to get PLLB\n");
		ret = PTR_ERR(pllb);
		goto err_mclk;
	}
	ret = clk_set_parent(mclk, pllb);
	clk_put(pllb);
	if (ret != 0) {
		printk(KERN_ERR "ASoC: Failed to set MCLK parent\n");
		goto err_mclk;
	}

	clk_set_rate(mclk, MCLK_RATE);

	card->dev = &pdev->dev;

	/* Parse device node info */
	ret = snd_soc_of_parse_card_name(card, "atmel,model");
	if (ret)
		goto err;

	ret = snd_soc_of_parse_audio_routing(card,
		"atmel,audio-routing");
	if (ret)
		goto err;

	/* Parse codec info */
	at91sam9g20ek_dai.codec_name = NULL;
	codec_np = of_parse_phandle(np, "atmel,audio-codec", 0);
	if (!codec_np) {
		dev_err(&pdev->dev, "codec info missing\n");
		return -EINVAL;
	}
	at91sam9g20ek_dai.codec_of_node = codec_np;

	/* Parse dai and platform info */
	at91sam9g20ek_dai.cpu_dai_name = NULL;
	at91sam9g20ek_dai.platform_name = NULL;
	cpu_np = of_parse_phandle(np, "atmel,ssc-controller", 0);
	if (!cpu_np) {
		dev_err(&pdev->dev, "dai and pcm info missing\n");
		return -EINVAL;
	}
	at91sam9g20ek_dai.cpu_of_node = cpu_np;
	at91sam9g20ek_dai.platform_of_node = cpu_np;

	of_node_put(codec_np);
	of_node_put(cpu_np);

	ret = snd_soc_register_card(card);
	if (ret) {
		printk(KERN_ERR "ASoC: snd_soc_register_card() failed\n");
	}

	return ret;

err_mclk:
	clk_put(mclk);
	mclk = NULL;
err:
	atmel_ssc_put_audio(0);
	return ret;
}
Exemplo n.º 13
0
static int omap_twl4030_probe(struct platform_device *pdev)
{
	struct omap_tw4030_pdata *pdata = dev_get_platdata(&pdev->dev);
	struct device_node *node = pdev->dev.of_node;
	struct snd_soc_card *card = &omap_twl4030_card;
	struct omap_twl4030 *priv;
	int ret = 0;

	card->dev = &pdev->dev;

	priv = devm_kzalloc(&pdev->dev, sizeof(struct omap_twl4030), GFP_KERNEL);
	if (priv == NULL)
		return -ENOMEM;

	if (node) {
		struct device_node *dai_node;
		struct property *prop;

		if (snd_soc_of_parse_card_name(card, "ti,model")) {
			dev_err(&pdev->dev, "Card name is not provided\n");
			return -ENODEV;
		}

		dai_node = of_parse_phandle(node, "ti,mcbsp", 0);
		if (!dai_node) {
			dev_err(&pdev->dev, "McBSP node is not provided\n");
			return -EINVAL;
		}
		omap_twl4030_dai_links[0].cpu_dai_name  = NULL;
		omap_twl4030_dai_links[0].cpu_of_node = dai_node;

		dai_node = of_parse_phandle(node, "ti,mcbsp-voice", 0);
		if (!dai_node) {
			card->num_links = 1;
		} else {
			omap_twl4030_dai_links[1].cpu_dai_name  = NULL;
			omap_twl4030_dai_links[1].cpu_of_node = dai_node;
		}

		priv->jack_detect = of_get_named_gpio(node,
						      "ti,jack-det-gpio", 0);

		/* Optional: audio routing can be provided */
		prop = of_find_property(node, "ti,audio-routing", NULL);
		if (prop) {
			ret = snd_soc_of_parse_audio_routing(card,
							    "ti,audio-routing");
			if (ret)
				return ret;

			card->fully_routed = 1;
		}
	} else if (pdata) {
		if (pdata->card_name) {
			card->name = pdata->card_name;
		} else {
			dev_err(&pdev->dev, "Card name is not provided\n");
			return -ENODEV;
		}

		if (!pdata->voice_connected)
			card->num_links = 1;

		priv->jack_detect = pdata->jack_detect;
	} else {
		dev_err(&pdev->dev, "Missing pdata\n");
		return -ENODEV;
	}

	snd_soc_card_set_drvdata(card, priv);
	ret = snd_soc_register_card(card);
	if (ret) {
		dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
			ret);
		return ret;
	}

	return 0;
}
Exemplo n.º 14
0
static int mt2701_cs42448_machine_probe(struct platform_device *pdev)
{
	struct snd_soc_card *card = &mt2701_cs42448_soc_card;
	int ret;
	int i;
	struct device_node *platform_node, *codec_node, *codec_node_bt_mrg;
	struct mt2701_cs42448_private *priv =
		devm_kzalloc(&pdev->dev, sizeof(struct mt2701_cs42448_private),
			     GFP_KERNEL);
	struct device *dev = &pdev->dev;

	if (!priv)
		return -ENOMEM;

	platform_node = of_parse_phandle(pdev->dev.of_node,
					 "mediatek,platform", 0);
	if (!platform_node) {
		dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
		return -EINVAL;
	}
	for (i = 0; i < card->num_links; i++) {
		if (mt2701_cs42448_dai_links[i].platform_name)
			continue;
		mt2701_cs42448_dai_links[i].platform_of_node = platform_node;
	}

	card->dev = dev;

	codec_node = of_parse_phandle(pdev->dev.of_node,
				      "mediatek,audio-codec", 0);
	if (!codec_node) {
		dev_err(&pdev->dev,
			"Property 'audio-codec' missing or invalid\n");
		return -EINVAL;
	}
	for (i = 0; i < card->num_links; i++) {
		if (mt2701_cs42448_dai_links[i].codec_name)
			continue;
		mt2701_cs42448_dai_links[i].codec_of_node = codec_node;
	}

	codec_node_bt_mrg = of_parse_phandle(pdev->dev.of_node,
					     "mediatek,audio-codec-bt-mrg", 0);
	if (!codec_node_bt_mrg) {
		dev_err(&pdev->dev,
			"Property 'audio-codec-bt-mrg' missing or invalid\n");
		return -EINVAL;
	}
	mt2701_cs42448_dai_links[DAI_LINK_BE_MRG_BT].codec_of_node
							= codec_node_bt_mrg;

	ret = snd_soc_of_parse_audio_routing(card, "audio-routing");
	if (ret) {
		dev_err(&pdev->dev, "failed to parse audio-routing: %d\n", ret);
		return ret;
	}

	priv->i2s1_in_mux_gpio_sel_1 =
		of_get_named_gpio(dev->of_node, "i2s1-in-sel-gpio1", 0);
	if (gpio_is_valid(priv->i2s1_in_mux_gpio_sel_1)) {
		ret = devm_gpio_request(dev, priv->i2s1_in_mux_gpio_sel_1,
					"i2s1_in_mux_gpio_sel_1");
		if (ret)
			dev_warn(&pdev->dev, "%s devm_gpio_request fail %d\n",
				 __func__, ret);
		gpio_direction_output(priv->i2s1_in_mux_gpio_sel_1, 0);
	}

	priv->i2s1_in_mux_gpio_sel_2 =
		of_get_named_gpio(dev->of_node, "i2s1-in-sel-gpio2", 0);
	if (gpio_is_valid(priv->i2s1_in_mux_gpio_sel_2)) {
		ret = devm_gpio_request(dev, priv->i2s1_in_mux_gpio_sel_2,
					"i2s1_in_mux_gpio_sel_2");
		if (ret)
			dev_warn(&pdev->dev, "%s devm_gpio_request fail2 %d\n",
				 __func__, ret);
		gpio_direction_output(priv->i2s1_in_mux_gpio_sel_2, 0);
	}
	snd_soc_card_set_drvdata(card, priv);

	ret = devm_snd_soc_register_card(&pdev->dev, card);

	if (ret)
		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
			__func__, ret);
	return ret;
}
Exemplo n.º 15
0
static int tegra_wm8753_driver_probe(struct platform_device *pdev)
{
	struct snd_soc_card *card = &snd_soc_tegra_wm8753;
	struct tegra_wm8753 *machine;
	struct tegra_asoc_platform_data *pdata;
	int ret;


	pdata = pdev->dev.platform_data;
	if (!pdata) {
		dev_err(&pdev->dev, "No platform data supplied\n");
		return -EINVAL;
	}

	machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8753),
			       GFP_KERNEL);
	if (!machine) {
		dev_err(&pdev->dev, "Can't allocate tegra_wm8753 struct\n");
		ret = -ENOMEM;
		goto err;
	}

	card->dev = &pdev->dev;
	platform_set_drvdata(pdev, card);
	snd_soc_card_set_drvdata(card, machine);

	ret = snd_soc_of_parse_card_name(card, "nvidia,model");
	if (ret)
		goto err;

	ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing");
	if (ret)
		goto err;

	tegra_wm8753_dai.codec_of_node = of_parse_phandle(
			pdev->dev.of_node, "nvidia,audio-codec", 0);
	if (!tegra_wm8753_dai.codec_of_node) {
		dev_err(&pdev->dev,
			"Property 'nvidia,audio-codec' missing or invalid\n");
		ret = -EINVAL;
		goto err;
	}

	tegra_wm8753_dai.cpu_of_node = of_parse_phandle(
			pdev->dev.of_node, "nvidia,i2s-controller", 0);
	if (!tegra_wm8753_dai.cpu_of_node) {
		dev_err(&pdev->dev,
			"Property 'nvidia,i2s-controller' missing or invalid\n");
		ret = -EINVAL;
		goto err;
	}

	tegra_wm8753_dai.platform_of_node =
				tegra_wm8753_dai.cpu_of_node;

	ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev, card);
	if (ret)
		goto err;

	ret = snd_soc_register_card(card);
	if (ret) {
		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
			ret);
		goto err_fini_utils;
	}

	if (!card->instantiated) {
		dev_err(&pdev->dev, "No WM8753 codec\n");
		goto err_unregister_card;
	}

#ifdef CONFIG_SWITCH
	/* Add h2w swith class support */
	ret = tegra_asoc_switch_register(&wired_switch_dev);
	if (ret < 0) {
		dev_err(&pdev->dev, "not able to register switch device\n");
		goto err_unregister_card;
	}
#endif

#ifndef CONFIG_ARCH_TEGRA_2x_SOC
	ret = tegra_asoc_utils_set_parent(&machine->util_data,
				pdata->i2s_param[HIFI_CODEC].is_i2s_master);
	if (ret) {
		dev_err(&pdev->dev, "tegra_asoc_utils_set_parent failed (%d)\n",
			ret);
		goto err_unregister_card;
	}
#endif

	return 0;

err_unregister_card:
	snd_soc_unregister_card(card);
err_fini_utils:
	tegra_asoc_utils_fini(&machine->util_data);
err:
	return ret;
}
static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
{
	struct snd_soc_card *card = &snd_soc_tegra_wm8903;
	struct tegra_wm8903 *machine;
	int ret;

	if (!pdev->dev.platform_data && !pdev->dev.of_node) {
		dev_err(&pdev->dev, "No platform data supplied\n");
		return -EINVAL;
	}

	machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8903),
			       GFP_KERNEL);
	if (!machine) {
		dev_err(&pdev->dev, "Can't allocate tegra_wm8903 struct\n");
		ret = -ENOMEM;
		goto err;
	}
	machine->pcm_dev = ERR_PTR(-EINVAL);

	card->dev = &pdev->dev;
	platform_set_drvdata(pdev, card);
	snd_soc_card_set_drvdata(card, machine);

	if (pdev->dev.of_node) {
		ret = snd_soc_of_parse_card_name(card, "nvidia,model");
		if (ret)
			goto err;

		ret = snd_soc_of_parse_audio_routing(card,
						     "nvidia,audio-routing");
		if (ret)
			goto err;

		tegra_wm8903_dai.codec_name = NULL;
		tegra_wm8903_dai.codec_of_node = of_parse_phandle(
				pdev->dev.of_node, "nvidia,audio-codec", 0);
		if (!tegra_wm8903_dai.codec_of_node) {
			dev_err(&pdev->dev,
				"Property 'nvidia,audio-codec' missing or invalid\n");
			ret = -EINVAL;
			goto err;
		}

		tegra_wm8903_dai.cpu_dai_name = NULL;
		tegra_wm8903_dai.cpu_dai_of_node = of_parse_phandle(
				pdev->dev.of_node, "nvidia,i2s-controller", 0);
		if (!tegra_wm8903_dai.cpu_dai_of_node) {
			dev_err(&pdev->dev,
				"Property 'nvidia,i2s-controller' missing or invalid\n");
			ret = -EINVAL;
			goto err;
		}

		machine->pcm_dev = platform_device_register_simple(
					"tegra-pcm-audio", -1, NULL, 0);
		if (IS_ERR(machine->pcm_dev)) {
			dev_err(&pdev->dev,
				"Can't instantiate tegra-pcm-audio\n");
			ret = PTR_ERR(machine->pcm_dev);
			goto err;
		}
	} else {
		if (machine_is_harmony()) {
			card->dapm_routes = harmony_audio_map;
			card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map);
		} else if (machine_is_seaboard()) {
			card->dapm_routes = seaboard_audio_map;
			card->num_dapm_routes = ARRAY_SIZE(seaboard_audio_map);
		} else if (machine_is_kaen()) {
			card->dapm_routes = kaen_audio_map;
			card->num_dapm_routes = ARRAY_SIZE(kaen_audio_map);
		} else {
			card->dapm_routes = aebl_audio_map;
			card->num_dapm_routes = ARRAY_SIZE(aebl_audio_map);
		}
	}

	ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
	if (ret)
		goto err_unregister;

	ret = snd_soc_register_card(card);
	if (ret) {
		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
			ret);
		goto err_fini_utils;
	}

	return 0;

err_fini_utils:
	tegra_asoc_utils_fini(&machine->util_data);
err_unregister:
	if (!IS_ERR(machine->pcm_dev))
		platform_device_unregister(machine->pcm_dev);
err:
	return ret;
}
Exemplo n.º 17
0
static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct device_node *codec_np, *cpu_np;
	struct snd_soc_card *card;
	struct snd_soc_dai_link *dai;
	struct sam9x5_drvdata *priv;
	int ret;

	if (!np) {
		dev_err(&pdev->dev, "No device node supplied\n");
		return -EINVAL;
	}

	card = devm_kzalloc(&pdev->dev, sizeof(*card), GFP_KERNEL);
	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
	dai = devm_kzalloc(&pdev->dev, sizeof(*dai), GFP_KERNEL);
	if (!dai || !card || !priv) {
		ret = -ENOMEM;
		goto out;
	}

	snd_soc_card_set_drvdata(card, priv);

	card->dev = &pdev->dev;
	card->owner = THIS_MODULE;
	card->dai_link = dai;
	card->num_links = 1;
	card->dapm_widgets = sam9x5_dapm_widgets;
	card->num_dapm_widgets = ARRAY_SIZE(sam9x5_dapm_widgets);
	dai->name = "WM8731";
	dai->stream_name = "WM8731 PCM";
	dai->codec_dai_name = "wm8731-hifi";
	dai->init = sam9x5_wm8731_init;
	dai->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF
		| SND_SOC_DAIFMT_CBM_CFM;

	ret = snd_soc_of_parse_card_name(card, "atmel,model");
	if (ret) {
		dev_err(&pdev->dev, "atmel,model node missing\n");
		goto out;
	}

	ret = snd_soc_of_parse_audio_routing(card, "atmel,audio-routing");
	if (ret) {
		dev_err(&pdev->dev, "atmel,audio-routing node missing\n");
		goto out;
	}

	codec_np = of_parse_phandle(np, "atmel,audio-codec", 0);
	if (!codec_np) {
		dev_err(&pdev->dev, "atmel,audio-codec node missing\n");
		ret = -EINVAL;
		goto out;
	}

	dai->codec_of_node = codec_np;

	cpu_np = of_parse_phandle(np, "atmel,ssc-controller", 0);
	if (!cpu_np) {
		dev_err(&pdev->dev, "atmel,ssc-controller node missing\n");
		ret = -EINVAL;
		goto out;
	}
	dai->cpu_of_node = cpu_np;
	dai->platform_of_node = cpu_np;

	priv->ssc_id = of_alias_get_id(cpu_np, "ssc");

	ret = atmel_ssc_set_audio(priv->ssc_id);
	if (ret != 0) {
		dev_err(&pdev->dev, "Failed to set SSC %d for audio: %d\n",
			ret, priv->ssc_id);
		goto out;
	}

	of_node_put(codec_np);
	of_node_put(cpu_np);

	ret = snd_soc_register_card(card);
	if (ret) {
		dev_err(&pdev->dev, "Platform device allocation failed\n");
		goto out_put_audio;
	}

	dev_dbg(&pdev->dev, "%s ok\n", __func__);

	return ret;

out_put_audio:
	atmel_ssc_put_audio(priv->ssc_id);
out:
	return ret;
}
Exemplo n.º 18
0
static int tegra_wm8903_driver_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct snd_soc_card *card = &snd_soc_tegra_wm8903;
	struct tegra_wm8903 *machine;
	struct tegra_asoc_platform_data *pdata = pdev->dev.platform_data;
	int ret;

	if (!pdata && !pdev->dev.of_node) {
		dev_err(&pdev->dev, "No platform data supplied\n");
		return -EINVAL;
	}

	machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8903),
			       GFP_KERNEL);
	if (!machine) {
		dev_err(&pdev->dev, "Can't allocate tegra_wm8903 struct\n");
		ret = -ENOMEM;
		goto err;
	}
	pdata = &machine->pdata;

	machine->pdata = pdata;

	if (machine_is_cardhu() || machine_is_ventana()) {
		machine->spk_reg = regulator_get(&pdev->dev, "vdd_spk_amp");
		if (IS_ERR(machine->spk_reg)) {
			dev_info(&pdev->dev, "No speaker regulator found\n");
			machine->spk_reg = 0;
		}
	}

	if (machine_is_ventana()) {
		machine->dmic_reg = regulator_get(&pdev->dev, "vdd_dmic");
		if (IS_ERR(machine->dmic_reg)) {
			dev_info(&pdev->dev, "No digital mic"
						" regulator found\n");
			machine->dmic_reg = 0;
		}
	}

	if (machine_is_cardhu()) {
		tegra_wm8903_dai[0].codec_name = "wm8903.4-001a",
		tegra_wm8903_dai[0].cpu_dai_name = "tegra30-i2s.1";

		tegra_wm8903_dai[1].cpu_dai_name = "tegra30-spdif";

		tegra_wm8903_dai[2].cpu_dai_name = "tegra30-i2s.3";
	}

	if (machine_is_curacao() || machine_is_dolak()) {
		tegra_wm8903_dai[0].codec_name = "wm8903.0-001a";
		tegra_wm8903_dai[0].cpu_dai_name = "tegra30-i2s.0";
	}

#ifdef CONFIG_SWITCH
	/* Addd h2w swith class support */
	ret = tegra_asoc_switch_register(&tegra_wm8903_headset_switch);
	if (ret < 0)
		goto err_fini_utils;
#endif

	card->dev = &pdev->dev;
	platform_set_drvdata(pdev, card);
	snd_soc_card_set_drvdata(card, machine);

	if (pdev->dev.platform_data) {
		memcpy(pdata, card->dev->platform_data, sizeof(*pdata));
	} else if (np) {
		pdata = devm_kzalloc(&pdev->dev,
			sizeof(struct tegra_asoc_platform_data), GFP_KERNEL);
		if (!pdata) {
			dev_err(&pdev->dev,
				"no memory for tegra_asoc_platform_data\n");
			ret = -ENOMEM;
			goto err;
		}

		pdata->gpio_spkr_en = of_get_named_gpio(np,
						"nvidia,spkr-en-gpios", 0);
		if (pdata->gpio_spkr_en == -EPROBE_DEFER)
			return -EPROBE_DEFER;

		pdata->gpio_hp_mute = of_get_named_gpio(np,
						"nvidia,hp-mute-gpios", 0);
		if (pdata->gpio_hp_mute == -EPROBE_DEFER)
			return -EPROBE_DEFER;

		pdata->gpio_hp_det = of_get_named_gpio(np,
						"nvidia,hp-det-gpios", 0);
		if (pdata->gpio_hp_det == -EPROBE_DEFER)
			return -EPROBE_DEFER;

		pdata->gpio_int_mic_en = of_get_named_gpio(np,
						"nvidia,int-mic-en-gpios", 0);
		if (pdata->gpio_int_mic_en == -EPROBE_DEFER)
			return -EPROBE_DEFER;

		pdata->gpio_ext_mic_en = of_get_named_gpio(np,
						"nvidia,ext-mic-en-gpios", 0);
		if (pdata->gpio_ext_mic_en == -EPROBE_DEFER)
			return -EPROBE_DEFER;
	}

	if (np) {
		card->controls = tegra_wm8903_controls;
		card->num_controls = ARRAY_SIZE(tegra_wm8903_controls);

		card->dapm_widgets = tegra_wm8903_default_dapm_widgets;
		card->num_dapm_widgets = ARRAY_SIZE(tegra_wm8903_default_dapm_widgets);

		ret = snd_soc_of_parse_card_name(card, "nvidia,model");
		if (ret)
			goto err;

		ret = snd_soc_of_parse_audio_routing(card,
						     "nvidia,audio-routing");
		if (ret)
			goto err;

		tegra_wm8903_dai[0].codec_name = NULL;
		tegra_wm8903_dai[0].codec_of_node = of_parse_phandle(np,
				"nvidia,audio-codec", 0);
		if (!tegra_wm8903_dai[0].codec_of_node) {
			dev_err(&pdev->dev,
				"Property 'nvidia,audio-codec' missing or invalid\n");
			ret = -EINVAL;
			goto err;
		}

		tegra_wm8903_dai[0].cpu_dai_name = NULL;
		tegra_wm8903_dai[0].cpu_of_node = of_parse_phandle(np,
				"nvidia,i2s-controller", 0);
		if (!tegra_wm8903_dai[0].cpu_of_node) {
			dev_err(&pdev->dev,
				"Property 'nvidia,i2s-controller' missing or invalid\n");
			ret = -EINVAL;
			goto err;
		}

		tegra_wm8903_dai[0].platform_name = NULL;
		tegra_wm8903_dai[0].platform_of_node =
					tegra_wm8903_dai.cpu_of_node;
	} else {
		if (machine_is_cardhu() || machine_is_ventana()) {
			card->controls = cardhu_controls;
			card->num_controls = ARRAY_SIZE(cardhu_controls);

			card->dapm_widgets = cardhu_dapm_widgets;
			card->num_dapm_widgets = ARRAY_SIZE(cardhu_dapm_widgets);
		} else if (machine_is_dolak()) {
			card->controls = dolak_controls;
			card->num_controls = ARRAY_SIZE(dolak_controls);

			card->dapm_widgets = dolak_dapm_widgets;
			card->num_dapm_widgets = ARRAY_SIZE(dolak_dapm_widgets);
		} else {
			card->controls = tegra_wm8903_controls;
			card->num_controls = ARRAY_SIZE(tegra_wm8903_controls);

			card->dapm_widgets = tegra_wm8903_default_dapm_widgets;
			card->num_dapm_widgets = ARRAY_SIZE(tegra_wm8903_default_dapm_widgets);
		}

		if (machine_is_ventana() || machine_is_cardhu()) {
			card->dapm_routes = cardhu_audio_map;
			card->num_dapm_routes = ARRAY_SIZE(cardhu_audio_map);
		} else if (machine_is_dolak()) {
			card->dapm_routes = dolak_audio_map;
			card->num_dapm_routes = ARRAY_SIZE(dolak_audio_map);
		} else {
			card->dapm_routes = harmony_audio_map;
			card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map);
		}
	}

	if (gpio_is_valid(pdata->gpio_spkr_en)) {
		ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_spkr_en,
					    GPIOF_OUT_INIT_LOW, "spkr_en");
		if (ret) {
			dev_err(card->dev, "cannot get spkr_en gpio\n");
			return ret;
		}
	}

	if (gpio_is_valid(pdata->gpio_hp_mute)) {
		ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_hp_mute,
					    GPIOF_OUT_INIT_HIGH, "hp_mute");
		if (ret) {
			dev_err(card->dev, "cannot get hp_mute gpio\n");
			return ret;
		}
	}

	if (gpio_is_valid(pdata->gpio_int_mic_en)) {
		/* Disable int mic; enable signal is active-high */
		ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_int_mic_en,
					    GPIOF_OUT_INIT_LOW, "int_mic_en");
		if (ret) {
			dev_err(card->dev, "cannot get int_mic_en gpio\n");
			return ret;
		}
	}

	if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
		/* Enable ext mic; enable signal is active-low */
		ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_ext_mic_en,
					    GPIOF_OUT_INIT_LOW, "ext_mic_en");
		if (ret) {
			dev_err(card->dev, "cannot get ext_mic_en gpio\n");
			return ret;
		}
	}

	ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev, card);
	if (ret)
		goto err;

	ret = snd_soc_register_card(card);
	if (ret) {
		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
			ret);
		goto err_unregister_switch;
	}

	if (!card->instantiated) {
		ret = -ENODEV;
		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
			ret);
		goto err_unregister_card;
	}

#ifndef CONFIG_ARCH_TEGRA_2x_SOC
	ret = tegra_asoc_utils_set_parent(&machine->util_data,
				pdata->i2s_param[HIFI_CODEC].is_i2s_master);
	if (ret) {
		dev_err(&pdev->dev, "tegra_asoc_utils_set_parent failed (%d)\n",
			ret);
		goto err_unregister_card;
	}
#endif

	return 0;

err_unregister_card:
	snd_soc_unregister_card(card);
err_unregister_switch:
#ifdef CONFIG_SWITCH
	tegra_asoc_switch_unregister(&tegra_wm8903_headset_switch);
err_fini_utils:
#endif
	tegra_asoc_utils_fini(&machine->util_data);
err:
	return ret;
}
Exemplo n.º 19
0
static int tegra_sgtl5000_driver_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct snd_soc_card *card = &snd_soc_tegra_sgtl5000;
	struct tegra_sgtl5000 *machine;
	int ret;

	machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_sgtl5000),
			       GFP_KERNEL);
	if (!machine)
		return -ENOMEM;

	card->dev = &pdev->dev;
	snd_soc_card_set_drvdata(card, machine);

	ret = snd_soc_of_parse_card_name(card, "nvidia,model");
	if (ret)
		goto err;

	ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing");
	if (ret)
		goto err;

	tegra_sgtl5000_dai.codec_of_node = of_parse_phandle(np,
			"nvidia,audio-codec", 0);
	if (!tegra_sgtl5000_dai.codec_of_node) {
		dev_err(&pdev->dev,
			"Property 'nvidia,audio-codec' missing or invalid\n");
		ret = -EINVAL;
		goto err;
	}

	tegra_sgtl5000_dai.cpu_of_node = of_parse_phandle(np,
			"nvidia,i2s-controller", 0);
	if (!tegra_sgtl5000_dai.cpu_of_node) {
		dev_err(&pdev->dev,
			"Property 'nvidia,i2s-controller' missing/invalid\n");
		ret = -EINVAL;
		goto err;
	}

	tegra_sgtl5000_dai.platform_of_node = tegra_sgtl5000_dai.cpu_of_node;

	ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
	if (ret)
		goto err;

	ret = snd_soc_register_card(card);
	if (ret) {
		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
			ret);
		goto err_fini_utils;
	}

	return 0;

err_fini_utils:
	tegra_asoc_utils_fini(&machine->util_data);
err:
	return ret;
}
Exemplo n.º 20
0
static int tegra_alc5632_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct snd_soc_card *card = &snd_soc_tegra_alc5632;
	struct tegra_alc5632 *alc5632;
	int ret;

	alc5632 = devm_kzalloc(&pdev->dev,
			sizeof(struct tegra_alc5632), GFP_KERNEL);
	if (!alc5632) {
		dev_err(&pdev->dev, "Can't allocate tegra_alc5632\n");
		return -ENOMEM;
	}

	card->dev = &pdev->dev;
	platform_set_drvdata(pdev, card);
	snd_soc_card_set_drvdata(card, alc5632);

	alc5632->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0);
	if (alc5632->gpio_hp_det == -EPROBE_DEFER)
		return -EPROBE_DEFER;

	ret = snd_soc_of_parse_card_name(card, "nvidia,model");
	if (ret)
		goto err;

	ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing");
	if (ret)
		goto err;

	tegra_alc5632_dai.codec_of_node = of_parse_phandle(
			pdev->dev.of_node, "nvidia,audio-codec", 0);

	if (!tegra_alc5632_dai.codec_of_node) {
		dev_err(&pdev->dev,
			"Property 'nvidia,audio-codec' missing or invalid\n");
		ret = -EINVAL;
		goto err;
	}

	tegra_alc5632_dai.cpu_of_node = of_parse_phandle(np,
			"nvidia,i2s-controller", 0);
	if (!tegra_alc5632_dai.cpu_of_node) {
		dev_err(&pdev->dev,
			"Property 'nvidia,i2s-controller' missing or invalid\n");
		ret = -EINVAL;
		goto err;
	}

	tegra_alc5632_dai.platform_of_node = tegra_alc5632_dai.cpu_of_node;

	ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev);
	if (ret)
		goto err;

	ret = snd_soc_register_card(card);
	if (ret) {
		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
			ret);
		goto err_fini_utils;
	}

	return 0;

err_fini_utils:
	tegra_asoc_utils_fini(&alc5632->util_data);
err:
	return ret;
}
static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
{
	struct snd_soc_card *card = &snd_soc_tegra_alc5632;
	struct tegra_alc5632 *alc5632;
	int ret;

	alc5632 = devm_kzalloc(&pdev->dev,
			sizeof(struct tegra_alc5632), GFP_KERNEL);
	if (!alc5632) {
		dev_err(&pdev->dev, "Can't allocate tegra_alc5632\n");
		ret = -ENOMEM;
		goto err;
	}

	card->dev = &pdev->dev;
	platform_set_drvdata(pdev, card);
	snd_soc_card_set_drvdata(card, alc5632);

	alc5632->pcm_dev = ERR_PTR(-EINVAL);

	if (!(pdev->dev.of_node)) {
		dev_err(&pdev->dev, "Must be instantiated using device tree\n");
		ret = -EINVAL;
		goto err;
	}

	ret = snd_soc_of_parse_card_name(card, "nvidia,model");
	if (ret)
		goto err;

	ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing");
	if (ret)
		goto err;

	tegra_alc5632_dai.codec_of_node = of_parse_phandle(
			pdev->dev.of_node, "nvidia,audio-codec", 0);

	if (!tegra_alc5632_dai.codec_of_node) {
		dev_err(&pdev->dev,
			"Property 'nvidia,audio-codec' missing or invalid\n");
		ret = -EINVAL;
		goto err;
	}

	tegra_alc5632_dai.cpu_dai_of_node = of_parse_phandle(
			pdev->dev.of_node, "nvidia,i2s-controller", 0);
	if (!tegra_alc5632_dai.cpu_dai_of_node) {
		dev_err(&pdev->dev,
		"Property 'nvidia,i2s-controller' missing or invalid\n");
		ret = -EINVAL;
		goto err;
	}

	alc5632->pcm_dev = platform_device_register_simple(
		"tegra-pcm-audio", -1, NULL, 0);
	if (IS_ERR(alc5632->pcm_dev)) {
		dev_err(&pdev->dev,
			"Can't instantiate tegra-pcm-audio\n");
		ret = PTR_ERR(alc5632->pcm_dev);
		goto err;
	}

	ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev);
	if (ret)
		goto err_unregister;

	ret = snd_soc_register_card(card);
	if (ret) {
		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
			ret);
		goto err_fini_utils;
	}

	return 0;

err_fini_utils:
	tegra_asoc_utils_fini(&alc5632->util_data);
err_unregister:
	if (!IS_ERR(alc5632->pcm_dev))
		platform_device_unregister(alc5632->pcm_dev);
err:
	return ret;
}
Exemplo n.º 22
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++;
	}
Exemplo n.º 23
0
static int omap_abe_probe(struct platform_device *pdev)
{
	struct omap_abe_twl6040_data *pdata = dev_get_platdata(&pdev->dev);
	struct device_node *node = pdev->dev.of_node;
	struct snd_soc_card *card = &omap_abe_card;
	struct abe_twl6040 *priv;
	int num_links = 0;
	int ret = 0;

	card->dev = &pdev->dev;

	priv = devm_kzalloc(&pdev->dev, sizeof(struct abe_twl6040), GFP_KERNEL);
	if (priv == NULL)
		return -ENOMEM;

	priv->dmic_codec_dev = ERR_PTR(-EINVAL);

	if (node) {
		struct device_node *dai_node;

		if (snd_soc_of_parse_card_name(card, "ti,model")) {
			dev_err(&pdev->dev, "Card name is not provided\n");
			return -ENODEV;
		}

		ret = snd_soc_of_parse_audio_routing(card,
						"ti,audio-routing");
		if (ret) {
			dev_err(&pdev->dev,
				"Error while parsing DAPM routing\n");
			return ret;
		}

		dai_node = of_parse_phandle(node, "ti,mcpdm", 0);
		if (!dai_node) {
			dev_err(&pdev->dev, "McPDM node is not provided\n");
			return -EINVAL;
		}
		abe_twl6040_dai_links[0].cpu_dai_name  = NULL;
		abe_twl6040_dai_links[0].cpu_of_node = dai_node;

		dai_node = of_parse_phandle(node, "ti,dmic", 0);
		if (dai_node) {
			num_links = 2;
			abe_twl6040_dai_links[1].cpu_dai_name  = NULL;
			abe_twl6040_dai_links[1].cpu_of_node = dai_node;

			priv->dmic_codec_dev = platform_device_register_simple(
						"dmic-codec", -1, NULL, 0);
			if (IS_ERR(priv->dmic_codec_dev)) {
				dev_err(&pdev->dev,
					"Can't instantiate dmic-codec\n");
				return PTR_ERR(priv->dmic_codec_dev);
			}
		} else {
			num_links = 1;
		}

		priv->jack_detection = of_property_read_bool(node,
							   "ti,jack-detection");
		of_property_read_u32(node, "ti,mclk-freq",
				     &priv->mclk_freq);
		if (!priv->mclk_freq) {
			dev_err(&pdev->dev, "MCLK frequency not provided\n");
			ret = -EINVAL;
			goto err_unregister;
		}

		omap_abe_card.fully_routed = 1;
	} else if (pdata) {
		if (pdata->card_name) {
			card->name = pdata->card_name;
		} else {
			dev_err(&pdev->dev, "Card name is not provided\n");
			return -ENODEV;
		}

		if (pdata->has_dmic)
			num_links = 2;
		else
			num_links = 1;

		priv->jack_detection = pdata->jack_detection;
		priv->mclk_freq = pdata->mclk_freq;
	} else {
		dev_err(&pdev->dev, "Missing pdata\n");
		return -ENODEV;
	}


	if (!priv->mclk_freq) {
		dev_err(&pdev->dev, "MCLK frequency missing\n");
		ret = -ENODEV;
		goto err_unregister;
	}

	card->dai_link = abe_twl6040_dai_links;
	card->num_links = num_links;

	snd_soc_card_set_drvdata(card, priv);

	ret = snd_soc_register_card(card);
	if (ret) {
		dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
			ret);
		goto err_unregister;
	}

	return 0;

err_unregister:
	if (!IS_ERR(priv->dmic_codec_dev))
		platform_device_unregister(priv->dmic_codec_dev);

	return ret;
}
Exemplo n.º 24
0
static int tegra_rt5677_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct snd_soc_card *card = &snd_soc_tegra_rt5677;
	struct tegra_rt5677 *machine;
	int ret;

	machine = devm_kzalloc(&pdev->dev,
			sizeof(struct tegra_rt5677), GFP_KERNEL);
	if (!machine)
		return -ENOMEM;

	card->dev = &pdev->dev;
	platform_set_drvdata(pdev, card);
	snd_soc_card_set_drvdata(card, machine);

	machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0);
	if (machine->gpio_hp_det == -EPROBE_DEFER)
		return -EPROBE_DEFER;

	machine->gpio_mic_present = of_get_named_gpio(np,
			"nvidia,mic-present-gpios", 0);
	if (machine->gpio_mic_present == -EPROBE_DEFER)
		return -EPROBE_DEFER;

	machine->gpio_hp_en = of_get_named_gpio(np, "nvidia,hp-en-gpios", 0);
	if (machine->gpio_hp_en == -EPROBE_DEFER)
		return -EPROBE_DEFER;
	if (gpio_is_valid(machine->gpio_hp_en)) {
		ret = devm_gpio_request_one(&pdev->dev, machine->gpio_hp_en,
				GPIOF_OUT_INIT_LOW, "hp_en");
		if (ret) {
			dev_err(card->dev, "cannot get hp_en gpio\n");
			return ret;
		}
	}

	machine->gpio_dmic_clk_en = of_get_named_gpio(np,
		"nvidia,dmic-clk-en-gpios", 0);
	if (machine->gpio_dmic_clk_en == -EPROBE_DEFER)
		return -EPROBE_DEFER;
	if (gpio_is_valid(machine->gpio_dmic_clk_en)) {
		ret = devm_gpio_request_one(&pdev->dev,
				machine->gpio_dmic_clk_en,
				GPIOF_OUT_INIT_HIGH, "dmic_clk_en");
		if (ret) {
			dev_err(card->dev, "cannot get dmic_clk_en gpio\n");
			return ret;
		}
	}

	ret = snd_soc_of_parse_card_name(card, "nvidia,model");
	if (ret)
		goto err;

	ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing");
	if (ret)
		goto err;

	tegra_rt5677_dai.codec_of_node = of_parse_phandle(np,
			"nvidia,audio-codec", 0);
	if (!tegra_rt5677_dai.codec_of_node) {
		dev_err(&pdev->dev,
			"Property 'nvidia,audio-codec' missing or invalid\n");
		ret = -EINVAL;
		goto err;
	}

	tegra_rt5677_dai.cpu_of_node = of_parse_phandle(np,
			"nvidia,i2s-controller", 0);
	if (!tegra_rt5677_dai.cpu_of_node) {
		dev_err(&pdev->dev,
			"Property 'nvidia,i2s-controller' missing or invalid\n");
		ret = -EINVAL;
		goto err;
	}
	tegra_rt5677_dai.platform_of_node = tegra_rt5677_dai.cpu_of_node;

	ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
	if (ret)
		goto err;

	ret = snd_soc_register_card(card);
	if (ret) {
		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
			ret);
		goto err_fini_utils;
	}

	return 0;

err_fini_utils:
	tegra_asoc_utils_fini(&machine->util_data);
err:
	return ret;
}
Exemplo n.º 25
0
static int map_probe_dt(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct device_node *dailink_np;
	const struct of_device_id *match;
	struct of_phandle_args out_args;
	u32 fixup_index;
	int i, ret = 0;

	if (!np)
		return 1;	/* no device tree */

	ret = snd_soc_of_parse_audio_routing(&snd_soc_map, "map,dapm-route");
	if (ret) {
		dev_err(&pdev->dev, "invalid DAPM routing\n");
		return ret;
	}

	i = 0;
	for_each_child_of_node(np, dailink_np) {
		match = of_match_node(dailink_matches, dailink_np);
		if (!match)
			continue;

		if (i >= ARRAY_SIZE(map_dai)) {
			dev_err(&pdev->dev, "index 0x%x overflow map_dai\n", i);
			return -EINVAL;
		}

		map_dai[i].ops = match->data;

		ret =
		    of_parse_phandle_with_args(dailink_np, "marvell,cpu-dai",
					       "#dailink-cells", 0, &out_args);
		if (ret) {
			dev_err(&pdev->dev, "can't parse cpu-dai for ops[%d]\n",
				i);
			return -EINVAL;
		}
		map_dai[i].cpu_of_node = out_args.np;
		map_dai[i].cpu_dai_id = out_args.args[0];
		map_dai[i].platform_of_node = out_args.np;

		ret =
		    of_parse_phandle_with_args(dailink_np, "marvell,codec-dai",
					       "#dailink-cells", 0, &out_args);
		if (ret) {
			dev_err(&pdev->dev,
				"can't parse codec-dai for ops[%d]\n", i);
			return -EINVAL;
		}
		map_dai[i].codec_of_node = out_args.np;
		map_dai[i].codec_dai_id = out_args.args[0];

		ret =
		    of_property_read_string(dailink_np, "dai-name",
					    &map_dai[i].name);
		if (ret < 0) {
			dev_err(&pdev->dev, "invalid dailink name in dt!\n");
			return -EINVAL;
		}

		ret =
		    of_property_read_string(dailink_np, "stream-name",
					    &map_dai[i].stream_name);
		if (ret < 0) {
			dev_err(&pdev->dev,
				"invalid dailink stream_name in dt!\n");
			return -EINVAL;
		}

		/*
		 * snd-soc-dummy has no dt, and we need to parse codec_name.
		 * clear codec_of_node if codec doesn't have dt.
		 */
		ret =
		    of_property_read_string(dailink_np, "marvell,codec-name",
					    &map_dai[i].codec_name);
		if (ret == 0) {
			map_dai[i].codec_of_node = NULL;
			ret =
			    of_property_read_string(dailink_np,
						    "marvell,codec-dai-name",
						    &map_dai[i].codec_dai_name);
			if (ret < 0) {
				dev_err(&pdev->dev,
					"codec-name & codec-dai-name mismatch in dt!\n");
				return -EINVAL;
			}
		}

		map_dai[i].dynamic = 1;
		map_dai[i].dpcm_playback = 1;
		map_dai[i].dpcm_capture = 1;

		if (of_property_read_bool(dailink_np, "marvell,playback-only")) {
			map_dai[i].dpcm_capture = 0;
		}

		if (of_property_read_bool(dailink_np, "marvell,capture-only")) {
			map_dai[i].dpcm_playback = 0;
		}

		if (of_property_read_bool(dailink_np, "marvell,dai-no-pcm")) {
			map_dai[i].no_pcm = 1;
			map_dai[i].platform_of_node = NULL;
		}

		ret =
		    of_property_read_u32(dailink_np, "marvell,dai-fixup",
					 &fixup_index);
		if (ret == 0) {
			/* currently there are only two fixup functions */
			if (fixup_index == 0)
				map_dai[i].be_hw_params_fixup =
				    &map_aux_be_hw_params_fixup;
			else if (fixup_index == 1)
				map_dai[i].be_hw_params_fixup =
				    &map_tdm_be_hw_params_fixup;
		}

		i++;
	}
Exemplo n.º 26
0
static int imx_wm8962_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct device_node *ssi_np, *codec_np;
	struct platform_device *ssi_pdev;
	struct imx_priv *priv = &card_priv;
	struct i2c_client *codec_dev;
	struct imx_wm8962_data *data;
	int int_port, ext_port;
	int ret;

	priv->pdev = pdev;

	ret = of_property_read_u32(np, "mux-int-port", &int_port);
	if (ret) {
		dev_err(&pdev->dev, "mux-int-port missing or invalid\n");
		return ret;
	}
	ret = of_property_read_u32(np, "mux-ext-port", &ext_port);
	if (ret) {
		dev_err(&pdev->dev, "mux-ext-port missing or invalid\n");
		return ret;
	}

	/*
	 * The port numbering in the hardware manual starts at 1, while
	 * the audmux API expects it starts at 0.
	 */
	int_port--;
	ext_port--;
	ret = imx_audmux_v2_configure_port(int_port,
			IMX_AUDMUX_V2_PTCR_SYN |
			IMX_AUDMUX_V2_PTCR_TFSEL(ext_port) |
			IMX_AUDMUX_V2_PTCR_TCSEL(ext_port) |
			IMX_AUDMUX_V2_PTCR_TFSDIR |
			IMX_AUDMUX_V2_PTCR_TCLKDIR,
			IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port));
	if (ret) {
		dev_err(&pdev->dev, "audmux internal port setup failed\n");
		return ret;
	}
	ret = imx_audmux_v2_configure_port(ext_port,
			IMX_AUDMUX_V2_PTCR_SYN,
			IMX_AUDMUX_V2_PDCR_RXDSEL(int_port));
	if (ret) {
		dev_err(&pdev->dev, "audmux external port setup failed\n");
		return ret;
	}

	ssi_np = of_parse_phandle(pdev->dev.of_node, "ssi-controller", 0);
	codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
	if (!ssi_np || !codec_np) {
		dev_err(&pdev->dev, "phandle missing or invalid\n");
		ret = -EINVAL;
		goto fail;
	}

	ssi_pdev = of_find_device_by_node(ssi_np);
	if (!ssi_pdev) {
		dev_err(&pdev->dev, "failed to find SSI platform device\n");
		ret = -EINVAL;
		goto fail;
	}
	codec_dev = of_find_i2c_device_by_node(codec_np);
	if (!codec_dev || !codec_dev->dev.driver) {
		dev_err(&pdev->dev, "failed to find codec platform device\n");
		ret = -EINVAL;
		goto fail;
	}

	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
	if (!data) {
		ret = -ENOMEM;
		goto fail;
	}

	data->codec_clk = devm_clk_get(&codec_dev->dev, NULL);
	if (IS_ERR(data->codec_clk)) {
		ret = PTR_ERR(data->codec_clk);
		dev_err(&codec_dev->dev, "failed to get codec clk: %d\n", ret);
		goto fail;
	}

	data->clk_frequency = clk_get_rate(data->codec_clk);
	ret = clk_prepare_enable(data->codec_clk);
	if (ret) {
		dev_err(&codec_dev->dev, "failed to enable codec clk: %d\n", ret);
		goto fail;
	}

	data->dai.name = "HiFi";
	data->dai.stream_name = "HiFi";
	data->dai.codec_dai_name = "wm8962";
	data->dai.codec_of_node = codec_np;
	data->dai.cpu_dai_name = dev_name(&ssi_pdev->dev);
	data->dai.platform_of_node = ssi_np;
	data->dai.ops = &imx_hifi_ops;
	data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
			    SND_SOC_DAIFMT_CBM_CFM;

	data->card.dev = &pdev->dev;
	ret = snd_soc_of_parse_card_name(&data->card, "model");
	if (ret)
		goto clk_fail;
	ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing");
	if (ret)
		goto clk_fail;
	data->card.num_links = 1;
	data->card.owner = THIS_MODULE;
	data->card.dai_link = &data->dai;
	data->card.dapm_widgets = imx_wm8962_dapm_widgets;
	data->card.num_dapm_widgets = ARRAY_SIZE(imx_wm8962_dapm_widgets);

	data->card.late_probe = imx_wm8962_late_probe;
	data->card.set_bias_level = imx_wm8962_set_bias_level;

	platform_set_drvdata(pdev, &data->card);
	snd_soc_card_set_drvdata(&data->card, data);

	ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
	if (ret) {
		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
		goto clk_fail;
	}

	of_node_put(ssi_np);
	of_node_put(codec_np);

	return 0;

clk_fail:
	clk_disable_unprepare(data->codec_clk);
fail:
	of_node_put(ssi_np);
	of_node_put(codec_np);

	return ret;
}
Exemplo n.º 27
0
static int fsl_asoc_card_probe(struct platform_device *pdev)
{
	struct device_node *cpu_np, *codec_np, *asrc_np;
	struct device_node *np = pdev->dev.of_node;
	struct platform_device *asrc_pdev = NULL;
	struct platform_device *cpu_pdev;
	struct fsl_asoc_card_priv *priv;
	struct i2c_client *codec_dev;
	const char *codec_dai_name;
	u32 width;
	int ret;

	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	cpu_np = of_parse_phandle(np, "audio-cpu", 0);
	/* Give a chance to old DT binding */
	if (!cpu_np)
		cpu_np = of_parse_phandle(np, "ssi-controller", 0);
	if (!cpu_np) {
		dev_err(&pdev->dev, "CPU phandle missing or invalid\n");
		ret = -EINVAL;
		goto fail;
	}

	cpu_pdev = of_find_device_by_node(cpu_np);
	if (!cpu_pdev) {
		dev_err(&pdev->dev, "failed to find CPU DAI device\n");
		ret = -EINVAL;
		goto fail;
	}

	codec_np = of_parse_phandle(np, "audio-codec", 0);
	if (codec_np)
		codec_dev = of_find_i2c_device_by_node(codec_np);
	else
		codec_dev = NULL;

	asrc_np = of_parse_phandle(np, "audio-asrc", 0);
	if (asrc_np)
		asrc_pdev = of_find_device_by_node(asrc_np);

	/* Get the MCLK rate only, and leave it controlled by CODEC drivers */
	if (codec_dev) {
		struct clk *codec_clk = clk_get(&codec_dev->dev, NULL);

		if (!IS_ERR(codec_clk)) {
			priv->codec_priv.mclk_freq = clk_get_rate(codec_clk);
			clk_put(codec_clk);
		}
	}

	/* Default sample rate and format, will be updated in hw_params() */
	priv->sample_rate = 44100;
	priv->sample_format = SNDRV_PCM_FORMAT_S16_LE;

	/* Assign a default DAI format, and allow each card to overwrite it */
	priv->dai_fmt = DAI_FMT_BASE;

	/* Diversify the card configurations */
	if (of_device_is_compatible(np, "fsl,imx-audio-cs42888")) {
		codec_dai_name = "cs42888";
		priv->card.set_bias_level = NULL;
		priv->cpu_priv.sysclk_freq[TX] = priv->codec_priv.mclk_freq;
		priv->cpu_priv.sysclk_freq[RX] = priv->codec_priv.mclk_freq;
		priv->cpu_priv.sysclk_dir[TX] = SND_SOC_CLOCK_OUT;
		priv->cpu_priv.sysclk_dir[RX] = SND_SOC_CLOCK_OUT;
		priv->cpu_priv.slot_width = 32;
		priv->dai_fmt |= SND_SOC_DAIFMT_CBS_CFS;
	} else if (of_device_is_compatible(np, "fsl,imx-audio-cs427x")) {
		codec_dai_name = "cs4271-hifi";
		priv->codec_priv.mclk_id = CS427x_SYSCLK_MCLK;
		priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
	} else if (of_device_is_compatible(np, "fsl,imx-audio-sgtl5000")) {
		codec_dai_name = "sgtl5000";
		priv->codec_priv.mclk_id = SGTL5000_SYSCLK;
		priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
	} else if (of_device_is_compatible(np, "fsl,imx-audio-wm8962")) {
		codec_dai_name = "wm8962";
		priv->card.set_bias_level = fsl_asoc_card_set_bias_level;
		priv->codec_priv.mclk_id = WM8962_SYSCLK_MCLK;
		priv->codec_priv.fll_id = WM8962_SYSCLK_FLL;
		priv->codec_priv.pll_id = WM8962_FLL;
		priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
	} else if (of_device_is_compatible(np, "fsl,imx-audio-wm8960")) {
		codec_dai_name = "wm8960-hifi";
		priv->card.set_bias_level = fsl_asoc_card_set_bias_level;
		priv->codec_priv.fll_id = WM8960_SYSCLK_AUTO;
		priv->codec_priv.pll_id = WM8960_SYSCLK_AUTO;
		priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
	} else if (of_device_is_compatible(np, "fsl,imx-audio-ac97")) {
		codec_dai_name = "ac97-hifi";
		priv->card.set_bias_level = NULL;
		priv->dai_fmt = SND_SOC_DAIFMT_AC97;
	} else {
		dev_err(&pdev->dev, "unknown Device Tree compatible\n");
		ret = -EINVAL;
		goto asrc_fail;
	}

	if (!fsl_asoc_card_is_ac97(priv) && !codec_dev) {
		dev_err(&pdev->dev, "failed to find codec device\n");
		ret = -EINVAL;
		goto asrc_fail;
	}

	/* Common settings for corresponding Freescale CPU DAI driver */
	if (strstr(cpu_np->name, "ssi")) {
		/* Only SSI needs to configure AUDMUX */
		ret = fsl_asoc_card_audmux_init(np, priv);
		if (ret) {
			dev_err(&pdev->dev, "failed to init audmux\n");
			goto asrc_fail;
		}
	} else if (strstr(cpu_np->name, "esai")) {
		priv->cpu_priv.sysclk_id[1] = ESAI_HCKT_EXTAL;
		priv->cpu_priv.sysclk_id[0] = ESAI_HCKR_EXTAL;
	} else if (strstr(cpu_np->name, "sai")) {
		priv->cpu_priv.sysclk_id[1] = FSL_SAI_CLK_MAST1;
		priv->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1;
	}

	snprintf(priv->name, sizeof(priv->name), "%s-audio",
		 fsl_asoc_card_is_ac97(priv) ? "ac97" :
		 codec_dev->name);

	/* Initialize sound card */
	priv->pdev = pdev;
	priv->card.dev = &pdev->dev;
	priv->card.name = priv->name;
	priv->card.dai_link = priv->dai_link;
	priv->card.dapm_routes = fsl_asoc_card_is_ac97(priv) ?
				 audio_map_ac97 : audio_map;
	priv->card.late_probe = fsl_asoc_card_late_probe;
	priv->card.num_dapm_routes = ARRAY_SIZE(audio_map);
	priv->card.dapm_widgets = fsl_asoc_card_dapm_widgets;
	priv->card.num_dapm_widgets = ARRAY_SIZE(fsl_asoc_card_dapm_widgets);

	/* Drop the second half of DAPM routes -- ASRC */
	if (!asrc_pdev)
		priv->card.num_dapm_routes /= 2;

	memcpy(priv->dai_link, fsl_asoc_card_dai,
	       sizeof(struct snd_soc_dai_link) * ARRAY_SIZE(priv->dai_link));

	ret = snd_soc_of_parse_audio_routing(&priv->card, "audio-routing");
	if (ret) {
		dev_err(&pdev->dev, "failed to parse audio-routing: %d\n", ret);
		goto asrc_fail;
	}

	/* Normal DAI Link */
	priv->dai_link[0].cpu_of_node = cpu_np;
	priv->dai_link[0].codec_dai_name = codec_dai_name;

	if (!fsl_asoc_card_is_ac97(priv))
		priv->dai_link[0].codec_of_node = codec_np;
	else {
		u32 idx;

		ret = of_property_read_u32(cpu_np, "cell-index", &idx);
		if (ret) {
			dev_err(&pdev->dev,
				"cannot get CPU index property\n");
			goto asrc_fail;
		}

		priv->dai_link[0].codec_name =
				devm_kasprintf(&pdev->dev, GFP_KERNEL,
					       "ac97-codec.%u",
					       (unsigned int)idx);
	}

	priv->dai_link[0].platform_of_node = cpu_np;
	priv->dai_link[0].dai_fmt = priv->dai_fmt;
	priv->card.num_links = 1;

	if (asrc_pdev) {
		/* DPCM DAI Links only if ASRC exsits */
		priv->dai_link[1].cpu_of_node = asrc_np;
		priv->dai_link[1].platform_of_node = asrc_np;
		priv->dai_link[2].codec_dai_name = codec_dai_name;
		priv->dai_link[2].codec_of_node = codec_np;
		priv->dai_link[2].codec_name =
				priv->dai_link[0].codec_name;
		priv->dai_link[2].cpu_of_node = cpu_np;
		priv->dai_link[2].dai_fmt = priv->dai_fmt;
		priv->card.num_links = 3;

		ret = of_property_read_u32(asrc_np, "fsl,asrc-rate",
					   &priv->asrc_rate);
		if (ret) {
			dev_err(&pdev->dev, "failed to get output rate\n");
			ret = -EINVAL;
			goto asrc_fail;
		}

		ret = of_property_read_u32(asrc_np, "fsl,asrc-width", &width);
		if (ret) {
			dev_err(&pdev->dev, "failed to get output rate\n");
			ret = -EINVAL;
			goto asrc_fail;
		}

		if (width == 24)
			priv->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
		else
			priv->asrc_format = SNDRV_PCM_FORMAT_S16_LE;
	}

	/* Finish card registering */
	platform_set_drvdata(pdev, priv);
	snd_soc_card_set_drvdata(&priv->card, priv);

	ret = devm_snd_soc_register_card(&pdev->dev, &priv->card);
	if (ret)
		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);

asrc_fail:
	of_node_put(asrc_np);
	of_node_put(codec_np);
fail:
	of_node_put(cpu_np);

	return ret;
}
Exemplo n.º 28
0
static __devinit int msm8226_asoc_machine_probe(struct platform_device *pdev)
{
	struct snd_soc_card *card = &snd_soc_card_msm8226;
	struct msm8226_asoc_mach_data *pdata;
	int ret;
	const char *auxpcm_pri_gpio_set = NULL;

	if (!pdev->dev.of_node) {
		dev_err(&pdev->dev, "No platform supplied from device tree\n");
		return -EINVAL;
	}

	pdata = devm_kzalloc(&pdev->dev,
			sizeof(struct msm8226_asoc_mach_data), GFP_KERNEL);
	if (!pdata) {
		dev_err(&pdev->dev, "Can't allocate msm8226_asoc_mach_data\n");
		ret = -ENOMEM;
		goto err;
	}

	/* Parse AUXPCM info from DT */
	ret = msm8226_dtparse_auxpcm(pdev, &pdata->auxpcm_ctrl,
					msm_auxpcm_gpio_name);
	if (ret) {
		dev_err(&pdev->dev,
		"%s: Auxpcm pin data parse failed\n", __func__);
		goto err;
	}

	card->dev = &pdev->dev;
	platform_set_drvdata(pdev, card);
	snd_soc_card_set_drvdata(card, pdata);

	ret = snd_soc_of_parse_card_name(card, "qcom,model");
	if (ret)
		goto err;

	ret = snd_soc_of_parse_audio_routing(card,
			"qcom,audio-routing");
	if (ret)
		goto err;

	ret = of_property_read_u32(pdev->dev.of_node,
			"qcom,tapan-mclk-clk-freq", &pdata->mclk_freq);
	if (ret) {
		dev_err(&pdev->dev, "Looking up %s property in node %s failed",
			"qcom,tapan-mclk-clk-freq",
			pdev->dev.of_node->full_name);
		goto err;
	}

	if (pdata->mclk_freq != 9600000) {
		dev_err(&pdev->dev, "unsupported tapan mclk freq %u\n",
			pdata->mclk_freq);
		ret = -EINVAL;
		goto err;
	}

	pdata->mclk_gpio = of_get_named_gpio(pdev->dev.of_node,
				"qcom,cdc-mclk-gpios", 0);
	if (pdata->mclk_gpio < 0) {
		dev_err(&pdev->dev,
			"Looking up %s property in node %s failed %d\n",
			"qcom, cdc-mclk-gpios", pdev->dev.of_node->full_name,
			pdata->mclk_gpio);
		ret = -ENODEV;
		goto err;
	}

	vdd_spkr_gpio = of_get_named_gpio(pdev->dev.of_node,
				"qcom,cdc-vdd-spkr-gpios", 0);
	if (vdd_spkr_gpio < 0) {
		dev_err(&pdev->dev,
			"Looking up %s property in node %s failed %d\n",
			"qcom, cdc-vdd-spkr-gpios",
			pdev->dev.of_node->full_name, vdd_spkr_gpio);
	} else {
		ret = gpio_request(vdd_spkr_gpio, "TAPAN_CODEC_VDD_SPKR");
		if (ret) {
			/* GPIO to enable EXT VDD exists, but failed request */
			dev_err(card->dev,
					"%s: Failed to request tapan vdd spkr gpio %d\n",
					__func__, vdd_spkr_gpio);
			goto err;
		}
	}

	mbhc_cfg.gpio_level_insert = of_property_read_bool(pdev->dev.of_node,
					"qcom,headset-jack-type-NO");
	msm8226_setup_hs_jack(pdev, pdata);

	ret = msm8226_prepare_codec_mclk(card);
	if (ret)
		goto err_vdd_spkr;

	ret = snd_soc_register_card(card);
	if (ret) {
		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
			ret);
		goto err_vdd_spkr;
	}
	mutex_init(&cdc_mclk_mutex);

	ret = of_property_read_string(pdev->dev.of_node,
			"qcom,prim-auxpcm-gpio-set", &auxpcm_pri_gpio_set);
	if (ret) {
		dev_err(&pdev->dev, "Looking up %s property in node %s failed",
			"qcom,prim-auxpcm-gpio-set",
			pdev->dev.of_node->full_name);
		goto err_vdd_spkr;
	}
	if (!strcmp(auxpcm_pri_gpio_set, "prim-gpio-prim")) {
		lpaif_pri_muxsel_virt_addr = ioremap(LPAIF_PRI_MODE_MUXSEL, 4);
	} else if (!strcmp(auxpcm_pri_gpio_set, "prim-gpio-tert")) {
		lpaif_pri_muxsel_virt_addr = ioremap(LPAIF_TER_MODE_MUXSEL, 4);
	} else {
		dev_err(&pdev->dev, "Invalid value %s for AUXPCM GPIO set\n",
			auxpcm_pri_gpio_set);
		ret = -EINVAL;
		goto err_vdd_spkr;
	}
	if (lpaif_pri_muxsel_virt_addr == NULL) {
		pr_err("%s Pri muxsel virt addr is null\n", __func__);
		ret = -EINVAL;
		goto err_vdd_spkr;
	}

	return 0;

err_vdd_spkr:
	if (vdd_spkr_gpio >= 0) {
		gpio_free(vdd_spkr_gpio);
		vdd_spkr_gpio = -1;
	}

err:
	if (pdata->mclk_gpio > 0) {
		dev_dbg(&pdev->dev, "%s free gpio %d\n",
			__func__, pdata->mclk_gpio);
		gpio_free(pdata->mclk_gpio);
		pdata->mclk_gpio = 0;
	}
	devm_kfree(&pdev->dev, pdata);
	return ret;
}
Exemplo n.º 29
0
static int tegra_wm8903_driver_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct snd_soc_card *card = &snd_soc_tegra_wm8903;
	struct tegra_wm8903 *machine;
	int ret;

	machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8903),
			       GFP_KERNEL);
	if (!machine) {
		dev_err(&pdev->dev, "Can't allocate tegra_wm8903 struct\n");
		return -ENOMEM;
	}

	card->dev = &pdev->dev;
	platform_set_drvdata(pdev, card);
	snd_soc_card_set_drvdata(card, machine);

	machine->gpio_spkr_en = of_get_named_gpio(np, "nvidia,spkr-en-gpios",
						  0);
	if (machine->gpio_spkr_en == -EPROBE_DEFER)
		return -EPROBE_DEFER;
	if (gpio_is_valid(machine->gpio_spkr_en)) {
		ret = devm_gpio_request_one(&pdev->dev, machine->gpio_spkr_en,
					    GPIOF_OUT_INIT_LOW, "spkr_en");
		if (ret) {
			dev_err(card->dev, "cannot get spkr_en gpio\n");
			return ret;
		}
	}

	machine->gpio_hp_mute = of_get_named_gpio(np, "nvidia,hp-mute-gpios",
						  0);
	if (machine->gpio_hp_mute == -EPROBE_DEFER)
		return -EPROBE_DEFER;
	if (gpio_is_valid(machine->gpio_hp_mute)) {
		ret = devm_gpio_request_one(&pdev->dev, machine->gpio_hp_mute,
					    GPIOF_OUT_INIT_HIGH, "hp_mute");
		if (ret) {
			dev_err(card->dev, "cannot get hp_mute gpio\n");
			return ret;
		}
	}

	machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0);
	if (machine->gpio_hp_det == -EPROBE_DEFER)
		return -EPROBE_DEFER;

	machine->gpio_int_mic_en = of_get_named_gpio(np,
						"nvidia,int-mic-en-gpios", 0);
	if (machine->gpio_int_mic_en == -EPROBE_DEFER)
		return -EPROBE_DEFER;
	if (gpio_is_valid(machine->gpio_int_mic_en)) {
		/* Disable int mic; enable signal is active-high */
		ret = devm_gpio_request_one(&pdev->dev,
					    machine->gpio_int_mic_en,
					    GPIOF_OUT_INIT_LOW, "int_mic_en");
		if (ret) {
			dev_err(card->dev, "cannot get int_mic_en gpio\n");
			return ret;
		}
	}

	machine->gpio_ext_mic_en = of_get_named_gpio(np,
						"nvidia,ext-mic-en-gpios", 0);
	if (machine->gpio_ext_mic_en == -EPROBE_DEFER)
		return -EPROBE_DEFER;
	if (gpio_is_valid(machine->gpio_ext_mic_en)) {
		/* Enable ext mic; enable signal is active-low */
		ret = devm_gpio_request_one(&pdev->dev,
					    machine->gpio_ext_mic_en,
					    GPIOF_OUT_INIT_LOW, "ext_mic_en");
		if (ret) {
			dev_err(card->dev, "cannot get ext_mic_en gpio\n");
			return ret;
		}
	}

	ret = snd_soc_of_parse_card_name(card, "nvidia,model");
	if (ret)
		goto err;

	ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing");
	if (ret)
		goto err;

	tegra_wm8903_dai.codec_of_node = of_parse_phandle(np,
						"nvidia,audio-codec", 0);
	if (!tegra_wm8903_dai.codec_of_node) {
		dev_err(&pdev->dev,
			"Property 'nvidia,audio-codec' missing or invalid\n");
		ret = -EINVAL;
		goto err;
	}

	tegra_wm8903_dai.cpu_of_node = of_parse_phandle(np,
			"nvidia,i2s-controller", 0);
	if (!tegra_wm8903_dai.cpu_of_node) {
		dev_err(&pdev->dev,
			"Property 'nvidia,i2s-controller' missing or invalid\n");
		ret = -EINVAL;
		goto err;
	}

	tegra_wm8903_dai.platform_of_node = tegra_wm8903_dai.cpu_of_node;

	ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
	if (ret)
		goto err;

	ret = snd_soc_register_card(card);
	if (ret) {
		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
			ret);
		goto err_fini_utils;
	}

	return 0;

err_fini_utils:
	tegra_asoc_utils_fini(&machine->util_data);
err:
	return ret;
}
Exemplo n.º 30
0
static int aml_m8_audio_probe(struct platform_device *pdev)
{
    struct device_node *np;
    struct snd_soc_card *card = &aml_snd_soc_card;
    struct aml_audio_private_data *p_aml_audio;
	char tmp[NAME_SIZE];
    int ret = 0;

#ifdef CONFIG_USE_OF
    p_aml_audio = devm_kzalloc(&pdev->dev,
            sizeof(struct aml_audio_private_data), GFP_KERNEL);
    if (!p_aml_audio) {
        dev_err(&pdev->dev, "Can't allocate aml_audio_private_data\n");
        ret = -ENOMEM;
        goto err;
    }

    card->dev = &pdev->dev;
    platform_set_drvdata(pdev, card);
    snd_soc_card_set_drvdata(card, p_aml_audio);
    if (!(pdev->dev.of_node)) {
        dev_err(&pdev->dev, "Must be instantiated using device tree\n");
        ret = -EINVAL;
        goto err;
    }

    ret = snd_soc_of_parse_card_name(card, "aml,sound_card");
    if (ret)
        goto err;

    ret = of_property_read_string_index(pdev->dev.of_node, "aml,codec_dai",
            codec_info.codec_index, &aml_codec_dai_link[0].codec_dai_name);
    if (ret)
        goto err;

	printk("codec_name = %s\n", codec_info.name_bus);

	aml_codec_dai_link[0].codec_name = codec_info.name_bus;

    //ret = of_property_read_string_index(pdev->dev.of_node, "aml,codec_name",
    //        0, &aml_codec_dai_link[0].codec_name);
    //if (ret)
    //    goto err;

	 //aml_codec_dai_link[0].codec_of_node = of_parse_phandle(
	//		 pdev->dev.of_node, "aml,audio-codec", 0);
	snprintf(tmp, NAME_SIZE, "%s-%s", "aml,audio-routing", codec_info.name);

    ret = snd_soc_of_parse_audio_routing(card, tmp);
    if (ret)
    	goto err;

    ret = snd_soc_register_card(card);
    if (ret) {
        dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
            ret);
        goto err;
    }

    aml_m8_pinmux_init(card);


    return 0;
#endif

err:
    kfree(p_aml_audio);
    return ret;
}