diff options
author | Xinyu Chen <xinyu.chen@freescale.com> | 2012-11-30 11:59:33 +0800 |
---|---|---|
committer | Xinyu Chen <xinyu.chen@freescale.com> | 2012-11-30 11:59:33 +0800 |
commit | 08c473f52af7434b09214fedcfce222fb9821033 (patch) | |
tree | 555dc016292a132bd55096d42c945c61c6394174 /sound | |
parent | 9ae3b66a8ea648d977cbcebf02209f21cc9be3a4 (diff) | |
parent | 57ade285e32285186879f96c346dd5b45a7f0dd6 (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.c | 12 | ||||
-rw-r--r-- | sound/soc/imx/imx-esai.h | 2 | ||||
-rw-r--r-- | sound/soc/imx/imx-hdmi-dma.c | 107 | ||||
-rw-r--r-- | sound/soc/imx/imx-pcm-dma-mx2.c | 49 | ||||
-rw-r--r-- | sound/soc/imx/imx-pcm.h | 6 | ||||
-rw-r--r-- | sound/soc/imx/imx-ssi.c | 15 | ||||
-rw-r--r-- | sound/soc/imx/imx-ssi.h | 3 | ||||
-rw-r--r-- | sound/soc/imx/imx-wm8962.c | 18 |
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) { |