All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/7] ARM: tegra: add ac97 clock
@ 2012-12-19 23:17 Lucas Stach
       [not found] ` <1355959056-6009-1-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
  0 siblings, 1 reply; 21+ messages in thread
From: Lucas Stach @ 2012-12-19 23:17 UTC (permalink / raw)
  To: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
  Cc: patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	Liam Girdwood, Mark Brown, Stephen Warren,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

Add clock used by the AC97 host controller.

Signed-off-by: Lucas Stach <dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
---
 arch/arm/mach-tegra/board-dt-tegra20.c    | 2 ++
 arch/arm/mach-tegra/tegra20_clocks_data.c | 2 ++
 2 Dateien geändert, 4 Zeilen hinzugefügt(+)

diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c
index 734d9cc..acff2bd 100644
--- a/arch/arm/mach-tegra/board-dt-tegra20.c
+++ b/arch/arm/mach-tegra/board-dt-tegra20.c
@@ -78,6 +78,7 @@ struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
 	OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C2_BASE, "tegra-i2c.1", NULL),
 	OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C3_BASE, "tegra-i2c.2", NULL),
 	OF_DEV_AUXDATA("nvidia,tegra20-i2c-dvc", TEGRA_DVC_BASE, "tegra-i2c.3", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-ac97", TEGRA_AC97_BASE, "tegra20-ac97", NULL),
 	OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S1_BASE, "tegra20-i2s.0", NULL),
 	OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S2_BASE, "tegra20-i2s.1", NULL),
 	OF_DEV_AUXDATA("nvidia,tegra20-das", TEGRA_APB_MISC_DAS_BASE, "tegra20-das", NULL),
@@ -114,6 +115,7 @@ static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = {
 	{ "pll_a_out0", "pll_a",        11289600,       true },
 	{ "cdev1",      NULL,           0,              true },
 	{ "blink",      "clk_32k",      32768,          true },
+	{ "ac97",       "pll_a_out0",   24576000,       false},
 	{ "i2s1",       "pll_a_out0",   11289600,       false},
 	{ "i2s2",       "pll_a_out0",   11289600,       false},
 	{ "sdmmc1",	"pll_p",	48000000,	false},
diff --git a/arch/arm/mach-tegra/tegra20_clocks_data.c b/arch/arm/mach-tegra/tegra20_clocks_data.c
index a23a073..33f1230 100644
--- a/arch/arm/mach-tegra/tegra20_clocks_data.c
+++ b/arch/arm/mach-tegra/tegra20_clocks_data.c
@@ -891,6 +891,7 @@ DEFINE_CLK_TEGRA(emc, 0, &tegra_emc_clk_ops, 0, mux_pllm_pllc_pllp_clkm,
 PERIPH_CLK(apbdma,	"tegra-apbdma",		NULL,	34,	0,	108000000, mux_pclk,			0);
 PERIPH_CLK(rtc,		"rtc-tegra",		NULL,	4,	0,	32768,     mux_clk_32k,			PERIPH_NO_RESET);
 PERIPH_CLK(timer,	"timer",		NULL,	5,	0,	26000000,  mux_clk_m,			0);
+PERIPH_CLK(ac97,	"tegra20-ac97",		NULL,	3,	0,	26000000,  mux_pllaout0_audio2x_pllp_clkm,	DIV_U71);
 PERIPH_CLK(i2s1,	"tegra20-i2s.0",	NULL,	11,	0x100,	26000000,  mux_pllaout0_audio2x_pllp_clkm,	MUX | DIV_U71);
 PERIPH_CLK(i2s2,	"tegra20-i2s.1",	NULL,	18,	0x104,	26000000,  mux_pllaout0_audio2x_pllp_clkm,	MUX | DIV_U71);
 PERIPH_CLK(spdif_out,	"spdif_out",		NULL,	10,	0x108,	100000000, mux_pllaout0_audio2x_pllp_clkm,	MUX | DIV_U71);
@@ -957,6 +958,7 @@ static struct clk *tegra_list_clks[] = {
 	&tegra_apbdma,
 	&tegra_rtc,
 	&tegra_timer,
+	&tegra_ac97,
 	&tegra_i2s1,
 	&tegra_i2s2,
 	&tegra_spdif_out,
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 2/7] ASoC: allow wolfson wm9712 codec to be instantiated using device tree
       [not found] ` <1355959056-6009-1-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
@ 2012-12-19 23:17   ` Lucas Stach
       [not found]     ` <1355959056-6009-2-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
  2012-12-19 23:17   ` [PATCH 3/7] ASoC: tegra: setup DAP3<->DAC3 connection by default Lucas Stach
                     ` (5 subsequent siblings)
  6 siblings, 1 reply; 21+ messages in thread
From: Lucas Stach @ 2012-12-19 23:17 UTC (permalink / raw)
  To: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
  Cc: patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	Liam Girdwood, Mark Brown, Stephen Warren,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

Signed-off-by: Lucas Stach <dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
---
 sound/soc/codecs/wm9712.c | 7 +++++++
 1 Datei geändert, 7 Zeilen hinzugefügt(+)

diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 8e9a6a3..4050e6a 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -697,10 +697,17 @@ static int wm9712_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct of_device_id wm9712_of_match[] = {
+	{ .compatible = "wlf,wm9712", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, wm9712_of_match);
+
 static struct platform_driver wm9712_codec_driver = {
 	.driver = {
 		.name = "wm9712-codec",
 		.owner = THIS_MODULE,
+		.of_match_table = wm9712_of_match,
 	},
 
 	.probe = wm9712_probe,
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 3/7] ASoC: tegra: setup DAP3<->DAC3 connection by default
       [not found] ` <1355959056-6009-1-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
  2012-12-19 23:17   ` [PATCH 2/7] ASoC: allow wolfson wm9712 codec to be instantiated using device tree Lucas Stach
@ 2012-12-19 23:17   ` Lucas Stach
       [not found]     ` <1355959056-6009-3-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
  2012-12-19 23:17   ` [PATCH 4/7] ASoC: tegra: add function to set ac97 rate Lucas Stach
                     ` (4 subsequent siblings)
  6 siblings, 1 reply; 21+ messages in thread
From: Lucas Stach @ 2012-12-19 23:17 UTC (permalink / raw)
  To: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
  Cc: patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	Liam Girdwood, Mark Brown, Stephen Warren,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

This connection is used by the AC97 controller.

Signed-off-by: Lucas Stach <dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
---
 sound/soc/tegra/tegra20_das.c | 13 +++++++++++++
 1 Datei geändert, 13 Zeilen hinzugefügt(+)

diff --git a/sound/soc/tegra/tegra20_das.c b/sound/soc/tegra/tegra20_das.c
index 6543184..e723929 100644
--- a/sound/soc/tegra/tegra20_das.c
+++ b/sound/soc/tegra/tegra20_das.c
@@ -191,6 +191,19 @@ static int tegra20_das_probe(struct platform_device *pdev)
 		goto err;
 	}
 
+	ret = tegra20_das_connect_dap_to_dac(TEGRA20_DAS_DAP_ID_3,
+					     TEGRA20_DAS_DAP_SEL_DAC3);
+	if (ret) {
+		dev_err(&pdev->dev, "Can't set up DAS DAP connection\n");
+		goto err;
+	}
+	ret = tegra20_das_connect_dac_to_dap(TEGRA20_DAS_DAC_ID_3,
+					     TEGRA20_DAS_DAC_SEL_DAP3);
+	if (ret) {
+		dev_err(&pdev->dev, "Can't set up DAS DAC connection\n");
+		goto err;
+	}
+
 	platform_set_drvdata(pdev, das);
 
 	return 0;
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 4/7] ASoC: tegra: add function to set ac97 rate
       [not found] ` <1355959056-6009-1-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
  2012-12-19 23:17   ` [PATCH 2/7] ASoC: allow wolfson wm9712 codec to be instantiated using device tree Lucas Stach
  2012-12-19 23:17   ` [PATCH 3/7] ASoC: tegra: setup DAP3<->DAC3 connection by default Lucas Stach
@ 2012-12-19 23:17   ` Lucas Stach
       [not found]     ` <1355959056-6009-4-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
  2012-12-19 23:17   ` [PATCH 5/7] ASoC: tegra: add ac97 host driver Lucas Stach
                     ` (3 subsequent siblings)
  6 siblings, 1 reply; 21+ messages in thread
From: Lucas Stach @ 2012-12-19 23:17 UTC (permalink / raw)
  To: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
  Cc: patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	Liam Girdwood, Mark Brown, Stephen Warren,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

AC97 uses a fixed rate, unrelated to the sample rate. Add a function to
make the setup more trivial.

Signed-off-by: Lucas Stach <dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
---
 sound/soc/tegra/tegra_asoc_utils.c | 53 ++++++++++++++++++++++++++++++++++++++
 sound/soc/tegra/tegra_asoc_utils.h |  1 +
 2 Dateien geändert, 54 Zeilen hinzugefügt(+)

diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c
index 6872c77..ba419f8 100644
--- a/sound/soc/tegra/tegra_asoc_utils.c
+++ b/sound/soc/tegra/tegra_asoc_utils.c
@@ -112,6 +112,59 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
 }
 EXPORT_SYMBOL_GPL(tegra_asoc_utils_set_rate);
 
+int tegra_asoc_utils_set_ac97_rate(struct tegra_asoc_utils_data *data)
+{
+	const int pll_rate = 73728000;
+	const int ac97_rate = 24576000;
+	int err;
+
+	clk_disable_unprepare(data->clk_cdev1);
+	clk_disable_unprepare(data->clk_pll_a_out0);
+	clk_disable_unprepare(data->clk_pll_a);
+
+	/*
+	 * AC97 rate is fixed at 24.576MHz and is used for both the host
+	 * controller and the external codec
+	 */
+	err = clk_set_rate(data->clk_pll_a, pll_rate);
+	if (err) {
+		dev_err(data->dev, "Can't set pll_a rate: %d\n", err);
+		return err;
+	}
+
+	err = clk_set_rate(data->clk_pll_a_out0, ac97_rate);
+	if (err) {
+		dev_err(data->dev, "Can't set pll_a_out0 rate: %d\n", err);
+		return err;
+	}
+
+	/* Don't set cdev1/extern1 rate; it's locked to pll_a_out0 */
+
+	err = clk_prepare_enable(data->clk_pll_a);
+	if (err) {
+		dev_err(data->dev, "Can't enable pll_a: %d\n", err);
+		return err;
+	}
+
+	err = clk_prepare_enable(data->clk_pll_a_out0);
+	if (err) {
+		dev_err(data->dev, "Can't enable pll_a_out0: %d\n", err);
+		return err;
+	}
+
+	err = clk_prepare_enable(data->clk_cdev1);
+	if (err) {
+		dev_err(data->dev, "Can't enable cdev1: %d\n", err);
+		return err;
+	}
+
+	data->set_baseclock = pll_rate;
+	data->set_mclk = ac97_rate;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(tegra_asoc_utils_set_ac97_rate);
+
 int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
 			  struct device *dev)
 {
diff --git a/sound/soc/tegra/tegra_asoc_utils.h b/sound/soc/tegra/tegra_asoc_utils.h
index 44db1db..974c9f8 100644
--- a/sound/soc/tegra/tegra_asoc_utils.h
+++ b/sound/soc/tegra/tegra_asoc_utils.h
@@ -43,6 +43,7 @@ struct tegra_asoc_utils_data {
 
 int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
 			      int mclk);
+int tegra_asoc_utils_set_ac97_rate(struct tegra_asoc_utils_data *data);
 int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
 			  struct device *dev);
 void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data);
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 5/7] ASoC: tegra: add ac97 host driver
       [not found] ` <1355959056-6009-1-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
                     ` (2 preceding siblings ...)
  2012-12-19 23:17   ` [PATCH 4/7] ASoC: tegra: add function to set ac97 rate Lucas Stach
