ALSA: pcmtest: Update comment about PCM copy ops
[platform/kernel/linux-rpi.git] / sound / drivers / pcmtest.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Virtual ALSA driver for PCM testing/fuzzing
4  *
5  * Copyright 2023 Ivan Orlov <ivan.orlov0322@gmail.com>
6  *
7  * This is a simple virtual ALSA driver, which can be used for audio applications/PCM middle layer
8  * testing or fuzzing.
9  * It can:
10  *      - Simulate 'playback' and 'capture' actions
11  *      - Generate random or pattern-based capture data
12  *      - Check playback buffer for containing looped template, and notify about the results
13  *      through the debugfs entry
14  *      - Inject delays into the playback and capturing processes. See 'inject_delay' parameter.
15  *      - Inject errors during the PCM callbacks.
16  *      - Register custom RESET ioctl and notify when it is called through the debugfs entry
17  *      - Work in interleaved and non-interleaved modes
18  *      - Support up to 8 substreams
19  *      - Support up to 4 channels
20  *      - Support framerates from 8 kHz to 48 kHz
21  *
22  * When driver works in the capture mode with multiple channels, it duplicates the looped
23  * pattern to each separate channel. For example, if we have 2 channels, format = U8, interleaved
24  * access mode and pattern 'abacaba', the DMA buffer will look like aabbccaabbaaaa..., so buffer for
25  * each channel will contain abacabaabacaba... Same for the non-interleaved mode.
26  *
27  * However, it may break the capturing on the higher framerates with small period size, so it is
28  * better to choose larger period sizes.
29  *
30  * You can find the corresponding selftest in the 'alsa' selftests folder.
31  */
32
33 #include <linux/module.h>
34 #include <linux/init.h>
35 #include <sound/pcm.h>
36 #include <sound/core.h>
37 #include <linux/dma-mapping.h>
38 #include <linux/platform_device.h>
39 #include <linux/timer.h>
40 #include <linux/random.h>
41 #include <linux/debugfs.h>
42 #include <linux/delay.h>
43
44 #define TIMER_PER_SEC 5
45 #define TIMER_INTERVAL (HZ / TIMER_PER_SEC)
46 #define DELAY_JIFFIES HZ
47 #define PLAYBACK_SUBSTREAM_CNT  8
48 #define CAPTURE_SUBSTREAM_CNT   8
49 #define MAX_CHANNELS_NUM        4
50
51 #define DEFAULT_PATTERN         "abacaba"
52 #define DEFAULT_PATTERN_LEN     7
53
54 #define FILL_MODE_RAND  0
55 #define FILL_MODE_PAT   1
56
57 #define MAX_PATTERN_LEN 4096
58
59 static int index = -1;
60 static char *id = "pcmtest";
61 static bool enable = true;
62 static int inject_delay;
63 static bool inject_hwpars_err;
64 static bool inject_prepare_err;
65 static bool inject_trigger_err;
66 static bool inject_open_err;
67
68 static short fill_mode = FILL_MODE_PAT;
69
70 static u8 playback_capture_test;
71 static u8 ioctl_reset_test;
72 static struct dentry *driver_debug_dir;
73
74 module_param(index, int, 0444);
75 MODULE_PARM_DESC(index, "Index value for pcmtest soundcard");
76 module_param(id, charp, 0444);
77 MODULE_PARM_DESC(id, "ID string for pcmtest soundcard");
78 module_param(enable, bool, 0444);
79 MODULE_PARM_DESC(enable, "Enable pcmtest soundcard.");
80 module_param(fill_mode, short, 0600);
81 MODULE_PARM_DESC(fill_mode, "Buffer fill mode: rand(0) or pattern(1)");
82 module_param(inject_delay, int, 0600);
83 MODULE_PARM_DESC(inject_delay, "Inject delays during playback/capture (in jiffies)");
84 module_param(inject_hwpars_err, bool, 0600);
85 MODULE_PARM_DESC(inject_hwpars_err, "Inject EBUSY error in the 'hw_params' callback");
86 module_param(inject_prepare_err, bool, 0600);
87 MODULE_PARM_DESC(inject_prepare_err, "Inject EINVAL error in the 'prepare' callback");
88 module_param(inject_trigger_err, bool, 0600);
89 MODULE_PARM_DESC(inject_trigger_err, "Inject EINVAL error in the 'trigger' callback");
90 module_param(inject_open_err, bool, 0600);
91 MODULE_PARM_DESC(inject_open_err, "Inject EBUSY error in the 'open' callback");
92
93 struct pcmtst {
94         struct snd_pcm *pcm;
95         struct snd_card *card;
96         struct platform_device *pdev;
97 };
98
99 struct pcmtst_buf_iter {
100         size_t buf_pos;                         // position in the DMA buffer
101         size_t period_pos;                      // period-relative position
102         size_t b_rw;                            // Bytes to write on every timer tick
103         size_t s_rw_ch;                         // Samples to write to one channel on every tick
104         unsigned int sample_bytes;              // sample_bits / 8
105         bool is_buf_corrupted;                  // playback test result indicator
106         size_t period_bytes;                    // bytes in a one period
107         bool interleaved;                       // Interleaved/Non-interleaved mode
108         size_t total_bytes;                     // Total bytes read/written
109         size_t chan_block;                      // Bytes in one channel buffer when non-interleaved
110         struct snd_pcm_substream *substream;
111         struct timer_list timer_instance;
112 };
113
114 static struct snd_pcm_hardware snd_pcmtst_hw = {
115         .info = (SNDRV_PCM_INFO_INTERLEAVED |
116                  SNDRV_PCM_INFO_BLOCK_TRANSFER |
117                  SNDRV_PCM_INFO_NONINTERLEAVED |
118                  SNDRV_PCM_INFO_MMAP_VALID),
119         .formats =              SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
120         .rates =                SNDRV_PCM_RATE_8000_48000,
121         .rate_min =             8000,
122         .rate_max =             48000,
123         .channels_min =         1,
124         .channels_max =         MAX_CHANNELS_NUM,
125         .buffer_bytes_max =     128 * 1024,
126         .period_bytes_min =     4096,
127         .period_bytes_max =     32768,
128         .periods_min =          1,
129         .periods_max =          1024,
130 };
131
132 struct pattern_buf {
133         char *buf;
134         u32 len;
135 };
136
137 static int buf_allocated;
138 static struct pattern_buf patt_bufs[MAX_CHANNELS_NUM];
139
140 static inline void inc_buf_pos(struct pcmtst_buf_iter *v_iter, size_t by, size_t bytes)
141 {
142         v_iter->total_bytes += by;
143         v_iter->buf_pos += by;
144         if (v_iter->buf_pos >= bytes)
145                 v_iter->buf_pos %= bytes;
146 }
147
148 /*
149  * Position in the DMA buffer when we are in the non-interleaved mode. We increment buf_pos
150  * every time we write a byte to any channel, so the position in the current channel buffer is
151  * (position in the DMA buffer) / count_of_channels + size_of_channel_buf * current_channel
152  */
153 static inline size_t buf_pos_n(struct pcmtst_buf_iter *v_iter, unsigned int channels,
154                                unsigned int chan_num)
155 {
156         return v_iter->buf_pos / channels + v_iter->chan_block * chan_num;
157 }
158
159 /*
160  * Get the count of bytes written for the current channel in the interleaved mode.
161  * This is (count of samples written for the current channel) * bytes_in_sample +
162  * (relative position in the current sample)
163  */
164 static inline size_t ch_pos_i(size_t b_total, unsigned int channels, unsigned int b_sample)
165 {
166         return b_total / channels / b_sample * b_sample + (b_total % b_sample);
167 }
168
169 static void check_buf_block_i(struct pcmtst_buf_iter *v_iter, struct snd_pcm_runtime *runtime)
170 {
171         size_t i;
172         short ch_num;
173         u8 current_byte;
174
175         for (i = 0; i < v_iter->b_rw; i++) {
176                 current_byte = runtime->dma_area[v_iter->buf_pos];
177                 if (!current_byte)
178                         break;
179                 ch_num = (v_iter->total_bytes / v_iter->sample_bytes) % runtime->channels;
180                 if (current_byte != patt_bufs[ch_num].buf[ch_pos_i(v_iter->total_bytes,
181                                                                    runtime->channels,
182                                                                    v_iter->sample_bytes)
183                                                           % patt_bufs[ch_num].len]) {
184                         v_iter->is_buf_corrupted = true;
185                         break;
186                 }
187                 inc_buf_pos(v_iter, 1, runtime->dma_bytes);
188         }
189         // If we broke during the loop, add remaining bytes to the buffer position.
190         inc_buf_pos(v_iter, v_iter->b_rw - i, runtime->dma_bytes);
191 }
192
193 static void check_buf_block_ni(struct pcmtst_buf_iter *v_iter, struct snd_pcm_runtime *runtime)
194 {
195         unsigned int channels = runtime->channels;
196         size_t i;
197         short ch_num;
198         u8 current_byte;
199
200         for (i = 0; i < v_iter->b_rw; i++) {
201                 ch_num = i % channels;
202                 current_byte = runtime->dma_area[buf_pos_n(v_iter, channels, ch_num)];
203                 if (!current_byte)
204                         break;
205                 if (current_byte != patt_bufs[ch_num].buf[(v_iter->total_bytes / channels)
206                                                           % patt_bufs[ch_num].len]) {
207                         v_iter->is_buf_corrupted = true;
208                         break;
209                 }
210                 inc_buf_pos(v_iter, 1, runtime->dma_bytes);
211         }
212         inc_buf_pos(v_iter, v_iter->b_rw - i, runtime->dma_bytes);
213 }
214
215 /*
216  * Check one block of the buffer. Here we iterate the buffer until we find '0'. This condition is
217  * necessary because we need to detect when the reading/writing ends, so we assume that the pattern
218  * doesn't contain zeros.
219  */
220 static void check_buf_block(struct pcmtst_buf_iter *v_iter, struct snd_pcm_runtime *runtime)
221 {
222         if (v_iter->interleaved)
223                 check_buf_block_i(v_iter, runtime);
224         else
225                 check_buf_block_ni(v_iter, runtime);
226 }
227
228 /*
229  * Fill buffer in the non-interleaved mode. The order of samples is C0, ..., C0, C1, ..., C1, C2...
230  * The channel buffers lay in the DMA buffer continuously (see default copy
231  * handlers in the pcm_lib.c file).
232  *
233  * Here we increment the DMA buffer position every time we write a byte to any channel 'buffer'.
234  * We need this to simulate the correct hardware pointer moving.
235  */
236 static void fill_block_pattern_n(struct pcmtst_buf_iter *v_iter, struct snd_pcm_runtime *runtime)
237 {
238         size_t i;
239         unsigned int channels = runtime->channels;
240         short ch_num;
241
242         for (i = 0; i < v_iter->b_rw; i++) {
243                 ch_num = i % channels;
244                 runtime->dma_area[buf_pos_n(v_iter, channels, ch_num)] =
245                         patt_bufs[ch_num].buf[(v_iter->total_bytes / channels)
246                                               % patt_bufs[ch_num].len];
247                 inc_buf_pos(v_iter, 1, runtime->dma_bytes);
248         }
249 }
250
251 // Fill buffer in the interleaved mode. The order of samples is C0, C1, C2, C0, C1, C2, ...
252 static void fill_block_pattern_i(struct pcmtst_buf_iter *v_iter, struct snd_pcm_runtime *runtime)
253 {
254         size_t sample;
255         size_t pos_in_ch, pos_pattern;
256         short ch, pos_sample;
257
258         pos_in_ch = ch_pos_i(v_iter->total_bytes, runtime->channels, v_iter->sample_bytes);
259
260         for (sample = 0; sample < v_iter->s_rw_ch; sample++) {
261                 for (ch = 0; ch < runtime->channels; ch++) {
262                         for (pos_sample = 0; pos_sample < v_iter->sample_bytes; pos_sample++) {
263                                 pos_pattern = (pos_in_ch + sample * v_iter->sample_bytes
264                                               + pos_sample) % patt_bufs[ch].len;
265                                 runtime->dma_area[v_iter->buf_pos] = patt_bufs[ch].buf[pos_pattern];
266                                 inc_buf_pos(v_iter, 1, runtime->dma_bytes);
267                         }
268                 }
269         }
270 }
271
272 static void fill_block_pattern(struct pcmtst_buf_iter *v_iter, struct snd_pcm_runtime *runtime)
273 {
274         if (v_iter->interleaved)
275                 fill_block_pattern_i(v_iter, runtime);
276         else
277                 fill_block_pattern_n(v_iter, runtime);
278 }
279
280 static void fill_block_rand_n(struct pcmtst_buf_iter *v_iter, struct snd_pcm_runtime *runtime)
281 {
282         unsigned int channels = runtime->channels;
283         // Remaining space in all channel buffers
284         size_t bytes_remain = runtime->dma_bytes - v_iter->buf_pos;
285         unsigned int i;
286
287         for (i = 0; i < channels; i++) {
288                 if (v_iter->b_rw <= bytes_remain) {
289                         //b_rw - count of bytes must be written for all channels at each timer tick
290                         get_random_bytes(runtime->dma_area + buf_pos_n(v_iter, channels, i),
291                                          v_iter->b_rw / channels);
292                 } else {
293                         // Write to the end of buffer and start from the beginning of it
294                         get_random_bytes(runtime->dma_area + buf_pos_n(v_iter, channels, i),
295                                          bytes_remain / channels);
296                         get_random_bytes(runtime->dma_area + v_iter->chan_block * i,
297                                          (v_iter->b_rw - bytes_remain) / channels);
298                 }
299         }
300         inc_buf_pos(v_iter, v_iter->b_rw, runtime->dma_bytes);
301 }
302
303 static void fill_block_rand_i(struct pcmtst_buf_iter *v_iter, struct snd_pcm_runtime *runtime)
304 {
305         size_t in_cur_block = runtime->dma_bytes - v_iter->buf_pos;
306
307         if (v_iter->b_rw <= in_cur_block) {
308                 get_random_bytes(&runtime->dma_area[v_iter->buf_pos], v_iter->b_rw);
309         } else {
310                 get_random_bytes(&runtime->dma_area[v_iter->buf_pos], in_cur_block);
311                 get_random_bytes(runtime->dma_area, v_iter->b_rw - in_cur_block);
312         }
313         inc_buf_pos(v_iter, v_iter->b_rw, runtime->dma_bytes);
314 }
315
316 static void fill_block_random(struct pcmtst_buf_iter *v_iter, struct snd_pcm_runtime *runtime)
317 {
318         if (v_iter->interleaved)
319                 fill_block_rand_i(v_iter, runtime);
320         else
321                 fill_block_rand_n(v_iter, runtime);
322 }
323
324 static void fill_block(struct pcmtst_buf_iter *v_iter, struct snd_pcm_runtime *runtime)
325 {
326         switch (fill_mode) {
327         case FILL_MODE_RAND:
328                 fill_block_random(v_iter, runtime);
329                 break;
330         case FILL_MODE_PAT:
331                 fill_block_pattern(v_iter, runtime);
332                 break;
333         }
334 }
335
336 /*
337  * Here we iterate through the buffer by (buffer_size / iterates_per_second) bytes.
338  * The driver uses timer to simulate the hardware pointer moving, and notify the PCM middle layer
339  * about period elapsed.
340  */
341 static void timer_timeout(struct timer_list *data)
342 {
343         struct pcmtst_buf_iter *v_iter;
344         struct snd_pcm_substream *substream;
345
346         v_iter = from_timer(v_iter, data, timer_instance);
347         substream = v_iter->substream;
348
349         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && !v_iter->is_buf_corrupted)
350                 check_buf_block(v_iter, substream->runtime);
351         else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
352                 fill_block(v_iter, substream->runtime);
353         else
354                 inc_buf_pos(v_iter, v_iter->b_rw, substream->runtime->dma_bytes);
355
356         v_iter->period_pos += v_iter->b_rw;
357         if (v_iter->period_pos >= v_iter->period_bytes) {
358                 v_iter->period_pos %= v_iter->period_bytes;
359                 snd_pcm_period_elapsed(substream);
360         }
361         mod_timer(&v_iter->timer_instance, jiffies + TIMER_INTERVAL + inject_delay);
362 }
363
364 static int snd_pcmtst_pcm_open(struct snd_pcm_substream *substream)
365 {
366         struct snd_pcm_runtime *runtime = substream->runtime;
367         struct pcmtst_buf_iter *v_iter;
368
369         if (inject_open_err)
370                 return -EBUSY;
371
372         v_iter = kzalloc(sizeof(*v_iter), GFP_KERNEL);
373         if (!v_iter)
374                 return -ENOMEM;
375
376         runtime->hw = snd_pcmtst_hw;
377         runtime->private_data = v_iter;
378         v_iter->substream = substream;
379         v_iter->buf_pos = 0;
380         v_iter->is_buf_corrupted = false;
381         v_iter->period_pos = 0;
382         v_iter->total_bytes = 0;
383
384         playback_capture_test = 0;
385         ioctl_reset_test = 0;
386
387         timer_setup(&v_iter->timer_instance, timer_timeout, 0);
388         mod_timer(&v_iter->timer_instance, jiffies + TIMER_INTERVAL);
389         return 0;
390 }
391
392 static int snd_pcmtst_pcm_close(struct snd_pcm_substream *substream)
393 {
394         struct pcmtst_buf_iter *v_iter = substream->runtime->private_data;
395
396         timer_shutdown_sync(&v_iter->timer_instance);
397         v_iter->substream = NULL;
398         playback_capture_test = !v_iter->is_buf_corrupted;
399         kfree(v_iter);
400         return 0;
401 }
402
403 static int snd_pcmtst_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
404 {
405         if (inject_trigger_err)
406                 return -EINVAL;
407
408         return 0;
409 }
410
411 static snd_pcm_uframes_t snd_pcmtst_pcm_pointer(struct snd_pcm_substream *substream)
412 {
413         struct pcmtst_buf_iter *v_iter = substream->runtime->private_data;
414
415         return bytes_to_frames(substream->runtime, v_iter->buf_pos);
416 }
417
418 static int snd_pcmtst_free(struct pcmtst *pcmtst)
419 {
420         if (!pcmtst)
421                 return 0;
422         kfree(pcmtst);
423         return 0;
424 }
425
426 // These callbacks are required, but empty - all freeing occurs in pdev_remove
427 static int snd_pcmtst_dev_free(struct snd_device *device)
428 {
429         return 0;
430 }
431
432 static void pcmtst_pdev_release(struct device *dev)
433 {
434 }
435
436 static int snd_pcmtst_pcm_prepare(struct snd_pcm_substream *substream)
437 {
438         struct snd_pcm_runtime *runtime = substream->runtime;
439         struct pcmtst_buf_iter *v_iter = runtime->private_data;
440
441         if (inject_prepare_err)
442                 return -EINVAL;
443
444         v_iter->sample_bytes = samples_to_bytes(runtime, 1);
445         v_iter->period_bytes = snd_pcm_lib_period_bytes(substream);
446         v_iter->interleaved = true;
447         if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED ||
448             runtime->access == SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED) {
449                 v_iter->chan_block = snd_pcm_lib_buffer_bytes(substream) / runtime->channels;
450                 v_iter->interleaved = false;
451         }
452         // We want to record RATE * ch_cnt samples per sec, it is rate * sample_bytes * ch_cnt bytes
453         v_iter->s_rw_ch = runtime->rate / TIMER_PER_SEC;
454         v_iter->b_rw = v_iter->s_rw_ch * v_iter->sample_bytes * runtime->channels;
455
456         return 0;
457 }
458
459 static int snd_pcmtst_pcm_hw_params(struct snd_pcm_substream *substream,
460                                     struct snd_pcm_hw_params *params)
461 {
462         if (inject_hwpars_err)
463                 return -EBUSY;
464         return 0;
465 }
466
467 static int snd_pcmtst_pcm_hw_free(struct snd_pcm_substream *substream)
468 {
469         return 0;
470 }
471
472 static int snd_pcmtst_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg)
473 {
474         switch (cmd) {
475         case SNDRV_PCM_IOCTL1_RESET:
476                 ioctl_reset_test = 1;
477                 break;
478         }
479         return snd_pcm_lib_ioctl(substream, cmd, arg);
480 }
481
482 static const struct snd_pcm_ops snd_pcmtst_playback_ops = {
483         .open =         snd_pcmtst_pcm_open,
484         .close =        snd_pcmtst_pcm_close,
485         .trigger =      snd_pcmtst_pcm_trigger,
486         .hw_params =    snd_pcmtst_pcm_hw_params,
487         .ioctl =        snd_pcmtst_ioctl,
488         .hw_free =      snd_pcmtst_pcm_hw_free,
489         .prepare =      snd_pcmtst_pcm_prepare,
490         .pointer =      snd_pcmtst_pcm_pointer,
491 };
492
493 static const struct snd_pcm_ops snd_pcmtst_capture_ops = {
494         .open =         snd_pcmtst_pcm_open,
495         .close =        snd_pcmtst_pcm_close,
496         .trigger =      snd_pcmtst_pcm_trigger,
497         .hw_params =    snd_pcmtst_pcm_hw_params,
498         .hw_free =      snd_pcmtst_pcm_hw_free,
499         .ioctl =        snd_pcmtst_ioctl,
500         .prepare =      snd_pcmtst_pcm_prepare,
501         .pointer =      snd_pcmtst_pcm_pointer,
502 };
503
504 static int snd_pcmtst_new_pcm(struct pcmtst *pcmtst)
505 {
506         struct snd_pcm *pcm;
507         int err;
508
509         err = snd_pcm_new(pcmtst->card, "PCMTest", 0, PLAYBACK_SUBSTREAM_CNT,
510                           CAPTURE_SUBSTREAM_CNT, &pcm);
511         if (err < 0)
512                 return err;
513         pcm->private_data = pcmtst;
514         strcpy(pcm->name, "PCMTest");
515         pcmtst->pcm = pcm;
516         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_pcmtst_playback_ops);
517         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_pcmtst_capture_ops);
518
519         err = snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, &pcmtst->pdev->dev,
520                                              0, 128 * 1024);
521         return err;
522 }
523
524 static int snd_pcmtst_create(struct snd_card *card, struct platform_device *pdev,
525                              struct pcmtst **r_pcmtst)
526 {
527         struct pcmtst *pcmtst;
528         int err;
529         static const struct snd_device_ops ops = {
530                 .dev_free = snd_pcmtst_dev_free,
531         };
532
533         pcmtst = kzalloc(sizeof(*pcmtst), GFP_KERNEL);
534         if (!pcmtst)
535                 return -ENOMEM;
536         pcmtst->card = card;
537         pcmtst->pdev = pdev;
538
539         err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, pcmtst, &ops);
540         if (err < 0)
541                 goto _err_free_chip;
542
543         err = snd_pcmtst_new_pcm(pcmtst);
544         if (err < 0)
545                 goto _err_free_chip;
546
547         *r_pcmtst = pcmtst;
548         return 0;
549
550 _err_free_chip:
551         snd_pcmtst_free(pcmtst);
552         return err;
553 }
554
555 static int pcmtst_probe(struct platform_device *pdev)
556 {
557         struct snd_card *card;
558         struct pcmtst *pcmtst;
559         int err;
560
561         err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
562         if (err)
563                 return err;
564
565         err = snd_devm_card_new(&pdev->dev, index, id, THIS_MODULE, 0, &card);
566         if (err < 0)
567                 return err;
568         err = snd_pcmtst_create(card, pdev, &pcmtst);
569         if (err < 0)
570                 return err;
571
572         strcpy(card->driver, "PCM-TEST Driver");
573         strcpy(card->shortname, "PCM-Test");
574         strcpy(card->longname, "PCM-Test virtual driver");
575
576         err = snd_card_register(card);
577         if (err < 0)
578                 return err;
579
580         platform_set_drvdata(pdev, pcmtst);
581
582         return 0;
583 }
584
585 static void pdev_remove(struct platform_device *pdev)
586 {
587         struct pcmtst *pcmtst = platform_get_drvdata(pdev);
588
589         snd_pcmtst_free(pcmtst);
590 }
591
592 static struct platform_device pcmtst_pdev = {
593         .name =         "pcmtest",
594         .dev.release =  pcmtst_pdev_release,
595 };
596
597 static struct platform_driver pcmtst_pdrv = {
598         .probe =        pcmtst_probe,
599         .remove_new =   pdev_remove,
600         .driver =       {
601                 .name = "pcmtest",
602         },
603 };
604
605 static ssize_t pattern_write(struct file *file, const char __user *u_buff, size_t len, loff_t *off)
606 {
607         struct pattern_buf *patt_buf = file->f_inode->i_private;
608         ssize_t to_write = len;
609
610         if (*off + to_write > MAX_PATTERN_LEN)
611                 to_write = MAX_PATTERN_LEN - *off;
612
613         // Crop silently everything over the buffer
614         if (to_write <= 0)
615                 return len;
616
617         if (copy_from_user(patt_buf->buf + *off, u_buff, to_write))
618                 return -EFAULT;
619
620         patt_buf->len = *off + to_write;
621         *off += to_write;
622
623         return to_write;
624 }
625
626 static ssize_t pattern_read(struct file *file, char __user *u_buff, size_t len, loff_t *off)
627 {
628         struct pattern_buf *patt_buf = file->f_inode->i_private;
629         ssize_t to_read = len;
630
631         if (*off + to_read >= MAX_PATTERN_LEN)
632                 to_read = MAX_PATTERN_LEN - *off;
633         if (to_read <= 0)
634                 return 0;
635
636         if (copy_to_user(u_buff, patt_buf->buf + *off, to_read))
637                 to_read = 0;
638         else
639                 *off += to_read;
640
641         return to_read;
642 }
643
644 static const struct file_operations fill_pattern_fops = {
645         .read = pattern_read,
646         .write = pattern_write,
647 };
648
649 static int setup_patt_bufs(void)
650 {
651         size_t i;
652
653         for (i = 0; i < ARRAY_SIZE(patt_bufs); i++) {
654                 patt_bufs[i].buf = kzalloc(MAX_PATTERN_LEN, GFP_KERNEL);
655                 if (!patt_bufs[i].buf)
656                         break;
657                 strcpy(patt_bufs[i].buf, DEFAULT_PATTERN);
658                 patt_bufs[i].len = DEFAULT_PATTERN_LEN;
659         }
660
661         return i;
662 }
663
664 static const char * const pattern_files[] = { "fill_pattern0", "fill_pattern1",
665                                               "fill_pattern2", "fill_pattern3"};
666 static int init_debug_files(int buf_count)
667 {
668         size_t i;
669         char len_file_name[32];
670
671         driver_debug_dir = debugfs_create_dir("pcmtest", NULL);
672         if (IS_ERR(driver_debug_dir))
673                 return PTR_ERR(driver_debug_dir);
674         debugfs_create_u8("pc_test", 0444, driver_debug_dir, &playback_capture_test);
675         debugfs_create_u8("ioctl_test", 0444, driver_debug_dir, &ioctl_reset_test);
676
677         for (i = 0; i < buf_count; i++) {
678                 debugfs_create_file(pattern_files[i], 0600, driver_debug_dir,
679                                     &patt_bufs[i], &fill_pattern_fops);
680                 snprintf(len_file_name, sizeof(len_file_name), "%s_len", pattern_files[i]);
681                 debugfs_create_u32(len_file_name, 0444, driver_debug_dir, &patt_bufs[i].len);
682         }
683
684         return 0;
685 }
686
687 static void free_pattern_buffers(void)
688 {
689         int i;
690
691         for (i = 0; i < buf_allocated; i++)
692                 kfree(patt_bufs[i].buf);
693 }
694
695 static void clear_debug_files(void)
696 {
697         debugfs_remove_recursive(driver_debug_dir);
698 }
699
700 static int __init mod_init(void)
701 {
702         int err = 0;
703
704         buf_allocated = setup_patt_bufs();
705         if (!buf_allocated)
706                 return -ENOMEM;
707
708         snd_pcmtst_hw.channels_max = buf_allocated;
709
710         err = init_debug_files(buf_allocated);
711         if (err)
712                 return err;
713         err = platform_device_register(&pcmtst_pdev);
714         if (err)
715                 return err;
716         err = platform_driver_register(&pcmtst_pdrv);
717         if (err)
718                 platform_device_unregister(&pcmtst_pdev);
719         return err;
720 }
721
722 static void __exit mod_exit(void)
723 {
724         clear_debug_files();
725         free_pattern_buffers();
726
727         platform_driver_unregister(&pcmtst_pdrv);
728         platform_device_unregister(&pcmtst_pdev);
729 }
730
731 MODULE_LICENSE("GPL");
732 MODULE_AUTHOR("Ivan Orlov");
733 module_init(mod_init);
734 module_exit(mod_exit);