summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVinod G <vinodg@nvidia.com>2011-05-09 14:14:01 -0700
committerVarun Colbert <vcolbert@nvidia.com>2011-05-17 12:04:08 -0700
commit45c8916ab8e12fdc3e122a64e564467d5cbe20ec (patch)
treeb5050dcd70ff53babf787118f7b249b921d7c0d2
parent3bcc4026c53db3a0b001e900b5cd79b5cfb0f948 (diff)
arm: tegra: Add audio manager common interfaces.
Audio manager common interfaces are defined to be called from SOC code. Audio manager will make the decision which all modules to be controlled based on use case connection. Correction added to the speaker amp and i2c gpio is provided for controlling the speaker amplification. Removed the speakersetting call. Change-Id: Id2c7f953fc78f66bee2e1d4773e03548de0ba5b4 Reviewed-on: http://git-master/r/30891 Reviewed-by: Vinod Gopalakrishnakurup <vinodg@nvidia.com> Tested-by: Vinod Gopalakrishnakurup <vinodg@nvidia.com> Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/Makefile2
-rw-r--r--arch/arm/mach-tegra/audio_manager.c409
-rw-r--r--arch/arm/mach-tegra/board-cardhu.c23
-rw-r--r--arch/arm/mach-tegra/board-cardhu.h9
-rw-r--r--arch/arm/mach-tegra/include/mach/audio_manager.h85
-rw-r--r--arch/arm/mach-tegra/include/mach/spdif.h52
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra2_i2s.h8
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra3_i2s.h4
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra_i2s.h46
-rw-r--r--arch/arm/mach-tegra/spdif.c145
-rw-r--r--arch/arm/mach-tegra/tegra2_i2s.c121
-rw-r--r--arch/arm/mach-tegra/tegra3_i2s.c98
-rw-r--r--sound/soc/tegra/tegra_i2s.c129
-rw-r--r--sound/soc/tegra/tegra_pcm.c9
-rw-r--r--sound/soc/tegra/tegra_soc.h10
-rw-r--r--sound/soc/tegra/tegra_soc_wm8903.c61
-rw-r--r--sound/soc/tegra/tegra_spdif.c110
-rw-r--r--sound/soc/tegra/tegra_wired_jack.c10
18 files changed, 934 insertions, 397 deletions
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 2ecaba1bca03..b53bf925b330 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -20,6 +20,7 @@ obj-y += kfuse.o
ifeq ($(CONFIG_TEGRA_ALSA),y)
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_i2s.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra3_i2s.o
+obj-y += audio_manager.o
else
obj-y += tegra_i2s_audio.o
obj-y += tegra_spdif_audio.o
@@ -29,7 +30,6 @@ obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += dam.o
obj-y += spdif.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += audio_jack.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra_das.o
-obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += audio_manager.o
obj-y += mc.o
obj-$(CONFIG_USB_SUPPORT) += usb_phy.o
obj-$(CONFIG_FIQ) += fiq.o
diff --git a/arch/arm/mach-tegra/audio_manager.c b/arch/arm/mach-tegra/audio_manager.c
index 21ba3f16544e..ac517b6c5002 100644
--- a/arch/arm/mach-tegra/audio_manager.c
+++ b/arch/arm/mach-tegra/audio_manager.c
@@ -34,6 +34,232 @@
#include <mach/iomap.h>
#include <mach/pinmux.h>
#include <mach/tegra_das.h>
+#include <mach/tegra_i2s.h>
+#include <mach/spdif.h>
+#include <mach/audio_manager.h>
+
+
+static struct am_dev_fns init_am_dev_fns[] = {
+[AUDIO_I2S_DEVICE] = {
+ .aud_dev_suspend = i2s_suspend,
+ .aud_dev_resume = i2s_resume,
+ .aud_dev_set_stream_state = i2s_fifo_enable,
+ .aud_dev_get_dma_requestor = i2s_get_dma_requestor,
+ .aud_dev_free_dma_requestor = i2s_free_dma_requestor,
+ .aud_dev_get_fifo_phy_base = i2s_get_fifo_phy_base,
+ .aud_dev_set_fifo_attention = i2s_set_fifo_attention,
+ .aud_dev_get_status = i2s_get_status,
+ .aud_dev_clock_disable = i2s_clock_disable,
+ .aud_dev_clock_enable = i2s_clock_enable,
+ .aud_dev_clock_set_parent = i2s_clock_set_parent,
+ .aud_dev_clock_set_rate = i2s_clock_set_rate,
+ .aud_dev_deinit = i2s_close,
+ },
+
+[AUDIO_SPDIF_DEVICE] = {
+ .aud_dev_suspend = spdif_suspend,
+ .aud_dev_resume = spdif_resume,
+ .aud_dev_set_stream_state = spdif_fifo_enable,
+ .aud_dev_get_dma_requestor = spdif_get_dma_requestor,
+ .aud_dev_free_dma_requestor = spdif_free_dma_requestor,
+ .aud_dev_get_fifo_phy_base = spdif_get_fifo_phy_base,
+ .aud_dev_set_fifo_attention = spdif_set_fifo_attention,
+ .aud_dev_get_status = spdif_get_status,
+ .aud_dev_clock_disable = spdif_clock_disable,
+ .aud_dev_clock_enable = spdif_clock_enable,
+ .aud_dev_clock_set_parent = spdif_clock_set_parent,
+ .aud_dev_clock_set_rate = spdif_clock_set_rate,
+ .aud_dev_deinit = spdif_close,
+ },
+
+};
+
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+
+int am_suspend(aud_dev_info* devinfo)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_suspend(devinfo->dev_id);
+}
+
+int am_resume(aud_dev_info* devinfo)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_resume(devinfo->dev_id);
+}
+
+int am_set_stream_state(aud_dev_info* devinfo, bool enable)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_set_stream_state(
+ devinfo->dev_id,
+ devinfo->fifo_mode,
+ ((enable)? 1 : 0));
+}
+
+int am_get_dma_requestor(aud_dev_info* devinfo)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_get_dma_requestor(
+ devinfo->dev_id,
+ devinfo->fifo_mode);
+}
+
+int am_free_dma_requestor(aud_dev_info* devinfo)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_free_dma_requestor(
+ devinfo->dev_id,
+ devinfo->fifo_mode);
+}
+
+phys_addr_t am_get_fifo_phy_base(aud_dev_info* devinfo)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_get_fifo_phy_base(
+ devinfo->dev_id,
+ devinfo->fifo_mode);
+}
+
+int am_set_fifo_attention(aud_dev_info* devinfo, int buffersize)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_set_fifo_attention(
+ devinfo->dev_id,
+ buffersize,
+ devinfo->fifo_mode);
+}
+
+u32 am_get_status(aud_dev_info* devinfo)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_get_status(
+ devinfo->dev_id,
+ devinfo->fifo_mode);
+}
+
+int am_clock_disable(aud_dev_info* devinfo)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_clock_disable(
+ devinfo->dev_id,
+ devinfo->fifo_mode);
+}
+
+int am_clock_enable(aud_dev_info* devinfo)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_clock_enable(
+ devinfo->dev_id,
+ devinfo->fifo_mode);
+}
+
+int am_clock_set_parent(aud_dev_info* devinfo, int parent)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_clock_set_parent(
+ devinfo->dev_id,
+ devinfo->fifo_mode,
+ parent);
+}
+
+int am_clock_set_rate(aud_dev_info* devinfo, int rate)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_clock_set_rate(
+ devinfo->dev_id,
+ devinfo->fifo_mode,
+ rate);
+}
+
+int am_device_deinit(aud_dev_info* devinfo)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_deinit(devinfo->dev_id);
+}
+
+int am_set_stream_format(aud_dev_info* devinfo, am_stream_format_info *format)
+{
+ if (devinfo->dev_type == AUDIO_I2S_DEVICE) {
+ i2s_set_bit_size(devinfo->dev_id, format->bitsize);
+ i2s_set_samplerate(devinfo->dev_id, format->samplerate);
+ i2s_set_channels(devinfo->dev_id, format->channels);
+ i2s_set_fifo_attention(devinfo->dev_id,
+ devinfo->fifo_mode, format->buffersize);
+
+ } else if (devinfo->dev_type == AUDIO_SPDIF_DEVICE) {
+ spdif_set_bit_mode(devinfo->dev_id, format->bitsize);
+ /* fixme - move to appropriate locn later */
+ spdif_set_fifo_packed(devinfo->dev_id, 1);
+
+ spdif_set_sample_rate(devinfo->dev_id,
+ devinfo->fifo_mode, format->samplerate);
+ spdif_set_fifo_attention(devinfo->dev_id,
+ devinfo->fifo_mode, format->buffersize);
+ }
+ return 0;
+}
+
+int am_set_device_format(aud_dev_info* devinfo, am_dev_format_info *format)
+{
+ if (devinfo->dev_type == AUDIO_I2S_DEVICE) {
+ i2s_set_loopback(devinfo->dev_id, format->loopmode);
+ i2s_set_master(devinfo->dev_id, format->mastermode);
+ i2s_set_bit_format(devinfo->dev_id, format->audiomode);
+ i2s_set_left_right_control_polarity(
+ devinfo->dev_id,
+ format->polarity);
+
+ } else if (devinfo->dev_type == AUDIO_SPDIF_DEVICE) {
+
+ }
+ return 0;
+}
+
+int am_device_init(aud_dev_info* devinfo, void *dev_fmt, void *strm_fmt)
+{
+ am_stream_format_info *sfmt = (am_stream_format_info*)strm_fmt;
+ am_dev_format_info *dfmt = (am_dev_format_info*)dev_fmt;
+
+ if (devinfo->dev_type == AUDIO_I2S_DEVICE) {
+ struct tegra_i2s_property i2sprop;
+
+
+ memset(&i2sprop, 0, sizeof(i2sprop));
+
+ if (sfmt) {
+ i2sprop.bit_size = sfmt->bitsize;
+ i2sprop.sample_rate = sfmt->samplerate;
+ }
+
+ if (dfmt) {
+ i2sprop.master_mode = dfmt->mastermode;
+ i2sprop.audio_mode = dfmt->audiomode;
+ i2sprop.clk_rate = dfmt->clkrate;
+ i2sprop.fifo_fmt = dfmt->fifofmt;
+ }
+
+ return i2s_init(devinfo->dev_id, &i2sprop);
+
+ } else if (devinfo->dev_type == AUDIO_SPDIF_DEVICE) {
+
+ struct tegra_spdif_property spdifprop;
+ memset(&spdifprop, 0, sizeof(spdifprop));
+
+ if (dfmt) {
+ spdifprop.clk_rate = dfmt->clkrate;
+
+ return spdif_init(
+ devinfo->base,
+ devinfo->phy_base,
+ devinfo->fifo_mode,
+ &spdifprop);
+ }
+ }
+ return 0;
+}
+
+#else
struct audio_manager_context {
struct clk *mclk;
@@ -45,6 +271,188 @@ struct audio_manager_context {
struct audio_manager_context *aud_manager;
+int am_suspend(aud_dev_info* devinfo)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_suspend(devinfo->dev_id);
+}
+
+int am_resume(aud_dev_info* devinfo)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_resume(devinfo->dev_id);
+}
+
+int am_set_stream_state(aud_dev_info* devinfo, bool enable)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_set_stream_state(
+ devinfo->dev_id,
+ devinfo->fifo_mode,
+ ((enable)? 1 : 0));
+}
+
+int am_get_dma_requestor(aud_dev_info* devinfo)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_get_dma_requestor(
+ devinfo->dev_id,
+ devinfo->fifo_mode);
+}
+
+int am_free_dma_requestor(aud_dev_info* devinfo)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_free_dma_requestor(
+ devinfo->dev_id,
+ devinfo->fifo_mode);
+}
+
+phys_addr_t am_get_fifo_phy_base(aud_dev_info* devinfo)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_get_fifo_phy_base(
+ devinfo->dev_id,
+ devinfo->fifo_mode);
+}
+
+int am_set_fifo_attention(aud_dev_info* devinfo, int buffersize)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_set_fifo_attention(
+ devinfo->dev_id,
+ buffersize,
+ devinfo->fifo_mode);
+}
+
+u32 am_get_status(aud_dev_info* devinfo)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_get_status(
+ devinfo->dev_id,
+ devinfo->fifo_mode);
+}
+
+int am_clock_disable(aud_dev_info* devinfo)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_clock_disable(
+ devinfo->dev_id,
+ devinfo->fifo_mode);
+}
+
+int am_clock_enable(aud_dev_info* devinfo)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_clock_enable(
+ devinfo->dev_id,
+ devinfo->fifo_mode);
+}
+
+int am_clock_set_parent(aud_dev_info* devinfo, int parent)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_clock_set_parent(
+ devinfo->dev_id,
+ devinfo->fifo_mode,
+ parent);
+}
+
+int am_clock_set_rate(aud_dev_info* devinfo, int rate)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_clock_set_rate(
+ devinfo->dev_id,
+ devinfo->fifo_mode,
+ rate);
+}
+
+int am_device_deinit(aud_dev_info* devinfo)
+{
+ struct am_dev_fns* am_fn = &init_am_dev_fns[devinfo->dev_type];
+ return am_fn->aud_dev_deinit(devinfo->dev_id);
+}
+
+int am_set_stream_format(aud_dev_info* devinfo, am_stream_format_info *format)
+{
+ if (devinfo->dev_type == AUDIO_I2S_DEVICE) {
+ i2s_set_bit_size(devinfo->dev_id, format->bitsize);
+ i2s_set_samplerate(devinfo->dev_id, format->samplerate);
+ i2s_set_channels(devinfo->dev_id, format->channels);
+ i2s_set_fifo_attention(devinfo->dev_id,
+ devinfo->fifo_mode, format->buffersize);
+
+ } else if (devinfo->dev_type == AUDIO_SPDIF_DEVICE) {
+ spdif_set_bit_mode(devinfo->dev_id, format->bitsize);
+ spdif_set_sample_rate(
+ devinfo->dev_id,
+ devinfo->fifo_mode,
+ format->samplerate);
+ spdif_set_fifo_attention(devinfo->dev_id,
+ devinfo->fifo_mode, format->buffersize);
+ }
+ return 0;
+}
+
+int am_set_device_format(aud_dev_info* devinfo, am_dev_format_info *format)
+{
+ if (devinfo->dev_type == AUDIO_I2S_DEVICE) {
+ i2s_set_loopback(devinfo->dev_id, format->loopmode);
+ i2s_set_master(devinfo->dev_id, format->mastermode);
+ i2s_set_bit_format(devinfo->dev_id, format->audiomode);
+ i2s_set_left_right_control_polarity(
+ devinfo->dev_id,
+ format->polarity);
+
+ } else if (devinfo->dev_type == AUDIO_SPDIF_DEVICE) {
+
+ }
+ return 0;
+}
+
+int am_device_init(aud_dev_info* devinfo, void *dev_fmt, void *strm_fmt)
+{
+ am_stream_format_info *sfmt = (am_stream_format_info*)strm_fmt;
+ am_dev_format_info *dfmt = (am_dev_format_info*)dev_fmt;
+
+ if (devinfo->dev_type == AUDIO_I2S_DEVICE) {
+
+ struct tegra_i2s_property i2sprop;
+ memset(&i2sprop, 0, sizeof(i2sprop));
+
+ if (sfmt) {
+ i2sprop.bit_size = sfmt->bitsize;
+ i2sprop.sample_rate = sfmt->samplerate;
+ }
+
+ if (dfmt) {
+ i2sprop.master_mode = dfmt->mastermode;
+ i2sprop.audio_mode = dfmt->audiomode;
+ i2sprop.clk_rate = dfmt->clkrate;
+ i2sprop.fifo_fmt = dfmt->fifofmt;
+ }
+
+ return i2s_init(devinfo->dev_id, &i2sprop);
+
+ } else if (devinfo->dev_type == AUDIO_SPDIF_DEVICE) {
+
+ struct tegra_spdif_property spdifprop;
+ memset(&spdifprop, 0, sizeof(spdifprop));
+
+ if (dfmt) {
+ spdifprop.clk_rate = dfmt->clkrate;
+
+ return spdif_init(
+ devinfo->base,
+ devinfo->phy_base,
+ devinfo->fifo_mode,
+ &spdifprop);
+ }
+ }
+
+ return 0;
+}
+
int tegra_das_set_connection(enum tegra_das_port_con_id new_con_id)
{
return 0;
@@ -200,3 +608,4 @@ int tegra_das_get_mclk_rate(void)
EXPORT_SYMBOL_GPL(tegra_das_get_mclk_rate);
MODULE_LICENSE("GPL");
+#endif
diff --git a/arch/arm/mach-tegra/board-cardhu.c b/arch/arm/mach-tegra/board-cardhu.c
index d9aad8b07c86..fa0a0c63daf0 100644
--- a/arch/arm/mach-tegra/board-cardhu.c
+++ b/arch/arm/mach-tegra/board-cardhu.c
@@ -47,6 +47,7 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/usb_phy.h>
+#include <sound/wm8903.h>
#include "board.h"
#include "clock.h"
@@ -263,9 +264,25 @@ static struct platform_device androidusb_device = {
},
};
+static struct wm8903_platform_data wm8903_pdata = {
+ .irq_active_low = 0,
+ .micdet_cfg = 0x83, /* enable mic bias current */
+ .micdet_delay = 0,
+ .gpio_base = WM8903_GPIO_BASE,
+ .gpio_cfg = {
+ WM8903_GPIO_NO_CONFIG,
+ WM8903_GPIO_NO_CONFIG,
+ 0, /* as output pin */
+ WM8903_GPn_FN_GPIO_MICBIAS_CURRENT_DETECT
+ << WM8903_GP4_FN_SHIFT, /* as micbias current detect */
+ WM8903_GPIO_NO_CONFIG,
+ },
+};
+
static struct i2c_board_info __initdata cardhu_i2c_bus1_board_info[] = {
{
I2C_BOARD_INFO("wm8903", 0x1a),
+ .platform_data = &wm8903_pdata,
},
};
@@ -345,9 +362,9 @@ static struct tegra_audio_platform_data tegra_spdif_pdata = {
struct wired_jack_conf audio_wr_jack_conf = {
.hp_det_n = TEGRA_GPIO_PW2,
- .en_mic_ext = TEGRA_GPIO_PX1,
- .en_mic_int = TEGRA_GPIO_PX0,
- .spkr_amp_reg = "avdd_amp"
+ .cdc_irq = TEGRA_GPIO_PW3,
+ .en_spkr = WM8903_GP3,
+ .spkr_amp_reg = "vdd_3v3_spk_amp"
};
static void cardhu_audio_init(void)
diff --git a/arch/arm/mach-tegra/board-cardhu.h b/arch/arm/mach-tegra/board-cardhu.h
index ae32baaa00a3..05af0b482725 100644
--- a/arch/arm/mach-tegra/board-cardhu.h
+++ b/arch/arm/mach-tegra/board-cardhu.h
@@ -90,6 +90,15 @@
#define CAM_I2C_MUX_RST_EXP CAM_TCA6416_GPIO_BASE + 15
#define CAM_TCA6416_GPIO_END CAM_TCA6416_GPIO_BASE + 16
+/* WM8903 gpios */
+#define WM8903_GPIO_BASE CAM_TCA6416_GPIO_END
+#define WM8903_GP1 (WM8903_GPIO_BASE + 0)
+#define WM8903_GP2 (WM8903_GPIO_BASE + 1)
+#define WM8903_GP3 (WM8903_GPIO_BASE + 2)
+#define WM8903_GP4 (WM8903_GPIO_BASE + 3)
+#define WM8903_GP5 (WM8903_GPIO_BASE + 4)
+#define WM8903_GPIO_END (WM8903_GPIO_BASE + 5)
+
/* CAMERA RELATED GPIOs on CARDHU */
#define OV5650_RESETN_GPIO TEGRA_GPIO_PBB0
#define CAM1_POWER_DWN_GPIO TEGRA_GPIO_PBB5
diff --git a/arch/arm/mach-tegra/include/mach/audio_manager.h b/arch/arm/mach-tegra/include/mach/audio_manager.h
new file mode 100644
index 000000000000..9bdd2aa435d1
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/audio_manager.h
@@ -0,0 +1,85 @@
+/*
+ * arch/arm/mach-tegra/include/mach/audio_manager.h
+ *
+ * Copyright (C) 2010-2011 NVIDIA Corporation
+ *
+ * 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 __ARCH_ARM_MACH_TEGRA_AUDIO_MANAGER_H
+#define __ARCH_ARM_MACH_TEGRA_AUDIO_MANAGER_H
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#define AUDIO_I2S_DEVICE 0
+#define AUDIO_SPDIF_DEVICE 1
+#define AUDIO_MAX_DEVICE 2
+
+typedef struct aud_dev_info_ {
+ int dev_type;
+ int dev_id;
+ int fifo_mode;
+ unsigned long base;
+ phys_addr_t phy_base;
+}aud_dev_info;
+
+typedef struct am_stream_format_info_{
+ int samplerate;
+ int channels;
+ int bitsize;
+ int buffersize;
+}am_stream_format_info;
+
+typedef struct am_dev_format_info_{
+ int mastermode;
+ int audiomode;
+ int polarity;
+ int clkrate;
+ int fifofmt;
+ int loopmode;
+}am_dev_format_info;
+
+struct am_dev_fns {
+ int (*aud_dev_suspend)(int);
+ int (*aud_dev_resume)(int);
+ int (*aud_dev_set_stream_state)(int, int, int);
+ int (*aud_dev_get_dma_requestor)(int, int);
+ int (*aud_dev_free_dma_requestor)(int, int);
+ phys_addr_t (*aud_dev_get_fifo_phy_base)(int, int);
+ int (*aud_dev_set_fifo_attention)(int, int, int);
+ u32 (*aud_dev_get_status)(int, int);
+ int (*aud_dev_clock_disable)(int, int);
+ int (*aud_dev_clock_enable)(int, int);
+ int (*aud_dev_clock_set_parent)(int, int, int);
+ int (*aud_dev_clock_set_rate)(int, int, int);
+ int (*aud_dev_deinit)(int);
+};
+
+int am_suspend(aud_dev_info* devinfo);
+int am_resume(aud_dev_info* devinfo);
+int am_set_stream_state(aud_dev_info* devinfo, bool enable);
+int am_get_dma_requestor(aud_dev_info* devinfo);
+int am_free_dma_requestor(aud_dev_info* devinfo);
+phys_addr_t am_get_fifo_phy_base(aud_dev_info* devinfo);
+int am_set_fifo_attention(aud_dev_info* devinfo, int buffersize);
+u32 am_get_status(aud_dev_info* devinfo);
+int am_clock_disable(aud_dev_info* devinfo);
+int am_clock_enable(aud_dev_info* devinfo);
+int am_clock_set_parent(aud_dev_info* devinfo, int parent);
+int am_clock_set_rate(aud_dev_info* devinfo, int rate);
+
+int am_device_init(aud_dev_info* devinfo, void *dev_fmt, void *strm_fmt);
+int am_device_deinit(aud_dev_info* devinfo);
+int am_set_stream_format(aud_dev_info* devinfo, am_stream_format_info *format);
+int am_set_device_format(aud_dev_info* devinfo, am_dev_format_info *format);
+
+#endif /* __ARCH_ARM_MACH_TEGRA_AUDIO_MANAGER_H */
diff --git a/arch/arm/mach-tegra/include/mach/spdif.h b/arch/arm/mach-tegra/include/mach/spdif.h
index 5647e8ad87c4..a41a3d76ea31 100644
--- a/arch/arm/mach-tegra/include/mach/spdif.h
+++ b/arch/arm/mach-tegra/include/mach/spdif.h
@@ -509,34 +509,36 @@ struct tegra_spdif_device_context {
};
/* spdif apis */
-void spdif_fifo_enable(unsigned long base, int mode, int on);
-int spdif_set_bit_mode(unsigned long base, unsigned mode);
-int spdif_set_fifo_packed(unsigned long base, unsigned on);
-int spdif_set_sample_rate(int fifo_mode, unsigned int sample_rate);
-void spdif_fifo_write(unsigned long base, int mode, u32 data);
-int spdif_fifo_set_attention_level(unsigned long base,
- int mode, unsigned int level);
-void spdif_fifo_clear(unsigned long base, int mode);
-u32 spdif_get_status(unsigned long base, int mode);
-u32 spdif_get_control(unsigned long base);
-void spdif_ack_status(unsigned long base);
-u32 spdif_get_fifo_scr(unsigned long base);
-phys_addr_t spdif_get_fifo_phy_base(phys_addr_t phy_base, int mode);
-u32 spdif_get_fifo_full_empty_count(unsigned long base, int mode);
+int spdif_fifo_enable(int ifc, int mode, int on);
+int spdif_get_dma_requestor(int ifc, int mode);
+int spdif_free_dma_requestor(int ifc, int mode);
+phys_addr_t spdif_get_fifo_phy_base(int ifc, int mode);
+int spdif_set_fifo_attention(int ifc, int fifo_mode, int buffersize);
+int spdif_fifo_clear(int ifc, int mode);
+int spdif_fifo_set_attention_level(int ifc, int mode, unsigned int level);
+int spdif_fifo_write(int ifc, int mode, u32 data);
+u32 spdif_get_status(int ifc, int mode);
+int spdif_clock_enable(int ifc, int mode);
+int spdif_clock_disable(int ifc, int mode);
+int spdif_suspend(int ifc);
+int spdif_resume(int ifc);
+
+int spdif_set_bit_mode(int ifc, unsigned mode);
+int spdif_set_fifo_packed(int ifc, unsigned on);
+int spdif_set_sample_rate(int ifc, int fifo_mode, unsigned int sample_rate);
+
+u32 spdif_get_control(int ifc);
+int spdif_ack_status(int ifc);
+u32 spdif_get_fifo_scr(int ifc);
+
+u32 spdif_get_fifo_full_empty_count(int ifc, int mode);
int spdif_initialize(unsigned long base, int mode);
void spdif_get_all_regs(unsigned long base, struct spdif_regs_cache* regs);
void spdif_set_all_regs(unsigned long base, struct spdif_regs_cache* regs);
-int spdif_get_dma_requestor(int mode);
-int spdif_free_dma_requestor(int mode);
-void spdif_set_fifo_attention(int buffersize, int fifo_mode);
-
-int spdif_init(unsigned long base, int mode,
+int spdif_init(unsigned long base, phys_addr_t phy_base, int mode,
struct tegra_spdif_property* pspdifprop);
-int spdif_close(void);
-int spdif_clock_enable(int mode);
-int spdif_clock_disable(int mode);
-int spdif_clock_set_parent(int mode, int rate);
-int spdif_suspend(void);
-int spdif_resume(void);
+int spdif_close(int ifc);
+int spdif_clock_set_parent(int ifc, int mode, int parent);
+int spdif_clock_set_rate(int ifc, int mode, int rate);
#endif /* __ARCH_ARM_MACH_TEGRA_SPDIF_H */
diff --git a/arch/arm/mach-tegra/include/mach/tegra2_i2s.h b/arch/arm/mach-tegra/include/mach/tegra2_i2s.h
index 61a88aa7c0ae..e48ccacd1422 100644
--- a/arch/arm/mach-tegra/include/mach/tegra2_i2s.h
+++ b/arch/arm/mach-tegra/include/mach/tegra2_i2s.h
@@ -293,11 +293,11 @@
/*
* API
*/
-void i2s_set_fifo_mode(int ifc, int fifo, int tx);
+int i2s_set_fifo_mode(int ifc, int fifo, int tx);
int i2s_set_fifo_format(int ifc, unsigned fmt);
int i2s_set_pcm_edge_mode(int ifc, unsigned edge_mode);
int i2s_set_pcm_mask_bits(int ifc, unsigned mask_bits, int tx);
-void i2s_set_pcm_fsync_width(int ifc, int fsync_long);
-void i2s_enable_pcm_mode(int ifc, int enable);
-void i2s_enable_fifos(int ifc, int on);
+int i2s_set_pcm_fsync_width(int ifc, int fsync_long);
+int i2s_enable_pcm_mode(int ifc, int enable);
+int i2s_enable_fifos(int ifc, int on);
#endif /* __ARCH_ARM_MACH_TEGRA_I2S_H */
diff --git a/arch/arm/mach-tegra/include/mach/tegra3_i2s.h b/arch/arm/mach-tegra/include/mach/tegra3_i2s.h
index dadd396f1fe3..546d0730674c 100644
--- a/arch/arm/mach-tegra/include/mach/tegra3_i2s.h
+++ b/arch/arm/mach-tegra/include/mach/tegra3_i2s.h
@@ -307,8 +307,8 @@
* API
*/
-void i2s_set_clock_gating(int ifc, int enable);
-void i2s_set_soft_reset(int ifc, int enable);
+int i2s_set_clock_gating(int ifc, int enable);
+int i2s_set_soft_reset(int ifc, int enable);
int i2s_set_bit_code(int ifc, unsigned bitcode);
int i2s_set_data_offset(int ifc, int tx, int dataoffset);
diff --git a/arch/arm/mach-tegra/include/mach/tegra_i2s.h b/arch/arm/mach-tegra/include/mach/tegra_i2s.h
index 99497a4e4b3f..6e6cd035d01e 100644
--- a/arch/arm/mach-tegra/include/mach/tegra_i2s.h
+++ b/arch/arm/mach-tegra/include/mach/tegra_i2s.h
@@ -60,45 +60,43 @@ struct tegra_i2s_property {
/* APIs */
void i2s_dump_registers(int ifc);
-void i2s_suspend(int ifc);
-void i2s_resume(int ifc);
-void i2s_fifo_enable(int ifc, int fifo, int on);
-void i2s_fifo_clear(int ifc, int fifo);
-
-void i2s_set_loopback(int ifc, int on);
-void i2s_set_master(int ifc, int master);
-void i2s_set_left_right_control_polarity(int ifc, int left_low);
-
-int i2s_set_channel_bit_count(int ifc, int sampling, int bitclk);
+int i2s_suspend(int ifc);
+int i2s_resume(int ifc);
+int i2s_fifo_enable(int ifc, int fifo, int on);
+int i2s_fifo_clear(int ifc, int fifo);
int i2s_fifo_set_attention_level(int ifc, int fifo, unsigned level);
-
-int i2s_init(int ifc, struct tegra_i2s_property* pi2sprop);
int i2s_get_dma_requestor(int ifc, int fifo_mode);
int i2s_free_dma_requestor(int ifc, int fifo_mode);
+phys_addr_t i2s_get_fifo_phy_base(int ifc, int fifo);
+u32 i2s_get_status(int ifc, int fifo);
+
+int i2s_set_loopback(int ifc, int on);
+int i2s_set_master(int ifc, int master);
+int i2s_set_left_right_control_polarity(int ifc, int left_low);
+int i2s_set_channel_bit_count(int ifc, int sampling, int bitclk);
+int i2s_init(int ifc, struct tegra_i2s_property* pi2sprop);
int i2s_set_bit_format(int ifc, unsigned format);
int i2s_set_bit_size(int ifc, unsigned bit_size);
-phys_addr_t i2s_get_fifo_phy_base(int ifc, int fifo);
-void i2s_set_fifo_irq_on_err(int ifc, int fifo, int on);
-void i2s_set_fifo_irq_on_qe(int ifc, int fifo, int on);
+int i2s_set_fifo_irq_on_err(int ifc, int fifo, int on);
+int i2s_set_fifo_irq_on_qe(int ifc, int fifo, int on);
-void i2s_fifo_write(int ifc, int fifo, u32 data);
+int i2s_fifo_write(int ifc, int fifo, u32 data);
u32 i2s_fifo_read(int ifc, int fifo);
-u32 i2s_get_status(int ifc, int fifo);
+
u32 i2s_get_control(int ifc);
-void i2s_ack_status(int ifc);
+int i2s_ack_status(int ifc);
u32 i2s_get_fifo_scr(int ifc);
u32 i2s_get_fifo_full_empty_count(int ifc, int fifo);
struct clk *i2s_get_clock_by_name(const char *name);
-void i2s_set_fifo_attention(int ifc, int buffersize, int fifo_mode);
+int i2s_set_fifo_attention(int ifc, int fifo_mode, int buffersize);
int i2s_set_samplerate(int ifc, int samplerate);
int i2s_set_channels(int ifc, int channels);
-int i2s_clock_disable(int ifc);
-int i2s_clock_enable(int ifc);
+int i2s_clock_disable(int ifc, int fifo_mode);
+int i2s_clock_enable(int ifc, int fifo_mode);
int i2s_close(int ifc);
-int i2s_clock_set_parent(int ifc, int parent);
-int i2s_clock_rate(int ifc, int rate);
-
+int i2s_clock_set_parent(int ifc, int mode, int parent);
+int i2s_clock_set_rate(int ifc, int mode, int rate);
#endif /* __ARCH_ARM_MACH_TEGRA_I2S_H */
diff --git a/arch/arm/mach-tegra/spdif.c b/arch/arm/mach-tegra/spdif.c
index 972ca2bc8e06..845ecfd8c663 100644
--- a/arch/arm/mach-tegra/spdif.c
+++ b/arch/arm/mach-tegra/spdif.c
@@ -48,6 +48,7 @@ struct spdif_controller_info {
struct tegra_spdif_clk_info spclk;
unsigned long base;
+ phys_addr_t phy_base;
int refcnt;
void* reg_cache;
};
@@ -70,7 +71,7 @@ static inline u32 spdif_readl(unsigned long base, u32 reg)
return val;
}
-int spdif_set_clock_rate(int mode, int rate)
+int spdif_clock_set_rate(int ifc, int mode, int rate)
{
spinfo->spdev[mode].ch_prop.clk_rate = rate;
@@ -83,8 +84,9 @@ int spdif_set_clock_rate(int mode, int rate)
return 0;
}
-int spdif_set_bit_mode(unsigned long base, unsigned mode)
+int spdif_set_bit_mode(int ifc, unsigned mode)
{
+ unsigned long base = spinfo->base;
u32 val = spdif_readl(base, SPDIF_CTRL_0);
val &= ~SPDIF_CTRL_0_BIT_MODE_MASK;
@@ -100,7 +102,7 @@ int spdif_set_bit_mode(unsigned long base, unsigned mode)
return 0;
}
-int spdif_set_sample_rate(int fifo_mode, unsigned int sample_rate)
+int spdif_set_sample_rate(int ifc, int fifo_mode, unsigned int sample_rate)
{
unsigned int rate = 0;
unsigned long base = spinfo->base;
@@ -144,17 +146,17 @@ int spdif_set_sample_rate(int fifo_mode, unsigned int sample_rate)
spdif_writel(base, ch_sta[5], SPDIF_CH_STA_TX_F_0);
rate = sample_rate << 7; /* sr*128 */
- spdif_set_clock_rate(fifo_mode, rate);
+ spdif_clock_set_rate(0, fifo_mode, rate);
return 0;
}
-u32 spdif_get_control(unsigned long base)
+u32 spdif_get_control(int ifc)
{
- return spdif_readl(base, SPDIF_CTRL_0);
+ return spdif_readl(spinfo->base, SPDIF_CTRL_0);
}
-int spdif_close(void)
+int spdif_close(int ifc)
{
SPDIF_DEBUG_PRINT(" %s \n", __func__);
@@ -232,7 +234,7 @@ static int spdif_open(void)
fail_spdif_open:
- spdif_close();
+ spdif_close(0);
return err;
}
@@ -246,12 +248,12 @@ int spdif_initialize(unsigned long base, int mode)
spdif_set_bit_mode(base, SPDIF_BIT_MODE_MODE16BIT);
spdif_set_fifo_packed(base, 1);
- spdif_set_sample_rate(mode, 44100);
+ spdif_set_sample_rate(0, mode, 44100);
return 0;
}
-int spdif_init(unsigned long base, int mode,
+int spdif_init(unsigned long base, phys_addr_t phy_base, int mode,
struct tegra_spdif_property* spdifprop)
{
int err = 0;
@@ -263,31 +265,32 @@ int spdif_init(unsigned long base, int mode,
/* open audio_switch first */
err = audio_switch_open();
if (err) {
- spdif_close();
+ spdif_close(0);
return err;
}
spinfo->base = base;
+ spinfo->phy_base = phy_base;
spinfo->spdev[mode].ch_prop.clk_rate = spdifprop->clk_rate;
- spdif_clock_set_parent(mode, 0);
+ spdif_clock_set_parent(0, mode, 0);
- err = spdif_clock_enable(mode);
+ err = spdif_clock_enable(0, mode);
if (err) {
audio_switch_close();
- spdif_close();
+ spdif_close(0);
return err;
}
spdif_initialize(base, mode);
- spdif_clock_disable(mode);
+ spdif_clock_disable(0, mode);
SPDIF_DEBUG_PRINT(" %s -- \n", __func__);
return 0;
}
-int spdif_clock_enable(int mode)
+int spdif_clock_enable(int ifc, int mode)
{
int err = 0;
@@ -305,7 +308,7 @@ int spdif_clock_enable(int mode)
} else {
- spdif_set_clock_rate(mode,
+ spdif_clock_set_rate(0, mode,
spinfo->spdev[mode].ch_prop.clk_rate);
if (mode == AUDIO_TX_MODE) {
@@ -336,11 +339,11 @@ int spdif_clock_enable(int mode)
spdif_clock_enable_failed:
- spdif_clock_disable(mode);
+ spdif_clock_disable(0, mode);
return err;
}
-int spdif_clock_disable(int mode)
+int spdif_clock_disable(int ifc, int mode)
{
SPDIF_DEBUG_PRINT(" %s ++ \n", __func__);
@@ -370,7 +373,7 @@ int spdif_clock_disable(int mode)
return 0;
}
-int spdif_clock_set_parent(int mode, int parent)
+int spdif_clock_set_parent(int ifc, int mode, int parent)
{
/* Fix set the parent properly */
struct clk *pll_a_out0_clk = clk_get_sys(NULL, "pll_a_out0");
@@ -389,27 +392,27 @@ int spdif_clock_set_parent(int mode, int parent)
}
-int spdif_suspend(void)
+int spdif_suspend(int ifc)
{
SPDIF_DEBUG_PRINT(" %s ++ \n", __func__);
/* FIXME : check for Rx mode if needed */
if (spinfo->spdev[AUDIO_TX_MODE].clk_refs == 0)
- spdif_clock_enable(AUDIO_TX_MODE);
+ spdif_clock_enable(0, AUDIO_TX_MODE);
spdif_save_regs(spinfo->base);
audio_switch_suspend();
- spdif_clock_disable(AUDIO_TX_MODE);
+ spdif_clock_disable(0, AUDIO_TX_MODE);
return 0;
}
-int spdif_resume(void)
+int spdif_resume(int ifc)
{
SPDIF_DEBUG_PRINT(" %s ++ \n", __func__);
/* FIXME : check for Rx mode if needed */
- spdif_clock_enable(AUDIO_TX_MODE);
+ spdif_clock_enable(0, AUDIO_TX_MODE);
audio_switch_resume();
spdif_restore_regs(spinfo->base);
@@ -417,18 +420,23 @@ int spdif_resume(void)
}
#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
-void spdif_fifo_write(unsigned long base, int mode, u32 data)
+int spdif_fifo_write(int ifc, int mode, u32 data)
{
+ unsigned long base = spinfo->base;
+
if (mode == AUDIO_TX_MODE) {
spdif_writel(base, data, SPDIF_DATA_OUT_0);
} else {
spdif_writel(base, data, SPDIF_DATA_IN_0);
}
+
+ return 0;
}
-int spdif_fifo_set_attention_level(unsigned long base, int mode, unsigned level)
+int spdif_fifo_set_attention_level(int ifc, int mode, unsigned int level)
{
u32 val;
+ unsigned long base = spinfo->base;
if (level > SPDIF_FIFO_ATN_LVL_TWELVE_SLOTS) {
pr_err("%s: invalid fifo level selector %d\n", __func__,
@@ -447,8 +455,10 @@ int spdif_fifo_set_attention_level(unsigned long base, int mode, unsigned level)
return 0;
}
-void spdif_fifo_clear(unsigned long base, int mode)
+int spdif_fifo_clear(int ifc, int mode)
{
+ unsigned long base = spinfo->base;
+
u32 val = spdif_readl(base, SPDIF_DATA_FIFO_CSR_0);
if (mode == AUDIO_TX_MODE) {
@@ -457,47 +467,52 @@ void spdif_fifo_clear(unsigned long base, int mode)
val |= SPDIF_DATA_FIFO_CSR_0_TX_CLR |
SPDIF_DATA_FIFO_CSR_0_TU_CLR;
}
+
spdif_writel(base, val, SPDIF_DATA_FIFO_CSR_0);
+ return 0;
}
-int spdif_set_fifo_packed(unsigned long base, unsigned on)
+int spdif_set_fifo_packed(int ifc, unsigned on)
{
- u32 val = spdif_readl(base, SPDIF_CTRL_0);
+ u32 val = spdif_readl(spinfo->base, SPDIF_CTRL_0);
val &= ~SPDIF_CTRL_0_PACK;
val |= on ? (SPDIF_CTRL_0_PACK) : 0;
- spdif_writel(base, val, SPDIF_CTRL_0);
+ spdif_writel(spinfo->base, val, SPDIF_CTRL_0);
return 0;
}
-u32 spdif_get_status(unsigned long base, int mode)
+u32 spdif_get_status(int ifc, int mode)
{
- return spdif_readl(base, SPDIF_STATUS_0);
+ return spdif_readl(spinfo->base, SPDIF_STATUS_0);
}
-void spdif_ack_status(unsigned long base)
+int spdif_ack_status(int ifc)
{
- return spdif_writel(base, spdif_readl(base, SPDIF_STATUS_0),
+ unsigned long base = spinfo->base;
+ spdif_writel(base, spdif_readl(base, SPDIF_STATUS_0),
SPDIF_STATUS_0);
+ return 0;
}
-u32 spdif_get_fifo_scr(unsigned long base)
+u32 spdif_get_fifo_scr(int ifc)
{
- return spdif_readl(base, SPDIF_DATA_FIFO_CSR_0);
+ return spdif_readl(spinfo->base, SPDIF_DATA_FIFO_CSR_0);
}
-phys_addr_t spdif_get_fifo_phy_base(phys_addr_t phy_base, int mode)
+phys_addr_t spdif_get_fifo_phy_base(int ifc, int mode)
{
if (mode == AUDIO_TX_MODE)
- return phy_base + SPDIF_DATA_OUT_0;
+ return spinfo->phy_base + SPDIF_DATA_OUT_0;
else
- return phy_base + SPDIF_DATA_IN_0;
+ return spinfo->phy_base + SPDIF_DATA_IN_0;
return 0;
}
-u32 spdif_get_fifo_full_empty_count(unsigned long base, int mode)
+u32 spdif_get_fifo_full_empty_count(int ifc, int mode)
{
+ unsigned long base = spinfo->base;
u32 val = spdif_readl(base, SPDIF_DATA_FIFO_CSR_0);
if (mode == AUDIO_TX_MODE) {
@@ -508,20 +523,21 @@ u32 spdif_get_fifo_full_empty_count(unsigned long base, int mode)
return 0;
}
-int spdif_get_dma_requestor(int fifo_mode)
+int spdif_get_dma_requestor(int ifc, int fifo_mode)
{
return TEGRA_DMA_REQ_SEL_SPD_I;
}
-int spdif_free_dma_requestor(int fifo_mode)
+int spdif_free_dma_requestor(int ifc, int fifo_mode)
{
return 0;
}
-void spdif_set_fifo_attention(int buffersize, int fifo_mode)
+int spdif_set_fifo_attention(int ifc, int fifo_mode, int buffersize)
{
int fifoattn = SPDIF_FIFO_ATN_LVL_FOUR_SLOTS;
spinfo->spdev[fifo_mode].fifo_attn = fifoattn;
+ return 0;
}
void spdif_save_regs(unsigned long base)
@@ -573,6 +589,7 @@ void spdif_restore_regs(unsigned long base)
spdif_writel(base, regs->spdif_usr_sta_rx_a_0, SPDIF_USR_STA_RX_A_0);
spdif_writel(base, regs->spdif_usr_dat_tx_a_0, SPDIF_USR_DAT_TX_A_0);
}
+
#else
static int spdif_get_apbif_channel(int fifo_mode)
@@ -580,22 +597,23 @@ static int spdif_get_apbif_channel(int fifo_mode)
return spinfo->spdev[fifo_mode].dma_ch;
}
-int spdif_set_fifo_packed(unsigned long base, unsigned on)
+int spdif_set_fifo_packed(int ifc, unsigned on)
{
/* This register is obsolete after T20 */
return 0;
}
-void spdif_fifo_write(unsigned long base, int mode, u32 data)
+int spdif_fifo_write(int ifc, int mode, u32 data)
{
int apbif_ifc = spdif_get_apbif_channel(mode);
if (apbif_ifc != -ENOENT)
apbif_fifo_write(apbif_ifc, mode, data);
+
+ return 0;
}
-int spdif_fifo_set_attention_level(unsigned long base, int mode,
- unsigned level)
+int spdif_fifo_set_attention_level(int ifc, int mode, unsigned int level)
{
int apbif_ifc = spdif_get_apbif_channel(mode);
@@ -606,15 +624,17 @@ int spdif_fifo_set_attention_level(unsigned long base, int mode,
return 0;
}
-void spdif_fifo_clear(unsigned long base, int mode)
+int spdif_fifo_clear(int ifc, int mode)
{
int apbif_ifc = spdif_get_apbif_channel(mode);
if (apbif_ifc != -ENOENT)
apbif_soft_reset(apbif_ifc, mode, 1);
+
+ return 0;
}
-u32 spdif_get_status(unsigned long base, int mode)
+u32 spdif_get_status(int ifc, int mode)
{
int apbif_ifc = spdif_get_apbif_channel(mode);
@@ -624,18 +644,19 @@ u32 spdif_get_status(unsigned long base, int mode)
return 0;
}
-void spdif_ack_status(unsigned long base)
+int spdif_ack_status(int ifc)
{
/*FIXME: add apbif call here */
+ return 0;
}
-u32 spdif_get_fifo_scr(unsigned long base)
+u32 spdif_get_fifo_scr(int ifc)
{
/*FIXME: add apbif call here */
return 0;
}
-phys_addr_t spdif_get_fifo_phy_base(phys_addr_t phy_base, int mode)
+phys_addr_t spdif_get_fifo_phy_base(int ifc, int mode)
{
int apbif_ifc = spdif_get_apbif_channel(mode);
@@ -645,7 +666,7 @@ phys_addr_t spdif_get_fifo_phy_base(phys_addr_t phy_base, int mode)
return 0;
}
-u32 spdif_get_fifo_full_empty_count(unsigned long base, int mode)
+u32 spdif_get_fifo_full_empty_count(int ifc, int mode)
{
int apbif_ifc = spdif_get_apbif_channel(mode);
@@ -655,7 +676,7 @@ u32 spdif_get_fifo_full_empty_count(unsigned long base, int mode)
return 0;
}
-int spdif_free_dma_requestor(int fifo_mode)
+int spdif_free_dma_requestor(int ifc, int fifo_mode)
{
int apbif_ifc = spdif_get_apbif_channel(fifo_mode);
@@ -695,7 +716,7 @@ int spdif_set_acif(int fifo_mode, struct audio_cif *cifInfo)
return 0;
}
-int spdif_get_dma_requestor(int fifo_mode)
+int spdif_get_dma_requestor(int ifc, int fifo_mode)
{
int dma_index = 0;
int apbif_ifc = ahubrx0_spdif;
@@ -715,7 +736,7 @@ int spdif_get_dma_requestor(int fifo_mode)
return dma_index;
}
-void spdif_set_fifo_attention(int buffersize, int fifo_mode)
+int spdif_set_fifo_attention(int ifc, int fifo_mode, int buffersize)
{
int fifoattn = SPDIF_FIFO_ATN_LVL_FOUR_SLOTS;
@@ -727,6 +748,7 @@ void spdif_set_fifo_attention(int buffersize, int fifo_mode)
fifoattn = SPDIF_FIFO_ATN_LVL_EIGHT_SLOTS;
spinfo->spdev[fifo_mode].fifo_attn = fifoattn;
+ return 0;
}
void spdif_save_regs(unsigned long base)
@@ -751,16 +773,17 @@ void spdif_restore_regs(unsigned long base)
#endif
-void spdif_fifo_enable(unsigned long base, int mode, int on)
+int spdif_fifo_enable(int ifc, int mode, int on)
{
u32 val = 0;
+ unsigned long base = spinfo->base;
#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
int apbif_ifc = spdif_get_apbif_channel(mode);
if (apbif_ifc == -ENOENT)
- return;
+ return apbif_ifc;
apbif_channel_enable(apbif_ifc, mode, on);
#endif
@@ -776,9 +799,9 @@ void spdif_fifo_enable(unsigned long base, int mode, int on)
}
if (on)
- spdif_fifo_set_attention_level(base, mode,
+ spdif_fifo_set_attention_level(ifc, mode,
spinfo->spdev[mode].fifo_attn);
spdif_writel(base, val, SPDIF_CTRL_0);
-
+ return 0;
}
diff --git a/arch/arm/mach-tegra/tegra2_i2s.c b/arch/arm/mach-tegra/tegra2_i2s.c
index c10e366369f5..2c323aabf24e 100644
--- a/arch/arm/mach-tegra/tegra2_i2s.c
+++ b/arch/arm/mach-tegra/tegra2_i2s.c
@@ -121,15 +121,15 @@ struct tegra_i2s_property* i2s_get_prop(int ifc)
return &i2s_cont_info[ifc].i2sprop;
}
-void i2s_suspend(int ifc)
+int i2s_suspend(int ifc)
{
struct i2s_controller_info *info = &i2s_cont_info[ifc];
struct i2s_runtime_data* ird = &info->i2s_reg_data;
- check_ifc(ifc);
+ check_ifc(ifc, -EINVAL);
if (info->clk_refs == 0)
- i2s_clock_enable(ifc);
+ i2s_clock_enable(ifc, 0);
ird->i2s_ctrl_0 = i2s_readl(ifc, I2S_I2S_CTRL_0);
ird->i2s_status_0 = i2s_readl(ifc, I2S_I2S_STATUS_0);
@@ -142,16 +142,17 @@ void i2s_suspend(int ifc)
ird->i2s_fifo1_0 = i2s_readl(ifc, I2S_I2S_FIFO1_0);
ird->i2s_fifo2_0 = i2s_readl(ifc, I2S_I2S_FIFO2_0);
- i2s_clock_disable(ifc);
+ i2s_clock_disable(ifc, 0);
+ return 0;
}
-void i2s_resume(int ifc)
+int i2s_resume(int ifc)
{
struct i2s_runtime_data* ird = &i2s_cont_info[ifc].i2s_reg_data;
- check_ifc(ifc);
+ check_ifc(ifc, -EINVAL);
- i2s_clock_enable(ifc);
+ i2s_clock_enable(ifc, 0);
i2s_writel(ifc, ird->i2s_ctrl_0, I2S_I2S_CTRL_0);
i2s_writel(ifc, ird->i2s_status_0, I2S_I2S_STATUS_0);
i2s_writel(ifc, ird->i2s_timing_0, I2S_I2S_TIMING_0);
@@ -162,6 +163,7 @@ void i2s_resume(int ifc)
i2s_writel(ifc, ird->i2s_tdm_tx_rx_ctrl_0, I2S_I2S_TDM_TX_RX_CTRL_0);
i2s_writel(ifc, ird->i2s_fifo1_0, I2S_I2S_FIFO1_0);
i2s_writel(ifc, ird->i2s_fifo2_0, I2S_I2S_FIFO2_0);
+ return 0;
}
int i2s_set_channel_bit_count(int ifc, int sampling, int bitclk)
@@ -203,7 +205,6 @@ int i2s_set_samplerate(int ifc, int samplerate)
i2s_set_channel_bit_count(ifc, samplerate, rate);
}
-
return 0;
}
@@ -216,11 +217,11 @@ int i2s_set_channels(int ifc, int channels)
return 0;
}
-void i2s_set_fifo_mode(int ifc, int fifo, int tx)
+int i2s_set_fifo_mode(int ifc, int fifo, int tx)
{
u32 val;
- check_ifc(ifc);
+ check_ifc(ifc, -EINVAL);
val = i2s_readl(ifc, I2S_I2S_CTRL_0);
if (fifo == 0) {
@@ -231,20 +232,23 @@ void i2s_set_fifo_mode(int ifc, int fifo, int tx)
val &= ~I2S_I2S_CTRL_FIFO2_TX_ENABLE;
val |= tx ? I2S_I2S_CTRL_FIFO2_TX_ENABLE : 0;
}
+
i2s_writel(ifc, val, I2S_I2S_CTRL_0);
+ return 0;
}
-void i2s_set_loopback(int ifc, int on)
+int i2s_set_loopback(int ifc, int on)
{
u32 val;
- check_ifc(ifc);
+ check_ifc(ifc, -EINVAL);
val = i2s_readl(ifc, I2S_I2S_CTRL_0);
val &= ~I2S_I2S_CTRL_FIFO_LPBK_ENABLE;
val |= on ? I2S_I2S_CTRL_FIFO_LPBK_ENABLE : 0;
i2s_writel(ifc, val, I2S_I2S_CTRL_0);
+ return 0;
}
int i2s_fifo_set_attention_level(int ifc, int fifo, unsigned level)
@@ -274,12 +278,12 @@ int i2s_fifo_set_attention_level(int ifc, int fifo, unsigned level)
return 0;
}
-void i2s_fifo_enable(int ifc, int fifo, int on)
+int i2s_fifo_enable(int ifc, int fifo, int on)
{
u32 val;
struct i2s_controller_info *info = &i2s_cont_info[ifc];
- check_ifc(ifc);
+ check_ifc(ifc, -EINVAL);
val = i2s_readl(ifc, I2S_I2S_CTRL_0);
if (!fifo) {
@@ -296,13 +300,14 @@ void i2s_fifo_enable(int ifc, int fifo, int on)
info->i2s_ch_prop[fifo].fifo_attn);
i2s_writel(ifc, val, I2S_I2S_CTRL_0);
+ return 0;
}
-void i2s_fifo_clear(int ifc, int fifo)
+int i2s_fifo_clear(int ifc, int fifo)
{
u32 val;
- check_ifc(ifc);
+ check_ifc(ifc, -EINVAL);
val = i2s_readl(ifc, I2S_I2S_FIFO_SCR_0);
if (!fifo) {
@@ -315,16 +320,18 @@ void i2s_fifo_clear(int ifc, int fifo)
}
i2s_writel(ifc, val, I2S_I2S_FIFO_SCR_0);
+ return 0;
}
-void i2s_set_master(int ifc, int master)
+int i2s_set_master(int ifc, int master)
{
u32 val;
- check_ifc(ifc);
+ check_ifc(ifc, -EINVAL);
val = i2s_readl(ifc, I2S_I2S_CTRL_0);
val &= ~I2S_I2S_CTRL_MASTER_ENABLE;
val |= master ? I2S_I2S_CTRL_MASTER_ENABLE : 0;
i2s_writel(ifc, val, I2S_I2S_CTRL_0);
+ return 0;
}
int i2s_set_bit_format(int ifc, unsigned fmt)
@@ -350,6 +357,7 @@ int i2s_set_bit_format(int ifc, unsigned fmt)
else {
i2s_enable_pcm_mode(ifc, 0);
}
+
return 0;
}
@@ -394,28 +402,30 @@ int i2s_set_fifo_format(int ifc, unsigned fmt)
return 0;
}
-void i2s_set_left_right_control_polarity(int ifc, int high_low)
+int i2s_set_left_right_control_polarity(int ifc, int high_low)
{
u32 val;
- check_ifc(ifc);
+ check_ifc(ifc, -EINVAL);
val = i2s_readl(ifc, I2S_I2S_CTRL_0);
val &= ~I2S_I2S_CTRL_L_R_CTRL;
val |= high_low ? I2S_I2S_CTRL_L_R_CTRL : 0;
i2s_writel(ifc, val, I2S_I2S_CTRL_0);
+ return 0;
}
-void i2s_enable_pcm_mode(int ifc, int on)
+int i2s_enable_pcm_mode(int ifc, int on)
{
u32 val;
- check_ifc(ifc);
+ check_ifc(ifc, -EINVAL);
val = i2s_readl(ifc, I2S_I2S_PCM_CTRL_0);
val &= ~(I2S_I2S_PCM_CTRL_TRM_MODE | I2S_I2S_PCM_CTRL_RCV_MODE);
val |= on ? (I2S_I2S_PCM_CTRL_TRM_MODE | I2S_I2S_PCM_CTRL_RCV_MODE) : 0;
i2s_writel(ifc, val, I2S_I2S_PCM_CTRL_0);
+ return 0;
}
int i2s_set_pcm_edge_mode(int ifc, unsigned edge_mode)
@@ -464,24 +474,25 @@ int i2s_set_pcm_mask_bits(int ifc, unsigned mask_bits, int tx)
return 0;
}
-void i2s_set_pcm_fsync_width(int ifc, int fsync_long)
+int i2s_set_pcm_fsync_width(int ifc, int fsync_long)
{
u32 val;
- check_ifc(ifc);
+ check_ifc(ifc, -EINVAL);
val = i2s_readl(ifc, I2S_I2S_PCM_CTRL_0);
val &= ~I2S_I2S_PCM_CTRL_FSYNC_PCM_CTRL;
val |= fsync_long ? I2S_I2S_PCM_CTRL_FSYNC_PCM_CTRL : 0;
i2s_writel(ifc, val, I2S_I2S_PCM_CTRL_0);
+ return 0;
}
-void i2s_set_fifo_irq_on_err(int ifc, int fifo, int on)
+int i2s_set_fifo_irq_on_err(int ifc, int fifo, int on)
{
u32 val;
- check_ifc(ifc);
+ check_ifc(ifc, -EINVAL);
val = i2s_readl(ifc, I2S_I2S_CTRL_0);
if (!fifo) {
@@ -492,14 +503,16 @@ void i2s_set_fifo_irq_on_err(int ifc, int fifo, int on)
val &= ~I2S_I2S_IE_FIFO2_ERR;
val |= on ? I2S_I2S_IE_FIFO2_ERR : 0;
}
+
i2s_writel(ifc, val, I2S_I2S_CTRL_0);
+ return 0;
}
-void i2s_set_fifo_irq_on_qe(int ifc, int fifo, int on)
+int i2s_set_fifo_irq_on_qe(int ifc, int fifo, int on)
{
u32 val;
- check_ifc(ifc);
+ check_ifc(ifc, -EINVAL);
val = i2s_readl(ifc, I2S_I2S_CTRL_0);
if (!fifo) {
@@ -510,21 +523,24 @@ void i2s_set_fifo_irq_on_qe(int ifc, int fifo, int on)
val &= ~I2S_I2S_QE_FIFO2;
val |= on ? I2S_I2S_QE_FIFO2 : 0;
}
+
i2s_writel(ifc, val, I2S_I2S_CTRL_0);
+ return 0;
}
-void i2s_set_fifo_attention(int ifc, int buffersize, int fifo_mode)
+int i2s_set_fifo_attention(int ifc, int fifo_mode, int buffersize)
{
int fifoattn = I2S_FIFO_ATN_LVL_FOUR_SLOTS;
struct i2s_controller_info *info = &i2s_cont_info[ifc];
info->i2s_ch_prop[fifo_mode].fifo_attn = fifoattn;
+ return 0;
}
-void i2s_enable_fifos(int ifc, int on)
+int i2s_enable_fifos(int ifc, int on)
{
u32 val;
- check_ifc(ifc);
+ check_ifc(ifc, -EINVAL);
val = i2s_readl(ifc, I2S_I2S_CTRL_0);
if (on)
@@ -535,12 +551,14 @@ void i2s_enable_fifos(int ifc, int on)
I2S_I2S_IE_FIFO1_ERR | I2S_I2S_IE_FIFO2_ERR);
i2s_writel(ifc, val, I2S_I2S_CTRL_0);
+ return 0;
}
-void i2s_fifo_write(int ifc, int fifo, u32 data)
+int i2s_fifo_write(int ifc, int fifo, u32 data)
{
- check_ifc(ifc);
+ check_ifc(ifc, -EINVAL);
i2s_writel(ifc, data, fifo ? I2S_I2S_FIFO2_0 : I2S_I2S_FIFO1_0);
+ return 0;
}
u32 i2s_fifo_read(int ifc, int fifo)
@@ -569,11 +587,12 @@ u32 i2s_get_control(int ifc)
return i2s_readl(ifc, I2S_I2S_CTRL_0);
}
-void i2s_ack_status(int ifc)
+int i2s_ack_status(int ifc)
{
- check_ifc(ifc);
- return i2s_writel(ifc, i2s_readl(ifc, I2S_I2S_STATUS_0),
+ check_ifc(ifc, -EINVAL);
+ i2s_writel(ifc, i2s_readl(ifc, I2S_I2S_STATUS_0),
I2S_I2S_STATUS_0);
+ return 0;
}
u32 i2s_get_fifo_scr(int ifc)
@@ -666,11 +685,10 @@ int i2s_init(int ifc, struct tegra_i2s_property* pi2sprop)
if (i2s_open(ifc))
return err;
- i2s_clock_rate(ifc, pi2sprop->clk_rate);
- i2s_clock_set_parent(ifc, 0);
-
- err = i2s_clock_enable(ifc);
+ i2s_clock_set_rate(ifc, 0, pi2sprop->clk_rate);
+ i2s_clock_set_parent(ifc, 0, 0);
+ err = i2s_clock_enable(ifc, 0);
if (err) {
i2s_close(ifc);
return err;
@@ -689,13 +707,13 @@ int i2s_init(int ifc, struct tegra_i2s_property* pi2sprop)
i2s_set_bit_size(ifc, pi2sprop->bit_size);
i2s_set_fifo_format(ifc, pi2sprop->fifo_fmt);
- i2s_clock_disable(ifc);
+ i2s_clock_disable(ifc, 0);
return 0;
}
-int i2s_clock_enable(int ifc)
+int i2s_clock_enable(int ifc, int fifo_mode)
{
int err = 0;
struct i2s_controller_info *info = &i2s_cont_info[ifc];
@@ -716,7 +734,7 @@ int i2s_clock_enable(int ifc)
return err;
}
-int i2s_clock_disable(int ifc)
+int i2s_clock_disable(int ifc, int fifo_mode)
{
struct i2s_controller_info *info = &i2s_cont_info[ifc];
@@ -733,7 +751,14 @@ int i2s_clock_disable(int ifc)
return 0;
}
-int i2s_clock_set_parent(int ifc, int parent)
+int i2s_clock_set_rate(int ifc, int mode, int rate)
+{
+ struct i2s_controller_info *info = &i2s_cont_info[ifc];
+ info->i2sprop.clk_rate = rate;
+ return 0;
+}
+
+int i2s_clock_set_parent(int ifc, int mode, int parent)
{
/* Fix set the parent properly */
struct clk *pll_a_out0_clk = clk_get_sys(NULL, "pll_a_out0");
@@ -744,11 +769,3 @@ int i2s_clock_set_parent(int ifc, int parent)
return 0;
}
-
-int i2s_clock_rate(int ifc, int rate)
-{
- struct i2s_controller_info *info = &i2s_cont_info[ifc];
- info->i2sprop.clk_rate = rate;
- return 0;
-}
-
diff --git a/arch/arm/mach-tegra/tegra3_i2s.c b/arch/arm/mach-tegra/tegra3_i2s.c
index c565f9a4d198..074abde72732 100644
--- a/arch/arm/mach-tegra/tegra3_i2s.c
+++ b/arch/arm/mach-tegra/tegra3_i2s.c
@@ -146,36 +146,40 @@ static void i2s_restore_registers(int ifc)
}
-void i2s_suspend(int ifc)
+int i2s_suspend(int ifc)
{
struct i2s_controller_info *info = &i2s_cont_info[ifc];
if (info->clk_refs == 0)
- i2s_clock_enable(ifc);
+ i2s_clock_enable(ifc, 0);
i2s_save_registers(ifc);
audio_switch_suspend();
- i2s_clock_disable(ifc);
+ i2s_clock_disable(ifc, 0);
+
+ return 0;
}
-void i2s_resume(int ifc)
+int i2s_resume(int ifc)
{
- i2s_clock_enable(ifc);
+ i2s_clock_enable(ifc, 0);
audio_switch_resume();
i2s_restore_registers(ifc);
+
+ return 0;
}
/*
* Set the fifo mode as Tx or Rx or both
*/
-void i2s_fifo_enable(int ifc, int tx, int enable)
+int i2s_fifo_enable(int ifc, int tx, int enable)
{
u32 val;
struct i2s_controller_info *info = &i2s_cont_info[ifc];
int apbif_ifc = 0;
- check_i2s_ifc(ifc);
+ check_i2s_ifc(ifc, -EINVAL);
apbif_ifc = i2s_get_apbif_channel(ifc, tx);
@@ -194,74 +198,81 @@ void i2s_fifo_enable(int ifc, int tx, int enable)
info->i2s_ch_prop[tx].fifo_attn);
i2s_writel(ifc, val, I2S_CTRL_0);
+
+ return 0;
}
/*
* Set the 2nd level clock gating
*/
-void i2s_set_clock_gating(int ifc, int enable)
+int i2s_set_clock_gating(int ifc, int enable)
{
u32 val;
- check_i2s_ifc(ifc);
+ check_i2s_ifc(ifc, -EINVAL);
val = i2s_readl(ifc, I2S_CTRL_0);
set_reg_mode(val, I2S_CTRL_CG_EN, enable);
i2s_writel(ifc, val, I2S_CTRL_0);
+ return 0;
}
/*
* Set i2s soft reset
*/
-void i2s_set_soft_reset(int ifc, int enable)
+int i2s_set_soft_reset(int ifc, int enable)
{
u32 val;
- check_i2s_ifc(ifc);
+ check_i2s_ifc(ifc, -EINVAL);
val = i2s_readl(ifc, I2S_CTRL_0);
set_reg_mode(val, I2S_CTRL_SOFT_RESET, enable);
i2s_writel(ifc, val, I2S_CTRL_0);
+ return 0;
}
/*
* I2s loopback mode
*/
-void i2s_set_loopback(int ifc, int on)
+int i2s_set_loopback(int ifc, int on)
{
u32 val;
- check_i2s_ifc(ifc);
+ check_i2s_ifc(ifc, -EINVAL);
val = i2s_readl(ifc, I2S_CTRL_0);
set_reg_mode(val, I2S_CTRL_LPBK_ENABLE, on);
i2s_writel(ifc, val, I2S_CTRL_0);
+ return 0;
}
/*
* I2s master/Slave mode
*/
-void i2s_set_master(int ifc, int master)
+int i2s_set_master(int ifc, int master)
{
u32 val;
- check_i2s_ifc(ifc);
+ check_i2s_ifc(ifc, -EINVAL);
val = i2s_readl(ifc, I2S_CTRL_0);
set_reg_mode(val, I2S_CTRL_MASTER_ENABLE, master);
i2s_writel(ifc, val, I2S_CTRL_0);
+ return 0;
}
/*
* I2s lrck polarity
*/
-void i2s_set_left_right_control_polarity(int ifc, int left_low)
+int i2s_set_left_right_control_polarity(int ifc, int left_low)
{
u32 val;
- check_i2s_ifc(ifc);
+ check_i2s_ifc(ifc, -EINVAL);
val = i2s_readl(ifc, I2S_CTRL_0);
set_reg_mode(val, I2S_CTRL_LRCK_R_LOW, left_low);
i2s_writel(ifc, val, I2S_CTRL_0);
+ return 0;
}
/*
@@ -587,15 +598,17 @@ int i2s_fifo_set_attention_level(int ifc, int fifo, unsigned level)
return 0;
}
-void i2s_fifo_clear(int ifc, int fifo)
+int i2s_fifo_clear(int ifc, int fifo)
{
int apbif_ifc = i2s_get_apbif_channel(ifc, fifo);
if (apbif_ifc != -ENOENT)
apbif_soft_reset(apbif_ifc, fifo, 1);
+
+ return 0;
}
-void i2s_set_fifo_attention(int ifc, int buffersize, int fifo_mode)
+int i2s_set_fifo_attention(int ifc, int fifo_mode, int buffersize)
{
int fifoattn = I2S_FIFO_ATN_LVL_FOUR_SLOTS;
struct i2s_controller_info *info = &i2s_cont_info[ifc];
@@ -608,30 +621,35 @@ void i2s_set_fifo_attention(int ifc, int buffersize, int fifo_mode)
fifoattn = I2S_FIFO_ATN_LVL_EIGHT_SLOTS;
info->i2s_ch_prop[fifo_mode].fifo_attn = fifoattn;
+ return 0;
}
-void i2s_set_fifo_irq_on_err(int ifc, int fifo, int on)
+int i2s_set_fifo_irq_on_err(int ifc, int fifo, int on)
{
/* FIXME: fifo are part of apbif channel, so pass call to apbif
* or provide generic call to apbif to handle this
*/
+ return 0;
}
-void i2s_set_fifo_irq_on_qe(int ifc, int fifo, int on)
+int i2s_set_fifo_irq_on_qe(int ifc, int fifo, int on)
{
/* FIXME: fifo are part of apbif channel, so pass call to apbif
* or provide generic call to apbif to handle this
*/
+ return 0;
}
-void i2s_fifo_write(int ifc, int fifo, u32 data)
+int i2s_fifo_write(int ifc, int fifo, u32 data)
{
int apbif_ifc = i2s_get_apbif_channel(ifc, fifo);
if (apbif_ifc != -ENOENT)
apbif_fifo_write(apbif_ifc, fifo, data);
+
+ return 0;
}
u32 i2s_fifo_read(int ifc, int fifo)
@@ -665,11 +683,12 @@ u32 i2s_get_control(int ifc)
return i2s_readl(ifc, I2S_CTRL_0);
}
-void i2s_ack_status(int ifc)
+int i2s_ack_status(int ifc)
{
/* FIXME: fifo are part of apbif channel, so pass call to apbif
* or provide generic call to apbif to handle this
*/
+ return 0;
}
u32 i2s_get_fifo_scr(int ifc)
@@ -858,11 +877,10 @@ int i2s_init(int ifc, struct tegra_i2s_property* pi2sprop)
return err;
}
- i2s_clock_rate(ifc, pi2sprop->clk_rate);
- i2s_clock_set_parent(ifc, 0);
-
- err = i2s_clock_enable(ifc);
+ i2s_clock_set_rate(ifc, 0, pi2sprop->clk_rate);
+ i2s_clock_set_parent(ifc, 0, 0);
+ err = i2s_clock_enable(ifc, 0);
if (err) {
audio_switch_close();
i2s_close(ifc);
@@ -881,13 +899,13 @@ int i2s_init(int ifc, struct tegra_i2s_property* pi2sprop)
i2s_set_samplerate(ifc, pi2sprop->sample_rate);
- i2s_clock_disable(ifc);
+ i2s_clock_disable(ifc, 0);
return 0;
}
-int i2s_clock_enable(int ifc)
+int i2s_clock_enable(int ifc, int fifo_mode)
{
int err = 0;
struct i2s_controller_info *info = &i2s_cont_info[ifc];
@@ -916,7 +934,7 @@ int i2s_clock_enable(int ifc)
return err;
}
-int i2s_clock_disable(int ifc)
+int i2s_clock_disable(int ifc, int fifo_mode)
{
struct i2s_controller_info *info = &i2s_cont_info[ifc];
@@ -958,22 +976,22 @@ int i2s_clock_disable(int ifc)
return 0;
}
-int i2s_clock_set_parent(int ifc, int parent)
+int i2s_clock_set_rate(int ifc, int mode, int rate)
{
- /* Fix set the parent properly */
- struct clk *pll_a_out0_clk = clk_get_sys(NULL, "pll_a_out0");
struct i2s_controller_info *info = &i2s_cont_info[ifc];
-
- if (info->i2sprop.i2s_clk)
- clk_set_parent(info->i2sprop.i2s_clk, pll_a_out0_clk);
-
+ info->i2sprop.clk_rate = rate;
return 0;
}
-int i2s_clock_rate(int ifc, int rate)
+int i2s_clock_set_parent(int ifc, int mode, int parent)
{
+ /* Fix set the parent properly */
+ struct clk *pll_a_out0_clk = clk_get_sys(NULL, "pll_a_out0");
struct i2s_controller_info *info = &i2s_cont_info[ifc];
- info->i2sprop.clk_rate = rate;
+
+ if (info->i2sprop.i2s_clk)
+ clk_set_parent(info->i2sprop.i2s_clk,
+ pll_a_out0_clk);
+
return 0;
}
-
diff --git a/sound/soc/tegra/tegra_i2s.c b/sound/soc/tegra/tegra_i2s.c
index 6bde5f719cf0..840a2138533c 100644
--- a/sound/soc/tegra/tegra_i2s.c
+++ b/sound/soc/tegra/tegra_i2s.c
@@ -29,6 +29,7 @@ struct tegra_i2s_info {
unsigned int bit_format;
bool i2s_master;
int ref_count;
+ aud_dev_info i2sdev_info;
struct das_regs_cache das_regs;
};
@@ -38,13 +39,14 @@ void free_i2s_dma_request(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+ struct tegra_i2s_info *info = cpu_dai->private_data;
- int fifo_mode = AUDIO_RX_MODE;
+ info->i2sdev_info.fifo_mode = AUDIO_RX_MODE;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- fifo_mode = AUDIO_TX_MODE;
+ info->i2sdev_info.fifo_mode = AUDIO_TX_MODE;
- i2s_free_dma_requestor(cpu_dai->id, fifo_mode);
+ am_free_dma_requestor(&info->i2sdev_info);
}
void setup_i2s_dma_request(struct snd_pcm_substream *substream,
@@ -56,17 +58,17 @@ void setup_i2s_dma_request(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
struct tegra_i2s_info *info = cpu_dai->private_data;
- int fifo_mode = AUDIO_RX_MODE;
+ info->i2sdev_info.fifo_mode = AUDIO_RX_MODE;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- fifo_mode = AUDIO_TX_MODE;
+ info->i2sdev_info.fifo_mode = AUDIO_TX_MODE;
- req->req_sel = i2s_get_dma_requestor(cpu_dai->id, fifo_mode);
+ req->req_sel = am_get_dma_requestor(&info->i2sdev_info);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
req->to_memory = false;
req->dest_addr =
- i2s_get_fifo_phy_base(cpu_dai->id, fifo_mode);
+ am_get_fifo_phy_base(&info->i2sdev_info);
req->dest_wrap = 4;
req->source_wrap = 0;
if (info->bit_format == AUDIO_FRAME_FORMAT_DSP)
@@ -77,7 +79,7 @@ void setup_i2s_dma_request(struct snd_pcm_substream *substream,
} else {
req->to_memory = true;
req->source_addr =
- i2s_get_fifo_phy_base(cpu_dai->id, fifo_mode);
+ am_get_fifo_phy_base(&info->i2sdev_info);
req->dest_wrap = 0;
req->source_wrap = 4;
if (info->bit_format == AUDIO_FRAME_FORMAT_DSP)
@@ -93,44 +95,40 @@ void setup_i2s_dma_request(struct snd_pcm_substream *substream,
return;
}
-void set_i2s_fifo_attention(struct snd_pcm_substream *substream,
- int buffersize)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
-
- i2s_set_fifo_attention(cpu_dai->id,
- buffersize,
- (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)?
- AUDIO_TX_MODE: AUDIO_RX_MODE);
-}
-
/* playback */
static inline void start_i2s_playback(struct snd_soc_dai *cpu_dai)
{
- i2s_fifo_enable(cpu_dai->id, AUDIO_TX_MODE, 1);
+ struct tegra_i2s_info *info = cpu_dai->private_data;
+
+ info->i2sdev_info.fifo_mode = AUDIO_TX_MODE;
+ am_set_stream_state(&info->i2sdev_info, true);
}
static inline void stop_i2s_playback(struct snd_soc_dai *cpu_dai)
{
- i2s_set_fifo_irq_on_err(cpu_dai->id, AUDIO_TX_MODE, 0);
- i2s_set_fifo_irq_on_qe(cpu_dai->id, AUDIO_TX_MODE, 0);
- i2s_fifo_enable(cpu_dai->id, AUDIO_TX_MODE, 0);
- while (i2s_get_status(cpu_dai->id, AUDIO_TX_MODE));
+ struct tegra_i2s_info *info = cpu_dai->private_data;
+
+ info->i2sdev_info.fifo_mode = AUDIO_TX_MODE;
+ am_set_stream_state(&info->i2sdev_info, false);
+ while (am_get_status(&info->i2sdev_info));
}
/* recording */
static inline void start_i2s_capture(struct snd_soc_dai *cpu_dai)
{
- i2s_fifo_enable(cpu_dai->id, AUDIO_RX_MODE, 1);
+ struct tegra_i2s_info *info = cpu_dai->private_data;
+
+ info->i2sdev_info.fifo_mode = AUDIO_RX_MODE;
+ am_set_stream_state(&info->i2sdev_info, true);
}
static inline void stop_i2s_capture(struct snd_soc_dai *cpu_dai)
{
- i2s_set_fifo_irq_on_err(cpu_dai->id, AUDIO_RX_MODE, 0);
- i2s_set_fifo_irq_on_qe(cpu_dai->id, AUDIO_RX_MODE, 0);
- i2s_fifo_enable(cpu_dai->id, AUDIO_RX_MODE, 0);
- while (i2s_get_status(cpu_dai->id, AUDIO_RX_MODE));
+ struct tegra_i2s_info *info = cpu_dai->private_data;
+
+ info->i2sdev_info.fifo_mode = AUDIO_RX_MODE;
+ am_set_stream_state(&info->i2sdev_info, false);
+ while (am_get_status(&info->i2sdev_info));
}
@@ -138,8 +136,14 @@ static int tegra_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
- unsigned int i2s_id = dai->id;
int val;
+ am_stream_format_info fmt;
+ struct tegra_i2s_info *info = dai->private_data;
+
+ info->i2sdev_info.fifo_mode = AUDIO_RX_MODE;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ info->i2sdev_info.fifo_mode = AUDIO_TX_MODE;
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
@@ -154,12 +158,8 @@ static int tegra_i2s_hw_params(struct snd_pcm_substream *substream,
default:
return -EINVAL;
}
- i2s_set_bit_size(i2s_id, val);
- if (tegra_i2sloopback_func == TEGRA_INT_I2SLOOPBACK_ON)
- i2s_set_loopback(i2s_id,1);
- else
- i2s_set_loopback(i2s_id,0);
+ fmt.bitsize = val;
switch (params_rate(params)) {
case 8000:
@@ -174,7 +174,7 @@ static int tegra_i2s_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
- i2s_set_samplerate(i2s_id, val);
+ fmt.samplerate = val;
switch (params_channels(params)) {
case 1: val = AUDIO_CHANNEL_1; break;
@@ -189,7 +189,10 @@ static int tegra_i2s_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
- i2s_set_channels(i2s_id, val);
+ fmt.channels = val;
+ fmt.buffersize = params_period_bytes(params);
+
+ am_set_stream_format(&info->i2sdev_info, &fmt);
return 0;
}
@@ -198,9 +201,9 @@ static int tegra_i2s_hw_params(struct snd_pcm_substream *substream,
static int tegra_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
unsigned int fmt)
{
- struct tegra_i2s_info *info = cpu_dai->private_data;
- unsigned int i2s_id = cpu_dai->id;
int val1, val2;
+ am_dev_format_info devfmt;
+ struct tegra_i2s_info *info = cpu_dai->private_data;
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBS_CFS:
@@ -216,7 +219,8 @@ static int tegra_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
default:
return -EINVAL;
}
- i2s_set_master(i2s_id, info->i2s_master);
+
+ devfmt.mastermode = info->i2s_master;
val2 = AUDIO_LRCK_LEFT_LOW;
@@ -242,9 +246,12 @@ static int tegra_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
return -EINVAL;
}
- i2s_set_bit_format(i2s_id, val1);
- i2s_set_left_right_control_polarity(i2s_id, val2);
+ devfmt.audiomode = val1;
+ devfmt.polarity = val2;
+ devfmt.loopmode =
+ (tegra_i2sloopback_func == TEGRA_INT_I2SLOOPBACK_ON)? 1 : 0;
+ am_set_device_format(&info->i2sdev_info, &devfmt);
return 0;
}
@@ -287,18 +294,21 @@ static int i2s_configure(struct tegra_i2s_info *info )
{
struct platform_device *pdev = info->pdev;
struct tegra_audio_platform_data *pdata = pdev->dev.platform_data;
- struct tegra_i2s_property i2sprop;
- memset(&i2sprop, 0, sizeof(i2sprop));
+ am_stream_format_info strm_fmt;
+ am_dev_format_info dev_fmt;
+
+ memset(&dev_fmt, 0, sizeof(dev_fmt));
+ dev_fmt.mastermode = pdata->i2s_master;
+ dev_fmt.audiomode = pdata->mode;
+ dev_fmt.clkrate = pdata->dev_clk_rate;
+ dev_fmt.fifofmt = pdata->fifo_fmt;
- i2sprop.master_mode = pdata->i2s_master;
- i2sprop.audio_mode = pdata->mode;
- i2sprop.bit_size = pdata->bit_size;
- i2sprop.clk_rate = pdata->dev_clk_rate;
- i2sprop.sample_rate = pdata->i2s_master_clk;
- i2sprop.fifo_fmt = pdata->fifo_fmt;
+ memset(&strm_fmt, 0, sizeof(strm_fmt));
+ strm_fmt.bitsize = pdata->bit_size;
+ strm_fmt.samplerate = pdata->i2s_master_clk;
- i2s_init(pdev->id, &i2sprop);
+ am_device_init(&info->i2sdev_info, (void*)&dev_fmt, (void*)&strm_fmt);
return 0;
}
@@ -308,7 +318,7 @@ int tegra_i2s_suspend(struct snd_soc_dai *cpu_dai)
{
struct tegra_i2s_info *info = cpu_dai->private_data;
- i2s_suspend(cpu_dai->id);
+ am_suspend(&info->i2sdev_info);
tegra_das_get_all_regs(&info->das_regs);
@@ -321,12 +331,12 @@ int tegra_i2s_resume(struct snd_soc_dai *cpu_dai)
tegra_das_set_all_regs(&info->das_regs);
- i2s_resume(cpu_dai->id);
+ am_resume(&info->i2sdev_info);
tegra_jack_resume();
/* disabled clock as it is being enabled back on startup */
- i2s_clock_disable(cpu_dai->id);
+ am_clock_disable(&info->i2sdev_info);
return 0;
}
@@ -341,7 +351,7 @@ static int tegra_i2s_startup(struct snd_pcm_substream *substream,
struct tegra_i2s_info *info = dai->private_data;
if (!info->ref_count)
- i2s_clock_enable(dai->id);
+ am_clock_enable(&info->i2sdev_info);
info->ref_count++;
return 0;
@@ -356,7 +366,7 @@ static void tegra_i2s_shutdown(struct snd_pcm_substream *substream,
info->ref_count--;
if (!info->ref_count)
- i2s_clock_disable(dai->id);
+ am_clock_disable(&info->i2sdev_info);
return;
}
@@ -426,6 +436,9 @@ static int tegra_i2s_driver_probe(struct platform_device *pdev)
info->pdata->driver_data = info;
BUG_ON(!info->pdata);
+ info->i2sdev_info.dev_type = AUDIO_I2S_DEVICE;
+ info->i2sdev_info.dev_id = pdev->id;
+
err = i2s_configure(info);
if (err) {
goto fail_clock;
@@ -447,7 +460,7 @@ static int tegra_i2s_driver_probe(struct platform_device *pdev)
return 0;
fail_clock:
- i2s_close(pdev->id);
+ am_device_deinit(&info->i2sdev_info);
kfree(info);
return err;
}
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index d5601b2b6f4f..b531841cbc7c 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -97,16 +97,7 @@ static void dma_complete_callback (struct tegra_dma_req *req)
static int tegra_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
- int buffersize = params_period_bytes(params);
-
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
-
- if (strcmp(cpu_dai->name, "tegra-spdif") == 0)
- set_spdif_fifo_attention(substream, buffersize);
- else
- set_i2s_fifo_attention(substream, buffersize);
return 0;
}
diff --git a/sound/soc/tegra/tegra_soc.h b/sound/soc/tegra/tegra_soc.h
index 4b839e33bf0e..361cbc79c3ee 100644
--- a/sound/soc/tegra/tegra_soc.h
+++ b/sound/soc/tegra/tegra_soc.h
@@ -39,9 +39,7 @@
#include <linux/tegra_audio.h>
#include <linux/regulator/consumer.h>
#include <mach/iomap.h>
-#include <mach/spdif.h>
-#include <mach/tegra_i2s.h>
-#include <mach/spdif.h>
+#include <mach/audio_manager.h>
#include <mach/irqs.h>
#include <mach/pinmux.h>
#include <mach/audio.h>
@@ -122,20 +120,16 @@ int tegra_jack_init(struct snd_soc_codec *codec);
void tegra_jack_exit(void);
void tegra_jack_resume(void);
void tegra_switch_set_state(int state);
-void speaker_settings(struct snd_soc_codec *codec, int value);
void setup_i2s_dma_request(struct snd_pcm_substream *substream,
struct tegra_dma_req *req,
void (*dma_callback)(struct tegra_dma_req *req),
void *dma_data);
void free_i2s_dma_request(struct snd_pcm_substream *substream);
-void set_i2s_fifo_attention(struct snd_pcm_substream *substream,
- int buffersize);
+
void setup_spdif_dma_request(struct snd_pcm_substream *substream,
struct tegra_dma_req *req,
void (*dma_callback)(struct tegra_dma_req *req),
void *dma_data);
void free_spdif_dma_request(struct snd_pcm_substream *substream);
-void set_spdif_fifo_attention(struct snd_pcm_substream *substream,
- int buffersize);
#endif
diff --git a/sound/soc/tegra/tegra_soc_wm8903.c b/sound/soc/tegra/tegra_soc_wm8903.c
index dcc48cdbc64f..c73ab053b8b1 100644
--- a/sound/soc/tegra/tegra_soc_wm8903.c
+++ b/sound/soc/tegra/tegra_soc_wm8903.c
@@ -328,62 +328,6 @@ static struct snd_soc_ops tegra_spdif_ops = {
.hw_params = tegra_spdif_hw_params,
};
-void speaker_settings(struct snd_soc_codec *codec, int value)
-{
- int CtrlReg = 0;
-
- /* Set Spkr */
- CtrlReg = snd_soc_read(codec, WM8903_ANALOGUE_SPK_MIX_LEFT_0);
- CtrlReg &= ~WM8903_DACL_TO_MIXSPKL_MASK;
- CtrlReg |= (value << WM8903_DACL_TO_MIXSPKL_SHIFT);
-
- snd_soc_write(codec, WM8903_ANALOGUE_SPK_MIX_LEFT_0, CtrlReg);
-
-
- CtrlReg = snd_soc_read(codec, WM8903_ANALOGUE_SPK_MIX_RIGHT_0);
- CtrlReg &= ~WM8903_DACR_TO_MIXSPKR_MASK;
- CtrlReg |= (value << WM8903_DACR_TO_MIXSPKR_SHIFT);
-
- snd_soc_write(codec, WM8903_ANALOGUE_SPK_MIX_RIGHT_0, CtrlReg);
-
- CtrlReg = snd_soc_read(codec, WM8903_POWER_MANAGEMENT_4);
- CtrlReg = SET_REG_VAL(CtrlReg,
- WM8903_MIXSPKL_ENA_WIDTH,
- WM8903_MIXSPKL_ENA_SHIFT, value);
- CtrlReg = SET_REG_VAL(CtrlReg,
- WM8903_MIXSPKR_ENA_WIDTH,
- WM8903_MIXSPKR_ENA_SHIFT, value);
-
- snd_soc_write(codec, WM8903_POWER_MANAGEMENT_4, CtrlReg);
-
- CtrlReg = snd_soc_read(codec, WM8903_ANALOGUE_OUT3_LEFT);
- CtrlReg = SET_REG_VAL(CtrlReg, 1, 8, ~value);
- snd_soc_write(codec, WM8903_ANALOGUE_OUT3_LEFT, CtrlReg);
-
- CtrlReg = snd_soc_read(codec, WM8903_ANALOGUE_OUT3_RIGHT);
- CtrlReg = SET_REG_VAL(CtrlReg, 1, 8, ~value);
- snd_soc_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, CtrlReg);
-
- CtrlReg = snd_soc_read(codec, WM8903_POWER_MANAGEMENT_5);
- CtrlReg &= ~WM8903_SPKL_ENA_MASK;
- CtrlReg |= (value << WM8903_SPKL_ENA_SHIFT);
- CtrlReg &= ~WM8903_SPKR_ENA_MASK;
- CtrlReg |= (value << WM8903_SPKR_ENA_SHIFT);
-
-
- snd_soc_write(codec, WM8903_POWER_MANAGEMENT_5, CtrlReg);
-
-
- CtrlReg = snd_soc_read(codec, WM8903_GPIO_CONTROL_3);
-
- if (value)
- CtrlReg = 0x33;
- else
- CtrlReg = 0;
-
- snd_soc_write(codec, WM8903_GPIO_CONTROL_3, CtrlReg);
-}
-
void tegra_ext_control(struct snd_soc_codec *codec, int new_con)
{
struct tegra_audio_data* audio_data = codec->socdev->codec_data;
@@ -426,11 +370,6 @@ void tegra_ext_control(struct snd_soc_codec *codec, int new_con)
audio_data->codec_con = new_con;
- /* using this function until pin/widget works*/
- if (new_con & TEGRA_SPK)
- speaker_settings(codec, 1);
- else
- speaker_settings(codec, 0);
/* signal a DAPM event */
snd_soc_dapm_sync(codec);
diff --git a/sound/soc/tegra/tegra_spdif.c b/sound/soc/tegra/tegra_spdif.c
index dff38ffe0b72..82cd5d88b15d 100644
--- a/sound/soc/tegra/tegra_spdif.c
+++ b/sound/soc/tegra/tegra_spdif.c
@@ -19,6 +19,7 @@
*/
#include "tegra_soc.h"
+#include <mach/spdif.h>
/* spdif controller */
struct tegra_spdif_info {
@@ -26,16 +27,21 @@ struct tegra_spdif_info {
struct tegra_audio_platform_data *pdata;
unsigned long spdif_phys;
unsigned long spdif_base;
+ aud_dev_info spdev_info;
};
void free_spdif_dma_request(struct snd_pcm_substream *substream)
{
- int fifo_mode = AUDIO_RX_MODE;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+ struct tegra_spdif_info *info = cpu_dai->private_data;
+
+ info->spdev_info.fifo_mode = AUDIO_RX_MODE;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- fifo_mode = AUDIO_TX_MODE;
+ info->spdev_info.fifo_mode = AUDIO_TX_MODE;
- spdif_free_dma_requestor(fifo_mode);
+ am_free_dma_requestor(&info->spdev_info);
}
void setup_spdif_dma_request(struct snd_pcm_substream *substream,
@@ -47,23 +53,21 @@ void setup_spdif_dma_request(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
struct tegra_spdif_info *info = cpu_dai->private_data;
- int fifo_mode = AUDIO_RX_MODE;
+ info->spdev_info.fifo_mode = AUDIO_RX_MODE;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- fifo_mode = AUDIO_TX_MODE;
+ info->spdev_info.fifo_mode = AUDIO_TX_MODE;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
req->to_memory = false;
- req->dest_addr = spdif_get_fifo_phy_base(info->spdif_phys,
- fifo_mode);
+ req->dest_addr = am_get_fifo_phy_base(&info->spdev_info);
req->dest_wrap = 4;
req->source_wrap = 0;
req->dest_bus_width = 32;
req->source_bus_width = 32;
} else {
req->to_memory = true;
- req->dest_addr = spdif_get_fifo_phy_base(info->spdif_phys,
- fifo_mode);
+ req->dest_addr = am_get_fifo_phy_base(&info->spdev_info);
req->dest_wrap = 0;
req->source_wrap = 4;
req->dest_bus_width = 32;
@@ -71,35 +75,29 @@ void setup_spdif_dma_request(struct snd_pcm_substream *substream,
}
req->complete = dma_callback;
req->dev = dma_data;
- req->req_sel = spdif_get_dma_requestor(fifo_mode);
+ req->req_sel = am_get_dma_requestor(&info->spdev_info);
return;
}
-void set_spdif_fifo_attention(struct snd_pcm_substream *substream,
- int buffersize)
-{
- spdif_set_fifo_attention(
- buffersize,
- (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)?
- AUDIO_TX_MODE: AUDIO_RX_MODE);
-}
-
/* playback */
static inline void start_spdif_playback(struct snd_soc_dai *dai)
{
struct tegra_spdif_info *info = dai->private_data;
- spdif_fifo_enable(info->spdif_base, AUDIO_TX_MODE, true);
+ info->spdev_info.fifo_mode = AUDIO_TX_MODE;
+
+ am_set_stream_state(&info->spdev_info, true);
}
static inline void stop_spdif_playback(struct snd_soc_dai *dai)
{
struct tegra_spdif_info *info = dai->private_data;
- spdif_fifo_enable(info->spdif_base, AUDIO_TX_MODE, false);
- while (spdif_get_status(info->spdif_base, AUDIO_TX_MODE) &
- SPDIF_STATUS_0_TX_BSY);
+ info->spdev_info.fifo_mode = AUDIO_TX_MODE;
+
+ am_set_stream_state(&info->spdev_info, false);
+ while (am_get_status(&info->spdev_info) & SPDIF_STATUS_0_TX_BSY);
}
/* capture */
@@ -107,28 +105,31 @@ static inline void start_spdif_capture(struct snd_soc_dai *dai)
{
struct tegra_spdif_info *info = dai->private_data;
- spdif_fifo_enable(info->spdif_base, AUDIO_RX_MODE, true);
+ info->spdev_info.fifo_mode = AUDIO_RX_MODE;
+ am_set_stream_state(&info->spdev_info, true);
}
static inline void stop_spdif_capture(struct snd_soc_dai *dai)
{
struct tegra_spdif_info *info = dai->private_data;
- spdif_fifo_enable(info->spdif_base, AUDIO_RX_MODE, false);
- while (spdif_get_status(info->spdif_base, AUDIO_RX_MODE) &
- SPDIF_STATUS_0_RX_BSY);
+ info->spdev_info.fifo_mode = AUDIO_RX_MODE;
+ am_set_stream_state(&info->spdev_info, false);
+ while (am_get_status(&info->spdev_info) & SPDIF_STATUS_0_RX_BSY);
}
static int tegra_spdif_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
- struct tegra_spdif_info *info = dai->private_data;
int val;
- int fifo_mode = AUDIO_RX_MODE;
+ am_stream_format_info fmt;
+ struct tegra_spdif_info *info = dai->private_data;
+
+ info->spdev_info.fifo_mode = AUDIO_RX_MODE;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- fifo_mode = AUDIO_TX_MODE;
+ info->spdev_info.fifo_mode = AUDIO_TX_MODE;
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
@@ -144,8 +145,7 @@ static int tegra_spdif_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
- spdif_set_bit_mode(info->spdif_base, val);
- spdif_set_fifo_packed(info->spdif_base, 1);
+ fmt.bitsize = val;
switch (params_rate(params)) {
case 8000:
@@ -160,7 +160,10 @@ static int tegra_spdif_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
- spdif_set_sample_rate(fifo_mode, val);
+ fmt.channels = val;
+ fmt.buffersize = params_period_bytes(params);
+
+ am_set_stream_format(&info->spdev_info, &fmt);
return 0;
}
@@ -210,16 +213,18 @@ static int tegra_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
#ifdef CONFIG_PM
int tegra_spdif_suspend(struct snd_soc_dai *cpu_dai)
{
- spdif_suspend();
+ struct tegra_spdif_info *info = cpu_dai->private_data;
+ am_suspend(&info->spdev_info);
return 0;
}
int tegra_spdif_resume(struct snd_soc_dai *cpu_dai)
{
- spdif_resume();
+ struct tegra_spdif_info *info = cpu_dai->private_data;
+ am_resume(&info->spdev_info);
/* disabled clock as startup code enable the clock */
- spdif_clock_disable(AUDIO_TX_MODE);
+ am_clock_disable(&info->spdev_info);
return 0;
}
@@ -231,12 +236,14 @@ int tegra_spdif_resume(struct snd_soc_dai *cpu_dai)
static int tegra_spdif_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- int fifo_mode = AUDIO_RX_MODE;
+ struct tegra_spdif_info *info = dai->private_data;
+
+ info->spdev_info.fifo_mode = AUDIO_RX_MODE;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- fifo_mode = AUDIO_TX_MODE;
+ info->spdev_info.fifo_mode = AUDIO_TX_MODE;
- spdif_clock_enable(fifo_mode);
+ am_clock_enable(&info->spdev_info);
return 0;
}
@@ -244,12 +251,14 @@ static int tegra_spdif_startup(struct snd_pcm_substream *substream,
static void tegra_spdif_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- int fifo_mode = AUDIO_RX_MODE;
+ struct tegra_spdif_info *info = dai->private_data;
+
+ info->spdev_info.fifo_mode = AUDIO_RX_MODE;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- fifo_mode = AUDIO_TX_MODE;
+ info->spdev_info.fifo_mode = AUDIO_TX_MODE;
- spdif_clock_disable(fifo_mode);
+ am_clock_disable(&info->spdev_info);
return;
}
@@ -296,7 +305,7 @@ static int tegra_spdif_driver_probe(struct platform_device *pdev)
int err = 0;
struct resource *res, *mem;
struct tegra_spdif_info *info;
- struct tegra_spdif_property sp_prop;
+ am_dev_format_info dev_fmt;
pr_info("%s\n", __func__);
@@ -332,10 +341,19 @@ static int tegra_spdif_driver_probe(struct platform_device *pdev)
goto fail_release_mem;
}
- sp_prop.clk_rate = info->pdata->dev_clk_rate;
+ memset(&dev_fmt, 0, sizeof(dev_fmt));
+ dev_fmt.clkrate = info->pdata->dev_clk_rate;
+ info->spdev_info.base = info->spdif_base;
+ info->spdev_info.phy_base = info->spdif_phys;
+
+ info->spdev_info.dev_type = AUDIO_SPDIF_DEVICE;
+ info->spdev_info.dev_id = pdev->id;
+ info->spdev_info.fifo_mode = AUDIO_TX_MODE;
+
+ am_device_init(&info->spdev_info, (void *)&dev_fmt, 0);
- spdif_init(info->spdif_base, AUDIO_TX_MODE, &sp_prop);
- spdif_init(info->spdif_base, AUDIO_RX_MODE, &sp_prop);
+ info->spdev_info.fifo_mode = AUDIO_RX_MODE;
+ am_device_init(&info->spdev_info, (void *)&dev_fmt, 0);
tegra_spdif_dai.dev = &pdev->dev;
tegra_spdif_dai.private_data = info;
diff --git a/sound/soc/tegra/tegra_wired_jack.c b/sound/soc/tegra/tegra_wired_jack.c
index 1ee029856cb0..e51cb35c3158 100644
--- a/sound/soc/tegra/tegra_wired_jack.c
+++ b/sound/soc/tegra/tegra_wired_jack.c
@@ -144,7 +144,7 @@ static int tegra_wired_jack_probe(struct platform_device *pdev)
{
int ret;
int hp_det_n = 0, cdc_irq = 0;
- int en_mic_int = 0, en_mic_ext = 0;
+ int en_mic_int = -1, en_mic_ext = -1;
int en_spkr = 0;
struct wired_jack_conf *pdata;
@@ -152,9 +152,9 @@ static int tegra_wired_jack_probe(struct platform_device *pdev)
if (!pdata || !pdata->hp_det_n
#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
- || !pdata->cdc_irq || !pdata->en_spkr
+ || !pdata->en_mic_int || !pdata->en_mic_ext
#endif
- || !pdata->en_mic_int || !pdata->en_mic_ext) {
+ || !pdata->cdc_irq || !pdata->en_spkr) {
pr_err("Please set up gpio pins for jack.\n");
return -EBUSY;
}
@@ -176,6 +176,7 @@ static int tegra_wired_jack_probe(struct platform_device *pdev)
return ret;
}
+#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
/* Mic switch controlling pins */
en_mic_int = pdata->en_mic_int;
en_mic_ext = pdata->en_mic_ext;
@@ -204,6 +205,8 @@ static int tegra_wired_jack_probe(struct platform_device *pdev)
gpio_export(en_mic_ext, false);
}
+#endif
+
en_spkr = pdata->en_spkr;
ret = gpio_request(en_spkr, "en_spkr");
if (ret) {
@@ -212,6 +215,7 @@ static int tegra_wired_jack_probe(struct platform_device *pdev)
en_spkr = -1;
}
+
if (en_spkr != -1) {
gpio_direction_output(en_spkr, 0);
gpio_export(en_spkr, false);