@ 2012-12-19 23:17   ` Lucas Stach
       [not found]     ` <1355959056-6009-5-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
  2012-12-19 23:17   ` [PATCH 6/7] ASoC: tegra: add ac97 host controller to device tree Lucas Stach
                     ` (2 subsequent siblings)
  6 siblings, 1 reply; 21+ messages in thread
From: Lucas Stach @ 2012-12-19 23:17 UTC (permalink / raw)
  To: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
  Cc: patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	Liam Girdwood, Mark Brown, Stephen Warren,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Marcel Ziswiler

This adds the driver for the Tegra 2x AC97 host controller.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler-2KBjVHiyJgBBDgjK7y7TUQ@public.gmane.org>
Signed-off-by: Lucas Stach <dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
---
 sound/soc/tegra/Kconfig        |   8 +
 sound/soc/tegra/Makefile       |   2 +
 sound/soc/tegra/tegra20_ac97.c | 479 +++++++++++++++++++++++++++++++++++++++++
 sound/soc/tegra/tegra20_ac97.h |  95 ++++++++
 4 Dateien geändert, 584 Zeilen hinzugefügt(+)
 create mode 100644 sound/soc/tegra/tegra20_ac97.c
 create mode 100644 sound/soc/tegra/tegra20_ac97.h

diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index 19e5fe7..763c68d 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -6,6 +6,14 @@ config SND_SOC_TEGRA
 	help
 	  Say Y or M here if you want support for SoC audio on Tegra.
 
+config SND_SOC_TEGRA20_AC97
+	tristate
+	depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC
+	help
+	  Say Y or M if you want to add support for codecs attached to the
+	  Tegra20 AC97 interface. You will also need to select the individual
+	  machine drivers to support below.
+
 config SND_SOC_TEGRA20_DAS
 	tristate
 	depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
index 391e78a..02513d9 100644
--- a/sound/soc/tegra/Makefile
+++ b/sound/soc/tegra/Makefile
@@ -1,6 +1,7 @@
 # Tegra platform Support
 snd-soc-tegra-pcm-objs := tegra_pcm.o
 snd-soc-tegra-utils-objs += tegra_asoc_utils.o
+snd-soc-tegra20-ac97-objs := tegra20_ac97.o
 snd-soc-tegra20-das-objs := tegra20_das.o
 snd-soc-tegra20-i2s-objs := tegra20_i2s.o
 snd-soc-tegra20-spdif-objs := tegra20_spdif.o
@@ -9,6 +10,7 @@ snd-soc-tegra30-i2s-objs := tegra30_i2s.o
 
 obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-pcm.o
 obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-utils.o
+obj-$(CONFIG_SND_SOC_TEGRA20_AC97) += snd-soc-tegra20-ac97.o
 obj-$(CONFIG_SND_SOC_TEGRA20_DAS) += snd-soc-tegra20-das.o
 obj-$(CONFIG_SND_SOC_TEGRA20_I2S) += snd-soc-tegra20-i2s.o
 obj-$(CONFIG_SND_SOC_TEGRA20_SPDIF) += snd-soc-tegra20-spdif.o
diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c
new file mode 100644
index 0000000..a2f71cf
--- /dev/null
+++ b/sound/soc/tegra/tegra20_ac97.c
@@ -0,0 +1,479 @@
+/*
+ * tegra20_ac97.c - Tegra20 AC97 platform driver
+ *
+ * Copyright (c) 2012 Lucas Stach <dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
+ *
+ * Partly based on code copyright/by:
+ *
+ * Copyright (c) 2011,2012 Toradex Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include "tegra_asoc_utils.h"
+#include "tegra20_ac97.h"
+
+#define DRV_NAME "tegra20-ac97"
+
+static struct tegra20_ac97 *workdata;
+
+static void tegra20_ac97_codec_reset(struct snd_ac97 *ac97)
+{
+	u32 readback;
+	unsigned long timeout;
+
+	/* reset line is not driven by DAC pad group, have to toggle GPIO */
+	gpio_set_value(workdata->reset_gpio, 0);
+	udelay(2);
+
+	gpio_set_value(workdata->reset_gpio, 1);
+	udelay(2);
+
+	timeout = jiffies + msecs_to_jiffies(100);
+
+	do {
+		regmap_read(workdata->regmap, TEGRA20_AC97_STATUS1, &readback);
+		if (readback & TEGRA20_AC97_STATUS1_CODEC1_RDY)
+			break;
+		usleep_range(1000, 2000);
+	} while (!time_after(jiffies, timeout));
+}
+
+static void tegra20_ac97_codec_warm_reset(struct snd_ac97 *ac97)
+{
+	u32 readback;
+	unsigned long timeout;
+
+	/*
+	 * although sync line is driven by the DAC pad group warm reset using
+	 * the controller cmd is not working, have to toggle sync line
+	 * manually.
+	 */
+	gpio_request(workdata->sync_gpio, "codec-sync");
+
+	gpio_direction_output(workdata->sync_gpio, 1);
+
+	udelay(2);
+	gpio_set_value(workdata->sync_gpio, 0);
+	udelay(2);
+	gpio_free(workdata->sync_gpio);
+
+	timeout = jiffies + msecs_to_jiffies(100);
+
+	do {
+		regmap_read(workdata->regmap, TEGRA20_AC97_STATUS1, &readback);
+		if (readback & TEGRA20_AC97_STATUS1_CODEC1_RDY)
+			break;
+		usleep_range(1000, 2000);
+	} while (!time_after(jiffies, timeout));
+}
+
+static unsigned short tegra20_ac97_codec_read(struct snd_ac97 *ac97_snd,
+					      unsigned short reg)
+{
+	u32 readback;
+	unsigned long timeout;
+
+	regmap_write(workdata->regmap, TEGRA20_AC97_CMD,
+		     (((reg | 0x80) << TEGRA20_AC97_CMD_CMD_ADDR_SHIFT) &
+		      TEGRA20_AC97_CMD_CMD_ADDR_MASK) |
+		     TEGRA20_AC97_CMD_BUSY);
+
+	timeout = jiffies + msecs_to_jiffies(100);
+
+	do {
+		regmap_read(workdata->regmap, TEGRA20_AC97_STATUS1, &readback);
+		if (readback & TEGRA20_AC97_STATUS1_STA_VALID1)
+			break;
+		usleep_range(1000, 2000);
+	} while (!time_after(jiffies, timeout));
+
+	return ((readback & TEGRA20_AC97_STATUS1_STA_DATA1_MASK) >>
+		TEGRA20_AC97_STATUS1_STA_DATA1_SHIFT);
+}
+
+static void tegra20_ac97_codec_write(struct snd_ac97 *ac97_snd,
+				     unsigned short reg, unsigned short val)
+{
+	u32 readback;
+	unsigned long timeout;
+
+	regmap_write(workdata->regmap, TEGRA20_AC97_CMD,
+		     ((reg << TEGRA20_AC97_CMD_CMD_ADDR_SHIFT) &
+		      TEGRA20_AC97_CMD_CMD_ADDR_MASK) |
+		     ((val << TEGRA20_AC97_CMD_CMD_DATA_SHIFT) &
+		      TEGRA20_AC97_CMD_CMD_DATA_MASK) |
+		     TEGRA20_AC97_CMD_BUSY);
+
+	timeout = jiffies + msecs_to_jiffies(100);
+
+	do {
+		regmap_read(workdata->regmap, TEGRA20_AC97_CMD, &readback);
+		if (!(readback & TEGRA20_AC97_CMD_BUSY))
+			break;
+		usleep_range(1000, 2000);
+	} while (!time_after(jiffies, timeout));
+}
+
+struct snd_ac97_bus_ops soc_ac97_ops = {
+	.read		= tegra20_ac97_codec_read,
+	.write		= tegra20_ac97_codec_write,
+	.reset		= tegra20_ac97_codec_reset,
+	.warm_reset	= tegra20_ac97_codec_warm_reset,
+};
+EXPORT_SYMBOL_GPL(soc_ac97_ops);
+
+static inline void tegra20_ac97_start_playback(struct tegra20_ac97 *ac97)
+{
+	regmap_update_bits(ac97->regmap, TEGRA20_AC97_FIFO1_SCR,
+			   TEGRA20_AC97_FIFO_SCR_PB_QRT_MT_EN,
+			   TEGRA20_AC97_FIFO_SCR_PB_QRT_MT_EN);
+
+	regmap_update_bits(ac97->regmap, TEGRA20_AC97_CTRL,
+			   TEGRA20_AC97_CTRL_PCM_DAC_EN | TEGRA20_AC97_CTRL_STM_EN,
+			   TEGRA20_AC97_CTRL_PCM_DAC_EN | TEGRA20_AC97_CTRL_STM_EN);
+}
+
+static inline void tegra20_ac97_stop_playback(struct tegra20_ac97 *ac97)
+{
+	regmap_update_bits(ac97->regmap, TEGRA20_AC97_FIFO1_SCR,
+			   TEGRA20_AC97_FIFO_SCR_PB_QRT_MT_EN, 0);
+
+	regmap_update_bits(ac97->regmap, TEGRA20_AC97_CTRL,
+			   TEGRA20_AC97_CTRL_PCM_DAC_EN, 0);
+}
+
+static inline void tegra20_ac97_start_capture(struct tegra20_ac97 *ac97)
+{
+	regmap_update_bits(ac97->regmap, TEGRA20_AC97_FIFO1_SCR,
+			   TEGRA20_AC97_FIFO_SCR_REC_FULL_EN,
+			   TEGRA20_AC97_FIFO_SCR_REC_FULL_EN);
+}
+
+static inline void tegra20_ac97_stop_capture(struct tegra20_ac97 *ac97)
+{
+	regmap_update_bits(ac97->regmap, TEGRA20_AC97_FIFO1_SCR,
+			   TEGRA20_AC97_FIFO_SCR_REC_FULL_EN, 0);
+}
+
+static int tegra20_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
+				struct snd_soc_dai *dai)
+{
+	struct tegra20_ac97 *ac97 = snd_soc_dai_get_drvdata(dai);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+	case SNDRV_PCM_TRIGGER_RESUME:
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			tegra20_ac97_start_playback(ac97);
+		else
+			tegra20_ac97_start_capture(ac97);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			tegra20_ac97_stop_playback(ac97);
+		else
+			tegra20_ac97_stop_capture(ac97);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops tegra20_ac97_dai_ops = {
+	.trigger	= tegra20_ac97_trigger,
+};
+
+static int tegra20_ac97_probe(struct snd_soc_dai *dai)
+{
+	struct tegra20_ac97 *ac97 = snd_soc_dai_get_drvdata(dai);
+
+	dai->capture_dma_data = &ac97->capture_dma_data;
+	dai->playback_dma_data = &ac97->playback_dma_data;
+
+	return 0;
+}
+
+static struct snd_soc_dai_driver tegra20_ac97_dai = {
+	.name = "tegra-ac97-pcm",
+	.ac97_control = 1,
+	.probe = tegra20_ac97_probe,
+	.playback = {
+		.stream_name = "PCM Playback",
+		.channels_min = 2,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000_48000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+	},
+	.capture = {
+		.stream_name = "PCM Capture",
+		.channels_min = 2,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000_48000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+	},
+	.ops = &tegra20_ac97_dai_ops,
+};
+
+static bool tegra20_ac97_wr_rd_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case TEGRA20_AC97_CTRL:
+	case TEGRA20_AC97_CMD:
+	case TEGRA20_AC97_STATUS1:
+	case TEGRA20_AC97_FIFO1_SCR:
+	case TEGRA20_AC97_FIFO_TX1:
+	case TEGRA20_AC97_FIFO_RX1:
+		return true;
+	default:
+		break;
+	}
+
+	return false;
+}
+
+static bool tegra20_ac97_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case TEGRA20_AC97_CMD:
+	case TEGRA20_AC97_STATUS1:
+	case TEGRA20_AC97_FIFO1_SCR:
+	case TEGRA20_AC97_FIFO_TX1:
+	case TEGRA20_AC97_FIFO_RX1:
+		return true;
+	default:
+		break;
+	}
+
+	return false;
+}
+
+static bool tegra20_ac97_precious_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case TEGRA20_AC97_FIFO_TX1:
+	case TEGRA20_AC97_FIFO_RX1:
+		return true;
+	default:
+		break;
+	}
+
+	return false;
+}
+
+static const struct regmap_config tegra20_ac97_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = TEGRA20_AC97_FIFO_RX1,
+	.writeable_reg = tegra20_ac97_wr_rd_reg,
+	.readable_reg = tegra20_ac97_wr_rd_reg,
+	.volatile_reg = tegra20_ac97_volatile_reg,
+	.precious_reg = tegra20_ac97_precious_reg,
+	.cache_type = REGCACHE_RBTREE,
+};
+
+static int tegra20_ac97_platform_probe(struct platform_device *pdev)
+{
+	struct tegra20_ac97 *ac97;
+	struct resource *mem, *memregion;
+	u32 of_dma[2];
+	void __iomem *regs;
+	int ret = 0;
+
+	ac97 = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_ac97),
+			    GFP_KERNEL);
+	if (!ac97) {
+		dev_err(&pdev->dev, "Can't allocate tegra20_ac97\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+	dev_set_drvdata(&pdev->dev, ac97);
+
+	ac97->clk_ac97 = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(ac97->clk_ac97)) {
+		dev_err(&pdev->dev, "Can't retrieve ac97 clock\n");
+		ret = PTR_ERR(ac97->clk_ac97);
+		goto err;
+	}
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mem) {
+		dev_err(&pdev->dev, "No memory resource\n");
+		ret = -ENODEV;
+		goto err_clk_put;
+	}
+
+	memregion = devm_request_mem_region(&pdev->dev, mem->start,
+					    resource_size(mem), DRV_NAME);
+	if (!memregion) {
+		dev_err(&pdev->dev, "Memory region already claimed\n");
+		ret = -EBUSY;
+		goto err_clk_put;
+	}
+
+	regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
+	if (!regs) {
+		dev_err(&pdev->dev, "ioremap failed\n");
+		ret = -ENOMEM;
+		goto err_clk_put;
+	}
+
+	ac97->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
+					    &tegra20_ac97_regmap_config);
+	if (IS_ERR(ac97->regmap)) {
+		dev_err(&pdev->dev, "regmap init failed\n");
+		ret = PTR_ERR(ac97->regmap);
+		goto err_clk_put;
+	}
+
+	if (of_property_read_u32_array(pdev->dev.of_node,
+				       "nvidia,dma-request-selector",
+				       of_dma, 2) < 0) {
+		dev_err(&pdev->dev, "No DMA resource\n");
+		ret = -ENODEV;
+		goto err_clk_put;
+	}
+
+	ac97->reset_gpio = of_get_named_gpio(pdev->dev.of_node,
+					     "nvidia,codec-reset-gpio", 0);
+	if (gpio_is_valid(ac97->reset_gpio)) {
+		ret = devm_gpio_request_one(&pdev->dev, ac97->reset_gpio,
+					    GPIOF_OUT_INIT_HIGH, "codec-reset");
+		if (ret) {
+			dev_err(&pdev->dev, "could not get codec-reset GPIO\n");
+			goto err_clk_put;
+		}
+	} else {
+		dev_err(&pdev->dev, "no codec-reset GPIO supplied\n");
+		goto err_clk_put;
+	}
+
+	ac97->sync_gpio = of_get_named_gpio(pdev->dev.of_node,
+					    "nvidia,codec-sync-gpio", 0);
+	if (!gpio_is_valid(ac97->sync_gpio)) {
+		dev_err(&pdev->dev, "no codec-sync GPIO supplied\n");
+		goto err_clk_put;
+	}
+
+	ac97->capture_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_RX1;
+	ac97->capture_dma_data.wrap = 4;
+	ac97->capture_dma_data.width = 32;
+	ac97->capture_dma_data.req_sel = of_dma[1];
+
+	ac97->playback_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_TX1;
+	ac97->playback_dma_data.wrap = 4;
+	ac97->playback_dma_data.width = 32;
+	ac97->playback_dma_data.req_sel = of_dma[1];
+
+	ret = snd_soc_register_dais(&pdev->dev, &tegra20_ac97_dai, 1);
+	if (ret) {
+		dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
+		ret = -ENOMEM;
+		goto err_clk_put;
+	}
+
+	ret = tegra_pcm_platform_register(&pdev->dev);
+	if (ret) {
+		dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
+		goto err_unregister_dai;
+	}
+
+	ret = tegra_asoc_utils_init(&ac97->util_data, &pdev->dev);
+	if (ret)
+		goto err_unregister_pcm;
+
+	ret = tegra_asoc_utils_set_ac97_rate(&ac97->util_data);
+	if (ret)
+		goto err_asoc_utils_fini;
+
+	ret = clk_prepare_enable(ac97->clk_ac97);
+	if (ret) {
+		dev_err(&pdev->dev, "clk_enable failed: %d\n", ret);
+		goto err_asoc_utils_fini;
+	}
+
+	/* XXX: crufty ASoC AC97 API - only one AC97 codec allowed */
+	workdata = ac97;
+
+	return 0;
+
+err_asoc_utils_fini:
+	tegra_asoc_utils_fini(&ac97->util_data);
+err_unregister_pcm:
+	tegra_pcm_platform_unregister(&pdev->dev);
+err_unregister_dai:
+	snd_soc_unregister_dai(&pdev->dev);
+err_clk_put:
+	clk_put(ac97->clk_ac97);
+err:
+	return ret;
+}
+
+static int tegra20_ac97_platform_remove(struct platform_device *pdev)
+{
+	struct tegra20_ac97 *ac97 = dev_get_drvdata(&pdev->dev);
+
+	tegra_pcm_platform_unregister(&pdev->dev);
+	snd_soc_unregister_dai(&pdev->dev);
+
+	tegra_asoc_utils_fini(&ac97->util_data);
+
+	clk_disable_unprepare(ac97->clk_ac97);
+	clk_put(ac97->clk_ac97);
+
+	return 0;
+}
+
+static const struct of_device_id tegra20_ac97_of_match[] __devinitconst = {
+	{ .compatible = "nvidia,tegra20-ac97", },
+	{},
+};
+
+static struct platform_driver tegra20_ac97_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = tegra20_ac97_of_match,
+	},
+	.probe = tegra20_ac97_platform_probe,
+	.remove = tegra20_ac97_platform_remove,
+};
+module_platform_driver(tegra20_ac97_driver);
+
+MODULE_AUTHOR("Lucas Stach");
+MODULE_DESCRIPTION("Tegra20 AC97 ASoC driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, tegra20_ac97_of_match);
diff --git a/sound/soc/tegra/tegra20_ac97.h b/sound/soc/tegra/tegra20_ac97.h
new file mode 100644
index 0000000..a805aae
--- /dev/null
+++ b/sound/soc/tegra/tegra20_ac97.h
@@ -0,0 +1,95 @@
+/*
+ * tegra20_ac97.c - Definitions for the Tegra20 AC97 controller driver
+ *
+ * Copyright (c) 2012 Lucas Stach <dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
+ *
+ * Partly based on code copyright/by:
+ *
+ * Copyright (c) 2011,2012 Toradex Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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 __TEGRA20_AC97_H__
+#define __TEGRA20_AC97_H__
+
+#include "tegra_pcm.h"
+
+#define TEGRA20_AC97_CTRL				0x00
+#define TEGRA20_AC97_CMD				0x04
+#define TEGRA20_AC97_STATUS1				0x08
+/* ... */
+#define TEGRA20_AC97_FIFO1_SCR				0x1c
+/* ... */
+#define TEGRA20_AC97_FIFO_TX1				0x40
+#define TEGRA20_AC97_FIFO_RX1				0x80
+
+/* TEGRA20_AC97_CTRL */
+#define TEGRA20_AC97_CTRL_STM2_EN			(1 << 16)
+#define TEGRA20_AC97_CTRL_DOUBLE_SAMPLING_EN		(1 << 11)
+#define TEGRA20_AC97_CTRL_IO_CNTRL_EN			(1 << 10)
+#define TEGRA20_AC97_CTRL_HSET_DAC_EN			(1 << 9)
+#define TEGRA20_AC97_CTRL_LINE2_DAC_EN			(1 << 8)
+#define TEGRA20_AC97_CTRL_PCM_LFE_EN			(1 << 7)
+#define TEGRA20_AC97_CTRL_PCM_SUR_EN			(1 << 6)
+#define TEGRA20_AC97_CTRL_PCM_CEN_DAC_EN		(1 << 5)
+#define TEGRA20_AC97_CTRL_LINE1_DAC_EN			(1 << 4)
+#define TEGRA20_AC97_CTRL_PCM_DAC_EN			(1 << 3)
+#define TEGRA20_AC97_CTRL_COLD_RESET			(1 << 2)
+#define TEGRA20_AC97_CTRL_WARM_RESET			(1 << 1)
+#define TEGRA20_AC97_CTRL_STM_EN			(1 << 0)
+
+/* TEGRA20_AC97_CMD */
+#define TEGRA20_AC97_CMD_CMD_ADDR_SHIFT			24
+#define TEGRA20_AC97_CMD_CMD_ADDR_MASK			(0xff << TEGRA20_AC97_CMD_CMD_ADDR_SHIFT)
+#define TEGRA20_AC97_CMD_CMD_DATA_SHIFT			8
+#define TEGRA20_AC97_CMD_CMD_DATA_MASK			(0xffff << TEGRA20_AC97_CMD_CMD_DATA_SHIFT)
+#define TEGRA20_AC97_CMD_CMD_ID_SHIFT			2
+#define TEGRA20_AC97_CMD_CMD_ID_MASK			(0x3 << TEGRA20_AC97_CMD_CMD_ID_SHIFT)
+#define TEGRA20_AC97_CMD_BUSY				(1 << 0)
+
+/* TEGRA20_AC97_STATUS1 */
+#define TEGRA20_AC97_STATUS1_STA_ADDR1_SHIFT		24
+#define TEGRA20_AC97_STATUS1_STA_ADDR1_MASK		(0xff << TEGRA20_AC97_STATUS1_STA_ADDR1_SHIFT)
+#define TEGRA20_AC97_STATUS1_STA_DATA1_SHIFT		8
+#define TEGRA20_AC97_STATUS1_STA_DATA1_MASK		(0xffff << TEGRA20_AC97_STATUS1_STA_DATA1_SHIFT)
+#define TEGRA20_AC97_STATUS1_STA_VALID1			(1 << 2)
+#define TEGRA20_AC97_STATUS1_STANDBY1			(1 << 1)
+#define TEGRA20_AC97_STATUS1_CODEC1_RDY			(1 << 0)
+
+/* TEGRA20_AC97_FIFO1_SCR */
+#define TEGRA20_AC97_FIFO_SCR_REC_MT_CNT_SHIFT		27
+#define TEGRA20_AC97_FIFO_SCR_REC_MT_CNT_MASK		(0x1f << TEGRA20_AC97_FIFO_SCR_REC_MT_CNT_SHIFT)
+#define TEGRA20_AC97_FIFO_SCR_PB_MT_CNT_SHIFT		22
+#define TEGRA20_AC97_FIFO_SCR_PB_MT_CNT_MASK		(0x1f << TEGRA20_AC97_FIFO_SCR_PB_MT_CNT_SHIFT)
+#define TEGRA20_AC97_FIFO_SCR_REC_OVERRUN_INT_STA	(1 << 19)
+#define TEGRA20_AC97_FIFO_SCR_PB_UNDERRUN_INT_STA	(1 << 18)
+#define TEGRA20_AC97_FIFO_SCR_REC_FORCE_MT		(1 << 17)
+#define TEGRA20_AC97_FIFO_SCR_PB_FORCE_MT		(1 << 16)
+#define TEGRA20_AC97_FIFO_SCR_REC_FULL_EN		(1 << 15)
+#define TEGRA20_AC97_FIFO_SCR_REC_3QRT_FULL_EN		(1 << 14)
+#define TEGRA20_AC97_FIFO_SCR_REC_QRT_FULL_EN		(1 << 13)
+#define TEGRA20_AC97_FIFO_SCR_REC_EMPTY_EN		(1 << 12)
+#define TEGRA20_AC97_FIFO_SCR_PB_NOT_FULL_EN		(1 << 11)
+#define TEGRA20_AC97_FIFO_SCR_PB_QRT_MT_EN		(1 << 10)
+#define TEGRA20_AC97_FIFO_SCR_PB_3QRT_MT_EN		(1 << 9)
+#define TEGRA20_AC97_FIFO_SCR_PB_EMPTY_MT_EN		(1 << 8)
+
+struct tegra20_ac97 {
+	struct clk *clk_ac97;
+	struct tegra_pcm_dma_params capture_dma_data;
+	struct tegra_pcm_dma_params playback_dma_data;
+	struct regmap *regmap;
+	int reset_gpio;
+	int sync_gpio;
+	struct tegra_asoc_utils_data util_data;
+};
+#endif /* __TEGRA20_AC97_H__ */
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 6/7] ASoC: tegra:  add ac97 host controller to device tree
       [not found] ` <1355959056-6009-1-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
                     ` (3 preceding siblings ...)
  2012-12-19 23:17   ` [PATCH 5/7] ASoC: tegra: add ac97 host driver Lucas Stach
@ 2012-12-19 23:17   ` Lucas Stach
       [not found]     ` <1355959056-6009-6-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
  2012-12-19 23:17   ` [PATCH 7/7] ASoC: tegra: add machine driver using wm9712 codec Lucas Stach
  2012-12-20 19:24   ` [PATCH 1/7] ARM: tegra: add ac97 clock Stephen Warren
  6 siblings, 1 reply; 21+ messages in thread
From: Lucas Stach @ 2012-12-19 23:17 UTC (permalink / raw)
  To: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
  Cc: patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	Liam Girdwood, Mark Brown, Stephen Warren,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

This adds the DT bindings and a default entry for the Tegra 2x
AC97 host controller.

Signed-off-by: Lucas Stach <dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
---
 .../bindings/sound/nvidia,tegra20-ac97.txt         | 22 ++++++++++++++++++++++
 arch/arm/boot/dts/tegra20.dtsi                     |  8 ++++++++
 sound/soc/tegra/tegra20_ac97.c                     |  6 ++++--
 sound/soc/tegra/tegra20_ac97.h                     |  2 +-
 4 Dateien geändert, 35 Zeilen hinzugefügt(+), 3 Zeilen entfernt(-)
 create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra20-ac97.txt

diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra20-ac97.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra20-ac97.txt
new file mode 100644
index 0000000..c145497
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/nvidia,tegra20-ac97.txt
@@ -0,0 +1,22 @@
+NVIDIA Tegra 20 AC97 controller
+
+Required properties:
+- compatible : "nvidia,tegra20-ac97"
+- reg : Should contain AC97 controller registers location and length
+- interrupts : Should contain AC97 interrupt
+- nvidia,dma-request-selector : The Tegra DMA controller's phandle and
+  request selector for the AC97 controller
+- nvidia,codec-reset-gpio : The Tegra GPIO controller's phandle and the number
+  of the GPIO used to reset the external AC97 codec
+- nvidia,codec-sync-gpio : The Tegra GPIO controller's phandle and the number
+  of the GPIO corresponding with the AC97 DAP _FS line
+Example:
+
+ac97@70002000 {
+	compatible = "nvidia,tegra20-ac97";
+	reg = <0x70002000 0x200>;
+	interrupts = <0 81 0x04>;
+	nvidia,dma-request-selector = <&apbdma 12>;
+	nvidia,codec-reset-gpio = <&gpio 170 0>;
+	nvidia,codec-sync-gpio = <&gpio 120 0>;
+};
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index b8effa1..b720859 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -177,6 +177,14 @@
 		compatible = "nvidia,tegra20-das";
 		reg = <0x70000c00 0x80>;
 	};
+	
+	tegra_ac97: ac97@70002000 {
+		compatible = "nvidia,tegra20-ac97";
+		reg = <0x70002000 0x200>;
+		interrupts = <0 81 0x04>;
+		nvidia,dma-request-selector = <&apbdma 12>;
+		status = "disabled";
+	};
 
 	tegra_i2s1: i2s@70002800 {
 		compatible = "nvidia,tegra20-i2s";
diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c
index a2f71cf..a2cb89a 100644
--- a/sound/soc/tegra/tegra20_ac97.c
+++ b/sound/soc/tegra/tegra20_ac97.c
@@ -156,8 +156,10 @@ static inline void tegra20_ac97_start_playback(struct tegra20_ac97 *ac97)
 			   TEGRA20_AC97_FIFO_SCR_PB_QRT_MT_EN);
 
 	regmap_update_bits(ac97->regmap, TEGRA20_AC97_CTRL,
-			   TEGRA20_AC97_CTRL_PCM_DAC_EN | TEGRA20_AC97_CTRL_STM_EN,
-			   TEGRA20_AC97_CTRL_PCM_DAC_EN | TEGRA20_AC97_CTRL_STM_EN);
+			   TEGRA20_AC97_CTRL_PCM_DAC_EN |
+			   TEGRA20_AC97_CTRL_STM_EN,
+			   TEGRA20_AC97_CTRL_PCM_DAC_EN |
+			   TEGRA20_AC97_CTRL_STM_EN);
 }
 
 static inline void tegra20_ac97_stop_playback(struct tegra20_ac97 *ac97)
diff --git a/sound/soc/tegra/tegra20_ac97.h b/sound/soc/tegra/tegra20_ac97.h
index a805aae..dddc682 100644
--- a/sound/soc/tegra/tegra20_ac97.h
+++ b/sound/soc/tegra/tegra20_ac97.h
@@ -1,5 +1,5 @@
 /*
- * tegra20_ac97.c - Definitions for the Tegra20 AC97 controller driver
+ * tegra20_ac97.h - Definitions for the Tegra20 AC97 controller driver
  *
  * Copyright (c) 2012 Lucas Stach <dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
  *
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 7/7] ASoC: tegra: add machine driver using wm9712 codec
       [not found] ` <1355959056-6009-1-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
                     ` (4 preceding siblings ...)
  2012-12-19 23:17   ` [PATCH 6/7] ASoC: tegra: add ac97 host controller to device tree Lucas Stach
@ 2012-12-19 23:17   ` Lucas Stach
       [not found]     ` <1355959056-6009-7-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
  2012-12-20 19:24   ` [PATCH 1/7] ARM: tegra: add ac97 clock Stephen Warren
  6 siblings, 1 reply; 21+ messages in thread
From: Lucas Stach @ 2012-12-19 23:17 UTC (permalink / raw)
  To: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
  Cc: patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	Liam Girdwood, Mark Brown, Stephen Warren,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Marcel Ziswiler

This adds a simple machine driver using the Wolfson wm9712 AC97
codec.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler-2KBjVHiyJgBBDgjK7y7TUQ@public.gmane.org>
Signed-off-by: Lucas Stach <dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
---
 .../bindings/sound/nvidia,tegra-audio-wm9712.txt   |  53 +++++++
 sound/soc/tegra/Kconfig                            |  10 ++
 sound/soc/tegra/Makefile                           |   2 +
 sound/soc/tegra/tegra_wm9712.c                     | 167 +++++++++++++++++++++
 4 Dateien geändert, 232 Zeilen hinzugefügt(+)
 create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm9712.txt
 create mode 100644 sound/soc/tegra/tegra_wm9712.c

diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm9712.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm9712.txt
new file mode 100644
index 0000000..72bd589
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm9712.txt
@@ -0,0 +1,53 @@
+NVIDIA Tegra audio complex
+
+Required properties:
+- compatible : "nvidia,tegra-audio-wm9712"
+- nvidia,model : The user-visible name of this sound complex.
+- nvidia,audio-routing : A list of the connections between audio components.
+  Each entry is a pair of strings, the first being the connection's sink,
+  the second being the connection's source. Valid names for sources and
+  sinks are the WM9712's pins, and the jacks on the board:
+
+  WM9712 pins:
+
+  * MONOOUT
+  * HPOUTL
+  * HPOUTR
+  * LOUT2
+  * ROUT2
+  * OUT3
+  * LINEINL
+  * LINEINR
+  * PHONE
+  * PCBEEP
+  * MIC1
+  * MIC2
+  * Mic Bias
+
+  Board connectors:
+
+  * Headphone
+  * LineIn
+  * Mic
+
+- nvidia,ac97-controller : The phandle of the Tegra AC97 controller
+- nvidia,audio-codec : The phandle of the WM9712 audio codec
+
+
+Example:
+
+sound {
+	compatible = "nvidia,tegra-audio-wm9712-colibri_t20",
+		         "nvidia,tegra-audio-wm9712";
+	nvidia,model = "Toradex Colibri T20";
+
+	nvidia,audio-routing =
+		"Headphone", "HPOUTL",
+		"Headphone", "HPOUTR",
+		"LineIn", "LINEINL",
+		"LineIn", "LINEINR",
+		"Mic", "MIC1";
+
+	nvidia,ac97-controller = <&ac97>;
+	nvidia,audio-codec = <&wm9712>;
+};
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index 763c68d..0d62025 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -78,6 +78,16 @@ config SND_SOC_TEGRA_WM8903
 	  boards using the WM8093 codec. Currently, the supported boards are
 	  Harmony, Ventana, Seaboard, Kaen, and Aebl.
 
+config SND_SOC_TEGRA_WM9712
+	tristate "SoC Audio support for Tegra boards using a WM9712 codec"
+	depends on SND_SOC_TEGRA
+	select SND_SOC_TEGRA20_AC97 if ARCH_TEGRA_2x_SOC
+	select SND_SOC_AC97_BUS
+	select SND_SOC_WM9712
+	help
+	  Say Y or M here if you want to add support for SoC audio on Tegra
+	  boards using the WM9712 (or compatible) codec.
+
 config SND_SOC_TEGRA_TRIMSLICE
 	tristate "SoC Audio support for TrimSlice board"
 	depends on SND_SOC_TEGRA && I2C
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
index 02513d9..416a14b 100644
--- a/sound/soc/tegra/Makefile
+++ b/sound/soc/tegra/Makefile
@@ -20,10 +20,12 @@ obj-$(CONFIG_SND_SOC_TEGRA30_I2S) += snd-soc-tegra30-i2s.o
 # Tegra machine Support
 snd-soc-tegra-wm8753-objs := tegra_wm8753.o
 snd-soc-tegra-wm8903-objs := tegra_wm8903.o
+snd-soc-tegra-wm9712-objs := tegra_wm9712.o
 snd-soc-tegra-trimslice-objs := trimslice.o
 snd-soc-tegra-alc5632-objs := tegra_alc5632.o
 
 obj-$(CONFIG_SND_SOC_TEGRA_WM8753) += snd-soc-tegra-wm8753.o
 obj-$(CONFIG_SND_SOC_TEGRA_WM8903) += snd-soc-tegra-wm8903.o
+obj-$(CONFIG_SND_SOC_TEGRA_WM9712) += snd-soc-tegra-wm9712.o
 obj-$(CONFIG_SND_SOC_TEGRA_TRIMSLICE) += snd-soc-tegra-trimslice.o
 obj-$(CONFIG_SND_SOC_TEGRA_ALC5632) += snd-soc-tegra-alc5632.o
diff --git a/sound/soc/tegra/tegra_wm9712.c b/sound/soc/tegra/tegra_wm9712.c
new file mode 100644
index 0000000..2e9b588
--- /dev/null
+++ b/sound/soc/tegra/tegra_wm9712.c
@@ -0,0 +1,167 @@
+/*
+ * tegra20_wm9712.c - Tegra machine ASoC driver for boards using WM9712 codec.
+ *
+ * Copyright 2012 Lucas Stach <dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
+ *
+ * Partly based on code copyright/by:
+ * Copyright 2011,2012 Toradex Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+
+#include <sound/core.h>
+#include <sound/jack.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#define DRV_NAME "tegra-snd-wm9712"
+
+static const struct snd_soc_dapm_widget tegra_wm9712_dapm_widgets[] = {
+	SND_SOC_DAPM_HP("Headphone", NULL),
+	SND_SOC_DAPM_LINE("LineIn", NULL),
+	SND_SOC_DAPM_MIC("Mic", NULL),
+};
+
+static int tegra_wm9712_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_dapm_context *dapm = &codec->dapm;
+	int err;
+
+	snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
+
+	err = snd_soc_dapm_sync(dapm);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static int tegra_wm9712_remove(struct snd_soc_card *card)
+{
+	return 0;
+}
+
+static struct snd_soc_dai_link tegra_wm9712_dai = {
+	.name = "AC97 HiFi",
+	.stream_name = "AC97 HiFi",
+	.cpu_dai_name = "tegra-ac97-pcm",
+	.codec_dai_name = "wm9712-hifi",
+	.init = tegra_wm9712_init,
+};
+
+static struct snd_soc_card snd_soc_tegra_wm9712 = {
+	.name = "tegra-wm9712",
+	.owner = THIS_MODULE,
+	.dai_link = &tegra_wm9712_dai,
+	.num_links = 1,
+
+	.remove = tegra_wm9712_remove,
+
+	.dapm_widgets = tegra_wm9712_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(tegra_wm9712_dapm_widgets),
+	.fully_routed = true,
+};
+
+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;
+	int ret;
+
+	if (!pdev->dev.of_node) {
+		dev_err(&pdev->dev, "No platform data supplied\n");
+		return -EINVAL;
+	}
+
+	card->dev = &pdev->dev;
+	platform_set_drvdata(pdev, card);
+
+	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_wm9712_dai.codec_of_node = of_parse_phandle(np,
+					 "nvidia,audio-codec", 0);
+	if (!tegra_wm9712_dai.codec_of_node) {
+		dev_err(&pdev->dev,
+			"Property 'nvidia,audio-codec' missing or invalid\n");
+		ret = -EINVAL;
+		goto err;
+	}
+
+	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 err;
+	}
+
+	tegra_wm9712_dai.platform_of_node = tegra_wm9712_dai.cpu_of_node;
+
+	ret = snd_soc_register_card(card);
+	if (ret) {
+		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
+			ret);
+		goto err;
+	}
+
+	return 0;
+
+err:
+	return ret;
+}
+
+static int tegra_wm9712_driver_remove(struct platform_device *pdev)
+{
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+	snd_soc_unregister_card(card);
+
+	return 0;
+}
+
+static const struct of_device_id tegra_wm9712_of_match[] __devinitconst = {
+	{ .compatible = "nvidia,tegra-audio-wm9712", },
+	{},
+};
+
+static struct platform_driver tegra_wm9712_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+		.pm = &snd_soc_pm_ops,
+		.of_match_table = tegra_wm9712_of_match,
+	},
+	.probe = tegra_wm9712_driver_probe,
+	.remove = tegra_wm9712_driver_remove,
+};
+module_platform_driver(tegra_wm9712_driver);
+
+MODULE_AUTHOR("Lucas Stach");
+MODULE_DESCRIPTION("Tegra+WM9712 machine ASoC driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, tegra_wm9712_of_match);
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH 2/7] ASoC: allow wolfson wm9712 codec to be instantiated using device tree
       [not found]     ` <1355959056-6009-2-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
@ 2012-12-20  9:32       ` Mark Brown
  0 siblings, 0 replies; 21+ messages in thread
From: Mark Brown @ 2012-12-20  9:32 UTC (permalink / raw)
  To: Lucas Stach
  Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	Liam Girdwood, Stephen Warren,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 482 bytes --]

On Thu, Dec 20, 2012 at 12:17:31AM +0100, Lucas Stach wrote:

>  static struct platform_driver wm9712_codec_driver = {
>  	.driver = {
>  		.name = "wm9712-codec",
>  		.owner = THIS_MODULE,
> +		.of_match_table = wm9712_of_match,
>  	},

No, this is really not a sane way of handling AC'97 at all.  They're not
platform devices, there is no sane reason why they should appear in the
device tree as such.  Really we ought to be just hotplugging them, AC'97
is perfectly enumerable.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 3/7] ASoC: tegra: setup DAP3<->DAC3 connection by default
       [not found]     ` <1355959056-6009-3-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
@ 2012-12-20 19:20       ` Stephen Warren
  2012-12-24 16:01       ` Mark Brown
  1 sibling, 0 replies; 21+ messages in thread
From: Stephen Warren @ 2012-12-20 19:20 UTC (permalink / raw)
  To: Lucas Stach
  Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	Liam Girdwood, Mark Brown, linux-tegra-u79uwXL29TY76Z2rM5mHXA

