| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Au1000/Au1500/Au1100 Audio DMA support. |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 173 | 174 | .fifo_size = 16, |
|---|
| 174 | 175 | }; |
|---|
| 175 | 176 | |
|---|
| 176 | | -static inline struct alchemy_pcm_ctx *ss_to_ctx(struct snd_pcm_substream *ss) |
|---|
| 177 | +static inline struct alchemy_pcm_ctx *ss_to_ctx(struct snd_pcm_substream *ss, |
|---|
| 178 | + struct snd_soc_component *component) |
|---|
| 177 | 179 | { |
|---|
| 178 | | - struct snd_soc_pcm_runtime *rtd = ss->private_data; |
|---|
| 179 | | - struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); |
|---|
| 180 | 180 | return snd_soc_component_get_drvdata(component); |
|---|
| 181 | 181 | } |
|---|
| 182 | 182 | |
|---|
| 183 | | -static inline struct audio_stream *ss_to_as(struct snd_pcm_substream *ss) |
|---|
| 183 | +static inline struct audio_stream *ss_to_as(struct snd_pcm_substream *ss, |
|---|
| 184 | + struct snd_soc_component *component) |
|---|
| 184 | 185 | { |
|---|
| 185 | | - struct alchemy_pcm_ctx *ctx = ss_to_ctx(ss); |
|---|
| 186 | + struct alchemy_pcm_ctx *ctx = ss_to_ctx(ss, component); |
|---|
| 186 | 187 | return &(ctx->stream[ss->stream]); |
|---|
| 187 | 188 | } |
|---|
| 188 | 189 | |
|---|
| 189 | | -static int alchemy_pcm_open(struct snd_pcm_substream *substream) |
|---|
| 190 | +static int alchemy_pcm_open(struct snd_soc_component *component, |
|---|
| 191 | + struct snd_pcm_substream *substream) |
|---|
| 190 | 192 | { |
|---|
| 191 | | - struct alchemy_pcm_ctx *ctx = ss_to_ctx(substream); |
|---|
| 192 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
|---|
| 193 | + struct alchemy_pcm_ctx *ctx = ss_to_ctx(substream, component); |
|---|
| 194 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
|---|
| 193 | 195 | int *dmaids, s = substream->stream; |
|---|
| 194 | 196 | char *name; |
|---|
| 195 | 197 | |
|---|
| 196 | | - dmaids = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); |
|---|
| 198 | + dmaids = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); |
|---|
| 197 | 199 | if (!dmaids) |
|---|
| 198 | 200 | return -ENODEV; /* whoa, has ordering changed? */ |
|---|
| 199 | 201 | |
|---|
| .. | .. |
|---|
| 212 | 214 | return 0; |
|---|
| 213 | 215 | } |
|---|
| 214 | 216 | |
|---|
| 215 | | -static int alchemy_pcm_close(struct snd_pcm_substream *substream) |
|---|
| 217 | +static int alchemy_pcm_close(struct snd_soc_component *component, |
|---|
| 218 | + struct snd_pcm_substream *substream) |
|---|
| 216 | 219 | { |
|---|
| 217 | | - struct alchemy_pcm_ctx *ctx = ss_to_ctx(substream); |
|---|
| 220 | + struct alchemy_pcm_ctx *ctx = ss_to_ctx(substream, component); |
|---|
| 218 | 221 | int stype = substream->stream; |
|---|
| 219 | 222 | |
|---|
| 220 | 223 | ctx->stream[stype].substream = NULL; |
|---|
| .. | .. |
|---|
| 223 | 226 | return 0; |
|---|
| 224 | 227 | } |
|---|
| 225 | 228 | |
|---|
| 226 | | -static int alchemy_pcm_hw_params(struct snd_pcm_substream *substream, |
|---|
| 229 | +static int alchemy_pcm_hw_params(struct snd_soc_component *component, |
|---|
| 230 | + struct snd_pcm_substream *substream, |
|---|
| 227 | 231 | struct snd_pcm_hw_params *hw_params) |
|---|
| 228 | 232 | { |
|---|
| 229 | | - struct audio_stream *stream = ss_to_as(substream); |
|---|
| 230 | | - int err; |
|---|
| 233 | + struct audio_stream *stream = ss_to_as(substream, component); |
|---|
| 231 | 234 | |
|---|
| 232 | | - err = snd_pcm_lib_malloc_pages(substream, |
|---|
| 233 | | - params_buffer_bytes(hw_params)); |
|---|
| 234 | | - if (err < 0) |
|---|
| 235 | | - return err; |
|---|
| 236 | | - err = au1000_setup_dma_link(stream, |
|---|
| 237 | | - params_period_bytes(hw_params), |
|---|
| 238 | | - params_periods(hw_params)); |
|---|
| 239 | | - if (err) |
|---|
| 240 | | - snd_pcm_lib_free_pages(substream); |
|---|
| 241 | | - |
|---|
| 242 | | - return err; |
|---|
| 235 | + return au1000_setup_dma_link(stream, |
|---|
| 236 | + params_period_bytes(hw_params), |
|---|
| 237 | + params_periods(hw_params)); |
|---|
| 243 | 238 | } |
|---|
| 244 | 239 | |
|---|
| 245 | | -static int alchemy_pcm_hw_free(struct snd_pcm_substream *substream) |
|---|
| 240 | +static int alchemy_pcm_hw_free(struct snd_soc_component *component, |
|---|
| 241 | + struct snd_pcm_substream *substream) |
|---|
| 246 | 242 | { |
|---|
| 247 | | - struct audio_stream *stream = ss_to_as(substream); |
|---|
| 243 | + struct audio_stream *stream = ss_to_as(substream, component); |
|---|
| 248 | 244 | au1000_release_dma_link(stream); |
|---|
| 249 | | - return snd_pcm_lib_free_pages(substream); |
|---|
| 245 | + return 0; |
|---|
| 250 | 246 | } |
|---|
| 251 | 247 | |
|---|
| 252 | | -static int alchemy_pcm_trigger(struct snd_pcm_substream *substream, int cmd) |
|---|
| 248 | +static int alchemy_pcm_trigger(struct snd_soc_component *component, |
|---|
| 249 | + struct snd_pcm_substream *substream, int cmd) |
|---|
| 253 | 250 | { |
|---|
| 254 | | - struct audio_stream *stream = ss_to_as(substream); |
|---|
| 251 | + struct audio_stream *stream = ss_to_as(substream, component); |
|---|
| 255 | 252 | int err = 0; |
|---|
| 256 | 253 | |
|---|
| 257 | 254 | switch (cmd) { |
|---|
| .. | .. |
|---|
| 268 | 265 | return err; |
|---|
| 269 | 266 | } |
|---|
| 270 | 267 | |
|---|
| 271 | | -static snd_pcm_uframes_t alchemy_pcm_pointer(struct snd_pcm_substream *ss) |
|---|
| 268 | +static snd_pcm_uframes_t alchemy_pcm_pointer(struct snd_soc_component *component, |
|---|
| 269 | + struct snd_pcm_substream *ss) |
|---|
| 272 | 270 | { |
|---|
| 273 | | - struct audio_stream *stream = ss_to_as(ss); |
|---|
| 271 | + struct audio_stream *stream = ss_to_as(ss, component); |
|---|
| 274 | 272 | long location; |
|---|
| 275 | 273 | |
|---|
| 276 | 274 | location = get_dma_residue(stream->dma); |
|---|
| .. | .. |
|---|
| 280 | 278 | return bytes_to_frames(ss->runtime, location); |
|---|
| 281 | 279 | } |
|---|
| 282 | 280 | |
|---|
| 283 | | -static const struct snd_pcm_ops alchemy_pcm_ops = { |
|---|
| 284 | | - .open = alchemy_pcm_open, |
|---|
| 285 | | - .close = alchemy_pcm_close, |
|---|
| 286 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 287 | | - .hw_params = alchemy_pcm_hw_params, |
|---|
| 288 | | - .hw_free = alchemy_pcm_hw_free, |
|---|
| 289 | | - .trigger = alchemy_pcm_trigger, |
|---|
| 290 | | - .pointer = alchemy_pcm_pointer, |
|---|
| 291 | | -}; |
|---|
| 292 | | - |
|---|
| 293 | | -static int alchemy_pcm_new(struct snd_soc_pcm_runtime *rtd) |
|---|
| 281 | +static int alchemy_pcm_new(struct snd_soc_component *component, |
|---|
| 282 | + struct snd_soc_pcm_runtime *rtd) |
|---|
| 294 | 283 | { |
|---|
| 295 | 284 | struct snd_pcm *pcm = rtd->pcm; |
|---|
| 296 | 285 | |
|---|
| 297 | | - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, |
|---|
| 298 | | - snd_dma_continuous_data(GFP_KERNEL), 65536, (4096 * 1024) - 1); |
|---|
| 286 | + snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, |
|---|
| 287 | + NULL, 65536, (4096 * 1024) - 1); |
|---|
| 299 | 288 | |
|---|
| 300 | 289 | return 0; |
|---|
| 301 | 290 | } |
|---|
| 302 | 291 | |
|---|
| 303 | 292 | static struct snd_soc_component_driver alchemy_pcm_soc_component = { |
|---|
| 304 | 293 | .name = DRV_NAME, |
|---|
| 305 | | - .ops = &alchemy_pcm_ops, |
|---|
| 306 | | - .pcm_new = alchemy_pcm_new, |
|---|
| 294 | + .open = alchemy_pcm_open, |
|---|
| 295 | + .close = alchemy_pcm_close, |
|---|
| 296 | + .hw_params = alchemy_pcm_hw_params, |
|---|
| 297 | + .hw_free = alchemy_pcm_hw_free, |
|---|
| 298 | + .trigger = alchemy_pcm_trigger, |
|---|
| 299 | + .pointer = alchemy_pcm_pointer, |
|---|
| 300 | + .pcm_construct = alchemy_pcm_new, |
|---|
| 307 | 301 | }; |
|---|
| 308 | 302 | |
|---|
| 309 | 303 | static int alchemy_pcm_drvprobe(struct platform_device *pdev) |
|---|