diff options
author | Takashi Iwai <tiwai@suse.de> | 2018-06-05 16:51:55 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2018-06-05 16:51:55 +0200 |
commit | d4d5a1cd298e67cb68cca8dc7dd1ea3942cce3ff (patch) | |
tree | 282417771a28cb3d88fdd3246d9b778f1e3e8fd3 /sound/soc/omap | |
parent | ALSA: usb-audio: remove redundant check on err (diff) | |
parent | Merge branch 'asoc-4.17' into asoc-4.18 merge window (diff) | |
download | linux-dev-d4d5a1cd298e67cb68cca8dc7dd1ea3942cce3ff.tar.xz linux-dev-d4d5a1cd298e67cb68cca8dc7dd1ea3942cce3ff.zip |
Merge tag 'asoc-v4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Updates for v4.18
This is a very big update, mainly due to a huge set of new drivers some
of which are individually very large. We also have a lot of fixes for
the topology stuff, several of the users have stepped up and fixed some
the serious issues there, and continued progress on the transition away
from CODEC specific drivers to generic component drivers.
- Many fixes for the topology code, including fixes for the half done
v4 ABI compatibility from Guenter Roeck and other ABI fixes from
Kirill Marinushkin.
- Lots of cleanup for Intel platforms based on Realtek CODECs from Hans
de Goode.
- More followups on removing legacy CODEC things and transitioning to
components from Morimoto-san.
- Conversion of OMAP DMA to the new, more standard SDMA-PCM driver.
- A series of fixes and updates to the rather elderly Cirrus Logic SoC
drivers from Alexander Sverdlin.
- Qualcomm DSP support from Srinivas Kandagatla.
- New drivers for Analog SSM2305, Atmel I2S controllers, Mediatek
MT6351, MT6797 and MT7622, Qualcomm DSPs, Realtek RT1305, RT1306 and
RT5668 and TI TSCS454
Diffstat (limited to 'sound/soc/omap')
-rw-r--r-- | sound/soc/omap/Kconfig | 28 | ||||
-rw-r--r-- | sound/soc/omap/Makefile | 4 | ||||
-rw-r--r-- | sound/soc/omap/n810.c | 21 | ||||
-rw-r--r-- | sound/soc/omap/omap-dmic.c | 4 | ||||
-rw-r--r-- | sound/soc/omap/omap-hdmi-audio.c | 5 | ||||
-rw-r--r-- | sound/soc/omap/omap-mcbsp.c | 4 | ||||
-rw-r--r-- | sound/soc/omap/omap-mcpdm.c | 4 | ||||
-rw-r--r-- | sound/soc/omap/omap-pcm.c | 262 | ||||
-rw-r--r-- | sound/soc/omap/sdma-pcm.c | 74 | ||||
-rw-r--r-- | sound/soc/omap/sdma-pcm.h | 21 |
10 files changed, 136 insertions, 291 deletions
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index f5451c78ede5..6dccea6fdaeb 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig @@ -1,7 +1,12 @@ config SND_OMAP_SOC - tristate "SoC Audio for the Texas Instruments OMAP chips" + tristate "SoC Audio for Texas Instruments OMAP chips (deprecated)" depends on (ARCH_OMAP && DMA_OMAP) || (ARM && COMPILE_TEST) - select SND_DMAENGINE_PCM + select SND_SDMA_SOC + +config SND_SDMA_SOC + tristate "SoC Audio for Texas Instruments chips using sDMA" + depends on DMA_OMAP || COMPILE_TEST + select SND_SOC_GENERIC_DMAENGINE_PCM config SND_OMAP_SOC_DMIC tristate @@ -14,7 +19,7 @@ config SND_OMAP_SOC_MCPDM config SND_OMAP_SOC_HDMI_AUDIO tristate "HDMI audio support for OMAP4+ based SoCs" - depends on SND_OMAP_SOC + depends on SND_SDMA_SOC help For HDMI audio to work OMAPDSS HDMI support should be enabled. @@ -29,8 +34,7 @@ config SND_OMAP_SOC_HDMI_AUDIO config SND_OMAP_SOC_N810 tristate "SoC Audio support for Nokia N810" - depends on SND_OMAP_SOC && MACH_NOKIA_N810 && I2C - depends on OMAP_MUX + depends on SND_SDMA_SOC && MACH_NOKIA_N810 && I2C select SND_OMAP_SOC_MCBSP select SND_SOC_TLV320AIC3X help @@ -38,7 +42,7 @@ config SND_OMAP_SOC_N810 config SND_OMAP_SOC_RX51 tristate "SoC Audio support for Nokia N900 (RX-51)" - depends on SND_OMAP_SOC && ARM && I2C + depends on SND_SDMA_SOC && ARM && I2C select SND_OMAP_SOC_MCBSP select SND_SOC_TLV320AIC3X select SND_SOC_TPA6130A2 @@ -49,7 +53,7 @@ config SND_OMAP_SOC_RX51 config SND_OMAP_SOC_AMS_DELTA tristate "SoC Audio support for Amstrad E3 (Delta) videophone" - depends on SND_OMAP_SOC && MACH_AMS_DELTA && TTY + depends on SND_SDMA_SOC && MACH_AMS_DELTA && TTY select SND_OMAP_SOC_MCBSP select SND_SOC_CX20442 help @@ -68,7 +72,7 @@ config SND_OMAP_SOC_AMS_DELTA config SND_OMAP_SOC_OSK5912 tristate "SoC Audio support for omap osk5912" - depends on SND_OMAP_SOC && MACH_OMAP_OSK && I2C + depends on SND_SDMA_SOC && MACH_OMAP_OSK && I2C select SND_OMAP_SOC_MCBSP select SND_SOC_TLV320AIC23_I2C help @@ -76,7 +80,7 @@ config SND_OMAP_SOC_OSK5912 config SND_OMAP_SOC_AM3517EVM tristate "SoC Audio support for OMAP3517 / AM3517 EVM" - depends on SND_OMAP_SOC && MACH_OMAP3517EVM && I2C + depends on SND_SDMA_SOC && MACH_OMAP3517EVM && I2C select SND_OMAP_SOC_MCBSP select SND_SOC_TLV320AIC23_I2C help @@ -85,7 +89,7 @@ config SND_OMAP_SOC_AM3517EVM config SND_OMAP_SOC_OMAP_TWL4030 tristate "SoC Audio support for TI SoC based boards with twl4030 codec" - depends on TWL4030_CORE && SND_OMAP_SOC + depends on TWL4030_CORE && SND_SDMA_SOC select SND_OMAP_SOC_MCBSP select SND_SOC_TWL4030 help @@ -100,7 +104,7 @@ config SND_OMAP_SOC_OMAP_TWL4030 config SND_OMAP_SOC_OMAP_ABE_TWL6040 tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec" - depends on TWL6040_CORE && SND_OMAP_SOC && COMMON_CLK + depends on TWL6040_CORE && SND_SDMA_SOC && COMMON_CLK depends on ARCH_OMAP4 || (SOC_OMAP5 && MFD_PALMAS) || COMPILE_TEST select SND_OMAP_SOC_DMIC select SND_OMAP_SOC_MCPDM @@ -118,7 +122,7 @@ config SND_OMAP_SOC_OMAP_ABE_TWL6040 config SND_OMAP_SOC_OMAP3_PANDORA tristate "SoC Audio support for OMAP3 Pandora" - depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3_PANDORA + depends on TWL4030_CORE && SND_SDMA_SOC && MACH_OMAP3_PANDORA select SND_OMAP_SOC_MCBSP select SND_SOC_TWL4030 help diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile index a6785dc4fc90..53eba3413485 100644 --- a/sound/soc/omap/Makefile +++ b/sound/soc/omap/Makefile @@ -1,12 +1,12 @@ # SPDX-License-Identifier: GPL-2.0 # OMAP Platform Support -snd-soc-omap-objs := omap-pcm.o +snd-soc-sdma-objs := sdma-pcm.o snd-soc-omap-dmic-objs := omap-dmic.o snd-soc-omap-mcbsp-objs := omap-mcbsp.o mcbsp.o snd-soc-omap-mcpdm-objs := omap-mcpdm.o snd-soc-omap-hdmi-audio-objs := omap-hdmi-audio.o -obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o +obj-$(CONFIG_SND_SDMA_SOC) += snd-soc-sdma.o obj-$(CONFIG_SND_OMAP_SOC_DMIC) += snd-soc-omap-dmic.o obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o obj-$(CONFIG_SND_OMAP_SOC_MCPDM) += snd-soc-omap-mcpdm.o diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index 71e5f31fa306..9cfefe44a75f 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c @@ -80,9 +80,9 @@ static void n810_ext_control(struct snd_soc_dapm_context *dapm) else snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack"); if (line1l) - snd_soc_dapm_enable_pin_unlocked(dapm, "LINE1L"); + snd_soc_dapm_enable_pin_unlocked(dapm, "HS Mic"); else - snd_soc_dapm_disable_pin_unlocked(dapm, "LINE1L"); + snd_soc_dapm_disable_pin_unlocked(dapm, "HS Mic"); if (n810_dmic_func) snd_soc_dapm_enable_pin_unlocked(dapm, "DMic"); @@ -222,6 +222,7 @@ static const struct snd_soc_dapm_widget aic33_dapm_widgets[] = { SND_SOC_DAPM_SPK("Ext Spk", n810_spk_event), SND_SOC_DAPM_HP("Headphone Jack", n810_jack_event), SND_SOC_DAPM_MIC("DMic", NULL), + SND_SOC_DAPM_MIC("HS Mic", NULL), }; static const struct snd_soc_dapm_route audio_map[] = { @@ -231,8 +232,14 @@ static const struct snd_soc_dapm_route audio_map[] = { {"Ext Spk", NULL, "LLOUT"}, {"Ext Spk", NULL, "RLOUT"}, - {"DMic Rate 64", NULL, "Mic Bias"}, - {"Mic Bias", NULL, "DMic"}, + {"DMic Rate 64", NULL, "DMic"}, + {"DMic", NULL, "Mic Bias"}, + + /* + * Note that the mic bias is coming from Retu/Vilma and we don't have + * control over it atm. The analog HS mic is not working. <- TODO + */ + {"LINE1L", NULL, "HS Mic"}, }; static const char *spk_function[] = {"Off", "On"}; @@ -257,9 +264,9 @@ static const struct snd_kcontrol_new aic33_n810_controls[] = { static struct snd_soc_dai_link n810_dai = { .name = "TLV320AIC33", .stream_name = "AIC33", - .cpu_dai_name = "omap-mcbsp.2", - .platform_name = "omap-mcbsp.2", - .codec_name = "tlv320aic3x-codec.2-0018", + .cpu_dai_name = "48076000.mcbsp", + .platform_name = "48076000.mcbsp", + .codec_name = "tlv320aic3x-codec.1-0018", .codec_dai_name = "tlv320aic3x-hifi", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM, diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index b2f5d2fa354d..51dd7c65096b 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c @@ -40,9 +40,9 @@ #include <sound/initval.h> #include <sound/soc.h> #include <sound/dmaengine_pcm.h> -#include <sound/omap-pcm.h> #include "omap-dmic.h" +#include "sdma-pcm.h" struct omap_dmic { struct device *dev; @@ -501,7 +501,7 @@ static int asoc_dmic_probe(struct platform_device *pdev) if (ret) return ret; - ret = omap_pcm_platform_register(&pdev->dev); + ret = sdma_pcm_platform_register(&pdev->dev, NULL, "up_link"); if (ret) return ret; diff --git a/sound/soc/omap/omap-hdmi-audio.c b/sound/soc/omap/omap-hdmi-audio.c index 8eeac7cab1c1..8a99a8837dc9 100644 --- a/sound/soc/omap/omap-hdmi-audio.c +++ b/sound/soc/omap/omap-hdmi-audio.c @@ -26,9 +26,10 @@ #include <sound/dmaengine_pcm.h> #include <uapi/sound/asound.h> #include <sound/asoundef.h> -#include <sound/omap-pcm.h> #include <sound/omap-hdmi-audio.h> +#include "sdma-pcm.h" + #define DRV_NAME "omap-hdmi-audio" struct hdmi_audio_data { @@ -352,7 +353,7 @@ static int omap_hdmi_audio_probe(struct platform_device *pdev) if (ret) return ret; - ret = omap_pcm_platform_register(ad->dssdev); + ret = sdma_pcm_platform_register(ad->dssdev, "audio_tx", NULL); if (ret) return ret; diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 6b40bdbef336..d0ebb6b9bfac 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -34,11 +34,11 @@ #include <sound/initval.h> #include <sound/soc.h> #include <sound/dmaengine_pcm.h> -#include <sound/omap-pcm.h> #include <linux/platform_data/asoc-ti-mcbsp.h> #include "mcbsp.h" #include "omap-mcbsp.h" +#include "sdma-pcm.h" #define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000) @@ -868,7 +868,7 @@ static int asoc_mcbsp_probe(struct platform_device *pdev) if (ret) return ret; - return omap_pcm_platform_register(&pdev->dev); + return sdma_pcm_platform_register(&pdev->dev, NULL, NULL); } static int asoc_mcbsp_remove(struct platform_device *pdev) diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 64609c77a79d..0e97360f9890 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -40,9 +40,9 @@ #include <sound/pcm_params.h> #include <sound/soc.h> #include <sound/dmaengine_pcm.h> -#include <sound/omap-pcm.h> #include "omap-mcpdm.h" +#include "sdma-pcm.h" struct mcpdm_link_config { u32 link_mask; /* channel mask for the direction */ @@ -548,7 +548,7 @@ static int asoc_mcpdm_probe(struct platform_device *pdev) if (ret) return ret; - return omap_pcm_platform_register(&pdev->dev); + return sdma_pcm_platform_register(&pdev->dev, "dn_link", "up_link"); } static const struct of_device_id omap_mcpdm_of_match[] = { diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c deleted file mode 100644 index 778cc8f75b6a..000000000000 --- a/sound/soc/omap/omap-pcm.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * omap-pcm.c -- ALSA PCM interface for the OMAP SoC - * - * Copyright (C) 2008 Nokia Corporation - * - * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com> - * Peter Ujfalusi <peter.ujfalusi@ti.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 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 - * - */ - -#include <linux/dma-mapping.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/omap-dma.h> -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/dmaengine_pcm.h> -#include <sound/soc.h> -#include <sound/omap-pcm.h> - -#ifdef CONFIG_ARCH_OMAP1 -#define pcm_omap1510() cpu_is_omap1510() -#else -#define pcm_omap1510() 0 -#endif - -static struct snd_pcm_hardware omap_pcm_hardware = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_RESUME | - SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, - .period_bytes_min = 32, - .period_bytes_max = 64 * 1024, - .periods_min = 2, - .periods_max = 255, - .buffer_bytes_max = 128 * 1024, -}; - -/* sDMA supports only 1, 2, and 4 byte transfer elements. */ -static void omap_pcm_limit_supported_formats(void) -{ - int i; - - for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) { - switch (snd_pcm_format_physical_width(i)) { - case 8: - case 16: - case 32: - omap_pcm_hardware.formats |= (1LL << i); - break; - default: - break; - } - } -} - -/* this may get called several times by oss emulation */ -static int omap_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct omap_pcm_dma_data *dma_data; - struct dma_slave_config config; - struct dma_chan *chan; - int err = 0; - - memset(&config, 0x00, sizeof(config)); - - dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - - /* return if this is a bufferless transfer e.g. - * codec <--> BT codec or GSM modem -- lg FIXME */ - if (!dma_data) - return 0; - - snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); - runtime->dma_bytes = params_buffer_bytes(params); - - chan = snd_dmaengine_pcm_get_chan(substream); - if (!chan) - return -EINVAL; - - /* fills in addr_width and direction */ - err = snd_hwparams_to_dma_slave_config(substream, params, &config); - if (err) - return err; - - snd_dmaengine_pcm_set_config_from_dai_data(substream, - snd_soc_dai_get_dma_data(rtd->cpu_dai, substream), - &config); - - return dmaengine_slave_config(chan, &config); -} - -static int omap_pcm_hw_free(struct snd_pcm_substream *substream) -{ - snd_pcm_set_runtime_buffer(substream, NULL); - return 0; -} - -static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream) -{ - snd_pcm_uframes_t offset; - - if (pcm_omap1510()) - offset = snd_dmaengine_pcm_pointer_no_residue(substream); - else - offset = snd_dmaengine_pcm_pointer(substream); - - return offset; -} - -static int omap_pcm_open(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_dmaengine_dai_dma_data *dma_data; - int ret; - - snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware); - - dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - - /* DT boot: filter_data is the DMA name */ - if (rtd->cpu_dai->dev->of_node) { - struct dma_chan *chan; - - chan = dma_request_slave_channel(rtd->cpu_dai->dev, - dma_data->filter_data); - ret = snd_dmaengine_pcm_open(substream, chan); - } else { - ret = snd_dmaengine_pcm_open_request_chan(substream, - omap_dma_filter_fn, - dma_data->filter_data); - } - return ret; -} - -static int omap_pcm_mmap(struct snd_pcm_substream *substream, - struct vm_area_struct *vma) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - return dma_mmap_wc(substream->pcm->card->dev, vma, runtime->dma_area, - runtime->dma_addr, runtime->dma_bytes); -} - -static const struct snd_pcm_ops omap_pcm_ops = { - .open = omap_pcm_open, - .close = snd_dmaengine_pcm_close_release_chan, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = omap_pcm_hw_params, - .hw_free = omap_pcm_hw_free, - .trigger = snd_dmaengine_pcm_trigger, - .pointer = omap_pcm_pointer, - .mmap = omap_pcm_mmap, -}; - -static int omap_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, - int stream) -{ - struct snd_pcm_substream *substream = pcm->streams[stream].substream; - struct snd_dma_buffer *buf = &substream->dma_buffer; - size_t size = omap_pcm_hardware.buffer_bytes_max; - - buf->dev.type = SNDRV_DMA_TYPE_DEV; - buf->dev.dev = pcm->card->dev; - buf->private_data = NULL; - buf->area = dma_alloc_wc(pcm->card->dev, size, &buf->addr, GFP_KERNEL); - if (!buf->area) - return -ENOMEM; - - buf->bytes = size; - return 0; -} - -static void omap_pcm_free_dma_buffers(struct snd_pcm *pcm) -{ - struct snd_pcm_substream *substream; - struct snd_dma_buffer *buf; - int stream; - - for (stream = 0; stream < 2; stream++) { - substream = pcm->streams[stream].substream; - if (!substream) - continue; - - buf = &substream->dma_buffer; - if (!buf->area) - continue; - - dma_free_wc(pcm->card->dev, buf->bytes, buf->area, buf->addr); - buf->area = NULL; - } -} - -static int omap_pcm_new(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_card *card = rtd->card->snd_card; - struct snd_pcm *pcm = rtd->pcm; - int ret; - - ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32)); - if (ret) - return ret; - - if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { - ret = omap_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_PLAYBACK); - if (ret) - goto out; - } - - if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { - ret = omap_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_CAPTURE); - if (ret) - goto out; - } - -out: - /* free preallocated buffers in case of error */ - if (ret) - omap_pcm_free_dma_buffers(pcm); - - return ret; -} - -static const struct snd_soc_component_driver omap_soc_component = { - .ops = &omap_pcm_ops, - .pcm_new = omap_pcm_new, - .pcm_free = omap_pcm_free_dma_buffers, -}; - -int omap_pcm_platform_register(struct device *dev) -{ - omap_pcm_limit_supported_formats(); - return devm_snd_soc_register_component(dev, &omap_soc_component, - NULL, 0); -} -EXPORT_SYMBOL_GPL(omap_pcm_platform_register); - -MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>"); -MODULE_DESCRIPTION("OMAP PCM DMA module"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/omap/sdma-pcm.c b/sound/soc/omap/sdma-pcm.c new file mode 100644 index 000000000000..21a9c2499d48 --- /dev/null +++ b/sound/soc/omap/sdma-pcm.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com + * Author: Peter Ujfalusi <peter.ujfalusi@ti.com> + */ + +#include <linux/device.h> +#include <linux/module.h> +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> +#include <sound/dmaengine_pcm.h> +#include <linux/omap-dmaengine.h> + +#include "sdma-pcm.h" + +static const struct snd_pcm_hardware sdma_pcm_hardware = { + .info = SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP | + SNDRV_PCM_INFO_INTERLEAVED, + .period_bytes_min = 32, + .period_bytes_max = 64 * 1024, + .buffer_bytes_max = 128 * 1024, + .periods_min = 2, + .periods_max = 255, +}; + +static const struct snd_dmaengine_pcm_config sdma_dmaengine_pcm_config = { + .pcm_hardware = &sdma_pcm_hardware, + .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, + .compat_filter_fn = omap_dma_filter_fn, + .prealloc_buffer_size = 128 * 1024, +}; + +int sdma_pcm_platform_register(struct device *dev, + char *txdmachan, char *rxdmachan) +{ + struct snd_dmaengine_pcm_config *config; + unsigned int flags = SND_DMAENGINE_PCM_FLAG_COMPAT; + + /* Standard names for the directions: 'tx' and 'rx' */ + if (!txdmachan && !rxdmachan) + return devm_snd_dmaengine_pcm_register(dev, + &sdma_dmaengine_pcm_config, + flags); + + config = devm_kzalloc(dev, sizeof(*config), GFP_KERNEL); + if (!config) + return -ENOMEM; + + *config = sdma_dmaengine_pcm_config; + + if (!txdmachan || !rxdmachan) { + /* One direction only PCM */ + flags |= SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX; + if (!txdmachan) { + txdmachan = rxdmachan; + rxdmachan = NULL; + } + } + + config->chan_names[0] = txdmachan; + config->chan_names[1] = rxdmachan; + + return devm_snd_dmaengine_pcm_register(dev, config, flags); +} +EXPORT_SYMBOL_GPL(sdma_pcm_platform_register); + +MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); +MODULE_DESCRIPTION("sDMA PCM ASoC platform driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/omap/sdma-pcm.h b/sound/soc/omap/sdma-pcm.h new file mode 100644 index 000000000000..34a7f90b2587 --- /dev/null +++ b/sound/soc/omap/sdma-pcm.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com + * Author: Peter Ujfalusi <peter.ujfalusi@ti.com> + */ + +#ifndef __SDMA_PCM_H__ +#define __SDMA_PCM_H__ + +#if IS_ENABLED(CONFIG_SND_SDMA_SOC) +int sdma_pcm_platform_register(struct device *dev, + char *txdmachan, char *rxdmachan); +#else +static inline int sdma_pcm_platform_register(struct device *dev, + char *txdmachan, char *rxdmachan) +{ + return -ENODEV; +} +#endif /* CONFIG_SND_SDMA_SOC */ + +#endif /* __SDMA_PCM_H__ */ |