On 12/19/2012 04:17 PM, Lucas Stach wrote:
> This connection is used by the AC97 controller.

Acked-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4/7] ASoC: tegra: add function to set ac97 rate
       [not found]     ` <1355959056-6009-4-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
@ 2012-12-20 19:22       ` Stephen Warren
  2012-12-24 16:00       ` Mark Brown
  1 sibling, 0 replies; 21+ messages in thread
From: Stephen Warren @ 2012-12-20 19:22 UTC (permalink / raw)
  To: Lucas Stach
  Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	Liam Girdwood, Mark Brown, linux-tegra-u79uwXL29TY76Z2rM5mHXA

On 12/19/2012 04:17 PM, Lucas Stach wrote:
> AC97 uses a fixed rate, unrelated to the sample rate. Add a function to
> make the setup more trivial.

Acked-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/7] ARM: tegra: add ac97 clock
       [not found] ` <1355959056-6009-1-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
                     ` (5 preceding siblings ...)
  2012-12-19 23:17   ` [PATCH 7/7] ASoC: tegra: add machine driver using wm9712 codec Lucas Stach
@ 2012-12-20 19:24   ` Stephen Warren
  6 siblings, 0 replies; 21+ messages in thread
From: Stephen Warren @ 2012-12-20 19:24 UTC (permalink / raw)
  To: Lucas Stach
  Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	Liam Girdwood, Mark Brown, linux-tegra-u79uwXL29TY76Z2rM5mHXA

On 12/19/2012 04:17 PM, Lucas Stach wrote:
> Add clock used by the AC97 host controller.

This is going to conflict with Prashant's clock driver rework. Can you
rebase it on top of that once it's checked in. That might be a couple
weeks out though.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 5/7] ASoC: tegra: add ac97 host driver
       [not found]     ` <1355959056-6009-5-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
@ 2012-12-20 19:44       ` Stephen Warren
       [not found]         ` <50D36A98.7090204-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  0 siblings, 1 reply; 21+ messages in thread
From: Stephen Warren @ 2012-12-20 19:44 UTC (permalink / raw)
  To: Lucas Stach
  Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	Liam Girdwood, Mark Brown, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	Marcel Ziswiler

On 12/19/2012 04:17 PM, Lucas Stach wrote:
> This adds the driver for the Tegra 2x AC97 host controller.

The AC'97 DT binding file should really be added as part of this patch.

I'm not at all familiar with AC'97, but this mostly looks fine. I have a
bunch of comments below though, mostly for my own understanding.

> diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig

> +config SND_SOC_TEGRA20_AC97
> +	tristate
> +	depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC

This should also select SND_SOC_TEGRA20_DAS, just like the I2S driver.

> diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c

> +static struct tegra20_ac97 *workdata;

Why not put that into the device's drvdata? Oh, is there no way to stash
driver-private data into the struct snd_ac97?

