Commit d14bc151 authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branch 'asoc/topic/tegra' into asoc-next

parents 5b9fd769 a7fc5d25
NVIDIA Tegra30 AHUB (Audio Hub) NVIDIA Tegra30 AHUB (Audio Hub)
Required properties: 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 - 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 - interrupts : Should contain AHUB interrupt
- nvidia,dma-request-selector : The Tegra DMA controller's phandle and - nvidia,dma-request-selector : A list of the DMA channel specifiers. Each
request selector for the first APBIF channel. 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. - ranges : The bus address mapping for the configlink register bus.
Can be empty since the mapping is 1:1. Can be empty since the mapping is 1:1.
- #address-cells : For the configlink bus. Should be <1>; - #address-cells : For the configlink bus. Should be <1>;
...@@ -25,7 +35,13 @@ ahub@70080000 { ...@@ -25,7 +35,13 @@ ahub@70080000 {
reg = <0x70080000 0x200 0x70080200 0x100>; reg = <0x70080000 0x200 0x70080200 0x100>;
interrupts = < 0 103 0x04 >; interrupts = < 0 103 0x04 >;
nvidia,dma-request-selector = <&apbdma 1>; 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; ranges;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
......
/*
* 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) ...@@ -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); EXPORT_SYMBOL_GPL(tegra30_ahub_unset_rx_cif_source);
static const char * const configlink_clocks[] = { #define CLK_LIST_MASK_TEGRA30 BIT(0)
"i2s0", #define CLK_LIST_MASK_TEGRA114 BIT(1)
"i2s1",
"i2s2", #define CLK_LIST_MASK_TEGRA30_OR_LATER \
"i2s3", (CLK_LIST_MASK_TEGRA30 | CLK_LIST_MASK_TEGRA114)
"i2s4",
"dam0", static const struct {
"dam1", const char *clk_name;
"dam2", u32 clk_list_mask;
"spdif_in", } 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) \ #define LAST_REG(name) \
...@@ -424,8 +435,24 @@ static const struct regmap_config tegra30_ahub_ahub_regmap_config = { ...@@ -424,8 +435,24 @@ static const struct regmap_config tegra30_ahub_ahub_regmap_config = {
.cache_type = REGCACHE_RBTREE, .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) 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; struct clk *clk;
int i; int i;
struct resource *res0, *res1, *region; struct resource *res0, *res1, *region;
...@@ -436,16 +463,24 @@ static int tegra30_ahub_probe(struct platform_device *pdev) ...@@ -436,16 +463,24 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
if (ahub) if (ahub)
return -ENODEV; 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 * The AHUB hosts a register bus: the "configlink". For this to
* operate correctly, all devices on this bus must be out of reset. * operate correctly, all devices on this bus must be out of reset.
* Ensure that here. * Ensure that here.
*/ */
for (i = 0; i < ARRAY_SIZE(configlink_clocks); i++) { 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)) { if (IS_ERR(clk)) {
dev_err(&pdev->dev, "Can't get clock %s\n", dev_err(&pdev->dev, "Can't get clock %s\n",
configlink_clocks[i]); configlink_clocks[i].clk_name);
ret = PTR_ERR(clk); ret = PTR_ERR(clk);
goto err; goto err;
} }
...@@ -592,11 +627,6 @@ static int tegra30_ahub_remove(struct platform_device *pdev) ...@@ -592,11 +627,6 @@ static int tegra30_ahub_remove(struct platform_device *pdev)
return 0; 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 = { static const struct dev_pm_ops tegra30_ahub_pm_ops = {
SET_RUNTIME_PM_OPS(tegra30_ahub_runtime_suspend, SET_RUNTIME_PM_OPS(tegra30_ahub_runtime_suspend,
tegra30_ahub_runtime_resume, NULL) tegra30_ahub_runtime_resume, NULL)
......
...@@ -468,7 +468,23 @@ extern int tegra30_ahub_set_rx_cif_source(enum tegra30_ahub_rxcif rxcif, ...@@ -468,7 +468,23 @@ extern int tegra30_ahub_set_rx_cif_source(enum tegra30_ahub_rxcif rxcif,
enum tegra30_ahub_txcif txcif); enum tegra30_ahub_txcif txcif);
extern int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif); 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 { struct tegra30_ahub {
const struct tegra30_ahub_soc_data *soc_data;
struct device *dev; struct device *dev;
struct clk *clk_d_audio; struct clk *clk_d_audio;
struct clk *clk_apbif; struct clk *clk_apbif;
......
...@@ -161,20 +161,13 @@ static int tegra_alc5632_probe(struct platform_device *pdev) ...@@ -161,20 +161,13 @@ static int tegra_alc5632_probe(struct platform_device *pdev)
sizeof(struct tegra_alc5632), GFP_KERNEL); sizeof(struct tegra_alc5632), GFP_KERNEL);
if (!alc5632) { if (!alc5632) {
dev_err(&pdev->dev, "Can't allocate tegra_alc5632\n"); dev_err(&pdev->dev, "Can't allocate tegra_alc5632\n");
ret = -ENOMEM; return -ENOMEM;
goto err;
} }
card->dev = &pdev->dev; card->dev = &pdev->dev;
platform_set_drvdata(pdev, card); platform_set_drvdata(pdev, card);
snd_soc_card_set_drvdata(card, alc5632); 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); alc5632->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0);
if (alc5632->gpio_hp_det == -EPROBE_DEFER) if (alc5632->gpio_hp_det == -EPROBE_DEFER)
return -EPROBE_DEFER; return -EPROBE_DEFER;
...@@ -197,11 +190,11 @@ static int tegra_alc5632_probe(struct platform_device *pdev) ...@@ -197,11 +190,11 @@ static int tegra_alc5632_probe(struct platform_device *pdev)
goto err; goto err;
} }
tegra_alc5632_dai.cpu_of_node = of_parse_phandle( tegra_alc5632_dai.cpu_of_node = of_parse_phandle(np,
pdev->dev.of_node, "nvidia,i2s-controller", 0); "nvidia,i2s-controller", 0);
if (!tegra_alc5632_dai.cpu_of_node) { if (!tegra_alc5632_dai.cpu_of_node) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
"Property 'nvidia,i2s-controller' missing or invalid\n"); "Property 'nvidia,i2s-controller' missing or invalid\n");
ret = -EINVAL; ret = -EINVAL;
goto err; goto err;
} }
......
...@@ -43,8 +43,10 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, ...@@ -43,8 +43,10 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
case 88200: case 88200:
if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20) if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20)
new_baseclock = 56448000; new_baseclock = 56448000;
else else if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA30)
new_baseclock = 564480000; new_baseclock = 564480000;
else
new_baseclock = 282240000;
break; break;
case 8000: case 8000:
case 16000: case 16000:
...@@ -54,8 +56,10 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, ...@@ -54,8 +56,10 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
case 96000: case 96000:
if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20) if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20)
new_baseclock = 73728000; new_baseclock = 73728000;
else else if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA30)
new_baseclock = 552960000; new_baseclock = 552960000;
else
new_baseclock = 368640000;
break; break;
default: default:
return -EINVAL; return -EINVAL;
...@@ -169,6 +173,7 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, ...@@ -169,6 +173,7 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
struct device *dev) struct device *dev)
{ {
int ret; int ret;
bool new_clocks = false;
data->dev = dev; data->dev = dev;
...@@ -176,28 +181,37 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, ...@@ -176,28 +181,37 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20; data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20;
else if (of_machine_is_compatible("nvidia,tegra30")) else if (of_machine_is_compatible("nvidia,tegra30"))
data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA30; data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA30;
else if (!dev->of_node) else if (of_machine_is_compatible("nvidia,tegra114")) {
/* non-DT is always Tegra20 */ data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA114;
data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20; new_clocks = true;
else } else {
/* DT boot, but unknown SoC */ dev_err(data->dev, "SoC unknown to Tegra ASoC utils\n");
return -EINVAL; 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)) { if (IS_ERR(data->clk_pll_a)) {
dev_err(data->dev, "Can't retrieve clk pll_a\n"); dev_err(data->dev, "Can't retrieve clk pll_a\n");
ret = PTR_ERR(data->clk_pll_a); ret = PTR_ERR(data->clk_pll_a);
goto err; 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)) { if (IS_ERR(data->clk_pll_a_out0)) {
dev_err(data->dev, "Can't retrieve clk pll_a_out0\n"); dev_err(data->dev, "Can't retrieve clk pll_a_out0\n");
ret = PTR_ERR(data->clk_pll_a_out0); ret = PTR_ERR(data->clk_pll_a_out0);
goto err_put_pll_a; 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"); data->clk_cdev1 = clk_get_sys(NULL, "cdev1");
else else
data->clk_cdev1 = clk_get_sys("extern1", NULL); data->clk_cdev1 = clk_get_sys("extern1", NULL);
......
...@@ -29,6 +29,7 @@ struct device; ...@@ -29,6 +29,7 @@ struct device;
enum tegra_asoc_utils_soc { enum tegra_asoc_utils_soc {
TEGRA_ASOC_UTILS_SOC_TEGRA20, TEGRA_ASOC_UTILS_SOC_TEGRA20,
TEGRA_ASOC_UTILS_SOC_TEGRA30, TEGRA_ASOC_UTILS_SOC_TEGRA30,
TEGRA_ASOC_UTILS_SOC_TEGRA114,
}; };
struct tegra_asoc_utils_data { struct tegra_asoc_utils_data {
......
...@@ -124,6 +124,7 @@ static struct snd_soc_card snd_soc_tegra_wm8753 = { ...@@ -124,6 +124,7 @@ static struct snd_soc_card snd_soc_tegra_wm8753 = {
static int tegra_wm8753_driver_probe(struct platform_device *pdev) 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 snd_soc_card *card = &snd_soc_tegra_wm8753;
struct tegra_wm8753 *machine; struct tegra_wm8753 *machine;
int ret; int ret;
...@@ -132,8 +133,7 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev) ...@@ -132,8 +133,7 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev)
GFP_KERNEL); GFP_KERNEL);
if (!machine) { if (!machine) {
dev_err(&pdev->dev, "Can't allocate tegra_wm8753 struct\n"); dev_err(&pdev->dev, "Can't allocate tegra_wm8753 struct\n");
ret = -ENOMEM; return -ENOMEM;
goto err;
} }
card->dev = &pdev->dev; card->dev = &pdev->dev;
...@@ -148,8 +148,8 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev) ...@@ -148,8 +148,8 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev)
if (ret) if (ret)
goto err; goto err;
tegra_wm8753_dai.codec_of_node = of_parse_phandle( tegra_wm8753_dai.codec_of_node = of_parse_phandle(np,
pdev->dev.of_node, "nvidia,audio-codec", 0); "nvidia,audio-codec", 0);
if (!tegra_wm8753_dai.codec_of_node) { if (!tegra_wm8753_dai.codec_of_node) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
"Property 'nvidia,audio-codec' missing or invalid\n"); "Property 'nvidia,audio-codec' missing or invalid\n");
...@@ -157,8 +157,8 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev) ...@@ -157,8 +157,8 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev)
goto err; goto err;
} }
tegra_wm8753_dai.cpu_of_node = of_parse_phandle( tegra_wm8753_dai.cpu_of_node = of_parse_phandle(np,
pdev->dev.of_node, "nvidia,i2s-controller", 0); "nvidia,i2s-controller", 0);
if (!tegra_wm8753_dai.cpu_of_node) { if (!tegra_wm8753_dai.cpu_of_node) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
"Property 'nvidia,i2s-controller' missing or invalid\n"); "Property 'nvidia,i2s-controller' missing or invalid\n");
...@@ -166,8 +166,7 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev) ...@@ -166,8 +166,7 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev)
goto err; goto err;
} }
tegra_wm8753_dai.platform_of_node = tegra_wm8753_dai.platform_of_node = tegra_wm8753_dai.cpu_of_node;
tegra_wm8753_dai.cpu_of_node;
ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
if (ret) if (ret)
......
...@@ -39,7 +39,6 @@ ...@@ -39,7 +39,6 @@
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/tegra_wm8903.h>
#include "../codecs/wm8903.h" #include "../codecs/wm8903.h"
...@@ -48,7 +47,11 @@ ...@@ -48,7 +47,11 @@
#define DRV_NAME "tegra-snd-wm8903" #define DRV_NAME "tegra-snd-wm8903"
struct tegra_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; struct tegra_asoc_utils_data util_data;
}; };
...@@ -129,12 +132,11 @@ static int tegra_wm8903_event_int_spk(struct snd_soc_dapm_widget *w, ...@@ -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_dapm_context *dapm = w->dapm;
struct snd_soc_card *card = dapm->card; struct snd_soc_card *card = dapm->card;
struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(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; return 0;
gpio_set_value_cansleep(pdata->gpio_spkr_en, gpio_set_value_cansleep(machine->gpio_spkr_en,
SND_SOC_DAPM_EVENT_ON(event)); SND_SOC_DAPM_EVENT_ON(event));
return 0; return 0;
...@@ -146,12 +148,11 @@ static int tegra_wm8903_event_hp(struct snd_soc_dapm_widget *w, ...@@ -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_dapm_context *dapm = w->dapm;
struct snd_soc_card *card = dapm->card; struct snd_soc_card *card = dapm->card;
struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(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; return 0;
gpio_set_value_cansleep(pdata->gpio_hp_mute, gpio_set_value_cansleep(machine->gpio_hp_mute,
!SND_SOC_DAPM_EVENT_ON(event)); !SND_SOC_DAPM_EVENT_ON(event));
return 0; return 0;
...@@ -163,17 +164,6 @@ static const struct snd_soc_dapm_widget tegra_wm8903_dapm_widgets[] = { ...@@ -163,17 +164,6 @@ static const struct snd_soc_dapm_widget tegra_wm8903_dapm_widgets[] = {
SND_SOC_DAPM_MIC("Mic Jack", NULL), 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[] = { static const struct snd_kcontrol_new tegra_wm8903_controls[] = {
SOC_DAPM_PIN_SWITCH("Int Spk"), SOC_DAPM_PIN_SWITCH("Int Spk"),
}; };
...@@ -185,10 +175,9 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) ...@@ -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_dapm_context *dapm = &codec->dapm;
struct snd_soc_card *card = codec->card; struct snd_soc_card *card = codec->card;
struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(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)) { if (gpio_is_valid(machine->gpio_hp_det)) {
tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det; tegra_wm8903_hp_jack_gpio.gpio = machine->gpio_hp_det;
snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
&tegra_wm8903_hp_jack); &tegra_wm8903_hp_jack);
snd_soc_jack_add_pins(&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) ...@@ -226,9 +215,6 @@ static int tegra_wm8903_remove(struct snd_soc_card *card)
static struct snd_soc_dai_link tegra_wm8903_dai = { static struct snd_soc_dai_link tegra_wm8903_dai = {
.name = "WM8903", .name = "WM8903",
.stream_name = "WM8903 PCM", .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", .codec_dai_name = "wm8903-hifi",
.init = tegra_wm8903_init, .init = tegra_wm8903_init,
.ops = &tegra_wm8903_ops, .ops = &tegra_wm8903_ops,
...@@ -257,96 +243,25 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev) ...@@ -257,96 +243,25 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev)
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
struct snd_soc_card *card = &snd_soc_tegra_wm8903; struct snd_soc_card *card = &snd_soc_tegra_wm8903;
struct tegra_wm8903 *machine; struct tegra_wm8903 *machine;
struct tegra_wm8903_platform_data *pdata;
int ret; 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), machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8903),
GFP_KERNEL); GFP_KERNEL);
if (!machine) { if (!machine) {
dev_err(&pdev->dev, "Can't allocate tegra_wm8903 struct\n"); dev_err(&pdev->dev, "Can't allocate tegra_wm8903 struct\n");
ret = -ENOMEM; return -ENOMEM;
goto err;
} }
pdata = &machine->pdata;
card->dev = &pdev->dev; card->dev = &pdev->dev;
platform_set_drvdata(pdev, card); platform_set_drvdata(pdev, card);
snd_soc_card_set_drvdata(card, machine); snd_soc_card_set_drvdata(card, machine);
if (pdev->dev.platform_data) { machine->gpio_spkr_en = of_get_named_gpio(np, "nvidia,spkr-en-gpios",
memcpy(pdata, card->dev->platform_data, sizeof(*pdata)); 0);
} else if (np) { if (machine->gpio_spkr_en == -EPROBE_DEFER)
pdata->gpio_spkr_en = of_get_named_gpio(np, return -EPROBE_DEFER;
"nvidia,spkr-en-gpios", 0); if (gpio_is_valid(machine->gpio_spkr_en)) {
if (pdata->gpio_spkr_en == -EPROBE_DEFER) ret = devm_gpio_request_one(&pdev->dev, machine->gpio_spkr_en,
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,
GPIOF_OUT_INIT_LOW, "spkr_en"); GPIOF_OUT_INIT_LOW, "spkr_en");
if (ret) { if (ret) {
dev_err(card->dev, "cannot get spkr_en gpio\n"); dev_err(card->dev, "cannot get spkr_en gpio\n");
...@@ -354,8 +269,12 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev) ...@@ -354,8 +269,12 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev)
} }
} }
if (gpio_is_valid(pdata->gpio_hp_mute)) { machine->gpio_hp_mute = of_get_named_gpio(np, "nvidia,hp-mute-gpios",
ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_hp_mute, 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"); GPIOF_OUT_INIT_HIGH, "hp_mute");
if (ret) { if (ret) {
dev_err(card->dev, "cannot get hp_mute gpio\n"); dev_err(card->dev, "cannot get hp_mute gpio\n");
...@@ -363,9 +282,18 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev) ...@@ -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 */ /* 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"); GPIOF_OUT_INIT_LOW, "int_mic_en");
if (ret) { if (ret) {
dev_err(card->dev, "cannot get int_mic_en gpio\n"); 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) ...@@ -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 */ /* 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"); GPIOF_OUT_INIT_LOW, "ext_mic_en");
if (ret) { if (ret) {
dev_err(card->dev, "cannot get ext_mic_en gpio\n"); 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) ...@@ -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); ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
if (ret) if (ret)
goto err; goto err;
......
...@@ -79,11 +79,6 @@ static int tegra_wm9712_driver_probe(struct platform_device *pdev) ...@@ -79,11 +79,6 @@ static int tegra_wm9712_driver_probe(struct platform_device *pdev)
struct tegra_wm9712 *machine; struct tegra_wm9712 *machine;
int ret; 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), machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm9712),
GFP_KERNEL); GFP_KERNEL);
if (!machine) { if (!machine) {
......
...@@ -97,9 +97,6 @@ static const struct snd_soc_dapm_route trimslice_audio_map[] = { ...@@ -97,9 +97,6 @@ static const struct snd_soc_dapm_route trimslice_audio_map[] = {
static struct snd_soc_dai_link trimslice_tlv320aic23_dai = { static struct snd_soc_dai_link trimslice_tlv320aic23_dai = {
.name = "TLV320AIC23", .name = "TLV320AIC23",
.stream_name = "AIC23", .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", .codec_dai_name = "tlv320aic23-hifi",
.ops = &trimslice_asoc_ops, .ops = &trimslice_asoc_ops,
.dai_fmt = SND_SOC_DAIFMT_I2S | .dai_fmt = SND_SOC_DAIFMT_I2S |
...@@ -122,6 +119,7 @@ static struct snd_soc_card snd_soc_trimslice = { ...@@ -122,6 +119,7 @@ static struct snd_soc_card snd_soc_trimslice = {
static int tegra_snd_trimslice_probe(struct platform_device *pdev) 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 snd_soc_card *card = &snd_soc_trimslice;
struct tegra_trimslice *trimslice; struct tegra_trimslice *trimslice;
int ret; int ret;
...@@ -130,44 +128,38 @@ static int tegra_snd_trimslice_probe(struct platform_device *pdev) ...@@ -130,44 +128,38 @@ static int tegra_snd_trimslice_probe(struct platform_device *pdev)
GFP_KERNEL); GFP_KERNEL);
if (!trimslice) { if (!trimslice) {
dev_err(&pdev->dev, "Can't allocate tegra_trimslice\n"); dev_err(&pdev->dev, "Can't allocate tegra_trimslice\n");
ret = -ENOMEM; return -ENOMEM;
}
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; goto err;
} }
if (pdev->dev.of_node) { trimslice_tlv320aic23_dai.cpu_of_node = of_parse_phandle(np,
trimslice_tlv320aic23_dai.codec_name = NULL; "nvidia,i2s-controller", 0);
trimslice_tlv320aic23_dai.codec_of_node = of_parse_phandle( if (!trimslice_tlv320aic23_dai.cpu_of_node) {
pdev->dev.of_node, "nvidia,audio-codec", 0); dev_err(&pdev->dev,
if (!trimslice_tlv320aic23_dai.codec_of_node) { "Property 'nvidia,i2s-controller' missing or invalid\n");
dev_err(&pdev->dev, ret = -EINVAL;
"Property 'nvidia,audio-codec' missing or invalid\n"); goto err;
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;
} }
trimslice_tlv320aic23_dai.platform_of_node =
trimslice_tlv320aic23_dai.cpu_of_node;
ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev); ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev);
if (ret) if (ret)
goto err; goto err;
card->dev = &pdev->dev;
platform_set_drvdata(pdev, card);
snd_soc_card_set_drvdata(card, trimslice);
ret = snd_soc_register_card(card); ret = snd_soc_register_card(card);
if (ret) { if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment