diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-03 12:10:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-03 12:10:23 -0400 |
commit | 9992ba72327fa0d8bdc9fb624e80f5cce338a711 (patch) | |
tree | e0bf31ae53cb19c44674df7e0d0343a26037ad34 /sound/soc/ux500 | |
parent | 00fdffb5131125dce0702bf61e24a806ec3aed80 (diff) | |
parent | 4ca231b2e6ed171107c5b21f9e92d1965fd6fd9e (diff) |
Merge tag 'sound-3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai:
"Mostly many small changes spread as seen in diffstat in sound/*
directory by this update. A significant change in the subsystem level
is the introduction of snd_soc_component, which will help more generic
handling of SoC and off-SoC components.
Also, snd_BUG_ON() macro is enabled unconditionally now due to its
misuses, so people might hit kernel warnings (it's a good thing for
us).
- compress-offload: support for capture by Charles Keepax
- HD-audio: codec delay support by Dylan Reid
- HD-audio: improvements/fixes in generic parser: better headphone
mic and headset mic support, jack_modes hint consolidation, proper
beep attach/detachment, generalized power filter controls by David
Henningsson, et al
- HD-audio: Improved management of HDMI codec pins/converters
- HD-audio: Better pin/DAC assignment for VIA codecs
- HD-audio: Haswell HDMI workarounds
- HD-audio: ALC268 codec support, a few new quirks for Chromebooks
- USB: regression fixes: USB-MIDI autopm fix, the recent ISO latency
fix by Clemens Ladisch
- USB: support for DSD formats by Daniel Mack
- USB: A few UAC2 device endian/cock fixes by Eldad Zack
- USB: quirks for Emu 192kHz support, Novation Twitch DJ controller,
Yamaha THRxx devices
- HDSPM: updates for TCO controls by Adrian Knoth
- ASoC: Add a snd_soc_component object type for generic handling of
SoC and off-SoC components by Kuninori Morimoto,
- dmaengine: a large set of cleanups and conversions by Lars-Peter
Clausen
- ASoC DAPM: performance optimizations from Ryo Tsutsui
- ASoC DAPM: support for mixer control sharing by Stephen Warren
- ASoC: multiplatform ARM cleanups from Arnd Bergmann
- ASoC: new codec drivers for AK5385 and TAS5086 from Daniel Mack"
* tag 'sound-3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (315 commits)
ALSA: usb-audio: caiaq: fix endianness bug in snd_usb_caiaq_maschine_dispatch
ALSA: asihpi: add format support check in snd_card_asihpi_capture_formats
ALSA: pcm_format_to_bits strong-typed conversion
ALSA: compress: fix the states to check for allowing read
ALSA: hda - Move Thinkpad X220 to use auto parser
ALSA: USB: adjust for changed 3.8 USB API
ALSA: usb - Avoid unnecessary sample rate changes on USB 2.0 clock sources
sound: oss/dmabuf: use dma_map_single
ALSA: ali5451: use mdelay instead of large udelay constants
ALSA: hda - Add the support for ALC286 codec
ALSA: usb-audio: USB quirk for Yamaha THR10C
ALSA: usb-audio: USB quirk for Yamaha THR5A
ALSA: usb-audio: USB quirk for Yamaha THR10
ALSA: usb-audio: Fix autopm error during probing
ALSA: snd-usb: try harder to find USB_DT_CS_ENDPOINT
ALSA: sound kconfig typo
ALSA: emu10k1: Fix dock firmware loading
ASoC: ux500: forward declare msp_i2s_platform_data
ASoC: davinci-mcasp: Add Support BCLK-to-LRCLK ratio for TDM modes
ASoC: davinci-pcm, davinci-mcasp: Clean up active_serializers
...
Diffstat (limited to 'sound/soc/ux500')
-rw-r--r-- | sound/soc/ux500/Kconfig | 2 | ||||
-rw-r--r-- | sound/soc/ux500/ux500_msp_dai.c | 13 | ||||
-rw-r--r-- | sound/soc/ux500/ux500_msp_dai.h | 5 | ||||
-rw-r--r-- | sound/soc/ux500/ux500_msp_i2s.h | 1 | ||||
-rw-r--r-- | sound/soc/ux500/ux500_pcm.c | 229 | ||||
-rw-r--r-- | sound/soc/ux500/ux500_pcm.h | 14 |
6 files changed, 41 insertions, 223 deletions
diff --git a/sound/soc/ux500/Kconfig b/sound/soc/ux500/Kconfig index 6b799c0e88df..aa5011894c74 100644 --- a/sound/soc/ux500/Kconfig +++ b/sound/soc/ux500/Kconfig | |||
@@ -16,7 +16,7 @@ config SND_SOC_UX500_PLAT_MSP_I2S | |||
16 | config SND_SOC_UX500_PLAT_DMA | 16 | config SND_SOC_UX500_PLAT_DMA |
17 | tristate "Platform - DB8500 (DMA)" | 17 | tristate "Platform - DB8500 (DMA)" |
18 | depends on SND_SOC_UX500 | 18 | depends on SND_SOC_UX500 |
19 | select SND_SOC_DMAENGINE_PCM | 19 | select SND_SOC_GENERIC_DMAENGINE_PCM |
20 | help | 20 | help |
21 | Say Y if you want to enable the Ux500 platform-driver. | 21 | Say Y if you want to enable the Ux500 platform-driver. |
22 | 22 | ||
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index 54028cf76511..7d5fc1328523 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c | |||
@@ -766,6 +766,11 @@ static struct snd_soc_dai_driver ux500_msp_dai_drv[UX500_NBR_OF_DAI] = { | |||
766 | }, | 766 | }, |
767 | }; | 767 | }; |
768 | 768 | ||
769 | static const struct snd_soc_component_driver ux500_msp_component = { | ||
770 | .name = "ux500-msp", | ||
771 | }; | ||
772 | |||
773 | |||
769 | static int ux500_msp_drv_probe(struct platform_device *pdev) | 774 | static int ux500_msp_drv_probe(struct platform_device *pdev) |
770 | { | 775 | { |
771 | struct ux500_msp_i2s_drvdata *drvdata; | 776 | struct ux500_msp_i2s_drvdata *drvdata; |
@@ -823,8 +828,8 @@ static int ux500_msp_drv_probe(struct platform_device *pdev) | |||
823 | } | 828 | } |
824 | dev_set_drvdata(&pdev->dev, drvdata); | 829 | dev_set_drvdata(&pdev->dev, drvdata); |
825 | 830 | ||
826 | ret = snd_soc_register_dai(&pdev->dev, | 831 | ret = snd_soc_register_component(&pdev->dev, &ux500_msp_component, |
827 | &ux500_msp_dai_drv[drvdata->msp->id]); | 832 | &ux500_msp_dai_drv[drvdata->msp->id], 1); |
828 | if (ret < 0) { | 833 | if (ret < 0) { |
829 | dev_err(&pdev->dev, "Error: %s: Failed to register MSP%d!\n", | 834 | dev_err(&pdev->dev, "Error: %s: Failed to register MSP%d!\n", |
830 | __func__, drvdata->msp->id); | 835 | __func__, drvdata->msp->id); |
@@ -842,7 +847,7 @@ static int ux500_msp_drv_probe(struct platform_device *pdev) | |||
842 | return 0; | 847 | return 0; |
843 | 848 | ||
844 | err_reg_plat: | 849 | err_reg_plat: |
845 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv)); | 850 | snd_soc_unregister_component(&pdev->dev); |
846 | err_init_msp: | 851 | err_init_msp: |
847 | clk_put(drvdata->clk); | 852 | clk_put(drvdata->clk); |
848 | err_clk: | 853 | err_clk: |
@@ -859,7 +864,7 @@ static int ux500_msp_drv_remove(struct platform_device *pdev) | |||
859 | 864 | ||
860 | ux500_pcm_unregister_platform(pdev); | 865 | ux500_pcm_unregister_platform(pdev); |
861 | 866 | ||
862 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv)); | 867 | snd_soc_unregister_component(&pdev->dev); |
863 | 868 | ||
864 | devm_regulator_put(drvdata->reg_vape); | 869 | devm_regulator_put(drvdata->reg_vape); |
865 | prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, "ux500_msp_i2s"); | 870 | prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, "ux500_msp_i2s"); |
diff --git a/sound/soc/ux500/ux500_msp_dai.h b/sound/soc/ux500/ux500_msp_dai.h index 9c778d9c3838..f53104359f15 100644 --- a/sound/soc/ux500/ux500_msp_dai.h +++ b/sound/soc/ux500/ux500_msp_dai.h | |||
@@ -35,13 +35,8 @@ | |||
35 | #define FRAME_PER_8_SLOTS 138 | 35 | #define FRAME_PER_8_SLOTS 138 |
36 | #define FRAME_PER_16_SLOTS 277 | 36 | #define FRAME_PER_16_SLOTS 277 |
37 | 37 | ||
38 | #ifndef CONFIG_SND_SOC_UX500_AB5500 | ||
39 | #define UX500_MSP_INTERNAL_CLOCK_FREQ 40000000 | 38 | #define UX500_MSP_INTERNAL_CLOCK_FREQ 40000000 |
40 | #define UX500_MSP1_INTERNAL_CLOCK_FREQ UX500_MSP_INTERNAL_CLOCK_FREQ | 39 | #define UX500_MSP1_INTERNAL_CLOCK_FREQ UX500_MSP_INTERNAL_CLOCK_FREQ |
41 | #else | ||
42 | #define UX500_MSP_INTERNAL_CLOCK_FREQ 13000000 | ||
43 | #define UX500_MSP1_INTERNAL_CLOCK_FREQ (UX500_MSP_INTERNAL_CLOCK_FREQ * 2) | ||
44 | #endif | ||
45 | 40 | ||
46 | #define UX500_MSP_MIN_CHANNELS 1 | 41 | #define UX500_MSP_MIN_CHANNELS 1 |
47 | #define UX500_MSP_MAX_CHANNELS 8 | 42 | #define UX500_MSP_MAX_CHANNELS 8 |
diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h index 437f0c032c58..e5cd105c90f9 100644 --- a/sound/soc/ux500/ux500_msp_i2s.h +++ b/sound/soc/ux500/ux500_msp_i2s.h | |||
@@ -541,6 +541,7 @@ struct ux500_msp_dma_params { | |||
541 | struct stedma40_chan_cfg *dma_cfg; | 541 | struct stedma40_chan_cfg *dma_cfg; |
542 | }; | 542 | }; |
543 | 543 | ||
544 | struct msp_i2s_platform_data; | ||
544 | int ux500_msp_i2s_init_msp(struct platform_device *pdev, | 545 | int ux500_msp_i2s_init_msp(struct platform_device *pdev, |
545 | struct ux500_msp **msp_p, | 546 | struct ux500_msp **msp_p, |
546 | struct msp_i2s_platform_data *platform_data); | 547 | struct msp_i2s_platform_data *platform_data); |
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index 846fa82a58d0..b6e5ae277299 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c | |||
@@ -28,28 +28,19 @@ | |||
28 | #include "ux500_msp_i2s.h" | 28 | #include "ux500_msp_i2s.h" |
29 | #include "ux500_pcm.h" | 29 | #include "ux500_pcm.h" |
30 | 30 | ||
31 | static struct snd_pcm_hardware ux500_pcm_hw_playback = { | 31 | #define UX500_PLATFORM_MIN_RATE 8000 |
32 | .info = SNDRV_PCM_INFO_INTERLEAVED | | 32 | #define UX500_PLATFORM_MAX_RATE 48000 |
33 | SNDRV_PCM_INFO_MMAP | | 33 | |
34 | SNDRV_PCM_INFO_RESUME | | 34 | #define UX500_PLATFORM_MIN_CHANNELS 1 |
35 | SNDRV_PCM_INFO_PAUSE, | 35 | #define UX500_PLATFORM_MAX_CHANNELS 8 |
36 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | ||
37 | SNDRV_PCM_FMTBIT_U16_LE | | ||
38 | SNDRV_PCM_FMTBIT_S16_BE | | ||
39 | SNDRV_PCM_FMTBIT_U16_BE, | ||
40 | .rates = SNDRV_PCM_RATE_KNOT, | ||
41 | .rate_min = UX500_PLATFORM_MIN_RATE_PLAYBACK, | ||
42 | .rate_max = UX500_PLATFORM_MAX_RATE_PLAYBACK, | ||
43 | .channels_min = UX500_PLATFORM_MIN_CHANNELS, | ||
44 | .channels_max = UX500_PLATFORM_MAX_CHANNELS, | ||
45 | .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX, | ||
46 | .period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN, | ||
47 | .period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX, | ||
48 | .periods_min = UX500_PLATFORM_PERIODS_MIN, | ||
49 | .periods_max = UX500_PLATFORM_PERIODS_MAX, | ||
50 | }; | ||
51 | 36 | ||
52 | static struct snd_pcm_hardware ux500_pcm_hw_capture = { | 37 | #define UX500_PLATFORM_PERIODS_BYTES_MIN 128 |
38 | #define UX500_PLATFORM_PERIODS_BYTES_MAX (64 * PAGE_SIZE) | ||
39 | #define UX500_PLATFORM_PERIODS_MIN 2 | ||
40 | #define UX500_PLATFORM_PERIODS_MAX 48 | ||
41 | #define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE) | ||
42 | |||
43 | static const struct snd_pcm_hardware ux500_pcm_hw = { | ||
53 | .info = SNDRV_PCM_INFO_INTERLEAVED | | 44 | .info = SNDRV_PCM_INFO_INTERLEAVED | |
54 | SNDRV_PCM_INFO_MMAP | | 45 | SNDRV_PCM_INFO_MMAP | |
55 | SNDRV_PCM_INFO_RESUME | | 46 | SNDRV_PCM_INFO_RESUME | |
@@ -59,8 +50,8 @@ static struct snd_pcm_hardware ux500_pcm_hw_capture = { | |||
59 | SNDRV_PCM_FMTBIT_S16_BE | | 50 | SNDRV_PCM_FMTBIT_S16_BE | |
60 | SNDRV_PCM_FMTBIT_U16_BE, | 51 | SNDRV_PCM_FMTBIT_U16_BE, |
61 | .rates = SNDRV_PCM_RATE_KNOT, | 52 | .rates = SNDRV_PCM_RATE_KNOT, |
62 | .rate_min = UX500_PLATFORM_MIN_RATE_CAPTURE, | 53 | .rate_min = UX500_PLATFORM_MIN_RATE, |
63 | .rate_max = UX500_PLATFORM_MAX_RATE_CAPTURE, | 54 | .rate_max = UX500_PLATFORM_MAX_RATE, |
64 | .channels_min = UX500_PLATFORM_MIN_CHANNELS, | 55 | .channels_min = UX500_PLATFORM_MIN_CHANNELS, |
65 | .channels_max = UX500_PLATFORM_MAX_CHANNELS, | 56 | .channels_max = UX500_PLATFORM_MAX_CHANNELS, |
66 | .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX, | 57 | .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX, |
@@ -70,64 +61,23 @@ static struct snd_pcm_hardware ux500_pcm_hw_capture = { | |||
70 | .periods_max = UX500_PLATFORM_PERIODS_MAX, | 61 | .periods_max = UX500_PLATFORM_PERIODS_MAX, |
71 | }; | 62 | }; |
72 | 63 | ||
73 | static void ux500_pcm_dma_hw_free(struct device *dev, | 64 | static struct dma_chan *ux500_pcm_request_chan(struct snd_soc_pcm_runtime *rtd, |
74 | struct snd_pcm_substream *substream) | 65 | struct snd_pcm_substream *substream) |
75 | { | 66 | { |
76 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
77 | struct snd_dma_buffer *buf = runtime->dma_buffer_p; | ||
78 | |||
79 | if (runtime->dma_area == NULL) | ||
80 | return; | ||
81 | |||
82 | if (buf != &substream->dma_buffer) { | ||
83 | dma_free_coherent(buf->dev.dev, buf->bytes, buf->area, | ||
84 | buf->addr); | ||
85 | kfree(runtime->dma_buffer_p); | ||
86 | } | ||
87 | |||
88 | snd_pcm_set_runtime_buffer(substream, NULL); | ||
89 | } | ||
90 | |||
91 | static int ux500_pcm_open(struct snd_pcm_substream *substream) | ||
92 | { | ||
93 | int stream_id = substream->pstr->stream; | ||
94 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
95 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
96 | struct snd_soc_dai *dai = rtd->cpu_dai; | 67 | struct snd_soc_dai *dai = rtd->cpu_dai; |
97 | struct device *dev = dai->dev; | 68 | struct device *dev = dai->dev; |
98 | int ret; | ||
99 | struct ux500_msp_dma_params *dma_params; | ||
100 | u16 per_data_width, mem_data_width; | 69 | u16 per_data_width, mem_data_width; |
101 | struct stedma40_chan_cfg *dma_cfg; | 70 | struct stedma40_chan_cfg *dma_cfg; |
71 | struct ux500_msp_dma_params *dma_params; | ||
102 | 72 | ||
103 | dev_dbg(dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id, | 73 | dev_dbg(dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id, |
104 | snd_pcm_stream_str(substream)); | 74 | snd_pcm_stream_str(substream)); |
105 | 75 | ||
106 | dev_dbg(dev, "%s: Set runtime hwparams.\n", __func__); | 76 | dma_params = snd_soc_dai_get_dma_data(dai, substream); |
107 | if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) | 77 | dma_cfg = dma_params->dma_cfg; |
108 | snd_soc_set_runtime_hwparams(substream, | ||
109 | &ux500_pcm_hw_playback); | ||
110 | else | ||
111 | snd_soc_set_runtime_hwparams(substream, | ||
112 | &ux500_pcm_hw_capture); | ||
113 | |||
114 | /* ensure that buffer size is a multiple of period size */ | ||
115 | ret = snd_pcm_hw_constraint_integer(runtime, | ||
116 | SNDRV_PCM_HW_PARAM_PERIODS); | ||
117 | if (ret < 0) { | ||
118 | dev_err(dev, "%s: Error: snd_pcm_hw_constraints failed (%d)\n", | ||
119 | __func__, ret); | ||
120 | return ret; | ||
121 | } | ||
122 | |||
123 | dev_dbg(dev, "%s: Set hw-struct for %s.\n", __func__, | ||
124 | snd_pcm_stream_str(substream)); | ||
125 | runtime->hw = (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ? | ||
126 | ux500_pcm_hw_playback : ux500_pcm_hw_capture; | ||
127 | 78 | ||
128 | mem_data_width = STEDMA40_HALFWORD_WIDTH; | 79 | mem_data_width = STEDMA40_HALFWORD_WIDTH; |
129 | 80 | ||
130 | dma_params = snd_soc_dai_get_dma_data(dai, substream); | ||
131 | switch (dma_params->data_size) { | 81 | switch (dma_params->data_size) { |
132 | case 32: | 82 | case 32: |
133 | per_data_width = STEDMA40_WORD_WIDTH; | 83 | per_data_width = STEDMA40_WORD_WIDTH; |
@@ -140,13 +90,8 @@ static int ux500_pcm_open(struct snd_pcm_substream *substream) | |||
140 | break; | 90 | break; |
141 | default: | 91 | default: |
142 | per_data_width = STEDMA40_WORD_WIDTH; | 92 | per_data_width = STEDMA40_WORD_WIDTH; |
143 | dev_warn(rtd->platform->dev, | ||
144 | "%s: Unknown data-size (%d)! Assuming 32 bits.\n", | ||
145 | __func__, dma_params->data_size); | ||
146 | } | 93 | } |
147 | 94 | ||
148 | dma_cfg = dma_params->dma_cfg; | ||
149 | |||
150 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 95 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
151 | dma_cfg->src_info.data_width = mem_data_width; | 96 | dma_cfg->src_info.data_width = mem_data_width; |
152 | dma_cfg->dst_info.data_width = per_data_width; | 97 | dma_cfg->dst_info.data_width = per_data_width; |
@@ -155,137 +100,24 @@ static int ux500_pcm_open(struct snd_pcm_substream *substream) | |||
155 | dma_cfg->dst_info.data_width = mem_data_width; | 100 | dma_cfg->dst_info.data_width = mem_data_width; |
156 | } | 101 | } |
157 | 102 | ||
158 | 103 | return snd_dmaengine_pcm_request_channel(stedma40_filter, dma_cfg); | |
159 | ret = snd_dmaengine_pcm_open(substream, stedma40_filter, dma_cfg); | ||
160 | if (ret) { | ||
161 | dev_dbg(dai->dev, | ||
162 | "%s: ERROR: snd_dmaengine_pcm_open failed (%d)!\n", | ||
163 | __func__, ret); | ||
164 | return ret; | ||
165 | } | ||
166 | |||
167 | snd_dmaengine_pcm_set_data(substream, dma_cfg); | ||
168 | |||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | static int ux500_pcm_close(struct snd_pcm_substream *substream) | ||
173 | { | ||
174 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
175 | struct snd_soc_dai *dai = rtd->cpu_dai; | ||
176 | |||
177 | dev_dbg(dai->dev, "%s: Enter\n", __func__); | ||
178 | |||
179 | snd_dmaengine_pcm_close(substream); | ||
180 | |||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | static int ux500_pcm_hw_params(struct snd_pcm_substream *substream, | ||
185 | struct snd_pcm_hw_params *hw_params) | ||
186 | { | ||
187 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
188 | struct snd_dma_buffer *buf = runtime->dma_buffer_p; | ||
189 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
190 | int ret = 0; | ||
191 | int size; | ||
192 | |||
193 | dev_dbg(rtd->platform->dev, "%s: Enter\n", __func__); | ||
194 | |||
195 | size = params_buffer_bytes(hw_params); | ||
196 | |||
197 | if (buf) { | ||
198 | if (buf->bytes >= size) | ||
199 | goto out; | ||
200 | ux500_pcm_dma_hw_free(NULL, substream); | ||
201 | } | ||
202 | |||
203 | if (substream->dma_buffer.area != NULL && | ||
204 | substream->dma_buffer.bytes >= size) { | ||
205 | buf = &substream->dma_buffer; | ||
206 | } else { | ||
207 | buf = kmalloc(sizeof(struct snd_dma_buffer), GFP_KERNEL); | ||
208 | if (!buf) | ||
209 | goto nomem; | ||
210 | |||
211 | buf->dev.type = SNDRV_DMA_TYPE_DEV; | ||
212 | buf->dev.dev = NULL; | ||
213 | buf->area = dma_alloc_coherent(NULL, size, &buf->addr, | ||
214 | GFP_KERNEL); | ||
215 | buf->bytes = size; | ||
216 | buf->private_data = NULL; | ||
217 | |||
218 | if (!buf->area) | ||
219 | goto free; | ||
220 | } | ||
221 | snd_pcm_set_runtime_buffer(substream, buf); | ||
222 | ret = 1; | ||
223 | out: | ||
224 | runtime->dma_bytes = size; | ||
225 | return ret; | ||
226 | |||
227 | free: | ||
228 | kfree(buf); | ||
229 | nomem: | ||
230 | return -ENOMEM; | ||
231 | } | 104 | } |
232 | 105 | ||
233 | static int ux500_pcm_hw_free(struct snd_pcm_substream *substream) | 106 | static const struct snd_dmaengine_pcm_config ux500_dmaengine_pcm_config = { |
234 | { | 107 | .pcm_hardware = &ux500_pcm_hw, |
235 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 108 | .compat_request_channel = ux500_pcm_request_chan, |
236 | 109 | .prealloc_buffer_size = 128 * 1024, | |
237 | dev_dbg(rtd->platform->dev, "%s: Enter\n", __func__); | ||
238 | |||
239 | ux500_pcm_dma_hw_free(NULL, substream); | ||
240 | |||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | static int ux500_pcm_mmap(struct snd_pcm_substream *substream, | ||
245 | struct vm_area_struct *vma) | ||
246 | { | ||
247 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
248 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
249 | |||
250 | dev_dbg(rtd->platform->dev, "%s: Enter.\n", __func__); | ||
251 | |||
252 | return dma_mmap_coherent(NULL, vma, runtime->dma_area, | ||
253 | runtime->dma_addr, runtime->dma_bytes); | ||
254 | } | ||
255 | |||
256 | static struct snd_pcm_ops ux500_pcm_ops = { | ||
257 | .open = ux500_pcm_open, | ||
258 | .close = ux500_pcm_close, | ||
259 | .ioctl = snd_pcm_lib_ioctl, | ||
260 | .hw_params = ux500_pcm_hw_params, | ||
261 | .hw_free = ux500_pcm_hw_free, | ||
262 | .trigger = snd_dmaengine_pcm_trigger, | ||
263 | .pointer = snd_dmaengine_pcm_pointer_no_residue, | ||
264 | .mmap = ux500_pcm_mmap | ||
265 | }; | ||
266 | |||
267 | int ux500_pcm_new(struct snd_soc_pcm_runtime *rtd) | ||
268 | { | ||
269 | struct snd_pcm *pcm = rtd->pcm; | ||
270 | |||
271 | dev_dbg(rtd->platform->dev, "%s: Enter (id = '%s').\n", __func__, | ||
272 | pcm->id); | ||
273 | |||
274 | pcm->info_flags = 0; | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | static struct snd_soc_platform_driver ux500_pcm_soc_drv = { | ||
280 | .ops = &ux500_pcm_ops, | ||
281 | .pcm_new = ux500_pcm_new, | ||
282 | }; | 110 | }; |
283 | 111 | ||
284 | int ux500_pcm_register_platform(struct platform_device *pdev) | 112 | int ux500_pcm_register_platform(struct platform_device *pdev) |
285 | { | 113 | { |
286 | int ret; | 114 | int ret; |
287 | 115 | ||
288 | ret = snd_soc_register_platform(&pdev->dev, &ux500_pcm_soc_drv); | 116 | ret = snd_dmaengine_pcm_register(&pdev->dev, |
117 | &ux500_dmaengine_pcm_config, | ||
118 | SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | | ||
119 | SND_DMAENGINE_PCM_FLAG_COMPAT | | ||
120 | SND_DMAENGINE_PCM_FLAG_NO_DT); | ||
289 | if (ret < 0) { | 121 | if (ret < 0) { |
290 | dev_err(&pdev->dev, | 122 | dev_err(&pdev->dev, |
291 | "%s: ERROR: Failed to register platform '%s' (%d)!\n", | 123 | "%s: ERROR: Failed to register platform '%s' (%d)!\n", |
@@ -299,8 +131,7 @@ EXPORT_SYMBOL_GPL(ux500_pcm_register_platform); | |||
299 | 131 | ||
300 | int ux500_pcm_unregister_platform(struct platform_device *pdev) | 132 | int ux500_pcm_unregister_platform(struct platform_device *pdev) |
301 | { | 133 | { |
302 | snd_soc_unregister_platform(&pdev->dev); | 134 | snd_dmaengine_pcm_unregister(&pdev->dev); |
303 | |||
304 | return 0; | 135 | return 0; |
305 | } | 136 | } |
306 | EXPORT_SYMBOL_GPL(ux500_pcm_unregister_platform); | 137 | EXPORT_SYMBOL_GPL(ux500_pcm_unregister_platform); |
diff --git a/sound/soc/ux500/ux500_pcm.h b/sound/soc/ux500/ux500_pcm.h index 76d344476afc..d76e1aff6458 100644 --- a/sound/soc/ux500/ux500_pcm.h +++ b/sound/soc/ux500/ux500_pcm.h | |||
@@ -18,20 +18,6 @@ | |||
18 | 18 | ||
19 | #include <linux/workqueue.h> | 19 | #include <linux/workqueue.h> |
20 | 20 | ||
21 | #define UX500_PLATFORM_MIN_RATE_PLAYBACK 8000 | ||
22 | #define UX500_PLATFORM_MAX_RATE_PLAYBACK 48000 | ||
23 | #define UX500_PLATFORM_MIN_RATE_CAPTURE 8000 | ||
24 | #define UX500_PLATFORM_MAX_RATE_CAPTURE 48000 | ||
25 | |||
26 | #define UX500_PLATFORM_MIN_CHANNELS 1 | ||
27 | #define UX500_PLATFORM_MAX_CHANNELS 8 | ||
28 | |||
29 | #define UX500_PLATFORM_PERIODS_BYTES_MIN 128 | ||
30 | #define UX500_PLATFORM_PERIODS_BYTES_MAX (64 * PAGE_SIZE) | ||
31 | #define UX500_PLATFORM_PERIODS_MIN 2 | ||
32 | #define UX500_PLATFORM_PERIODS_MAX 48 | ||
33 | #define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE) | ||
34 | |||
35 | int ux500_pcm_register_platform(struct platform_device *pdev); | 21 | int ux500_pcm_register_platform(struct platform_device *pdev); |
36 | int ux500_pcm_unregister_platform(struct platform_device *pdev); | 22 | int ux500_pcm_unregister_platform(struct platform_device *pdev); |
37 | 23 | ||