> +static void tegra20_ac97_codec_reset(struct snd_ac97 *ac97)
> +{
> +	u32 readback;
> +	unsigned long timeout;
> +
> +	/* reset line is not driven by DAC pad group, have to toggle GPIO */
> +	gpio_set_value(workdata->reset_gpio, 0);
> +	udelay(2);

I'm not quite sure what that implies. Might some (Tegra) HW designs use
a dedicated signal from the AC'97 HW to reset the CODEC and others not?
That would make the GPIO optional. Or, does the comment mean that Tegra
doesn't ever have a dedicated CODEC reset signal, so we always have to
use a GPIO? If so, this comment might be more appropriate inside probe()
where I asked my related questions.

> +static void tegra20_ac97_codec_warm_reset(struct snd_ac97 *ac97)
> +{
> +	u32 readback;
> +	unsigned long timeout;
> +
> +	/*
> +	 * although sync line is driven by the DAC pad group warm reset using
> +	 * the controller cmd is not working, have to toggle sync line
> +	 * manually.
> +	 */
> +	gpio_request(workdata->sync_gpio, "codec-sync");

Hmm. There's an AC'97 command to reset the CODEC and we don't implement
it? Uggh.

> +static const struct snd_soc_dai_ops tegra20_ac97_dai_ops = {
> +	.trigger	= tegra20_ac97_trigger,
> +};

No .set_fmt or .hw_params? Does the AC'97 ASoC core code handle that
somehow? I guess that's what soc_ac97_ops is for?

> +static struct snd_soc_dai_driver tegra20_ac97_dai = {
> +	.name = "tegra-ac97-pcm",
> +	.ac97_control = 1,
> +	.probe = tegra20_ac97_probe,
> +	.playback = {
> +		.stream_name = "PCM Playback",

Out of curiosity, why "PCM Playback" not just "Playback"?

> +static bool tegra20_ac97_volatile_reg(struct device *dev, unsigned int reg)
> +{
> +	switch (reg) {
> +	case TEGRA20_AC97_CMD:
...
> +		return true;

CMD is volatile; did we put status bits in there?

> +static int tegra20_ac97_platform_probe(struct platform_device *pdev)

> +	ac97->reset_gpio = of_get_named_gpio(pdev->dev.of_node,
> +					     "nvidia,codec-reset-gpio", 0);
> +	if (gpio_is_valid(ac97->reset_gpio)) {
> +		ret = devm_gpio_request_one(&pdev->dev, ac97->reset_gpio,
> +					    GPIOF_OUT_INIT_HIGH, "codec-reset");

Shouldn't this get the flags from the GPIO specifier, and deal with
active-high/active-low resets, or is the polarity set by the AC'97 spec?

> +		if (ret) {
> +			dev_err(&pdev->dev, "could not get codec-reset GPIO\n");
> +			goto err_clk_put;
> +		}
> +	} else {
> +		dev_err(&pdev->dev, "no codec-reset GPIO supplied\n");
> +		goto err_clk_put;
> +	}

Is a reset GPIO necessarily required? What if a board arranged to reset
the CODEC during power-on-reset, and there was no software control over
the reset?

> +	ac97->sync_gpio = of_get_named_gpio(pdev->dev.of_node,
> +					    "nvidia,codec-sync-gpio", 0);
> +	if (!gpio_is_valid(ac97->sync_gpio)) {
> +		dev_err(&pdev->dev, "no codec-sync GPIO supplied\n");
> +		goto err_clk_put;
> +	}

I don't know what this is, so I'll ask if it's strictly required too.

> +	ret = snd_soc_register_dais(&pdev->dev, &tegra20_ac97_dai, 1);

snd_soc_register_dai() would be marginally simpler.

> +	ret = clk_prepare_enable(ac97->clk_ac97);
> +	if (ret) {
> +		dev_err(&pdev->dev, "clk_enable failed: %d\n", ret);
> +		goto err_asoc_utils_fini;
> +	}

Can you do runtime PM instead? See the I2S driver for an example.

> +MODULE_LICENSE("GPL");

"GPL v2"

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 6/7] ASoC: tegra:  add ac97 host controller to device tree
       [not found]     ` <1355959056-6009-6-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
@ 2012-12-20 19:47       ` Stephen Warren
  0 siblings, 0 replies; 21+ messages in thread
From: Stephen Warren @ 2012-12-20 19:47 UTC (permalink / raw)
  To: Lucas Stach
  Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	Liam Girdwood, Mark Brown, linux-tegra-u79uwXL29TY76Z2rM5mHXA

On 12/19/2012 04:17 PM, Lucas Stach wrote:
> This adds the DT bindings and a default entry for the Tegra 2x
> AC97 host controller.

Everything here except the .dtsi file should be part of the previous patch.

> diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra20-ac97.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra20-ac97.txt

> +- nvidia,codec-sync-gpio : The Tegra GPIO controller's phandle and the number
> +  of the GPIO corresponding with the AC97 DAP _FS line

Hmm, for I2S at least, FS (frame sync I assume) definitely is something
that the audio controller itself drives. Are you absolutely sure that
this should be represented as a GPIO here?

> diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi

> +	tegra_ac97: ac97@70002000 {

There's only 1 node named ac97, so you can leave out the unit address
since it's not required to generate a unique node name. In other words
just "ac97".

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 7/7] ASoC: tegra: add machine driver using wm9712 codec
       [not found]     ` <1355959056-6009-7-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
@ 2012-12-20 19:55       ` Stephen Warren
       [not found]         ` <50D36D3B.7080309-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  0 siblings, 1 reply; 21+ messages in thread
From: Stephen Warren @ 2012-12-20 19:55 UTC (permalink / raw)
  To: Lucas Stach
  Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	Liam Girdwood, Mark Brown, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	Marcel Ziswiler

On 12/19/2012 04:17 PM, Lucas Stach wrote:
> This adds a simple machine driver using the Wolfson wm9712 AC97
> codec.

If the AC'97 code is going to be reworked to probe the CODEC rather than
manually specify it in DT, then will this machine driver become generic
for any AC'97 system, and hence you could rename the DT binding to
nvidia,tegra-audio-ac97?

> diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm9712.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm9712.txt

> +- nvidia,audio-codec : The phandle of the WM9712 audio codec

I wonder how you'll get that if you dynamically probe the AC'97 bus...

> diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig

> +config SND_SOC_TEGRA_WM9712
> +	tristate "SoC Audio support for Tegra boards using a WM9712 codec"
> +	depends on SND_SOC_TEGRA

I'd suggest making this depend on the Tegra AC97 module, or
ARCH_TEGRA_2x_SOC instead, since it can only run on Tegra20. The AC'97
module has been removed on Tegra30 and replaced with an HD Audio
controller instead.

> +	select SND_SOC_TEGRA20_AC97 if ARCH_TEGRA_2x_SOC

That select (or a dependency as mentioned above) is always required.

> +	select SND_SOC_AC97_BUS

Shouldn'y the AC'97 driver select that?

> diff --git a/sound/soc/tegra/tegra_wm9712.c b/sound/soc/tegra/tegra_wm9712.c

> +static int tegra_wm9712_init(struct snd_soc_pcm_runtime *rtd)

> +	snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");

Hmm. I guess that potentially ties this driver to whichever CODECs
actually expose a widget with that exact name...

> +static int tegra_wm9712_remove(struct snd_soc_card *card)
> +{
> +	return 0;
> +}

Do you need to implement this at all if it does nothing?

> +MODULE_LICENSE("GPL");

"GPL v2"

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 5/7] ASoC: tegra: add ac97 host driver
       [not found]         ` <50D36A98.7090204-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2012-12-20 20:10           ` Lucas Stach
  2012-12-20 20:19             ` Stephen Warren
  2012-12-20 20:23           ` Mark Brown
  1 sibling, 1 reply; 21+ messages in thread
From: Lucas Stach @ 2012-12-20 20:10 UTC (permalink / raw)
  To: Stephen Warren
  Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	Liam Girdwood, Mark Brown, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	Marcel Ziswiler

Am Donnerstag, den 20.12.2012, 12:44 -0700 schrieb Stephen Warren:
> On 12/19/2012 04:17 PM, Lucas Stach wrote:
> > This adds the driver for the Tegra 2x AC97 host controller.
> 
> The AC'97 DT binding file should really be added as part of this patch.
> 
Ok, will squash this in.

> I'm not at all familiar with AC'97, but this mostly looks fine. I have a
> bunch of comments below though, mostly for my own understanding.
> 
> > diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
> 
> > +config SND_SOC_TEGRA20_AC97
> > +	tristate
> > +	depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC
> 
> This should also select SND_SOC_TEGRA20_DAS, just like the I2S driver.
> 
> > diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c
> 
> > +static struct tegra20_ac97 *workdata;
> 
> Why not put that into the device's drvdata? Oh, is there no way to stash
> driver-private data into the struct snd_ac97?
> 
I'll have to look up if I can get this right when really using ac97_bus,
which might be needed for the hotplug stuff Mark mentioned.

> > +static void tegra20_ac97_codec_reset(struct snd_ac97 *ac97)
> > +{
> > +	u32 readback;
> > +	unsigned long timeout;
> > +
> > +	/* reset line is not driven by DAC pad group, have to toggle GPIO */
> > +	gpio_set_value(workdata->reset_gpio, 0);
> > +	udelay(2);
> 
> I'm not quite sure what that implies. Might some (Tegra) HW designs use
> a dedicated signal from the AC'97 HW to reset the CODEC and others not?
> That would make the GPIO optional. Or, does the comment mean that Tegra
> doesn't ever have a dedicated CODEC reset signal, so we always have to
> use a GPIO? If so, this comment might be more appropriate inside probe()
> where I asked my related questions.
> 
We always have to use a GPIO for that. CODEC reset is not part of the
AC97 digital link and therefore not connected to the controller
directly.

> > +static void tegra20_ac97_codec_warm_reset(struct snd_ac97 *ac97)
> > +{
> > +	u32 readback;
> > +	unsigned long timeout;
> > +
> > +	/*
> > +	 * although sync line is driven by the DAC pad group warm reset using
> > +	 * the controller cmd is not working, have to toggle sync line
> > +	 * manually.
> > +	 */
> > +	gpio_request(workdata->sync_gpio, "codec-sync");
> 
> Hmm. There's an AC'97 command to reset the CODEC and we don't implement
> it? Uggh.
> 
As far as I could figure from the downstream register doc there is a
command implemented in the host controller that's supposed to do the
warm reset, but in my testing it didn't work. Sadly I have not received
any documentation about the host controller from NVIDIA up until now, so
I don't now if we could make this work somehow. Bug Submission ID#:
196075

> > +static const struct snd_soc_dai_ops tegra20_ac97_dai_ops = {
> > +	.trigger	= tegra20_ac97_trigger,
> > +};
> 
> No .set_fmt or .hw_params? Does the AC'97 ASoC core code handle that
> somehow? I guess that's what soc_ac97_ops is for?
> 
I don't think it's needed. The codec code handles those two.
> > +static struct snd_soc_dai_driver tegra20_ac97_dai = {
> > +	.name = "tegra-ac97-pcm",
> > +	.ac97_control = 1,
> > +	.probe = tegra20_ac97_probe,
> > +	.playback = {
> > +		.stream_name = "PCM Playback",
> 
> Out of curiosity, why "PCM Playback" not just "Playback"?
> 
AC97 provides a second playback DAI named "AUX Playback". I want to add
this later, but could not test it until now so excluded it from the
patch. To provide clear distinction between the two, I would like to
call this one PCM.

> > +static bool tegra20_ac97_volatile_reg(struct device *dev, unsigned int reg)
> > +{
> > +	switch (reg) {
> > +	case TEGRA20_AC97_CMD:
> ...
> > +		return true;
> 
> CMD is volatile; did we put status bits in there?
> 
No, this is an oversight from my debugging. Will remove this.

> > +static int tegra20_ac97_platform_probe(struct platform_device *pdev)
> 
> > +	ac97->reset_gpio = of_get_named_gpio(pdev->dev.of_node,
> > +					     "nvidia,codec-reset-gpio", 0);
> > +	if (gpio_is_valid(ac97->reset_gpio)) {
> > +		ret = devm_gpio_request_one(&pdev->dev, ac97->reset_gpio,
> > +					    GPIOF_OUT_INIT_HIGH, "codec-reset");
> 
> Shouldn't this get the flags from the GPIO specifier, and deal with
> active-high/active-low resets, or is the polarity set by the AC'97 spec?
> 
Polarity is mandated by the AC97 spec.

> > +		if (ret) {
> > +			dev_err(&pdev->dev, "could not get codec-reset GPIO\n");
> > +			goto err_clk_put;
> > +		}
> > +	} else {
> > +		dev_err(&pdev->dev, "no codec-reset GPIO supplied\n");
> > +		goto err_clk_put;
> > +	}
> 
> Is a reset GPIO necessarily required? What if a board arranged to reset
> the CODEC during power-on-reset, and there was no software control over
> the reset?
> 
Codec reset is needed after refclock is stable. Although it might be
possible to omit this line, the AC97 spec assumes a reset line connected
to the host, so I don't think any implementation would omit this.

> > +	ac97->sync_gpio = of_get_named_gpio(pdev->dev.of_node,
> > +					    "nvidia,codec-sync-gpio", 0);
> > +	if (!gpio_is_valid(ac97->sync_gpio)) {
> > +		dev_err(&pdev->dev, "no codec-sync GPIO supplied\n");
> > +		goto err_clk_put;
> > +	}
> 
> I don't know what this is, so I'll ask if it's strictly required too.
> 
Until we manage to get the host controller warm reset command working
this is fixed to be the _FS line of the DAP connected to the codec, so
strictly required.

> > +	ret = snd_soc_register_dais(&pdev->dev, &tegra20_ac97_dai, 1);
> 
> snd_soc_register_dai() would be marginally simpler.
> 
> > +	ret = clk_prepare_enable(ac97->clk_ac97);
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "clk_enable failed: %d\n", ret);
> > +		goto err_asoc_utils_fini;
> > +	}
> 
> Can you do runtime PM instead? See the I2S driver for an example.
> 
Not really possible as for AC97 host and codec are intertwined. The
codec drivers assume the host controller is always up to service
commands. Maybe this could be fixed by using ac97_bus properly.

> > +MODULE_LICENSE("GPL");
> 
> "GPL v2"
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 7/7] ASoC: tegra: add machine driver using wm9712 codec
       [not found]         ` <50D36D3B.7080309-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2012-12-20 20:16           ` Mark Brown
  0 siblings, 0 replies; 21+ messages in thread
From: Mark Brown @ 2012-12-20 20:16 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Lucas Stach, alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	Liam Girdwood, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	Marcel Ziswiler

[-- Attachment #1: Type: text/plain, Size: 497 bytes --]

On Thu, Dec 20, 2012 at 12:55:39PM -0700, Stephen Warren wrote:
> On 12/19/2012 04:17 PM, Lucas Stach wrote:

> > +	snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");

> Hmm. I guess that potentially ties this driver to whichever CODECs
> actually expose a widget with that exact name...

Yes, embedded AC'97 systems are often but not always generic - another
thing you can do is have a PLL in the CODEC rather than having a MCLK at
the right frequency, and there's things like external components.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 5/7] ASoC: tegra: add ac97 host driver
  2012-12-20 20:10           ` Lucas Stach
@ 2012-12-20 20:19             ` Stephen Warren
       [not found]               ` <50D372DF.2080600-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  0 siblings, 1 reply; 21+ messages in thread
From: Stephen Warren @ 2012-12-20 20:19 UTC (permalink / raw)
  To: Lucas Stach
  Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	Liam Girdwood, Mark Brown, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	Marcel Ziswiler

On 12/20/2012 01:10 PM, Lucas Stach wrote:
> Am Donnerstag, den 20.12.2012, 12:44 -0700 schrieb Stephen Warren:
>> On 12/19/2012 04:17 PM, Lucas Stach wrote:
>>> This adds the driver for the Tegra 2x AC97 host controller.

>>> +static void tegra20_ac97_codec_warm_reset(struct snd_ac97 *ac97)
>>> +{
>>> +	u32 readback;
>>> +	unsigned long timeout;
>>> +
>>> +	/*
>>> +	 * although sync line is driven by the DAC pad group warm reset using
>>> +	 * the controller cmd is not working, have to toggle sync line
>>> +	 * manually.
>>> +	 */
>>> +	gpio_request(workdata->sync_gpio, "codec-sync");
>>
>> Hmm. There's an AC'97 command to reset the CODEC and we don't implement
>> it? Uggh.
>
> As far as I could figure from the downstream register doc there is a
> command implemented in the host controller that's supposed to do the
> warm reset, but in my testing it didn't work. Sadly I have not received
> any documentation about the host controller from NVIDIA up until now, so
> I don't now if we could make this work somehow. Bug Submission ID#:
> 196075

What system was that bug submitted into? It's not a regular NVIDIA
internal bug number. I'll see who I can ask about this feature...

>>> +	ac97->sync_gpio = of_get_named_gpio(pdev->dev.of_node,
>>> +					    "nvidia,codec-sync-gpio", 0);
>>> +	if (!gpio_is_valid(ac97->sync_gpio)) {
>>> +		dev_err(&pdev->dev, "no codec-sync GPIO supplied\n");
>>> +		goto err_clk_put;
>>> +	}
>>
>> I don't know what this is, so I'll ask if it's strictly required too.
>
> Until we manage to get the host controller warm reset command working
> this is fixed to be the _FS line of the DAP connected to the codec, so
> strictly required.

I'd like to investigate whether the warm reset command can be made to
work before actually committing to a DT binding that requires this GPIO
to be specified; the DT binding is supposed to be basically static.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 5/7] ASoC: tegra: add ac97 host driver
       [not found]         ` <50D36A98.7090204-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  2012-12-20 20:10           ` Lucas Stach
@ 2012-12-20 20:23           ` Mark Brown
  1 sibling, 0 replies; 21+ messages in thread
From: Mark Brown @ 2012-12-20 20:23 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Lucas Stach, alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	Liam Girdwood, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	Marcel Ziswiler

[-- Attachment #1: Type: text/plain, Size: 1725 bytes --]

On Thu, Dec 20, 2012 at 12:44:24PM -0700, Stephen Warren wrote:
> On 12/19/2012 04:17 PM, Lucas Stach wrote:

> > +	/* reset line is not driven by DAC pad group, have to toggle GPIO */
> > +	gpio_set_value(workdata->reset_gpio, 0);
> > +	udelay(2);

> I'm not quite sure what that implies. Might some (Tegra) HW designs use
> a dedicated signal from the AC'97 HW to reset the CODEC and others not?
> That would make the GPIO optional. Or, does the comment mean that Tegra
> doesn't ever have a dedicated CODEC reset signal, so we always have to
> use a GPIO? If so, this comment might be more appropriate inside probe()
> where I asked my related questions.

The traditional approach, pioneered by almost everyone who made an AC'97
controller, is to fill the thing with bugs.  Failing to drive the reset
line correctly is just one of the common bugs.

> > +static const struct snd_soc_dai_ops tegra20_ac97_dai_ops = {
> > +	.trigger	= tegra20_ac97_trigger,
> > +};

> No .set_fmt or .hw_params? Does the AC'97 ASoC core code handle that
> somehow? I guess that's what soc_ac97_ops is for?

There should be no controller side configurations for these things.
AC'97 defines the clocking format completely and variable sample rates
are done by the CODEC flagging when data is present in a given timeslot.

> > +	ac97->reset_gpio = of_get_named_gpio(pdev->dev.of_node,
> > +					     "nvidia,codec-reset-gpio", 0);
> > +	if (gpio_is_valid(ac97->reset_gpio)) {
> > +		ret = devm_gpio_request_one(&pdev->dev, ac97->reset_gpio,
> > +					    GPIOF_OUT_INIT_HIGH, "codec-reset");

> Shouldn't this get the flags from the GPIO specifier, and deal with
> active-high/active-low resets, or is the polarity set by the AC'97 spec?

Spec.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 5/7] ASoC: tegra: add ac97 host driver
       [not found]               ` <50D372DF.2080600-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2012-12-20 20:32                 ` Lucas Stach
  0 siblings, 0 replies; 21+ messages in thread
From: Lucas Stach @ 2012-12-20 20:32 UTC (permalink / raw)
  To: Stephen Warren
  Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	Liam Girdwood, Mark Brown, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	Marcel Ziswiler

Am Donnerstag, den 20.12.2012, 13:19 -0700 schrieb Stephen Warren:
> On 12/20/2012 01:10 PM, Lucas Stach wrote:
> > Am Donnerstag, den 20.12.2012, 12:44 -0700 schrieb Stephen Warren:
> >> On 12/19/2012 04:17 PM, Lucas Stach wrote:
> >>> This adds the driver for the Tegra 2x AC97 host controller.
> 
> >>> +static void tegra20_ac97_codec_warm_reset(struct snd_ac97 *ac97)
> >>> +{
> >>> +	u32 readback;
> >>> +	unsigned long timeout;
> >>> +
> >>> +	/*
> >>> +	 * although sync line is driven by the DAC pad group warm reset using
> >>> +	 * the controller cmd is not working, have to toggle sync line
> >>> +	 * manually.
> >>> +	 */
> >>> +	gpio_request(workdata->sync_gpio, "codec-sync");
> >>
> >> Hmm. There's an AC'97 command to reset the CODEC and we don't implement
> >> it? Uggh.
> >
> > As far as I could figure from the downstream register doc there is a
> > command implemented in the host controller that's supposed to do the
> > warm reset, but in my testing it didn't work. Sadly I have not received
> > any documentation about the host controller from NVIDIA up until now, so
> > I don't now if we could make this work somehow. Bug Submission ID#:
> > 196075
> 
> What system was that bug submitted into? It's not a regular NVIDIA
> internal bug number. I'll see who I can ask about this feature...
> 
Submitted through the Tegra Registered Developer Program webpage. I got
a reply from someone saying they are looking if they can get anything
out, but haven't heard back until now.

> >>> +	ac97->sync_gpio = of_get_named_gpio(pdev->dev.of_node,
> >>> +					    "nvidia,codec-sync-gpio", 0);
> >>> +	if (!gpio_is_valid(ac97->sync_gpio)) {
> >>> +		dev_err(&pdev->dev, "no codec-sync GPIO supplied\n");
> >>> +		goto err_clk_put;
> >>> +	}
> >>
> >> I don't know what this is, so I'll ask if it's strictly required too.
> >
> > Until we manage to get the host controller warm reset command working
> > this is fixed to be the _FS line of the DAP connected to the codec, so
> > strictly required.
> 
> I'd like to investigate whether the warm reset command can be made to
> work before actually committing to a DT binding that requires this GPIO
> to be specified; the DT binding is supposed to be basically static.
> 
Ok with me. We still have plenty of time left for the 3.9 merge window
and that's what I'm targeting with those patches.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4/7] ASoC: tegra: add function to set ac97 rate
       [not found]     ` <1355959056-6009-4-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
  2012-12-20 19:22       ` Stephen Warren
@ 2012-12-24 16:00       ` Mark Brown
  1 sibling, 0 replies; 21+ messages in thread
From: Mark Brown @ 2012-12-24 16:00 UTC (permalink / raw)
  To: Lucas Stach
  Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	Liam Girdwood, Stephen Warren,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 307 bytes --]

On Thu, Dec 20, 2012 at 12:17:33AM +0100, Lucas Stach wrote:
> AC97 uses a fixed rate, unrelated to the sample rate. Add a function to
> make the setup more trivial.

Applied, though the above isn't strictly true - a number of later AC'97
CODECs had PLLs which allowed them to use non-standard AC'97 MCLKs.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 3/7] ASoC: tegra: setup DAP3<->DAC3 connection by default
       [not found]     ` <1355959056-6009-3-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
  2012-12-20 19:20       ` Stephen Warren
@ 2012-12-24 16:01       ` Mark Brown
  1 sibling, 0 replies; 21+ messages in thread
From: Mark Brown @ 2012-12-24 16:01 UTC (permalink / raw)
  To: Lucas Stach
  Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	Liam Girdwood, Stephen Warren,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 129 bytes --]

On Thu, Dec 20, 2012 at 12:17:32AM +0100, Lucas Stach wrote:
> This connection is used by the AC97 controller.

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2012-12-24 16:01 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-12-19 23:17 [PATCH 1/7] ARM: tegra: add ac97 clock Lucas Stach
     [not found] ` <1355959056-6009-1-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
2012-12-19 23:17   ` [PATCH 2/7] ASoC: allow wolfson wm9712 codec to be instantiated using device tree Lucas Stach
     [not found]     ` <1355959056-6009-2-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
2012-12-20  9:32       ` Mark Brown
2012-12-19 23:17   ` [PATCH 3/7] ASoC: tegra: setup DAP3<->DAC3 connection by default Lucas Stach
     [not found]     ` <1355959056-6009-3-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
2012-12-20 19:20       ` Stephen Warren
2012-12-24 16:01       ` Mark Brown
2012-12-19 23:17   ` [PATCH 4/7] ASoC: tegra: add function to set ac97 rate Lucas Stach
     [not found]     ` <1355959056-6009-4-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
2012-12-20 19:22       ` Stephen Warren
2012-12-24 16:00       ` Mark Brown
2012-12-19 23:17   ` [PATCH 5/7] ASoC: tegra: add ac97 host driver Lucas Stach
     [not found]     ` <1355959056-6009-5-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
2012-12-20 19:44       ` Stephen Warren
     [not found]         ` <50D36A98.7090204-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-12-20 20:10           ` Lucas Stach
2012-12-20 20:19             ` Stephen Warren
     [not found]               ` <50D372DF.2080600-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-12-20 20:32                 ` Lucas Stach
2012-12-20 20:23           ` Mark Brown
2012-12-19 23:17   ` [PATCH 6/7] ASoC: tegra: add ac97 host controller to device tree Lucas Stach
     [not found]     ` <1355959056-6009-6-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
2012-12-20 19:47       ` Stephen Warren
2012-12-19 23:17   ` [PATCH 7/7] ASoC: tegra: add machine driver using wm9712 codec Lucas Stach
     [not found]     ` <1355959056-6009-7-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
2012-12-20 19:55       ` Stephen Warren
     [not found]         ` <50D36D3B.7080309-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-12-20 20:16           ` Mark Brown
2012-12-20 19:24   ` [PATCH 1/7] ARM: tegra: add ac97 clock Stephen Warren

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.