GNU Linux-libre 4.19.264-gnu1
[releases.git] / sound / soc / uniphier / aio-compress.c
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // Socionext UniPhier AIO Compress Audio driver.
4 //
5 // Copyright (c) 2017-2018 Socionext Inc.
6
7 #include <linux/bitfield.h>
8 #include <linux/circ_buf.h>
9 #include <linux/dma-mapping.h>
10 #include <linux/errno.h>
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <sound/core.h>
14 #include <sound/pcm.h>
15 #include <sound/soc.h>
16
17 #include "aio.h"
18
19 static int uniphier_aio_compr_prepare(struct snd_compr_stream *cstream);
20 static int uniphier_aio_compr_hw_free(struct snd_compr_stream *cstream);
21
22 static int uniphier_aio_comprdma_new(struct snd_soc_pcm_runtime *rtd)
23 {
24         struct snd_compr *compr = rtd->compr;
25         struct device *dev = compr->card->dev;
26         struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
27         struct uniphier_aio_sub *sub = &aio->sub[compr->direction];
28         size_t size = AUD_RING_SIZE;
29         int dma_dir = DMA_FROM_DEVICE, ret;
30
31         ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(33));
32         if (ret)
33                 return ret;
34
35         sub->compr_area = kzalloc(size, GFP_KERNEL);
36         if (!sub->compr_area)
37                 return -ENOMEM;
38
39         if (sub->swm->dir == PORT_DIR_OUTPUT)
40                 dma_dir = DMA_TO_DEVICE;
41
42         sub->compr_addr = dma_map_single(dev, sub->compr_area, size, dma_dir);
43         if (dma_mapping_error(dev, sub->compr_addr)) {
44                 kfree(sub->compr_area);
45                 sub->compr_area = NULL;
46
47                 return -ENOMEM;
48         }
49
50         sub->compr_bytes = size;
51
52         return 0;
53 }
54
55 static int uniphier_aio_comprdma_free(struct snd_soc_pcm_runtime *rtd)
56 {
57         struct snd_compr *compr = rtd->compr;
58         struct device *dev = compr->card->dev;
59         struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
60         struct uniphier_aio_sub *sub = &aio->sub[compr->direction];
61         int dma_dir = DMA_FROM_DEVICE;
62
63         if (sub->swm->dir == PORT_DIR_OUTPUT)
64                 dma_dir = DMA_TO_DEVICE;
65
66         dma_unmap_single(dev, sub->compr_addr, sub->compr_bytes, dma_dir);
67         kfree(sub->compr_area);
68         sub->compr_area = NULL;
69
70         return 0;
71 }
72
73 static int uniphier_aio_compr_open(struct snd_compr_stream *cstream)
74 {
75         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
76         struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
77         struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
78         int ret;
79
80         if (sub->cstream)
81                 return -EBUSY;
82
83         sub->cstream = cstream;
84         sub->pass_through = 1;
85         sub->use_mmap = false;
86
87         ret = uniphier_aio_comprdma_new(rtd);
88         if (ret)
89                 return ret;
90
91         ret = aio_init(sub);
92         if (ret)
93                 return ret;
94
95         return 0;
96 }
97
98 static int uniphier_aio_compr_free(struct snd_compr_stream *cstream)
99 {
100         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
101         struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
102         struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
103         int ret;
104
105         ret = uniphier_aio_compr_hw_free(cstream);
106         if (ret)
107                 return ret;
108         ret = uniphier_aio_comprdma_free(rtd);
109         if (ret)
110                 return ret;
111
112         sub->cstream = NULL;
113
114         return 0;
115 }
116
117 static int uniphier_aio_compr_get_params(struct snd_compr_stream *cstream,
118                                          struct snd_codec *params)
119 {
120         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
121         struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
122         struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
123
124         *params = sub->cparams.codec;
125
126         return 0;
127 }
128
129 static int uniphier_aio_compr_set_params(struct snd_compr_stream *cstream,
130                                          struct snd_compr_params *params)
131 {
132         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
133         struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
134         struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
135         struct device *dev = &aio->chip->pdev->dev;
136         int ret;
137
138         if (params->codec.id != SND_AUDIOCODEC_IEC61937) {
139                 dev_err(dev, "Codec ID is not supported(%d)\n",
140                         params->codec.id);
141                 return -EINVAL;
142         }
143         if (params->codec.profile != SND_AUDIOPROFILE_IEC61937_SPDIF) {
144                 dev_err(dev, "Codec profile is not supported(%d)\n",
145                         params->codec.profile);
146                 return -EINVAL;
147         }
148
149         /* IEC frame type will be changed after received valid data */
150         sub->iec_pc = IEC61937_PC_AAC;
151
152         sub->cparams = *params;
153         sub->setting = 1;
154
155         aio_port_reset(sub);
156         aio_src_reset(sub);
157
158         ret = uniphier_aio_compr_prepare(cstream);
159         if (ret)
160                 return ret;
161
162         return 0;
163 }
164
165 static int uniphier_aio_compr_hw_free(struct snd_compr_stream *cstream)
166 {
167         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
168         struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
169         struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
170
171         sub->setting = 0;
172
173         return 0;
174 }
175
176 static int uniphier_aio_compr_prepare(struct snd_compr_stream *cstream)
177 {
178         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
179         struct snd_compr_runtime *runtime = cstream->runtime;
180         struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
181         struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
182         int bytes = runtime->fragment_size;
183         unsigned long flags;
184         int ret;
185
186         ret = aiodma_ch_set_param(sub);
187         if (ret)
188                 return ret;
189
190         spin_lock_irqsave(&sub->lock, flags);
191         ret = aiodma_rb_set_buffer(sub, sub->compr_addr,
192                                    sub->compr_addr + sub->compr_bytes,
193                                    bytes);
194         spin_unlock_irqrestore(&sub->lock, flags);
195         if (ret)
196                 return ret;
197
198         ret = aio_port_set_param(sub, sub->pass_through, &sub->params);
199         if (ret)
200                 return ret;
201         ret = aio_oport_set_stream_type(sub, sub->iec_pc);
202         if (ret)
203                 return ret;
204         aio_port_set_enable(sub, 1);
205
206         ret = aio_if_set_param(sub, sub->pass_through);
207         if (ret)
208                 return ret;
209
210         return 0;
211 }
212
213 static int uniphier_aio_compr_trigger(struct snd_compr_stream *cstream,
214                                       int cmd)
215 {
216         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
217         struct snd_compr_runtime *runtime = cstream->runtime;
218         struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
219         struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
220         struct device *dev = &aio->chip->pdev->dev;
221         int bytes = runtime->fragment_size, ret = 0;
222         unsigned long flags;
223
224         spin_lock_irqsave(&sub->lock, flags);
225         switch (cmd) {
226         case SNDRV_PCM_TRIGGER_START:
227                 aiodma_rb_sync(sub, sub->compr_addr, sub->compr_bytes, bytes);
228                 aiodma_ch_set_enable(sub, 1);
229                 sub->running = 1;
230
231                 break;
232         case SNDRV_PCM_TRIGGER_STOP:
233                 sub->running = 0;
234                 aiodma_ch_set_enable(sub, 0);
235
236                 break;
237         default:
238                 dev_warn(dev, "Unknown trigger(%d)\n", cmd);
239                 ret = -EINVAL;
240         }
241         spin_unlock_irqrestore(&sub->lock, flags);
242
243         return ret;
244 }
245
246 static int uniphier_aio_compr_pointer(struct snd_compr_stream *cstream,
247                                       struct snd_compr_tstamp *tstamp)
248 {
249         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
250         struct snd_compr_runtime *runtime = cstream->runtime;
251         struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
252         struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
253         int bytes = runtime->fragment_size;
254         unsigned long flags;
255         u32 pos;
256
257         spin_lock_irqsave(&sub->lock, flags);
258
259         aiodma_rb_sync(sub, sub->compr_addr, sub->compr_bytes, bytes);
260
261         if (sub->swm->dir == PORT_DIR_OUTPUT) {
262                 pos = sub->rd_offs;
263                 /* Size of AIO output format is double of IEC61937 */
264                 tstamp->copied_total = sub->rd_total / 2;
265         } else {
266                 pos = sub->wr_offs;
267                 tstamp->copied_total = sub->rd_total;
268         }
269         tstamp->byte_offset = pos;
270
271         spin_unlock_irqrestore(&sub->lock, flags);
272
273         return 0;
274 }
275
276 static int aio_compr_send_to_hw(struct uniphier_aio_sub *sub,
277                                 char __user *buf, size_t dstsize)
278 {
279         u32 __user *srcbuf = (u32 __user *)buf;
280         u32 *dstbuf = (u32 *)(sub->compr_area + sub->wr_offs);
281         int src = 0, dst = 0, ret;
282         u32 frm, frm_a, frm_b;
283
284         while (dstsize > 0) {
285                 ret = get_user(frm, srcbuf + src);
286                 if (ret)
287                         return ret;
288                 src++;
289
290                 frm_a = frm & 0xffff;
291                 frm_b = (frm >> 16) & 0xffff;
292
293                 if (frm == IEC61937_HEADER_SIGN) {
294                         frm_a |= 0x01000000;
295
296                         /* Next data is Pc and Pd */
297                         sub->iec_header = true;
298                 } else {
299                         u16 pc = be16_to_cpu((__be16)frm_a);
300
301                         if (sub->iec_header && sub->iec_pc != pc) {
302                                 /* Force overwrite IEC frame type */
303                                 sub->iec_pc = pc;
304                                 ret = aio_oport_set_stream_type(sub, pc);
305                                 if (ret)
306                                         return ret;
307                         }
308                         sub->iec_header = false;
309                 }
310                 dstbuf[dst++] = frm_a;
311                 dstbuf[dst++] = frm_b;
312
313                 dstsize -= sizeof(u32) * 2;
314         }
315
316         return 0;
317 }
318
319 static int uniphier_aio_compr_copy(struct snd_compr_stream *cstream,
320                                    char __user *buf, size_t count)
321 {
322         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
323         struct snd_compr_runtime *runtime = cstream->runtime;
324         struct device *carddev = rtd->compr->card->dev;
325         struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
326         struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
327         size_t cnt = min_t(size_t, count, aio_rb_space_to_end(sub) / 2);
328         int bytes = runtime->fragment_size;
329         unsigned long flags;
330         size_t s;
331         int ret;
332
333         if (cnt < sizeof(u32))
334                 return 0;
335
336         if (sub->swm->dir == PORT_DIR_OUTPUT) {
337                 dma_addr_t dmapos = sub->compr_addr + sub->wr_offs;
338
339                 /* Size of AIO output format is double of IEC61937 */
340                 s = cnt * 2;
341
342                 dma_sync_single_for_cpu(carddev, dmapos, s, DMA_TO_DEVICE);
343                 ret = aio_compr_send_to_hw(sub, buf, s);
344                 dma_sync_single_for_device(carddev, dmapos, s, DMA_TO_DEVICE);
345         } else {
346                 dma_addr_t dmapos = sub->compr_addr + sub->rd_offs;
347
348                 s = cnt;
349
350                 dma_sync_single_for_cpu(carddev, dmapos, s, DMA_FROM_DEVICE);
351                 ret = copy_to_user(buf, sub->compr_area + sub->rd_offs, s);
352                 dma_sync_single_for_device(carddev, dmapos, s, DMA_FROM_DEVICE);
353         }
354         if (ret)
355                 return -EFAULT;
356
357         spin_lock_irqsave(&sub->lock, flags);
358
359         sub->threshold = 2 * bytes;
360         aiodma_rb_set_threshold(sub, sub->compr_bytes, 2 * bytes);
361
362         if (sub->swm->dir == PORT_DIR_OUTPUT) {
363                 sub->wr_offs += s;
364                 if (sub->wr_offs >= sub->compr_bytes)
365                         sub->wr_offs -= sub->compr_bytes;
366         } else {
367                 sub->rd_offs += s;
368                 if (sub->rd_offs >= sub->compr_bytes)
369                         sub->rd_offs -= sub->compr_bytes;
370         }
371         aiodma_rb_sync(sub, sub->compr_addr, sub->compr_bytes, bytes);
372
373         spin_unlock_irqrestore(&sub->lock, flags);
374
375         return cnt;
376 }
377
378 static int uniphier_aio_compr_get_caps(struct snd_compr_stream *cstream,
379                                        struct snd_compr_caps *caps)
380 {
381         caps->num_codecs = 1;
382         caps->min_fragment_size = AUD_MIN_FRAGMENT_SIZE;
383         caps->max_fragment_size = AUD_MAX_FRAGMENT_SIZE;
384         caps->min_fragments = AUD_MIN_FRAGMENT;
385         caps->max_fragments = AUD_MAX_FRAGMENT;
386         caps->codecs[0] = SND_AUDIOCODEC_IEC61937;
387
388         return 0;
389 }
390
391 static const struct snd_compr_codec_caps caps_iec = {
392         .num_descriptors = 1,
393         .descriptor[0].max_ch = 8,
394         .descriptor[0].num_sample_rates = 0,
395         .descriptor[0].num_bitrates = 0,
396         .descriptor[0].profiles = SND_AUDIOPROFILE_IEC61937_SPDIF,
397         .descriptor[0].modes = SND_AUDIOMODE_IEC_AC3 |
398                                 SND_AUDIOMODE_IEC_MPEG1 |
399                                 SND_AUDIOMODE_IEC_MP3 |
400                                 SND_AUDIOMODE_IEC_DTS,
401         .descriptor[0].formats = 0,
402 };
403
404 static int uniphier_aio_compr_get_codec_caps(struct snd_compr_stream *stream,
405                                              struct snd_compr_codec_caps *codec)
406 {
407         if (codec->codec == SND_AUDIOCODEC_IEC61937)
408                 *codec = caps_iec;
409         else
410                 return -EINVAL;
411
412         return 0;
413 }
414
415 const struct snd_compr_ops uniphier_aio_compr_ops = {
416         .open           = uniphier_aio_compr_open,
417         .free           = uniphier_aio_compr_free,
418         .get_params     = uniphier_aio_compr_get_params,
419         .set_params     = uniphier_aio_compr_set_params,
420         .trigger        = uniphier_aio_compr_trigger,
421         .pointer        = uniphier_aio_compr_pointer,
422         .copy           = uniphier_aio_compr_copy,
423         .get_caps       = uniphier_aio_compr_get_caps,
424         .get_codec_caps = uniphier_aio_compr_get_codec_caps,
425 };