summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorXinyu Chen <xinyu.chen@freescale.com>2012-11-30 11:59:33 +0800
committerXinyu Chen <xinyu.chen@freescale.com>2012-11-30 11:59:33 +0800
commit08c473f52af7434b09214fedcfce222fb9821033 (patch)
tree555dc016292a132bd55096d42c945c61c6394174 /sound
parent9ae3b66a8ea648d977cbcebf02209f21cc9be3a4 (diff)
parent57ade285e32285186879f96c346dd5b45a7f0dd6 (diff)
Merge remote-tracking branch 'fsl-linux-sdk/imx_3.0.35_1.1.0' into imx_3.0.35_android
Conflicts: arch/arm/mach-mx6/board-mx6q_sabrelite.c arch/arm/mach-mx6/board-mx6q_sabresd.c arch/arm/plat-mxc/cpufreq.c
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/imx/imx-cs42888.c12
-rw-r--r--sound/soc/imx/imx-esai.h2
-rw-r--r--sound/soc/imx/imx-hdmi-dma.c107
-rw-r--r--sound/soc/imx/imx-pcm-dma-mx2.c49
-rw-r--r--sound/soc/imx/imx-pcm.h6
-rw-r--r--sound/soc/imx/imx-ssi.c15
-rw-r--r--sound/soc/imx/imx-ssi.h3
-rw-r--r--sound/soc/imx/imx-wm8962.c18
8 files changed, 100 insertions, 112 deletions
diff --git a/sound/soc/imx/imx-cs42888.c b/sound/soc/imx/imx-cs42888.c
index acec900618b1..62d221fb3908 100644
--- a/sound/soc/imx/imx-cs42888.c
+++ b/sound/soc/imx/imx-cs42888.c
@@ -82,7 +82,8 @@ static int config_asrc(struct snd_pcm_substream *substream,
if ((channel != 2) && (channel != 4) && (channel != 6))
return -EINVAL;
- ret = asrc_req_pair(channel, &iprtd->asrc_index);
+ ret = iprtd->asrc_pcm_p2p_ops_ko->
+ asrc_p2p_req_pair(channel, &iprtd->asrc_index);
if (ret < 0) {
pr_err("Fail to request asrc pair\n");
return -EINVAL;
@@ -97,7 +98,7 @@ static int config_asrc(struct snd_pcm_substream *substream,
config.inclk = INCLK_NONE;
config.outclk = OUTCLK_ESAI_TX;
- ret = asrc_config_pair(&config);
+ ret = iprtd->asrc_pcm_p2p_ops_ko->asrc_p2p_config_pair(&config);
if (ret < 0) {
pr_err("Fail to config asrc\n");
return ret;
@@ -142,8 +143,11 @@ static int imx_3stack_surround_hw_free(struct snd_pcm_substream *substream)
if (iprtd->asrc_enable) {
if (iprtd->asrc_index != -1) {
- asrc_release_pair(iprtd->asrc_index);
- asrc_finish_conv(iprtd->asrc_index);
+ iprtd->asrc_pcm_p2p_ops_ko->
+ asrc_p2p_release_pair(
+ iprtd->asrc_index);
+ iprtd->asrc_pcm_p2p_ops_ko->
+ asrc_p2p_finish_conv(iprtd->asrc_index);
}
iprtd->asrc_index = -1;
}
diff --git a/sound/soc/imx/imx-esai.h b/sound/soc/imx/imx-esai.h
index d27cbd00ae96..53c899e1b654 100644
--- a/sound/soc/imx/imx-esai.h
+++ b/sound/soc/imx/imx-esai.h
@@ -298,8 +298,6 @@
#define ESAI_RX_DIV_PM 4
#define ESAI_RX_DIV_FP 5
-#define IMX_ESAI_DMABUF_SIZE (64 * 1024)
-
#define DRV_NAME "imx-esai"
#include <linux/dmaengine.h>
diff --git a/sound/soc/imx/imx-hdmi-dma.c b/sound/soc/imx/imx-hdmi-dma.c
index a359e4cdcfe2..c845672be6aa 100644
--- a/sound/soc/imx/imx-hdmi-dma.c
+++ b/sound/soc/imx/imx-hdmi-dma.c
@@ -584,7 +584,7 @@ static void hdmi_sdma_isr(void *data)
struct imx_hdmi_dma_runtime_data *rtd = data;
struct snd_pcm_substream *substream = rtd->tx_substream;
struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long offset, count, space_to_end, appl_bytes;
+ unsigned long offset, count, appl_bytes;
unsigned long flags;
spin_lock_irqsave(&rtd->irq_lock, flags);
@@ -598,38 +598,11 @@ static void hdmi_sdma_isr(void *data)
* to hw_buffer and add the frame info. */
if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) {
appl_bytes = frames_to_bytes(runtime,
- runtime->control->appl_ptr);
-
- if (rtd->appl_bytes > appl_bytes) {
- if (appl_bytes > rtd->buffer_bytes)
- rtd->appl_bytes =
- appl_bytes - rtd->buffer_bytes;
- else
- rtd->appl_bytes = 0;
- } else {
- if ((appl_bytes - rtd->appl_bytes) >
- rtd->buffer_bytes)
- rtd->appl_bytes =
- appl_bytes - rtd->buffer_bytes;
-
- }
-
- offset = rtd->appl_bytes % rtd->buffer_bytes;
- space_to_end = rtd->buffer_bytes - offset;
- count = appl_bytes - rtd->appl_bytes;
- if (count > rtd->buffer_bytes)
- count = rtd->buffer_bytes;
-
- rtd->appl_bytes = appl_bytes;
-
- if (count <= space_to_end) {
- hdmi_dma_mmap_copy(substream, offset, count);
- } else {
- hdmi_dma_mmap_copy(substream,
- offset, space_to_end);
- hdmi_dma_mmap_copy(substream,
- 0, count - space_to_end);
- }
+ runtime->status->hw_ptr);
+ appl_bytes += 2 * rtd->period_bytes;
+ offset = appl_bytes % rtd->buffer_bytes;
+ count = rtd->period_bytes;
+ hdmi_dma_mmap_copy(substream, offset, count);
}
snd_pcm_period_elapsed(substream);
@@ -646,7 +619,7 @@ static irqreturn_t hdmi_dma_isr(int irq, void *dev_id)
struct imx_hdmi_dma_runtime_data *rtd = dev_id;
struct snd_pcm_substream *substream = rtd->tx_substream;
struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long offset, count, space_to_end, appl_bytes;
+ unsigned long offset, count, appl_bytes;
unsigned long flags;
unsigned int status;
@@ -664,34 +637,11 @@ static irqreturn_t hdmi_dma_isr(int irq, void *dev_id)
* to hw_buffer and add the frame info. */
if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) {
appl_bytes = frames_to_bytes(runtime,
- runtime->control->appl_ptr);
- if (rtd->appl_bytes > appl_bytes) {
- if (appl_bytes > rtd->buffer_bytes)
- rtd->appl_bytes =
- appl_bytes - rtd->buffer_bytes;
- else
- rtd->appl_bytes = 0;
- } else {
- if ((appl_bytes - rtd->appl_bytes) >
- rtd->buffer_bytes)
- rtd->appl_bytes =
- appl_bytes - rtd->buffer_bytes;
-
- }
-
- offset = rtd->appl_bytes % rtd->buffer_bytes;
- space_to_end = rtd->buffer_bytes - offset;
- count = appl_bytes - rtd->appl_bytes;
- if (count > rtd->buffer_bytes)
- count = rtd->buffer_bytes;
- rtd->appl_bytes = appl_bytes;
-
- if (count <= space_to_end) {
- hdmi_dma_mmap_copy(substream, offset, count);
- } else {
- hdmi_dma_mmap_copy(substream, offset, space_to_end);
- hdmi_dma_mmap_copy(substream, 0, count - space_to_end);
- }
+ runtime->status->hw_ptr);
+ appl_bytes += 2 * rtd->period_bytes;
+ offset = appl_bytes % rtd->buffer_bytes;
+ count = rtd->period_bytes;
+ hdmi_dma_mmap_copy(substream, offset, count);
}
snd_pcm_period_elapsed(substream);
@@ -1125,36 +1075,10 @@ static int hdmi_dma_trigger(struct snd_pcm_substream *substream, int cmd)
rtd->frame_idx = 0;
if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) {
appl_bytes = frames_to_bytes(runtime,
- runtime->control->appl_ptr);
- /* If resume, the rtd->appl_bytes may stil
- * keep the old value but the control->
- * appl_ptr is clear. Reset it if this
- * misalignment happens*/
- if (rtd->appl_bytes > appl_bytes) {
- if (appl_bytes > rtd->buffer_bytes)
- rtd->appl_bytes =
- appl_bytes - rtd->buffer_bytes;
- else
- rtd->appl_bytes = 0;
- } else {
- if ((appl_bytes - rtd->appl_bytes) >
- rtd->buffer_bytes)
- rtd->appl_bytes =
- appl_bytes - rtd->buffer_bytes;
-
- }
-
- offset = rtd->appl_bytes % rtd->buffer_bytes;
+ runtime->status->hw_ptr);
+ offset = appl_bytes % rtd->buffer_bytes;
+ count = rtd->buffer_bytes;
space_to_end = rtd->buffer_bytes - offset;
- count = appl_bytes - rtd->appl_bytes;
-
- if (count > rtd->buffer_bytes) {
- pr_err("Error Count,ring buffer size[%ld], count[%ld]!\n",
- rtd->buffer_bytes, count);
- return -EINVAL;
- }
-
- rtd->appl_bytes = appl_bytes;
if (count <= space_to_end) {
hdmi_dma_mmap_copy(substream, offset, count);
@@ -1164,7 +1088,6 @@ static int hdmi_dma_trigger(struct snd_pcm_substream *substream, int cmd)
hdmi_dma_mmap_copy(substream,
0, count - space_to_end);
}
-
}
dumpregs();
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c
index ad8d5a3329c7..047a5db6c491 100644
--- a/sound/soc/imx/imx-pcm-dma-mx2.c
+++ b/sound/soc/imx/imx-pcm-dma-mx2.c
@@ -35,6 +35,14 @@
#include "imx-ssi.h"
#include "imx-pcm.h"
+struct asrc_p2p_ops *asrc_pcm_p2p_ops;
+
+void asrc_p2p_hook(struct asrc_p2p_ops *asrc_p2p_ct)
+{
+ asrc_pcm_p2p_ops = asrc_p2p_ct;
+ return ;
+}
+EXPORT_SYMBOL(asrc_p2p_hook);
static void audio_dma_irq(void *data)
{
@@ -109,14 +117,16 @@ static int imx_ssi_asrc_dma_alloc(struct snd_pcm_substream *substream,
iprtd->asrc_dma_data.peripheral_type = IMX_DMATYPE_ASRC;
iprtd->asrc_dma_data.priority = DMA_PRIO_HIGH;
iprtd->asrc_dma_data.dma_request =
- asrc_get_dma_request(iprtd->asrc_index, 1);
+ iprtd->asrc_pcm_p2p_ops_ko->
+ asrc_p2p_get_dma_request(iprtd->asrc_index, 1);
iprtd->asrc_dma_chan = dma_request_channel(mask, asrc_filter, iprtd);
if (!iprtd->asrc_dma_chan)
goto error;
slave_config.direction = DMA_TO_DEVICE;
- slave_config.dst_addr = asrc_get_per_addr(iprtd->asrc_index, 1);
+ slave_config.dst_addr = iprtd->asrc_pcm_p2p_ops_ko->
+ asrc_p2p_per_addr(iprtd->asrc_index, 1);
slave_config.dst_addr_width = buswidth;
slave_config.dst_maxburst = dma_params->burstsize * buswidth;
@@ -127,7 +137,8 @@ static int imx_ssi_asrc_dma_alloc(struct snd_pcm_substream *substream,
iprtd->asrc_p2p_dma_data.peripheral_type = IMX_DMATYPE_ASRC;
iprtd->asrc_p2p_dma_data.priority = DMA_PRIO_HIGH;
iprtd->asrc_p2p_dma_data.dma_request =
- asrc_get_dma_request(iprtd->asrc_index, 0);
+ iprtd->asrc_pcm_p2p_ops_ko->
+ asrc_p2p_get_dma_request(iprtd->asrc_index, 0);
iprtd->asrc_p2p_dma_data.dma_request_p2p = dma_params->dma;
iprtd->asrc_p2p_dma_chan =
dma_request_channel(mask, asrc_p2p_filter, iprtd);
@@ -146,7 +157,8 @@ static int imx_ssi_asrc_dma_alloc(struct snd_pcm_substream *substream,
}
slave_config.direction = DMA_DEV_TO_DEV;
- slave_config.src_addr = asrc_get_per_addr(iprtd->asrc_index, 0);
+ slave_config.src_addr = iprtd->asrc_pcm_p2p_ops_ko->
+ asrc_p2p_per_addr(iprtd->asrc_index, 0);
slave_config.src_addr_width = buswidth;
slave_config.src_maxburst = dma_params->burstsize * buswidth;
slave_config.dst_addr = dma_params->dma_addr;
@@ -358,7 +370,8 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
if (iprtd->asrc_enable) {
dmaengine_submit(iprtd->asrc_p2p_desc);
dmaengine_submit(iprtd->asrc_desc);
- asrc_start_conv(iprtd->asrc_index);
+ iprtd->asrc_pcm_p2p_ops_ko->
+ asrc_p2p_start_conv(iprtd->asrc_index);
mdelay(1);
} else {
dmaengine_submit(iprtd->desc);
@@ -371,7 +384,8 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
if (iprtd->asrc_enable) {
dmaengine_terminate_all(iprtd->asrc_dma_chan);
dmaengine_terminate_all(iprtd->asrc_p2p_dma_chan);
- asrc_stop_conv(iprtd->asrc_index);
+ iprtd->asrc_pcm_p2p_ops_ko->
+ asrc_p2p_stop_conv(iprtd->asrc_index);
} else {
dmaengine_terminate_all(iprtd->dma_chan);
}
@@ -405,7 +419,7 @@ static struct snd_pcm_hardware snd_imx_hardware = {
.rate_min = 8000,
.channels_min = 2,
.channels_max = 2,
- .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
+ .buffer_bytes_max = IMX_DEFAULT_DMABUF_SIZE,
.period_bytes_min = 128,
.period_bytes_max = 65535, /* Limited by SDMA engine */
.periods_min = 2,
@@ -428,6 +442,11 @@ static int snd_imx_open(struct snd_pcm_substream *substream)
iprtd->p2p =
(struct asrc_p2p_params *)snd_soc_pcm_get_drvdata(rtd);
iprtd->asrc_index = -1;
+ if (!asrc_pcm_p2p_ops) {
+ pr_err("ASRC is not loaded!\n");
+ return -EINVAL;
+ }
+ iprtd->asrc_pcm_p2p_ops_ko = asrc_pcm_p2p_ops;
}
runtime->private_data = iprtd;
@@ -439,6 +458,15 @@ static int snd_imx_open(struct snd_pcm_substream *substream)
return ret;
}
+ if (!strncmp(rtd->cpu_dai->name, "imx-ssi", strlen("imx-ssi")))
+ snd_imx_hardware.buffer_bytes_max = IMX_SSI_DMABUF_SIZE;
+ else if (!strncmp(rtd->cpu_dai->name, "imx-esai", strlen("imx-esai")))
+ snd_imx_hardware.buffer_bytes_max = IMX_ESAI_DMABUF_SIZE;
+ else if (!strncmp(rtd->cpu_dai->name, "imx-spdif", strlen("imx-spdif")))
+ snd_imx_hardware.buffer_bytes_max = IMX_SPDIF_DMABUF_SIZE;
+ else
+ snd_imx_hardware.buffer_bytes_max = IMX_DEFAULT_DMABUF_SIZE;
+
snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
return 0;
@@ -476,8 +504,11 @@ static int __devinit imx_soc_platform_probe(struct platform_device *pdev)
{
struct imx_ssi *ssi = platform_get_drvdata(pdev);
- ssi->dma_params_tx.burstsize = 6;
- ssi->dma_params_rx.burstsize = 4;
+ if (ssi->dma_params_tx.burstsize == 0
+ && ssi->dma_params_rx.burstsize == 0) {
+ ssi->dma_params_tx.burstsize = 6;
+ ssi->dma_params_rx.burstsize = 4;
+ }
return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2);
}
diff --git a/sound/soc/imx/imx-pcm.h b/sound/soc/imx/imx-pcm.h
index c6126216a9cd..1b126be7a592 100644
--- a/sound/soc/imx/imx-pcm.h
+++ b/sound/soc/imx/imx-pcm.h
@@ -43,6 +43,11 @@
#include <mach/dma.h>
+#define IMX_DEFAULT_DMABUF_SIZE (64 * 1024)
+#define IMX_SSI_DMABUF_SIZE (64 * 1024)
+#define IMX_ESAI_DMABUF_SIZE (256 * 1024)
+#define IMX_SPDIF_DMABUF_SIZE (64 * 1024)
+
struct imx_pcm_runtime_data {
int period_bytes;
int periods;
@@ -55,6 +60,7 @@ struct imx_pcm_runtime_data {
struct dma_chan *dma_chan;
struct imx_dma_data dma_data;
int asrc_enable;
+ struct asrc_p2p_ops *asrc_pcm_p2p_ops_ko;
#if defined(CONFIG_MXC_ASRC) || defined(CONFIG_IMX_HAVE_PLATFORM_IMX_ASRC)
enum asrc_pair_index asrc_index;
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index e9b102db7f01..060d093a0aa9 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -56,6 +56,7 @@
#include <mach/hardware.h>
#include "imx-ssi.h"
+#include "imx-pcm.h"
#define SSI_SACNT_DEFAULT (SSI_SACNT_AC97EN | SSI_SACNT_FV)
#define IMX_SSI_FORMATS \
@@ -438,8 +439,18 @@ EXPORT_SYMBOL_GPL(snd_imx_pcm_mmap);
static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
{
struct snd_pcm_substream *substream = pcm->streams[stream].substream;
+ struct snd_soc_pcm_runtime *rtd = pcm->private_data;
struct snd_dma_buffer *buf = &substream->dma_buffer;
- size_t size = IMX_SSI_DMABUF_SIZE;
+ size_t size;
+
+ if (!strncmp(rtd->cpu_dai->name, "imx-ssi", strlen("imx-ssi")))
+ size = IMX_SSI_DMABUF_SIZE;
+ else if (!strncmp(rtd->cpu_dai->name, "imx-esai", strlen("imx-esai")))
+ size = IMX_ESAI_DMABUF_SIZE;
+ else if (!strncmp(rtd->cpu_dai->name, "imx-spdif", strlen("imx-spdif")))
+ size = IMX_SPDIF_DMABUF_SIZE;
+ else
+ size = IMX_DEFAULT_DMABUF_SIZE;
buf->dev.type = SNDRV_DMA_TYPE_DEV;
buf->dev.dev = pcm->card->dev;
@@ -743,7 +754,7 @@ static int imx_ssi_probe(struct platform_device *pdev)
ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0;
ssi->dma_params_tx.dma_addr = res->start + SSI_STX0;
- ssi->dma_params_tx.burstsize = 4;
+ ssi->dma_params_tx.burstsize = 6;
ssi->dma_params_rx.burstsize = 4;
ssi->dma_params_tx.peripheral_type = IMX_DMATYPE_SSI_SP;
diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/imx/imx-ssi.h
index c57f9fe4edaa..af8e5a2a7820 100644
--- a/sound/soc/imx/imx-ssi.h
+++ b/sound/soc/imx/imx-ssi.h
@@ -222,7 +222,4 @@ int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct
int imx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
struct snd_pcm *pcm);
void imx_pcm_free(struct snd_pcm *pcm);
-
-#define IMX_SSI_DMABUF_SIZE (256 * 1024)
-
#endif /* _IMX_SSI_H */
diff --git a/sound/soc/imx/imx-wm8962.c b/sound/soc/imx/imx-wm8962.c
index 2cc1c1b598e6..a9e52d3bdaf6 100644
--- a/sound/soc/imx/imx-wm8962.c
+++ b/sound/soc/imx/imx-wm8962.c
@@ -187,6 +187,14 @@ static void headphone_detect_handler(struct work_struct *wor)
/*sysfs_notify(&pdev->dev.kobj, NULL, "headphone");*/
priv->hp_status = gpio_get_value(plat->hp_gpio);
+ /* if headphone is inserted, disable speaker */
+ if (priv->hp_status != plat->hp_active_low)
+ snd_soc_dapm_nc_pin(&gcodec->dapm, "Ext Spk");
+ else
+ snd_soc_dapm_enable_pin(&gcodec->dapm, "Ext Spk");
+
+ snd_soc_dapm_sync(&gcodec->dapm);
+
/* setup a message for userspace headphone in */
buf = kmalloc(32, GFP_ATOMIC);
if (!buf) {
@@ -260,6 +268,8 @@ static void amic_detect_handler(struct work_struct *work)
else
snd_soc_dapm_enable_pin(&gcodec->dapm, "DMIC");
+ snd_soc_dapm_sync(&gcodec->dapm);
+
/* setup a message for userspace headphone in */
buf = kmalloc(32, GFP_ATOMIC);
if (!buf) {
@@ -349,6 +359,14 @@ static int imx_wm8962_init(struct snd_soc_pcm_runtime *rtd)
ret = -EINVAL;
return ret;
}
+
+ priv->hp_status = gpio_get_value(plat->hp_gpio);
+
+ /* if headphone is inserted, disable speaker */
+ if (priv->hp_status != plat->hp_active_low)
+ snd_soc_dapm_nc_pin(&codec->dapm, "Ext Spk");
+ else
+ snd_soc_dapm_enable_pin(&codec->dapm, "Ext Spk");
}
if (plat->mic_gpio != -1) {