Merge remote-tracking branch 'asoc/topic/tegra' into asoc-next
This commit is contained in:
commit
d14bc151a4
11 changed files with 217 additions and 226 deletions
|
@ -1,12 +1,22 @@
|
|||
NVIDIA Tegra30 AHUB (Audio Hub)
|
||||
|
||||
Required properties:
|
||||
- compatible : "nvidia,tegra30-ahub"
|
||||
- compatible : "nvidia,tegra30-ahub", "nvidia,tegra114-ahub", etc.
|
||||
- reg : Should contain the register physical address and length for each of
|
||||
the AHUB's APBIF registers and the AHUB's own registers.
|
||||
the AHUB's register blocks.
|
||||
- Tegra30 requires 2 entries, for the APBIF and AHUB/AUDIO register blocks.
|
||||
- Tegra114 requires an additional entry, for the APBIF2 register block.
|
||||
- interrupts : Should contain AHUB interrupt
|
||||
- nvidia,dma-request-selector : The Tegra DMA controller's phandle and
|
||||
request selector for the first APBIF channel.
|
||||
- nvidia,dma-request-selector : A list of the DMA channel specifiers. Each
|
||||
entry contains the Tegra DMA controller's phandle and request selector.
|
||||
If a single entry is present, the request selectors for the channels are
|
||||
assumed to be contiguous, and increment from this value.
|
||||
If multiple values are given, one value must be given per channel.
|
||||
- clocks : Must contain an entry for each required entry in clock-names.
|
||||
- clock-names : Must include the following entries:
|
||||
- Tegra30: Requires d_audio, apbif, i2s0, i2s1, i2s2, i2s3, i2s4, dam0,
|
||||
dam1, dam2, spdif_in.
|
||||
- Tegra114: Additionally requires amx, adx.
|
||||
- ranges : The bus address mapping for the configlink register bus.
|
||||
Can be empty since the mapping is 1:1.
|
||||
- #address-cells : For the configlink bus. Should be <1>;
|
||||
|
@ -25,7 +35,13 @@ ahub@70080000 {
|
|||
reg = <0x70080000 0x200 0x70080200 0x100>;
|
||||
interrupts = < 0 103 0x04 >;
|
||||
nvidia,dma-request-selector = <&apbdma 1>;
|
||||
|
||||
clocks = <&tegra_car 106>, <&tegra_car 107>, <&tegra_car 30>,
|
||||
<&tegra_car 11>, <&tegra_car 18>, <&tegra_car 101>,
|
||||
<&tegra_car 102>, <&tegra_car 108>, <&tegra_car 109>,
|
||||
<&tegra_car 110>, <&tegra_car 162>;
|
||||
clock-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2",
|
||||
"i2s3", "i2s4", "dam0", "dam1", "dam2",
|
||||
"spdif_in";
|
||||
ranges;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* Copyright 2011 NVIDIA, Inc.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SOUND_TEGRA_WM38903_H
|
||||
#define __SOUND_TEGRA_WM38903_H
|
||||
|
||||
struct tegra_wm8903_platform_data {
|
||||
int gpio_spkr_en;
|
||||
int gpio_hp_det;
|
||||
int gpio_hp_mute;
|
||||
int gpio_int_mic_en;
|
||||
int gpio_ext_mic_en;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -287,16 +287,27 @@ int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(tegra30_ahub_unset_rx_cif_source);
|
||||
|
||||
static const char * const configlink_clocks[] = {
|
||||
"i2s0",
|
||||
"i2s1",
|
||||
"i2s2",
|
||||
"i2s3",
|
||||
"i2s4",
|
||||
"dam0",
|
||||
"dam1",
|
||||
"dam2",
|
||||
"spdif_in",
|
||||
#define CLK_LIST_MASK_TEGRA30 BIT(0)
|
||||
#define CLK_LIST_MASK_TEGRA114 BIT(1)
|
||||
|
||||
#define CLK_LIST_MASK_TEGRA30_OR_LATER \
|
||||
(CLK_LIST_MASK_TEGRA30 | CLK_LIST_MASK_TEGRA114)
|
||||
|
||||
static const struct {
|
||||
const char *clk_name;
|
||||
u32 clk_list_mask;
|
||||
} configlink_clocks[] = {
|
||||
{ "i2s0", CLK_LIST_MASK_TEGRA30_OR_LATER },
|
||||
{ "i2s1", CLK_LIST_MASK_TEGRA30_OR_LATER },
|
||||
{ "i2s2", CLK_LIST_MASK_TEGRA30_OR_LATER },
|
||||
{ "i2s3", CLK_LIST_MASK_TEGRA30_OR_LATER },
|
||||
{ "i2s4", CLK_LIST_MASK_TEGRA30_OR_LATER },
|
||||
{ "dam0", CLK_LIST_MASK_TEGRA30_OR_LATER },
|
||||
{ "dam1", CLK_LIST_MASK_TEGRA30_OR_LATER },
|
||||
{ "dam2", CLK_LIST_MASK_TEGRA30_OR_LATER },
|
||||
{ "spdif_in", CLK_LIST_MASK_TEGRA30_OR_LATER },
|
||||
{ "amx", CLK_LIST_MASK_TEGRA114 },
|
||||
{ "adx", CLK_LIST_MASK_TEGRA114 },
|
||||
};
|
||||
|
||||
#define LAST_REG(name) \
|
||||
|
@ -424,8 +435,24 @@ static const struct regmap_config tegra30_ahub_ahub_regmap_config = {
|
|||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
static struct tegra30_ahub_soc_data soc_data_tegra30 = {
|
||||
.clk_list_mask = CLK_LIST_MASK_TEGRA30,
|
||||
};
|
||||
|
||||
static struct tegra30_ahub_soc_data soc_data_tegra114 = {
|
||||
.clk_list_mask = CLK_LIST_MASK_TEGRA114,
|
||||
};
|
||||
|
||||
static const struct of_device_id tegra30_ahub_of_match[] = {
|
||||
{ .compatible = "nvidia,tegra114-ahub", .data = &soc_data_tegra114 },
|
||||
{ .compatible = "nvidia,tegra30-ahub", .data = &soc_data_tegra30 },
|
||||
{},
|
||||
};
|
||||
|
||||
static int tegra30_ahub_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
const struct tegra30_ahub_soc_data *soc_data;
|
||||
struct clk *clk;
|
||||
int i;
|
||||
struct resource *res0, *res1, *region;
|
||||
|
@ -436,16 +463,24 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
|
|||
if (ahub)
|
||||
return -ENODEV;
|
||||
|
||||
match = of_match_device(tegra30_ahub_of_match, &pdev->dev);
|
||||
if (!match)
|
||||
return -EINVAL;
|
||||
soc_data = match->data;
|
||||
|
||||
/*
|
||||
* The AHUB hosts a register bus: the "configlink". For this to
|
||||
* operate correctly, all devices on this bus must be out of reset.
|
||||
* Ensure that here.
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(configlink_clocks); i++) {
|
||||
clk = clk_get(&pdev->dev, configlink_clocks[i]);
|
||||
if (!(configlink_clocks[i].clk_list_mask &
|
||||
soc_data->clk_list_mask))
|
||||
continue;
|
||||
clk = clk_get(&pdev->dev, configlink_clocks[i].clk_name);
|
||||
if (IS_ERR(clk)) {
|
||||
dev_err(&pdev->dev, "Can't get clock %s\n",
|
||||
configlink_clocks[i]);
|
||||
configlink_clocks[i].clk_name);
|
||||
ret = PTR_ERR(clk);
|
||||
goto err;
|
||||
}
|
||||
|
@ -592,11 +627,6 @@ static int tegra30_ahub_remove(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id tegra30_ahub_of_match[] = {
|
||||
{ .compatible = "nvidia,tegra30-ahub", },
|
||||
{},
|
||||
};
|
||||
|
||||
static const struct dev_pm_ops tegra30_ahub_pm_ops = {
|
||||
SET_RUNTIME_PM_OPS(tegra30_ahub_runtime_suspend,
|
||||
tegra30_ahub_runtime_resume, NULL)
|
||||
|
|
|
@ -468,7 +468,23 @@ extern int tegra30_ahub_set_rx_cif_source(enum tegra30_ahub_rxcif rxcif,
|
|||
enum tegra30_ahub_txcif txcif);
|
||||
extern int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif);
|
||||
|
||||
struct tegra30_ahub_soc_data {
|
||||
u32 clk_list_mask;
|
||||
/*
|
||||
* FIXME: There are many more differences in HW, such as:
|
||||
* - More APBIF channels.
|
||||
* - Extra separate chunks of register address space to represent
|
||||
* the extra APBIF channels.
|
||||
* - More units connected to the AHUB, so that tegra30_ahub_[rt]xcif
|
||||
* need expansion, coupled with there being more defined bits in
|
||||
* the AHUB routing registers.
|
||||
* However, the driver doesn't support those new features yet, so we
|
||||
* don't represent them here yet.
|
||||
*/
|
||||
};
|
||||
|
||||
struct tegra30_ahub {
|
||||
const struct tegra30_ahub_soc_data *soc_data;
|
||||
struct device *dev;
|
||||
struct clk *clk_d_audio;
|
||||
struct clk *clk_apbif;
|
||||
|
|
|
@ -161,20 +161,13 @@ static int tegra_alc5632_probe(struct platform_device *pdev)
|
|||
sizeof(struct tegra_alc5632), GFP_KERNEL);
|
||||
if (!alc5632) {
|
||||
dev_err(&pdev->dev, "Can't allocate tegra_alc5632\n");
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
card->dev = &pdev->dev;
|
||||
platform_set_drvdata(pdev, card);
|
||||
snd_soc_card_set_drvdata(card, alc5632);
|
||||
|
||||
if (!(pdev->dev.of_node)) {
|
||||
dev_err(&pdev->dev, "Must be instantiated using device tree\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
alc5632->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0);
|
||||
if (alc5632->gpio_hp_det == -EPROBE_DEFER)
|
||||
return -EPROBE_DEFER;
|
||||
|
@ -197,11 +190,11 @@ static int tegra_alc5632_probe(struct platform_device *pdev)
|
|||
goto err;
|
||||
}
|
||||
|
||||
tegra_alc5632_dai.cpu_of_node = of_parse_phandle(
|
||||
pdev->dev.of_node, "nvidia,i2s-controller", 0);
|
||||
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");
|
||||
"Property 'nvidia,i2s-controller' missing or invalid\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
|
|
@ -43,8 +43,10 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
|
|||
case 88200:
|
||||
if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20)
|
||||
new_baseclock = 56448000;
|
||||
else
|
||||
else if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA30)
|
||||
new_baseclock = 564480000;
|
||||
else
|
||||
new_baseclock = 282240000;
|
||||
break;
|
||||
case 8000:
|
||||
case 16000:
|
||||
|
@ -54,8 +56,10 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
|
|||
case 96000:
|
||||
if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20)
|
||||
new_baseclock = 73728000;
|
||||
else
|
||||
else if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA30)
|
||||
new_baseclock = 552960000;
|
||||
else
|
||||
new_baseclock = 368640000;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
@ -169,6 +173,7 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
|
|||
struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
bool new_clocks = false;
|
||||
|
||||
data->dev = dev;
|
||||
|
||||
|
@ -176,28 +181,37 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
|
|||
data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20;
|
||||
else if (of_machine_is_compatible("nvidia,tegra30"))
|
||||
data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA30;
|
||||
else if (!dev->of_node)
|
||||
/* non-DT is always Tegra20 */
|
||||
data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20;
|
||||
else
|
||||
/* DT boot, but unknown SoC */
|
||||
else if (of_machine_is_compatible("nvidia,tegra114")) {
|
||||
data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA114;
|
||||
new_clocks = true;
|
||||
} else {
|
||||
dev_err(data->dev, "SoC unknown to Tegra ASoC utils\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data->clk_pll_a = clk_get_sys(NULL, "pll_a");
|
||||
if (new_clocks)
|
||||
data->clk_pll_a = clk_get(dev, "pll_a");
|
||||
else
|
||||
data->clk_pll_a = clk_get_sys(NULL, "pll_a");
|
||||
if (IS_ERR(data->clk_pll_a)) {
|
||||
dev_err(data->dev, "Can't retrieve clk pll_a\n");
|
||||
ret = PTR_ERR(data->clk_pll_a);
|
||||
goto err;
|
||||
}
|
||||
|
||||
data->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0");
|
||||
if (new_clocks)
|
||||
data->clk_pll_a_out0 = clk_get(dev, "pll_a_out0");
|
||||
else
|
||||
data->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0");
|
||||
if (IS_ERR(data->clk_pll_a_out0)) {
|
||||
dev_err(data->dev, "Can't retrieve clk pll_a_out0\n");
|
||||
ret = PTR_ERR(data->clk_pll_a_out0);
|
||||
goto err_put_pll_a;
|
||||
}
|
||||
|
||||
if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20)
|
||||
if (new_clocks)
|
||||
data->clk_cdev1 = clk_get(dev, "mclk");
|
||||
else if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20)
|
||||
data->clk_cdev1 = clk_get_sys(NULL, "cdev1");
|
||||
else
|
||||
data->clk_cdev1 = clk_get_sys("extern1", NULL);
|
||||
|
|
|
@ -29,6 +29,7 @@ struct device;
|
|||
enum tegra_asoc_utils_soc {
|
||||
TEGRA_ASOC_UTILS_SOC_TEGRA20,
|
||||
TEGRA_ASOC_UTILS_SOC_TEGRA30,
|
||||
TEGRA_ASOC_UTILS_SOC_TEGRA114,
|
||||
};
|
||||
|
||||
struct tegra_asoc_utils_data {
|
||||
|
|
|
@ -124,6 +124,7 @@ static struct snd_soc_card snd_soc_tegra_wm8753 = {
|
|||
|
||||
static int tegra_wm8753_driver_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct snd_soc_card *card = &snd_soc_tegra_wm8753;
|
||||
struct tegra_wm8753 *machine;
|
||||
int ret;
|
||||
|
@ -132,8 +133,7 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev)
|
|||
GFP_KERNEL);
|
||||
if (!machine) {
|
||||
dev_err(&pdev->dev, "Can't allocate tegra_wm8753 struct\n");
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
card->dev = &pdev->dev;
|
||||
|
@ -148,8 +148,8 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
goto err;
|
||||
|
||||
tegra_wm8753_dai.codec_of_node = of_parse_phandle(
|
||||
pdev->dev.of_node, "nvidia,audio-codec", 0);
|
||||
tegra_wm8753_dai.codec_of_node = of_parse_phandle(np,
|
||||
"nvidia,audio-codec", 0);
|
||||
if (!tegra_wm8753_dai.codec_of_node) {
|
||||
dev_err(&pdev->dev,
|
||||
"Property 'nvidia,audio-codec' missing or invalid\n");
|
||||
|
@ -157,8 +157,8 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev)
|
|||
goto err;
|
||||
}
|
||||
|
||||
tegra_wm8753_dai.cpu_of_node = of_parse_phandle(
|
||||
pdev->dev.of_node, "nvidia,i2s-controller", 0);
|
||||
tegra_wm8753_dai.cpu_of_node = of_parse_phandle(np,
|
||||
"nvidia,i2s-controller", 0);
|
||||
if (!tegra_wm8753_dai.cpu_of_node) {
|
||||
dev_err(&pdev->dev,
|
||||
"Property 'nvidia,i2s-controller' missing or invalid\n");
|
||||
|
@ -166,8 +166,7 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev)
|
|||
goto err;
|
||||
}
|
||||
|
||||
tegra_wm8753_dai.platform_of_node =
|
||||
tegra_wm8753_dai.cpu_of_node;
|
||||
tegra_wm8753_dai.platform_of_node = tegra_wm8753_dai.cpu_of_node;
|
||||
|
||||
ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
|
||||
if (ret)
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/tegra_wm8903.h>
|
||||
|
||||
#include "../codecs/wm8903.h"
|
||||
|
||||
|
@ -48,7 +47,11 @@
|
|||
#define DRV_NAME "tegra-snd-wm8903"
|
||||
|
||||
struct tegra_wm8903 {
|
||||
struct tegra_wm8903_platform_data pdata;
|
||||
int gpio_spkr_en;
|
||||
int gpio_hp_det;
|
||||
int gpio_hp_mute;
|
||||
int gpio_int_mic_en;
|
||||
int gpio_ext_mic_en;
|
||||
struct tegra_asoc_utils_data util_data;
|
||||
};
|
||||
|
||||
|
@ -129,12 +132,11 @@ static int tegra_wm8903_event_int_spk(struct snd_soc_dapm_widget *w,
|
|||
struct snd_soc_dapm_context *dapm = w->dapm;
|
||||
struct snd_soc_card *card = dapm->card;
|
||||
struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
|
||||
struct tegra_wm8903_platform_data *pdata = &machine->pdata;
|
||||
|
||||
if (!gpio_is_valid(pdata->gpio_spkr_en))
|
||||
if (!gpio_is_valid(machine->gpio_spkr_en))
|
||||
return 0;
|
||||
|
||||
gpio_set_value_cansleep(pdata->gpio_spkr_en,
|
||||
gpio_set_value_cansleep(machine->gpio_spkr_en,
|
||||
SND_SOC_DAPM_EVENT_ON(event));
|
||||
|
||||
return 0;
|
||||
|
@ -146,12 +148,11 @@ static int tegra_wm8903_event_hp(struct snd_soc_dapm_widget *w,
|
|||
struct snd_soc_dapm_context *dapm = w->dapm;
|
||||
struct snd_soc_card *card = dapm->card;
|
||||
struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
|
||||
struct tegra_wm8903_platform_data *pdata = &machine->pdata;
|
||||
|
||||
if (!gpio_is_valid(pdata->gpio_hp_mute))
|
||||
if (!gpio_is_valid(machine->gpio_hp_mute))
|
||||
return 0;
|
||||
|
||||
gpio_set_value_cansleep(pdata->gpio_hp_mute,
|
||||
gpio_set_value_cansleep(machine->gpio_hp_mute,
|
||||
!SND_SOC_DAPM_EVENT_ON(event));
|
||||
|
||||
return 0;
|
||||
|
@ -163,17 +164,6 @@ static const struct snd_soc_dapm_widget tegra_wm8903_dapm_widgets[] = {
|
|||
SND_SOC_DAPM_MIC("Mic Jack", NULL),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route harmony_audio_map[] = {
|
||||
{"Headphone Jack", NULL, "HPOUTR"},
|
||||
{"Headphone Jack", NULL, "HPOUTL"},
|
||||
{"Int Spk", NULL, "ROP"},
|
||||
{"Int Spk", NULL, "RON"},
|
||||
{"Int Spk", NULL, "LOP"},
|
||||
{"Int Spk", NULL, "LON"},
|
||||
{"Mic Jack", NULL, "MICBIAS"},
|
||||
{"IN1L", NULL, "Mic Jack"},
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new tegra_wm8903_controls[] = {
|
||||
SOC_DAPM_PIN_SWITCH("Int Spk"),
|
||||
};
|
||||
|
@ -185,10 +175,9 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
|
|||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
struct snd_soc_card *card = codec->card;
|
||||
struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
|
||||
struct tegra_wm8903_platform_data *pdata = &machine->pdata;
|
||||
|
||||
if (gpio_is_valid(pdata->gpio_hp_det)) {
|
||||
tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det;
|
||||
if (gpio_is_valid(machine->gpio_hp_det)) {
|
||||
tegra_wm8903_hp_jack_gpio.gpio = machine->gpio_hp_det;
|
||||
snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
|
||||
&tegra_wm8903_hp_jack);
|
||||
snd_soc_jack_add_pins(&tegra_wm8903_hp_jack,
|
||||
|
@ -226,9 +215,6 @@ static int tegra_wm8903_remove(struct snd_soc_card *card)
|
|||
static struct snd_soc_dai_link tegra_wm8903_dai = {
|
||||
.name = "WM8903",
|
||||
.stream_name = "WM8903 PCM",
|
||||
.codec_name = "wm8903.0-001a",
|
||||
.platform_name = "tegra20-i2s.0",
|
||||
.cpu_dai_name = "tegra20-i2s.0",
|
||||
.codec_dai_name = "wm8903-hifi",
|
||||
.init = tegra_wm8903_init,
|
||||
.ops = &tegra_wm8903_ops,
|
||||
|
@ -257,96 +243,25 @@ 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_wm8903_platform_data *pdata;
|
||||
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;
|
||||
return -ENOMEM;
|
||||
}
|
||||
pdata = &machine->pdata;
|
||||
|
||||
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->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) {
|
||||
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(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_dai_name = NULL;
|
||||
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_name = NULL;
|
||||
tegra_wm8903_dai.platform_of_node =
|
||||
tegra_wm8903_dai.cpu_of_node;
|
||||
} 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,
|
||||
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");
|
||||
|
@ -354,8 +269,12 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev)
|
|||
}
|
||||
}
|
||||
|
||||
if (gpio_is_valid(pdata->gpio_hp_mute)) {
|
||||
ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_hp_mute,
|
||||
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");
|
||||
|
@ -363,9 +282,18 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev)
|
|||
}
|
||||
}
|
||||
|
||||
if (gpio_is_valid(pdata->gpio_int_mic_en)) {
|
||||
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, pdata->gpio_int_mic_en,
|
||||
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");
|
||||
|
@ -373,9 +301,14 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev)
|
|||
}
|
||||
}
|
||||
|
||||
if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
|
||||
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, pdata->gpio_ext_mic_en,
|
||||
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");
|
||||
|
@ -383,6 +316,34 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev)
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -79,11 +79,6 @@ static int tegra_wm9712_driver_probe(struct platform_device *pdev)
|
|||
struct tegra_wm9712 *machine;
|
||||
int ret;
|
||||
|
||||
if (!pdev->dev.of_node) {
|
||||
dev_err(&pdev->dev, "No platform data supplied\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm9712),
|
||||
GFP_KERNEL);
|
||||
if (!machine) {
|
||||
|
|
|
@ -97,9 +97,6 @@ static const struct snd_soc_dapm_route trimslice_audio_map[] = {
|
|||
static struct snd_soc_dai_link trimslice_tlv320aic23_dai = {
|
||||
.name = "TLV320AIC23",
|
||||
.stream_name = "AIC23",
|
||||
.codec_name = "tlv320aic23-codec.2-001a",
|
||||
.platform_name = "tegra20-i2s.0",
|
||||
.cpu_dai_name = "tegra20-i2s.0",
|
||||
.codec_dai_name = "tlv320aic23-hifi",
|
||||
.ops = &trimslice_asoc_ops,
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S |
|
||||
|
@ -122,6 +119,7 @@ static struct snd_soc_card snd_soc_trimslice = {
|
|||
|
||||
static int tegra_snd_trimslice_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct snd_soc_card *card = &snd_soc_trimslice;
|
||||
struct tegra_trimslice *trimslice;
|
||||
int ret;
|
||||
|
@ -130,44 +128,38 @@ static int tegra_snd_trimslice_probe(struct platform_device *pdev)
|
|||
GFP_KERNEL);
|
||||
if (!trimslice) {
|
||||
dev_err(&pdev->dev, "Can't allocate tegra_trimslice\n");
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (pdev->dev.of_node) {
|
||||
trimslice_tlv320aic23_dai.codec_name = NULL;
|
||||
trimslice_tlv320aic23_dai.codec_of_node = of_parse_phandle(
|
||||
pdev->dev.of_node, "nvidia,audio-codec", 0);
|
||||
if (!trimslice_tlv320aic23_dai.codec_of_node) {
|
||||
dev_err(&pdev->dev,
|
||||
"Property 'nvidia,audio-codec' missing or invalid\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
trimslice_tlv320aic23_dai.cpu_dai_name = NULL;
|
||||
trimslice_tlv320aic23_dai.cpu_of_node = of_parse_phandle(
|
||||
pdev->dev.of_node, "nvidia,i2s-controller", 0);
|
||||
if (!trimslice_tlv320aic23_dai.cpu_of_node) {
|
||||
dev_err(&pdev->dev,
|
||||
"Property 'nvidia,i2s-controller' missing or invalid\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
trimslice_tlv320aic23_dai.platform_name = NULL;
|
||||
trimslice_tlv320aic23_dai.platform_of_node =
|
||||
trimslice_tlv320aic23_dai.cpu_of_node;
|
||||
}
|
||||
|
||||
ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
card->dev = &pdev->dev;
|
||||
platform_set_drvdata(pdev, card);
|
||||
snd_soc_card_set_drvdata(card, trimslice);
|
||||
|
||||
trimslice_tlv320aic23_dai.codec_of_node = of_parse_phandle(np,
|
||||
"nvidia,audio-codec", 0);
|
||||
if (!trimslice_tlv320aic23_dai.codec_of_node) {
|
||||
dev_err(&pdev->dev,
|
||||
"Property 'nvidia,audio-codec' missing or invalid\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
trimslice_tlv320aic23_dai.cpu_of_node = of_parse_phandle(np,
|
||||
"nvidia,i2s-controller", 0);
|
||||
if (!trimslice_tlv320aic23_dai.cpu_of_node) {
|
||||
dev_err(&pdev->dev,
|
||||
"Property 'nvidia,i2s-controller' missing or invalid\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
trimslice_tlv320aic23_dai.platform_of_node =
|
||||
trimslice_tlv320aic23_dai.cpu_of_node;
|
||||
|
||||
ret = tegra_asoc_utils_init(&trimslice->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",
|
||||
|
|
Loading…
Reference in a new issue