summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVinod G <vinodg@nvidia.com>2011-04-28 10:47:57 -0700
committerVarun Colbert <vcolbert@nvidia.com>2011-04-29 18:27:02 -0700
commit92adadc0c2ade93c3cbd4765cfd12455cf441cf5 (patch)
treef010b2edeab2d6f719361a44dfcae28a11b9e288
parent8f97f5c0af17fc52ca7c502d8ce85bf83a85e107 (diff)
arm: tegra: fix audio issue
bug 820773 Fix the audio issue resulted from code merge. Change-Id: I37999fabec7de077eac337db33eb2b01939349fc Reviewed-on: http://git-master/r/29684 Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/audio_jack.c2
-rw-r--r--arch/arm/mach-tegra/audio_manager.c6
-rw-r--r--arch/arm/mach-tegra/board-aruba.c2
-rw-r--r--arch/arm/mach-tegra/board-cardhu.c3
-rw-r--r--arch/arm/mach-tegra/board-enterprise.c2
-rw-r--r--arch/arm/mach-tegra/board-ventana-jack.c2
-rw-r--r--arch/arm/mach-tegra/include/mach/audio.h3
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra_das.h4
-rw-r--r--arch/arm/mach-tegra/tegra2_i2s.c2
-rw-r--r--arch/arm/mach-tegra/tegra_das.c11
-rw-r--r--sound/soc/tegra/tegra_i2s.c18
-rw-r--r--sound/soc/tegra/tegra_pcm.c142
-rw-r--r--sound/soc/tegra/tegra_soc.h36
-rw-r--r--sound/soc/tegra/tegra_soc_controls.c4
-rw-r--r--sound/soc/tegra/tegra_soc_wm8753.c49
-rw-r--r--sound/soc/tegra/tegra_soc_wm8903.c57
-rw-r--r--sound/soc/tegra/tegra_spdif.c15
-rw-r--r--sound/soc/tegra/tegra_wired_jack.c4
18 files changed, 157 insertions, 205 deletions
diff --git a/arch/arm/mach-tegra/audio_jack.c b/arch/arm/mach-tegra/audio_jack.c
index e80d10e546c6..74acf642c8a3 100644
--- a/arch/arm/mach-tegra/audio_jack.c
+++ b/arch/arm/mach-tegra/audio_jack.c
@@ -26,7 +26,7 @@
#include "gpio-names.h"
-extern struct tegra_wired_jack_conf audio_wr_jack_conf;
+extern struct wired_jack_conf audio_wr_jack_conf;
static struct platform_device audio_hs_jack_device = {
.name = "tegra_wired_jack",
diff --git a/arch/arm/mach-tegra/audio_manager.c b/arch/arm/mach-tegra/audio_manager.c
index 0bf82a34219e..21ba3f16544e 100644
--- a/arch/arm/mach-tegra/audio_manager.c
+++ b/arch/arm/mach-tegra/audio_manager.c
@@ -193,4 +193,10 @@ int tegra_das_set_mclk_rate(int rate)
}
EXPORT_SYMBOL_GPL(tegra_das_set_mclk_rate);
+int tegra_das_get_mclk_rate(void)
+{
+ return clk_get_rate(aud_manager->mclk);
+}
+EXPORT_SYMBOL_GPL(tegra_das_get_mclk_rate);
+
MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-tegra/board-aruba.c b/arch/arm/mach-tegra/board-aruba.c
index ce730f8aa5da..881579139853 100644
--- a/arch/arm/mach-tegra/board-aruba.c
+++ b/arch/arm/mach-tegra/board-aruba.c
@@ -269,7 +269,7 @@ static struct tegra_audio_platform_data tegra_audio_pdata[] = {
}
};
-struct tegra_wired_jack_conf audio_wr_jack_conf = {
+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,
diff --git a/arch/arm/mach-tegra/board-cardhu.c b/arch/arm/mach-tegra/board-cardhu.c
index 5264f6b82fe0..dc0580f5a474 100644
--- a/arch/arm/mach-tegra/board-cardhu.c
+++ b/arch/arm/mach-tegra/board-cardhu.c
@@ -325,10 +325,11 @@ static struct tegra_audio_platform_data tegra_spdif_pdata = {
.fifo_fmt = AUDIO_FIFO_PACK_16,
};
-struct tegra_wired_jack_conf audio_wr_jack_conf = {
+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"
};
static void cardhu_i2c_init(void)
diff --git a/arch/arm/mach-tegra/board-enterprise.c b/arch/arm/mach-tegra/board-enterprise.c
index e2f1bf11bcb2..c681ef2dfe99 100644
--- a/arch/arm/mach-tegra/board-enterprise.c
+++ b/arch/arm/mach-tegra/board-enterprise.c
@@ -267,7 +267,7 @@ static struct tegra_audio_platform_data tegra_spdif_pdata = {
.fifo_fmt = 0,
};
-struct tegra_wired_jack_conf audio_wr_jack_conf = {
+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,
diff --git a/arch/arm/mach-tegra/board-ventana-jack.c b/arch/arm/mach-tegra/board-ventana-jack.c
index c01d77e4575b..10fb56f8c7a7 100644
--- a/arch/arm/mach-tegra/board-ventana-jack.c
+++ b/arch/arm/mach-tegra/board-ventana-jack.c
@@ -28,7 +28,7 @@
#include "gpio-names.h"
#include "board-ventana.h"
-static struct tegra_wired_jack_conf ventana_wr_jack_conf = {
+static struct wired_jack_conf ventana_wr_jack_conf = {
.hp_det_n = TEGRA_GPIO_PW2,
.en_mic_ext = TEGRA_GPIO_PX1,
.en_mic_int = TEGRA_GPIO_PX0,
diff --git a/arch/arm/mach-tegra/include/mach/audio.h b/arch/arm/mach-tegra/include/mach/audio.h
index 8fe7f2819e80..2210d8ab0ea2 100644
--- a/arch/arm/mach-tegra/include/mach/audio.h
+++ b/arch/arm/mach-tegra/include/mach/audio.h
@@ -178,7 +178,7 @@ struct tegra_audio_platform_data {
void *driver_data;
};
-struct tegra_wired_jack_conf {
+struct wired_jack_conf {
int hp_det_n; /* headphone jack detection gpio pin */
int en_mic_ext; /* external mic enable gpio pin */
int en_mic_int; /* internal mic enable gpio pin */
@@ -186,6 +186,7 @@ struct tegra_wired_jack_conf {
int en_spkr; /* gpio pin to drive amplifier */
const char *spkr_amp_reg; /* regulator name for speaker amp */
struct regulator *amp_reg; /* regulator for speaker amp */
+ int amp_reg_enabled;
};
int audio_wired_jack_init(void);
diff --git a/arch/arm/mach-tegra/include/mach/tegra_das.h b/arch/arm/mach-tegra/include/mach/tegra_das.h
index a94adc1a0150..75abcd4c3c3b 100644
--- a/arch/arm/mach-tegra/include/mach/tegra_das.h
+++ b/arch/arm/mach-tegra/include/mach/tegra_das.h
@@ -263,4 +263,8 @@ int tegra_das_disable_mclk(void);
*/
int tegra_das_set_mclk_rate(int rate);
+/*
+ * Function to get the mclk rate
+ */
+int tegra_das_get_mclk_rate(void);
#endif
diff --git a/arch/arm/mach-tegra/tegra2_i2s.c b/arch/arm/mach-tegra/tegra2_i2s.c
index 10b00fa7cd11..bc16ebf479fe 100644
--- a/arch/arm/mach-tegra/tegra2_i2s.c
+++ b/arch/arm/mach-tegra/tegra2_i2s.c
@@ -72,8 +72,8 @@ struct i2s_clk_info {
};
static struct i2s_clk_info i2sclk_info[NR_I2S_IFC] = {
- {"i2s0"},
{"i2s1"},
+ {"i2s2"},
};
static struct i2s_controller_info i2s_cont_info[NR_I2S_IFC];
diff --git a/arch/arm/mach-tegra/tegra_das.c b/arch/arm/mach-tegra/tegra_das.c
index e87dc74e2ba8..a4676d3750b1 100644
--- a/arch/arm/mach-tegra/tegra_das.c
+++ b/arch/arm/mach-tegra/tegra_das.c
@@ -506,7 +506,7 @@ int tegra_das_open(void)
{
int err = 0;
- das_drv_data->mclk = tegra_get_clock_by_name("cdev1");
+ das_drv_data->mclk = tegra_get_clock_by_name("clk_dev1");
if (!das_drv_data->mclk)
err = -ENODEV;
@@ -575,6 +575,15 @@ int tegra_das_set_mclk_rate(int rate)
}
EXPORT_SYMBOL_GPL(tegra_das_set_mclk_rate);
+int tegra_das_get_mclk_rate(void)
+{
+ if (!das_drv_data->mclk)
+ return -ENODEV;
+
+ return clk_get_rate(das_drv_data->mclk);
+}
+EXPORT_SYMBOL_GPL(tegra_das_get_mclk_rate);
+
static int tegra_das_probe(struct platform_device *pdev)
{
int rc = 0;
diff --git a/sound/soc/tegra/tegra_i2s.c b/sound/soc/tegra/tegra_i2s.c
index 6580ba3e3049..3285d3c7617c 100644
--- a/sound/soc/tegra/tegra_i2s.c
+++ b/sound/soc/tegra/tegra_i2s.c
@@ -136,23 +136,18 @@ static int tegra_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
- struct tegra_i2s_info *info = dai->private_data;
unsigned int i2s_id = dai->id;
int val;
- unsigned int sample_size;
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
val = AUDIO_BIT_SIZE_16;
- sample_size = 16;
break;
case SNDRV_PCM_FORMAT_S24_LE:
val = AUDIO_BIT_SIZE_24;
- sample_size = 24;
break;
case SNDRV_PCM_FORMAT_S32_LE:
val = AUDIO_BIT_SIZE_32;
- sample_size = 32;
break;
default:
return -EINVAL;
@@ -187,10 +182,10 @@ static int tegra_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBS_CFS:
- val1 = 1;
+ info->i2s_master = 1;
break;
case SND_SOC_DAIFMT_CBM_CFM:
- val1 = 0;
+ info->i2s_master = 0;
break;
case SND_SOC_DAIFMT_CBS_CFM:
case SND_SOC_DAIFMT_CBM_CFS:
@@ -199,9 +194,7 @@ static int tegra_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
default:
return -EINVAL;
}
- i2s_set_master(i2s_id, val1);
- info->i2s_master = val1;
-
+ i2s_set_master(i2s_id, info->i2s_master);
val2 = AUDIO_LRCK_LEFT_LOW;
@@ -292,12 +285,9 @@ int tegra_i2s_suspend(struct snd_soc_dai *cpu_dai)
{
struct tegra_i2s_info *info = cpu_dai->private_data;
- i2s_clock_enable(cpu_dai->id);
-
i2s_suspend(cpu_dai->id);
tegra_das_get_all_regs(&info->das_regs);
- i2s_clock_disable(cpu_dai->id);
return 0;
}
@@ -306,13 +296,11 @@ int tegra_i2s_resume(struct snd_soc_dai *cpu_dai)
{
struct tegra_i2s_info *info = cpu_dai->private_data;
- i2s_clock_enable(cpu_dai->id);
tegra_das_set_all_regs(&info->das_regs);
i2s_resume(cpu_dai->id);
tegra_jack_resume();
- i2s_clock_disable(cpu_dai->id);
/* disabled clock as it is being enabled back on startup */
i2s_clock_disable(cpu_dai->id);
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index 369e50743ace..e56ee2d8806d 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -24,48 +24,48 @@
#define PLAYBACK_STARTED true
#define PLAYBACK_STOPPED false
-static void tegra_pcm_play(struct tegra_runtime_data *prtd)
-{
- struct snd_pcm_substream *substream = prtd->substream;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
- struct tegra_dma_req *dma_req;
-
- if (runtime->dma_addr) {
- prtd->size = frames_to_bytes(runtime, runtime->period_size);
- if (prtd->dma_state != STATE_ABORT) {
- prtd->dma_reqid_tail = (prtd->dma_reqid_tail + 1) % DMA_REQ_QCOUNT;
- prtd->dma_req[prtd->dma_reqid_tail].source_addr = buf->addr +
- frames_to_bytes(runtime,prtd->dma_pos);
- prtd->dma_req[prtd->dma_reqid_tail].size = prtd->size;
- tegra_dma_enqueue_req(prtd->dma_chan,
- &prtd->dma_req[prtd->dma_reqid_tail]);
- }
- }
-
- prtd->dma_pos += runtime->period_size;
- if (prtd->dma_pos >= runtime->buffer_size) {
- prtd->dma_pos = 0;
- }
-
-}
+static const struct snd_pcm_hardware tegra_pcm_hardware = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_PAUSE |
+ SNDRV_PCM_INFO_RESUME |
+ SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID ,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 2,
+ .buffer_bytes_max = (PAGE_SIZE * 8),
+ .period_bytes_min = 128,
+ .period_bytes_max = (PAGE_SIZE),
+ .periods_min = 2,
+ .periods_max = 8,
+ .fifo_size = 4,
+};
-static void tegra_pcm_capture(struct tegra_runtime_data *prtd)
+static void tegra_pcm_queue_dma(struct tegra_runtime_data *prtd)
{
struct snd_pcm_substream *substream = prtd->substream;
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_dma_buffer *buf = &substream->dma_buffer;
+ struct tegra_dma_req *dma_req;
if (runtime->dma_addr) {
prtd->size = frames_to_bytes(runtime, runtime->period_size);
if (prtd->dma_state != STATE_ABORT) {
- prtd->dma_reqid_tail = (prtd->dma_reqid_tail + 1) % DMA_REQ_QCOUNT;
- prtd->dma_req[prtd->dma_reqid_tail].dest_addr = buf->addr +
- frames_to_bytes(runtime,prtd->dma_pos);
- prtd->dma_req[prtd->dma_reqid_tail].size = prtd->size;
- tegra_dma_enqueue_req(prtd->dma_chan,
- &prtd->dma_req[prtd->dma_reqid_tail]);
+ prtd->dma_tail_idx = (prtd->dma_tail_idx + 1) %
+ DMA_REQ_QCOUNT;
+ dma_req = &prtd->dma_req[prtd->dma_tail_idx];
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ dma_req->source_addr = buf->addr +
+ frames_to_bytes(runtime,prtd->dma_pos);
+ } else {
+ dma_req->dest_addr = buf->addr +
+ frames_to_bytes(runtime,prtd->dma_pos);
+ }
+
+ dma_req->size = prtd->size;
+ tegra_dma_enqueue_req(prtd->dma_chan, dma_req);
}
}
@@ -87,31 +87,13 @@ static void dma_complete_callback (struct tegra_dma_req *req)
}
if (prtd->dma_state != STATE_ABORT) {
- prtd->dma_reqid_head = (prtd->dma_reqid_head + 1) % DMA_REQ_QCOUNT;
+ prtd->dma_head_idx = (prtd->dma_head_idx + 1) %
+ DMA_REQ_QCOUNT;
snd_pcm_period_elapsed(substream);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- tegra_pcm_play(prtd);
- } else {
- tegra_pcm_capture(prtd);
- }
+ tegra_pcm_queue_dma(prtd);
}
}
-static const struct snd_pcm_hardware tegra_pcm_hardware = {
- .info = SNDRV_PCM_INFO_INTERLEAVED | \
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME | \
- SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID ,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (PAGE_SIZE * 8),
- .period_bytes_min = 128,
- .period_bytes_max = (PAGE_SIZE),
- .periods_min = 2,
- .periods_max = 8,
- .fifo_size = 4,
-};
-
static int tegra_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
@@ -140,8 +122,8 @@ static int tegra_pcm_prepare(struct snd_pcm_substream *substream)
prtd->dma_pos = 0;
prtd->period_index = 0;
- prtd->dma_reqid_head = 0;
- prtd->dma_reqid_tail = DMA_REQ_QCOUNT - 1;
+ prtd->dma_head_idx = 0;
+ prtd->dma_tail_idx = DMA_REQ_QCOUNT - 1;
return 0;
}
@@ -155,18 +137,10 @@ static int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- prtd->state = STATE_INIT;
- prtd->dma_state = STATE_INIT;
- for (i = 0; i < DMA_REQ_QCOUNT; i++)
- tegra_pcm_play(prtd); /* dma enqueue req */
- } else if (prtd->state != STATE_INIT) {
- /* start recording */
- prtd->state = STATE_INIT;
- prtd->dma_state = STATE_INIT;
- for (i = 0; i < DMA_REQ_QCOUNT; i++)
- tegra_pcm_capture(prtd); /* dma enqueue req */
- }
+
+ prtd->dma_state = STATE_INIT;
+ tegra_pcm_queue_dma(prtd); /* dma enqueue req1 */
+ tegra_pcm_queue_dma(prtd); /* dma enqueue req2 */
break;
case SNDRV_PCM_TRIGGER_STOP:
@@ -175,22 +149,13 @@ static int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
prtd->dma_state = STATE_ABORT;
tegra_dma_cancel(prtd->dma_chan);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (prtd->dma_chan) {
- for (i = 0; i < DMA_REQ_QCOUNT; i++)
- tegra_dma_dequeue_req(prtd->dma_chan,
- &prtd->dma_req[i]);
- prtd->dma_reqid_head = 0;
- prtd->dma_reqid_tail = DMA_REQ_QCOUNT - 1;
- }
- } else {
- if (prtd->dma_chan) {
- for (i = 0; i < DMA_REQ_QCOUNT; i++)
- tegra_dma_dequeue_req(prtd->dma_chan,
- &prtd->dma_req[i]);
- prtd->dma_reqid_head = 0;
- prtd->dma_reqid_tail = DMA_REQ_QCOUNT - 1;
- }
+
+ if (prtd->dma_chan) {
+ for (i = 0; i < DMA_REQ_QCOUNT; i++)
+ tegra_dma_dequeue_req(prtd->dma_chan,
+ &prtd->dma_req[i]);
+ prtd->dma_head_idx = 0;
+ prtd->dma_tail_idx = DMA_REQ_QCOUNT - 1;
}
break;
@@ -211,8 +176,9 @@ static snd_pcm_uframes_t tegra_pcm_pointer(struct snd_pcm_substream *substream)
bytes_to_frames(runtime,
tegra_dma_get_transfer_count(
prtd->dma_chan,
- &prtd->dma_req[prtd->dma_reqid_head],
+ &prtd->dma_req[prtd->dma_head_idx],
false));
+
return (size);
}
@@ -249,7 +215,7 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream)
runtime->private_data = prtd;
prtd->substream = substream;
- prtd->state = STATE_INVALID;
+ prtd->dma_state = STATE_INVALID;
if (strcmp(cpu_dai->name, "tegra-spdif") == 0)
{
@@ -286,7 +252,7 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream)
fail:
if (prtd) {
- prtd->state = STATE_EXIT;
+ prtd->dma_state = STATE_EXIT;
if (prtd->dma_chan) {
tegra_dma_flush(prtd->dma_chan);
@@ -324,8 +290,8 @@ static int tegra_pcm_close(struct snd_pcm_substream *substream)
tegra_dma_flush(prtd->dma_chan);
tegra_dma_free_channel(prtd->dma_chan);
prtd->dma_chan = NULL;
- prtd->dma_reqid_head = 0;
- prtd->dma_reqid_tail = DMA_REQ_QCOUNT - 1;
+ prtd->dma_head_idx = 0;
+ prtd->dma_tail_idx = DMA_REQ_QCOUNT - 1;
}
kfree(prtd);
diff --git a/sound/soc/tegra/tegra_soc.h b/sound/soc/tegra/tegra_soc.h
index bfaf998f973e..495f5c2b53cc 100644
--- a/sound/soc/tegra/tegra_soc.h
+++ b/sound/soc/tegra/tegra_soc.h
@@ -71,9 +71,7 @@
#define I2S2_CLK 2000000
#define TEGRA_DEFAULT_SR 44100
-#define TEGRA_SAMPLE_RATES \
- (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
+#define TEGRA_SAMPLE_RATES (SNDRV_PCM_RATE_8000_96000)
#define TEGRA_VOICE_SAMPLE_RATES SNDRV_PCM_RATE_8000
#define DMA_STEP_SIZE_MIN 8
@@ -95,12 +93,11 @@ struct tegra_runtime_data {
struct snd_pcm_substream *substream;
int size;
int dma_pos;
- struct tegra_dma_req dma_req[DMA_REQ_QCOUNT];
- int dma_reqid_head;
- int dma_reqid_tail;
- volatile int state;
+ int dma_tail_idx;
+ int dma_head_idx;
int period_index;
int dma_state;
+ struct tegra_dma_req dma_req[DMA_REQ_QCOUNT];
struct tegra_dma_channel *dma_chan;
};
@@ -116,39 +113,26 @@ struct tegra_audio_data {
int codec_con;
};
-struct wired_jack_conf {
- int hp_det_n;
- int en_mic_int;
- int en_mic_ext;
- int cdc_irq;
- int en_spkr;
- const char *spkr_amp_reg;
- struct regulator *amp_reg;
- int amp_reg_enabled;
-};
-
void tegra_ext_control(struct snd_soc_codec *codec, int new_con);
int tegra_controls_init(struct snd_soc_codec *codec);
int tegra_jack_init(struct snd_soc_codec *codec);
void tegra_jack_exit(void);
void tegra_jack_resume(void);
-void free_i2s_dma_request(struct snd_pcm_substream *substream);
-void set_i2s_fifo_attention(struct snd_pcm_substream *substream,
- int buffersize);
-void free_spdif_dma_request(struct snd_pcm_substream *substream);
-void set_spdif_fifo_attention(struct snd_pcm_substream *substream,
- int buffersize);
-
void tegra_switch_set_state(int state);
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_controls.c b/sound/soc/tegra/tegra_soc_controls.c
index dbb4bdf67aea..c430703f4bd4 100644
--- a/sound/soc/tegra/tegra_soc_controls.c
+++ b/sound/soc/tegra/tegra_soc_controls.c
@@ -79,7 +79,7 @@ static void tegra_audio_route(struct tegra_audio_data* audio_data,
if ((is_call_mode_new != audio_data->is_call_mode) ||
(is_bt_sco_mode != was_bt_sco_mode)) {
-#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
+
if (is_call_mode_new && is_bt_sco_mode) {
tegra_das_set_connection
(tegra_das_port_con_id_voicecall_with_bt);
@@ -96,7 +96,7 @@ static void tegra_audio_route(struct tegra_audio_data* audio_data,
tegra_das_set_connection
(tegra_das_port_con_id_hifi);
}
-#endif
+
audio_data->is_call_mode = is_call_mode_new;
}
}
diff --git a/sound/soc/tegra/tegra_soc_wm8753.c b/sound/soc/tegra/tegra_soc_wm8753.c
index 3456b2541ee8..85647bca9b9e 100644
--- a/sound/soc/tegra/tegra_soc_wm8753.c
+++ b/sound/soc/tegra/tegra_soc_wm8753.c
@@ -154,13 +154,12 @@ static int tegra_hifi_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
struct snd_soc_codec *codec = codec_dai->codec;
- struct tegra_audio_data* audio_data = rtd->socdev->codec_data;
- enum dac_dap_data_format data_fmt;
int dai_flag = 0, sys_clk;
unsigned int value;
int err;
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+ enum dac_dap_data_format data_fmt;
if (tegra_das_is_port_master(tegra_audio_codec_type_hifi))
dai_flag |= SND_SOC_DAIFMT_CBM_CFM;
else
@@ -190,7 +189,7 @@ static int tegra_hifi_hw_params(struct snd_pcm_substream *substream,
return err;
}
- sys_clk = clk_get_rate(audio_data->dap_mclk);
+ sys_clk = tegra_das_get_mclk_rate();
err = snd_soc_dai_set_sysclk(codec_dai, 0, sys_clk, SND_SOC_CLOCK_IN);
if (err < 0) {
pr_err("codec_dai clock not set\n");
@@ -322,12 +321,12 @@ static int tegra_voice_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
- struct tegra_audio_data* audio_data = rtd->socdev->codec_data;
- enum dac_dap_data_format data_fmt;
int dai_flag = 0, sys_clk;
int err;
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+ enum dac_dap_data_format data_fmt;
+
if (tegra_das_is_port_master(tegra_audio_codec_type_bluetooth))
dai_flag |= SND_SOC_DAIFMT_CBM_CFM;
else
@@ -356,7 +355,7 @@ static int tegra_voice_hw_params(struct snd_pcm_substream *substream,
return err;
}
- sys_clk = clk_get_rate(audio_data->dap_mclk);
+ sys_clk = tegra_das_get_mclk_rate();
err = snd_soc_dai_set_sysclk(codec_dai, 0, sys_clk, SND_SOC_CLOCK_IN);
if (err < 0) {
pr_err("cpu_dai clock not set\n");
@@ -402,20 +401,14 @@ int tegra_soc_suspend_pre(struct platform_device *pdev, pm_message_t state)
int tegra_soc_suspend_post(struct platform_device *pdev, pm_message_t state)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct tegra_audio_data* audio_data = socdev->codec_data;
-
- clk_disable(audio_data->dap_mclk);
+ tegra_das_disable_mclk();
return 0;
}
int tegra_soc_resume_pre(struct platform_device *pdev)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct tegra_audio_data* audio_data = socdev->codec_data;
-
- clk_enable(audio_data->dap_mclk);
+ tegra_das_enable_mclk();
return 0;
}
@@ -588,13 +581,20 @@ static int tegra_codec_init(struct snd_soc_codec *codec)
unsigned int value;
if (!audio_data->init_done) {
- audio_data->dap_mclk = tegra_das_get_dap_mclk();
- if (!audio_data->dap_mclk) {
- pr_err("Failed to get dap mclk \n");
+
+ ret = tegra_das_open();
+ if (ret) {
+ pr_err(" Failed get dap mclk \n");
+ ret = -ENODEV;
+ goto wm8753_init_fail;
+ }
+
+ ret = tegra_das_enable_mclk();
+ if (ret) {
+ pr_err(" Failed to enable dap mclk \n");
ret = -ENODEV;
- return ret;
+ goto wm8753_init_fail;
}
- clk_enable(audio_data->dap_mclk);
/* Add tegra specific widgets */
snd_soc_dapm_new_controls(codec, tegra_dapm_widgets,
@@ -608,7 +608,7 @@ static int tegra_codec_init(struct snd_soc_codec *codec)
ret = tegra_jack_init(codec);
if (ret < 0) {
pr_err("Failed in jack init \n");
- return ret;
+ goto wm8753_init_fail;
}
/* Default to OFF */
@@ -617,14 +617,15 @@ static int tegra_codec_init(struct snd_soc_codec *codec)
ret = tegra_controls_init(codec);
if (ret < 0) {
pr_err("Failed in controls init \n");
- return ret;
+ goto wm8753_init_fail;
}
if (!wm8753_jack) {
wm8753_jack = kzalloc(sizeof(*wm8753_jack), GFP_KERNEL);
if (!wm8753_jack) {
pr_err("failed to allocate wm8753-jack\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto wm8753_init_fail;
}
wm8753_jack->gpio = TEGRA_GPIO_PW3;
@@ -691,6 +692,10 @@ gpio_failed:
gpio_free(wm8753_jack->gpio);
failed:
kfree(wm8753_jack);
+
+wm8753_init_fail:
+ tegra_das_disable_mclk();
+ tegra_das_close();
wm8753_jack = NULL;
return ret;
}
diff --git a/sound/soc/tegra/tegra_soc_wm8903.c b/sound/soc/tegra/tegra_soc_wm8903.c
index 883941c119c0..b7ab17e37d66 100644
--- a/sound/soc/tegra/tegra_soc_wm8903.c
+++ b/sound/soc/tegra/tegra_soc_wm8903.c
@@ -75,12 +75,12 @@ static int tegra_hifi_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
struct snd_soc_codec *codec = codec_dai->codec;
- struct tegra_audio_data* audio_data = rtd->socdev->codec_data;
- enum dac_dap_data_format data_fmt;
int dai_flag = 0, sys_clk;
int err;
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+ enum dac_dap_data_format data_fmt;
+
if (tegra_das_is_port_master(tegra_audio_codec_type_hifi))
dai_flag |= SND_SOC_DAIFMT_CBM_CFM;
else
@@ -109,7 +109,9 @@ static int tegra_hifi_hw_params(struct snd_pcm_substream *substream,
return err;
}
- sys_clk = clk_get_rate(audio_data->dap_mclk);
+ /*FIXME: not sure this is the right way.
+ This should be samplerate times 256 or 128 based on codec need*/
+ sys_clk = tegra_das_get_mclk_rate();
err = snd_soc_dai_set_sysclk(codec_dai, 0, sys_clk, SND_SOC_CLOCK_IN);
if (err < 0) {
pr_err("codec_dai clock not set\n");
@@ -198,7 +200,6 @@ static int tegra_hifi_hw_params(struct snd_pcm_substream *substream,
/* Enable ADC Digital volumes */
VolumeCtrlReg = ADC_DIGITAL_VOL_9DB;
- // voulme for single ended mic
snd_soc_write(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT,
VolumeCtrlReg);
snd_soc_write(codec, WM8903_ADC_DIGITAL_VOLUME_RIGHT,
@@ -219,12 +220,12 @@ static int tegra_voice_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
- struct tegra_audio_data* audio_data = rtd->socdev->codec_data;
- enum dac_dap_data_format data_fmt;
int dai_flag = 0, sys_clk;
int err;
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+ enum dac_dap_data_format data_fmt;
+
if (tegra_das_is_port_master(tegra_audio_codec_type_bluetooth))
dai_flag |= SND_SOC_DAIFMT_CBM_CFM;
else
@@ -253,7 +254,7 @@ static int tegra_voice_hw_params(struct snd_pcm_substream *substream,
return err;
}
- sys_clk = clk_get_rate(audio_data->dap_mclk);
+ sys_clk = tegra_das_get_mclk_rate();
err = snd_soc_dai_set_sysclk(codec_dai, 0, sys_clk, SND_SOC_CLOCK_IN);
if (err < 0) {
pr_err("cpu_dai clock not set\n");
@@ -294,20 +295,14 @@ int tegra_soc_suspend_pre(struct platform_device *pdev, pm_message_t state)
int tegra_soc_suspend_post(struct platform_device *pdev, pm_message_t state)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct tegra_audio_data* audio_data = socdev->codec_data;
-
- clk_disable(audio_data->dap_mclk);
+ tegra_das_disable_mclk();
return 0;
}
int tegra_soc_resume_pre(struct platform_device *pdev)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct tegra_audio_data* audio_data = socdev->codec_data;
-
- clk_enable(audio_data->dap_mclk);
+ tegra_das_enable_mclk();
return 0;
}
@@ -482,15 +477,20 @@ static int tegra_codec_init(struct snd_soc_codec *codec)
int err = 0;
if (!audio_data->init_done) {
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
- audio_data->dap_mclk = tegra_das_get_dap_mclk();
- if (!audio_data->dap_mclk) {
- pr_err("Failed to get dap mclk \n");
+
+ err = tegra_das_open();
+ if (err) {
+ pr_err(" Failed get dap mclk \n");
err = -ENODEV;
- return err;
+ goto wm8903_init_fail;
+ }
+
+ err = tegra_das_enable_mclk();
+ if (err) {
+ pr_err(" Failed to enable dap mclk \n");
+ err = -ENODEV;
+ goto wm8903_init_fail;
}
- clk_enable(audio_data->dap_mclk);
-#endif
/* Add tegra specific widgets */
snd_soc_dapm_new_controls(codec, tegra_dapm_widgets,
@@ -504,7 +504,7 @@ static int tegra_codec_init(struct snd_soc_codec *codec)
err = tegra_jack_init(codec);
if (err < 0) {
pr_err("Failed in jack init \n");
- return err;
+ goto wm8903_init_fail;
}
/* Default to OFF */
@@ -513,7 +513,7 @@ static int tegra_codec_init(struct snd_soc_codec *codec)
err = tegra_controls_init(codec);
if (err < 0) {
pr_err("Failed in controls init \n");
- return err;
+ goto wm8903_init_fail;
}
audio_data->codec = codec;
@@ -521,6 +521,12 @@ static int tegra_codec_init(struct snd_soc_codec *codec)
}
return err;
+
+wm8903_init_fail:
+
+ tegra_das_disable_mclk();
+ tegra_das_close();
+ return err;
}
@@ -548,9 +554,6 @@ static struct snd_soc_dai_link tegra_soc_dai[] = {
TEGRA_CREATE_SOC_DAI_LINK("Tegra-generic", "Tegra Generic Voice",
&tegra_i2s_dai[1], &tegra_generic_codec_dai[1],
&tegra_voice_ops),
- TEGRA_CREATE_SOC_DAI_LINK("Tegra-spdif", "Tegra Spdif",
- &tegra_spdif_dai, &tegra_generic_codec_dai[1],
- &tegra_spdif_ops),
#else
/* FIXME: enabled once these device are enumerated
TEGRA_CREATE_SOC_DAI_LINK("Tegra-generic-0", "Tegra BB Voice",
diff --git a/sound/soc/tegra/tegra_spdif.c b/sound/soc/tegra/tegra_spdif.c
index 7243efd22044..dff38ffe0b72 100644
--- a/sound/soc/tegra/tegra_spdif.c
+++ b/sound/soc/tegra/tegra_spdif.c
@@ -24,11 +24,8 @@
struct tegra_spdif_info {
struct platform_device *pdev;
struct tegra_audio_platform_data *pdata;
- struct clk *spdif_clk;
unsigned long spdif_phys;
unsigned long spdif_base;
-
- int irq;
};
void free_spdif_dma_request(struct snd_pcm_substream *substream)
@@ -128,7 +125,6 @@ static int tegra_spdif_hw_params(struct snd_pcm_substream *substream,
{
struct tegra_spdif_info *info = dai->private_data;
int val;
- unsigned int rate, sample_size;
int fifo_mode = AUDIO_RX_MODE;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -137,15 +133,12 @@ static int tegra_spdif_hw_params(struct snd_pcm_substream *substream,
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
val = SPDIF_BIT_MODE_MODE16BIT;
- sample_size = 16;
break;
case SNDRV_PCM_FORMAT_S24_LE:
val = SPDIF_BIT_MODE_MODE24BIT;
- sample_size = 16;
break;
case SNDRV_PCM_FORMAT_S32_LE:
val = SPDIF_BIT_MODE_MODERAW;
- sample_size = 32;
break;
default:
return -EINVAL;
@@ -339,14 +332,6 @@ static int tegra_spdif_driver_probe(struct platform_device *pdev)
goto fail_release_mem;
}
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- dev_err(&pdev->dev, "no irq resource!\n");
- err = -ENODEV;
- goto fail_unmap_mem;
- }
- info->irq = res->start;
-
sp_prop.clk_rate = info->pdata->dev_clk_rate;
spdif_init(info->spdif_base, AUDIO_TX_MODE, &sp_prop);
diff --git a/sound/soc/tegra/tegra_wired_jack.c b/sound/soc/tegra/tegra_wired_jack.c
index 235f4893add9..1ee029856cb0 100644
--- a/sound/soc/tegra/tegra_wired_jack.c
+++ b/sound/soc/tegra/tegra_wired_jack.c
@@ -146,9 +146,9 @@ static int tegra_wired_jack_probe(struct platform_device *pdev)
int hp_det_n = 0, cdc_irq = 0;
int en_mic_int = 0, en_mic_ext = 0;
int en_spkr = 0;
- struct tegra_wired_jack_conf *pdata;
+ struct wired_jack_conf *pdata;
- pdata = (struct tegra_wired_jack_conf *)pdev->dev.platform_data;
+ pdata = (struct wired_jack_conf *)pdev->dev.platform_data;
if (!pdata || !pdata->hp_det_n
#if defined(CONFIG_ARCH_TEGRA_2x_SOC)