diff options
author | Vinod G <vinodg@nvidia.com> | 2011-02-28 19:03:06 -0800 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-04-26 15:52:25 -0700 |
commit | d482cadcf3b3fe4588b9f4617150915086ffc794 (patch) | |
tree | f3ba681f081622e521007f3fd5c2952d8e70152c /sound | |
parent | 9fe928c73d1f2c7a12d1ec62f933250f4b429298 (diff) |
arm: tegra: Cleanup the pcm dma code
Integrate the changes from main branch and latest code from alsa.
Original-Change-Id: Ifcfd19bfaa3897a0faed28b0b5357792b0b21a9f
Reviewed-on: http://git-master/r/21192
Reviewed-by: Vinod Gopalakrishnakurup <vinodg@nvidia.com>
Tested-by: Vinod Gopalakrishnakurup <vinodg@nvidia.com>
Reviewed-by: Scott Peterson <speterson@nvidia.com>
Change-Id: Ibc1bb27032e92da651ec356d6391d0ee0204c881
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/tegra/tegra_i2s.c | 28 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_pcm.c | 71 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_soc.h | 27 |
3 files changed, 73 insertions, 53 deletions
diff --git a/sound/soc/tegra/tegra_i2s.c b/sound/soc/tegra/tegra_i2s.c index 48115d8cbeb4..f96cfe6e0abf 100644 --- a/sound/soc/tegra/tegra_i2s.c +++ b/sound/soc/tegra/tegra_i2s.c @@ -1,20 +1,22 @@ /* * tegra_i2s.c -- ALSA Soc Audio Layer * - * (c) 2010-2011 Nvidia Graphics Pvt. Ltd. - * http://www.nvidia.com + * Copyright (c) 2009-2011, NVIDIA Corporation. * - * (c) 2006 Wolfson Microelectronics PLC. - * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. * - * (c) 2004-2005 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks <ben@simtec.co.uk> + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include "tegra_soc.h" @@ -111,7 +113,6 @@ static inline void stop_i2s_capture(struct snd_soc_dai *cpu_dai) i2s_fifo_enable(cpu_dai->id, I2S_FIFO_RX, 0); while (i2s_get_status(cpu_dai->id) & I2S_I2S_FIFO_RX_BUSY); } -#endif static int tegra_i2s_hw_params(struct snd_pcm_substream *substream, @@ -203,6 +204,7 @@ static int tegra_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, i2s_set_master(i2s_id, val1); info->i2s_master = val1; + val2 = AUDIO_LRCK_LEFT_LOW; switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { @@ -359,7 +361,7 @@ static void tegra_i2s_shutdown(struct snd_pcm_substream *substream, } static int tegra_i2s_probe(struct platform_device *pdev, - struct snd_soc_dai *dai) + struct snd_soc_dai *cpu_dai) { return 0; } diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index abb2e1115812..f42e981f4ca7 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c @@ -1,24 +1,25 @@ /* * tegra_pcm.c -- ALSA Soc Audio Layer * - * (c) 2010-2011 Nvidia Corporation. - * http://www.nvidia.com + * Copyright (c) 2009-2011, NVIDIA Corporation. * - * (c) 2006 Wolfson Microelectronics PLC. - * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. * - * (c) 2004-2005 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks <ben@simtec.co.uk> + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include "tegra_soc.h" -#include <mach/tegra_das.h> #define PLAYBACK_STARTED true #define PLAYBACK_STOPPED false @@ -28,6 +29,7 @@ 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); @@ -156,10 +158,11 @@ static int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd) tegra_pcm_capture(prtd); /* dma enqueue req */ } break; + case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - prtd->state = STATE_ABORT; + prtd->dma_state = STATE_ABORT; tegra_dma_cancel(prtd->dma_chan); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { @@ -180,6 +183,7 @@ static int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd) } } break; + default: ret = -EINVAL; break; @@ -228,11 +232,11 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream) goto fail; } + /* prtd = kzalloc(sizeof(struct tegra_runtime_data), GFP_KERNEL); if (prtd == NULL) return -ENOMEM; - memset(prtd, 0, sizeof(*prtd)); runtime->private_data = prtd; prtd->substream = substream; @@ -258,10 +262,10 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream) } prtd->dma_chan = tegra_dma_allocate_channel(TEGRA_DMA_MODE_CONTINUOUS_DOUBLE); - if (IS_ERR(prtd->dma_chan)) { - pr_err("%s: could not allocate DMA channel for I2S: %ld\n", - __func__, PTR_ERR(prtd->dma_chan)); - ret = PTR_ERR(prtd->dma_chan); + if (prtd->dma_chan == NULL) { + pr_err("%s: could not allocate DMA channel for PCM:\n", + __func__); + ret = -ENOMEM; goto fail; } @@ -296,8 +300,6 @@ static int tegra_pcm_close(struct snd_pcm_substream *substream) return 0; } - prtd->state = STATE_EXIT; - if (prtd->dma_chan) { prtd->dma_state = STATE_EXIT; for (i = 0; i < DMA_REQ_QCOUNT; i++) @@ -342,12 +344,17 @@ static int tegra_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) struct snd_dma_buffer *buf = &substream->dma_buffer; size_t size = tegra_pcm_hardware.buffer_bytes_max; + buf->area = dma_alloc_writecombine(pcm->card->dev, size, + &buf->addr, GFP_KERNEL); + + if (!buf->area) + return -ENOMEM; + buf->dev.type = SNDRV_DMA_TYPE_DEV; buf->dev.dev = pcm->card->dev; buf->private_data = NULL; - buf->area = dma_alloc_writecombine(pcm->card->dev, size, - &buf->addr, GFP_KERNEL); buf->bytes = size; + return 0; } @@ -371,7 +378,7 @@ static void tegra_pcm_deallocate_dma_buffer(struct snd_pcm *pcm, int stream) } } -static void tegra_pcm_free_dma_buffers(struct snd_pcm *pcm) +static void tegra_pcm_free(struct snd_pcm *pcm) { struct snd_pcm_substream *substream; struct snd_dma_buffer *buf; @@ -386,7 +393,6 @@ static void tegra_pcm_free_dma_buffers(struct snd_pcm *pcm) } tegra_pcm_deallocate_dma_buffer(pcm ,stream); } - } static u64 tegra_dma_mask = DMA_BIT_MASK(32); @@ -405,24 +411,29 @@ static int tegra_pcm_new(struct snd_card *card, ret = tegra_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); if (ret) - goto out; + goto err; } if (dai->capture.channels_min) { ret = tegra_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE); if (ret) - goto out; + goto err_free_play; } -out: + + return 0; + +err_free_play: + tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); +err: return ret; } struct snd_soc_platform tegra_soc_platform = { - .name = "tegra-audio", + .name = "tegra-pcm-audio", .pcm_ops = &tegra_pcm_ops, .pcm_new = tegra_pcm_new, - .pcm_free = tegra_pcm_free_dma_buffers, + .pcm_free = tegra_pcm_free, }; EXPORT_SYMBOL_GPL(tegra_soc_platform); @@ -438,5 +449,5 @@ static void __exit tegra_soc_platform_exit(void) } module_exit(tegra_soc_platform_exit); -MODULE_DESCRIPTION("Tegra PCM DMA module"); +MODULE_DESCRIPTION("Tegra PCM ASoC module"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/tegra/tegra_soc.h b/sound/soc/tegra/tegra_soc.h index 7554ecec90d7..cf878f6a77aa 100644 --- a/sound/soc/tegra/tegra_soc.h +++ b/sound/soc/tegra/tegra_soc.h @@ -1,19 +1,22 @@ /* * tegra_soc.h -- SoC audio for tegra * - * (c) 2010-2011 Nvidia Graphics Pvt. Ltd. - * http://www.nvidia.com +* Copyright (c) 2009-2011, NVIDIA Corporation. * - * Copyright 2007 Wolfson Microelectronics PLC. - * Author: Graeme Gregory - * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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. * - */ + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * */ #ifndef __TEGRA_AUDIO__ #define __TEGRA_AUDIO__ @@ -138,6 +141,10 @@ 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 setup_dma_request(struct snd_pcm_substream *substream, + struct tegra_dma_req *req, + void (*dma_callback)(struct tegra_dma_req *req), + void *dma_data); void tegra_switch_set_state(int state); |