1 // SPDX-License-Identifier: GPL-2.0
3 * sound.c - Sound component for Mostcore
5 * Copyright (C) 2015 Microchip Technology Germany II GmbH & Co. KG
8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10 #include <linux/module.h>
11 #include <linux/printk.h>
12 #include <linux/kernel.h>
13 #include <linux/slab.h>
14 #include <linux/init.h>
15 #include <sound/core.h>
16 #include <sound/pcm.h>
17 #include <sound/pcm_params.h>
18 #include <linux/sched.h>
19 #include <linux/kthread.h>
20 #include <linux/most.h>
22 #define DRIVER_NAME "sound"
23 #define STRING_SIZE 80
25 static struct most_component comp
;
28 * struct channel - private structure to keep channel specific data
29 * @substream: stores the substream structure
30 * @pcm_hardware: low-level hardware description
31 * @iface: interface for which the channel belongs to
32 * @cfg: channel configuration
33 * @card: registered sound card
34 * @list: list for private use
36 * @period_pos: current period position (ring buffer)
37 * @buffer_pos: current buffer position (ring buffer)
38 * @is_stream_running: identifies whether a stream is running or not
39 * @opened: set when the stream is opened
40 * @playback_task: playback thread
41 * @playback_waitq: waitq used by playback thread
42 * @copy_fn: copy function for PCM-specific format and width
45 struct snd_pcm_substream
*substream
;
46 struct snd_pcm_hardware pcm_hardware
;
47 struct most_interface
*iface
;
48 struct most_channel_config
*cfg
;
49 struct snd_card
*card
;
50 struct list_head list
;
52 unsigned int period_pos
;
53 unsigned int buffer_pos
;
54 bool is_stream_running
;
55 struct task_struct
*playback_task
;
56 wait_queue_head_t playback_waitq
;
57 void (*copy_fn
)(void *alsa
, void *most
, unsigned int bytes
);
60 struct sound_adapter
{
61 struct list_head dev_list
;
62 struct most_interface
*iface
;
63 struct snd_card
*card
;
64 struct list_head list
;
69 static struct list_head adpt_list
;
71 #define MOST_PCM_INFO (SNDRV_PCM_INFO_MMAP | \
72 SNDRV_PCM_INFO_MMAP_VALID | \
73 SNDRV_PCM_INFO_BATCH | \
74 SNDRV_PCM_INFO_INTERLEAVED | \
75 SNDRV_PCM_INFO_BLOCK_TRANSFER)
77 static void swap_copy16(u16
*dest
, const u16
*source
, unsigned int bytes
)
81 while (i
< (bytes
/ 2)) {
82 dest
[i
] = swab16(source
[i
]);
87 static void swap_copy24(u8
*dest
, const u8
*source
, unsigned int bytes
)
93 while (i
< bytes
- 2) {
94 dest
[i
] = source
[i
+ 2];
95 dest
[i
+ 1] = source
[i
+ 1];
96 dest
[i
+ 2] = source
[i
];
101 static void swap_copy32(u32
*dest
, const u32
*source
, unsigned int bytes
)
105 while (i
< bytes
/ 4) {
106 dest
[i
] = swab32(source
[i
]);
111 static void alsa_to_most_memcpy(void *alsa
, void *most
, unsigned int bytes
)
113 memcpy(most
, alsa
, bytes
);
116 static void alsa_to_most_copy16(void *alsa
, void *most
, unsigned int bytes
)
118 swap_copy16(most
, alsa
, bytes
);
121 static void alsa_to_most_copy24(void *alsa
, void *most
, unsigned int bytes
)
123 swap_copy24(most
, alsa
, bytes
);
126 static void alsa_to_most_copy32(void *alsa
, void *most
, unsigned int bytes
)
128 swap_copy32(most
, alsa
, bytes
);
131 static void most_to_alsa_memcpy(void *alsa
, void *most
, unsigned int bytes
)
133 memcpy(alsa
, most
, bytes
);
136 static void most_to_alsa_copy16(void *alsa
, void *most
, unsigned int bytes
)
138 swap_copy16(alsa
, most
, bytes
);
141 static void most_to_alsa_copy24(void *alsa
, void *most
, unsigned int bytes
)
143 swap_copy24(alsa
, most
, bytes
);
146 static void most_to_alsa_copy32(void *alsa
, void *most
, unsigned int bytes
)
148 swap_copy32(alsa
, most
, bytes
);
152 * get_channel - get pointer to channel
153 * @iface: interface structure
154 * @channel_id: channel ID
156 * This traverses the channel list and returns the channel matching the
159 * Returns pointer to channel on success or NULL otherwise.
161 static struct channel
*get_channel(struct most_interface
*iface
,
164 struct sound_adapter
*adpt
= iface
->priv
;
165 struct channel
*channel
;
167 list_for_each_entry(channel
, &adpt
->dev_list
, list
) {
168 if ((channel
->iface
== iface
) && (channel
->id
== channel_id
))
175 * copy_data - implements data copying function
177 * @mbo: MBO from core
179 * Copy data from/to ring buffer to/from MBO and update the buffer position
181 static bool copy_data(struct channel
*channel
, struct mbo
*mbo
)
183 struct snd_pcm_runtime
*const runtime
= channel
->substream
->runtime
;
184 unsigned int const frame_bytes
= channel
->cfg
->subbuffer_size
;
185 unsigned int const buffer_size
= runtime
->buffer_size
;
189 if (channel
->cfg
->direction
& MOST_CH_RX
)
190 frames
= mbo
->processed_length
/ frame_bytes
;
192 frames
= mbo
->buffer_length
/ frame_bytes
;
193 fr0
= min(buffer_size
- channel
->buffer_pos
, frames
);
195 channel
->copy_fn(runtime
->dma_area
+ channel
->buffer_pos
* frame_bytes
,
200 /* wrap around at end of ring buffer */
201 channel
->copy_fn(runtime
->dma_area
,
202 mbo
->virt_address
+ fr0
* frame_bytes
,
203 (frames
- fr0
) * frame_bytes
);
206 channel
->buffer_pos
+= frames
;
207 if (channel
->buffer_pos
>= buffer_size
)
208 channel
->buffer_pos
-= buffer_size
;
209 channel
->period_pos
+= frames
;
210 if (channel
->period_pos
>= runtime
->period_size
) {
211 channel
->period_pos
-= runtime
->period_size
;
218 * playback_thread - function implements the playback thread
219 * @data: private data
221 * Thread which does the playback functionality in a loop. It waits for a free
222 * MBO from mostcore for a particular channel and copy the data from ring buffer
223 * to MBO. Submit the MBO back to mostcore, after copying the data.
225 * Returns 0 on success or error code otherwise.
227 static int playback_thread(void *data
)
229 struct channel
*const channel
= data
;
231 while (!kthread_should_stop()) {
232 struct mbo
*mbo
= NULL
;
233 bool period_elapsed
= false;
235 wait_event_interruptible(
236 channel
->playback_waitq
,
237 kthread_should_stop() ||
238 (channel
->is_stream_running
&&
239 (mbo
= most_get_mbo(channel
->iface
, channel
->id
,
244 if (channel
->is_stream_running
)
245 period_elapsed
= copy_data(channel
, mbo
);
247 memset(mbo
->virt_address
, 0, mbo
->buffer_length
);
249 most_submit_mbo(mbo
);
251 snd_pcm_period_elapsed(channel
->substream
);
257 * pcm_open - implements open callback function for PCM middle layer
258 * @substream: pointer to ALSA PCM substream
260 * This is called when a PCM substream is opened. At least, the function should
261 * initialize the runtime->hw record.
263 * Returns 0 on success or error code otherwise.
265 static int pcm_open(struct snd_pcm_substream
*substream
)
267 struct channel
*channel
= substream
->private_data
;
268 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
269 struct most_channel_config
*cfg
= channel
->cfg
;
272 channel
->substream
= substream
;
274 if (cfg
->direction
== MOST_CH_TX
) {
275 channel
->playback_task
= kthread_run(playback_thread
, channel
,
276 "most_audio_playback");
277 if (IS_ERR(channel
->playback_task
)) {
278 pr_err("Couldn't start thread\n");
279 return PTR_ERR(channel
->playback_task
);
283 ret
= most_start_channel(channel
->iface
, channel
->id
, &comp
);
285 pr_err("most_start_channel() failed!\n");
286 if (cfg
->direction
== MOST_CH_TX
)
287 kthread_stop(channel
->playback_task
);
291 runtime
->hw
= channel
->pcm_hardware
;
296 * pcm_close - implements close callback function for PCM middle layer
297 * @substream: sub-stream pointer
299 * Obviously, this is called when a PCM substream is closed. Any private
300 * instance for a PCM substream allocated in the open callback will be
303 * Returns 0 on success or error code otherwise.
305 static int pcm_close(struct snd_pcm_substream
*substream
)
307 struct channel
*channel
= substream
->private_data
;
309 if (channel
->cfg
->direction
== MOST_CH_TX
)
310 kthread_stop(channel
->playback_task
);
311 most_stop_channel(channel
->iface
, channel
->id
, &comp
);
316 * pcm_prepare - implements prepare callback function for PCM middle layer
317 * @substream: substream pointer
319 * This callback is called when the PCM is "prepared". Format rate, sample rate,
320 * etc., can be set here. This callback can be called many times at each setup.
322 * Returns 0 on success or error code otherwise.
324 static int pcm_prepare(struct snd_pcm_substream
*substream
)
326 struct channel
*channel
= substream
->private_data
;
327 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
328 struct most_channel_config
*cfg
= channel
->cfg
;
329 int width
= snd_pcm_format_physical_width(runtime
->format
);
331 channel
->copy_fn
= NULL
;
333 if (cfg
->direction
== MOST_CH_TX
) {
334 if (snd_pcm_format_big_endian(runtime
->format
) || width
== 8)
335 channel
->copy_fn
= alsa_to_most_memcpy
;
336 else if (width
== 16)
337 channel
->copy_fn
= alsa_to_most_copy16
;
338 else if (width
== 24)
339 channel
->copy_fn
= alsa_to_most_copy24
;
340 else if (width
== 32)
341 channel
->copy_fn
= alsa_to_most_copy32
;
343 if (snd_pcm_format_big_endian(runtime
->format
) || width
== 8)
344 channel
->copy_fn
= most_to_alsa_memcpy
;
345 else if (width
== 16)
346 channel
->copy_fn
= most_to_alsa_copy16
;
347 else if (width
== 24)
348 channel
->copy_fn
= most_to_alsa_copy24
;
349 else if (width
== 32)
350 channel
->copy_fn
= most_to_alsa_copy32
;
353 if (!channel
->copy_fn
)
355 channel
->period_pos
= 0;
356 channel
->buffer_pos
= 0;
361 * pcm_trigger - implements trigger callback function for PCM middle layer
362 * @substream: substream pointer
363 * @cmd: action to perform
365 * This is called when the PCM is started, stopped or paused. The action will be
366 * specified in the second argument, SNDRV_PCM_TRIGGER_XXX
368 * Returns 0 on success or error code otherwise.
370 static int pcm_trigger(struct snd_pcm_substream
*substream
, int cmd
)
372 struct channel
*channel
= substream
->private_data
;
375 case SNDRV_PCM_TRIGGER_START
:
376 channel
->is_stream_running
= true;
377 wake_up_interruptible(&channel
->playback_waitq
);
380 case SNDRV_PCM_TRIGGER_STOP
:
381 channel
->is_stream_running
= false;
391 * pcm_pointer - implements pointer callback function for PCM middle layer
392 * @substream: substream pointer
394 * This callback is called when the PCM middle layer inquires the current
395 * hardware position on the buffer. The position must be returned in frames,
396 * ranging from 0 to buffer_size-1.
398 static snd_pcm_uframes_t
pcm_pointer(struct snd_pcm_substream
*substream
)
400 struct channel
*channel
= substream
->private_data
;
402 return channel
->buffer_pos
;
406 * Initialization of struct snd_pcm_ops
408 static const struct snd_pcm_ops pcm_ops
= {
411 .prepare
= pcm_prepare
,
412 .trigger
= pcm_trigger
,
413 .pointer
= pcm_pointer
,
416 static int split_arg_list(char *buf
, u16
*ch_num
, char **sample_res
)
421 num
= strsep(&buf
, "x");
424 ret
= kstrtou16(num
, 0, ch_num
);
427 *sample_res
= strsep(&buf
, ".\n");
433 pr_err("Bad PCM format\n");
437 static const struct sample_resolution_info
{
438 const char *sample_res
;
442 { "8", 1, SNDRV_PCM_FMTBIT_S8
},
443 { "16", 2, SNDRV_PCM_FMTBIT_S16_LE
| SNDRV_PCM_FMTBIT_S16_BE
},
444 { "24", 3, SNDRV_PCM_FMTBIT_S24_3LE
| SNDRV_PCM_FMTBIT_S24_3BE
},
445 { "32", 4, SNDRV_PCM_FMTBIT_S32_LE
| SNDRV_PCM_FMTBIT_S32_BE
},
448 static int audio_set_hw_params(struct snd_pcm_hardware
*pcm_hw
,
449 u16 ch_num
, char *sample_res
,
450 struct most_channel_config
*cfg
)
454 for (i
= 0; i
< ARRAY_SIZE(sinfo
); i
++) {
455 if (!strcmp(sample_res
, sinfo
[i
].sample_res
))
458 pr_err("Unsupported PCM format\n");
463 pr_err("Bad number of channels\n");
467 if (cfg
->subbuffer_size
!= ch_num
* sinfo
[i
].bytes
) {
468 pr_err("Audio resolution doesn't fit subbuffer size\n");
472 pcm_hw
->info
= MOST_PCM_INFO
;
473 pcm_hw
->rates
= SNDRV_PCM_RATE_48000
;
474 pcm_hw
->rate_min
= 48000;
475 pcm_hw
->rate_max
= 48000;
476 pcm_hw
->buffer_bytes_max
= cfg
->num_buffers
* cfg
->buffer_size
;
477 pcm_hw
->period_bytes_min
= cfg
->buffer_size
;
478 pcm_hw
->period_bytes_max
= cfg
->buffer_size
;
479 pcm_hw
->periods_min
= 1;
480 pcm_hw
->periods_max
= cfg
->num_buffers
;
481 pcm_hw
->channels_min
= ch_num
;
482 pcm_hw
->channels_max
= ch_num
;
483 pcm_hw
->formats
= sinfo
[i
].formats
;
487 static void release_adapter(struct sound_adapter
*adpt
)
489 struct channel
*channel
, *tmp
;
491 list_for_each_entry_safe(channel
, tmp
, &adpt
->dev_list
, list
) {
492 list_del(&channel
->list
);
496 snd_card_free(adpt
->card
);
497 list_del(&adpt
->list
);
502 * audio_probe_channel - probe function of the driver module
503 * @iface: pointer to interface instance
504 * @channel_id: channel index/ID
505 * @cfg: pointer to actual channel configuration
506 * @device_name: name of the device to be created in /dev
507 * @arg_list: string that provides the desired audio resolution
509 * Creates sound card, pcm device, sets pcm ops and registers sound card.
511 * Returns 0 on success or error code otherwise.
513 static int audio_probe_channel(struct most_interface
*iface
, int channel_id
,
514 struct most_channel_config
*cfg
,
515 char *device_name
, char *arg_list
)
517 struct channel
*channel
;
518 struct sound_adapter
*adpt
;
520 int playback_count
= 0;
521 int capture_count
= 0;
526 char arg_list_cpy
[STRING_SIZE
];
528 if (cfg
->data_type
!= MOST_CH_SYNC
) {
529 pr_err("Incompatible channel type\n");
532 strscpy(arg_list_cpy
, arg_list
, STRING_SIZE
);
533 ret
= split_arg_list(arg_list_cpy
, &ch_num
, &sample_res
);
537 list_for_each_entry(adpt
, &adpt_list
, list
) {
538 if (adpt
->iface
!= iface
)
540 if (adpt
->registered
)
543 goto skip_adpt_alloc
;
545 adpt
= kzalloc(sizeof(*adpt
), GFP_KERNEL
);
550 INIT_LIST_HEAD(&adpt
->dev_list
);
552 list_add_tail(&adpt
->list
, &adpt_list
);
553 ret
= snd_card_new(iface
->driver_dev
, -1, "INIC", THIS_MODULE
,
554 sizeof(*channel
), &adpt
->card
);
557 snprintf(adpt
->card
->driver
, sizeof(adpt
->card
->driver
),
559 snprintf(adpt
->card
->shortname
, sizeof(adpt
->card
->shortname
),
561 snprintf(adpt
->card
->longname
, sizeof(adpt
->card
->longname
),
562 "%s at %s", adpt
->card
->shortname
, iface
->description
);
564 if (get_channel(iface
, channel_id
)) {
565 pr_err("channel (%s:%d) is already linked\n",
566 iface
->description
, channel_id
);
570 if (cfg
->direction
== MOST_CH_TX
) {
572 direction
= SNDRV_PCM_STREAM_PLAYBACK
;
575 direction
= SNDRV_PCM_STREAM_CAPTURE
;
577 channel
= kzalloc(sizeof(*channel
), GFP_KERNEL
);
582 channel
->card
= adpt
->card
;
584 channel
->iface
= iface
;
585 channel
->id
= channel_id
;
586 init_waitqueue_head(&channel
->playback_waitq
);
587 list_add_tail(&channel
->list
, &adpt
->dev_list
);
589 ret
= audio_set_hw_params(&channel
->pcm_hardware
, ch_num
, sample_res
,
594 ret
= snd_pcm_new(adpt
->card
, device_name
, adpt
->pcm_dev_idx
,
595 playback_count
, capture_count
, &pcm
);
600 pcm
->private_data
= channel
;
601 strscpy(pcm
->name
, device_name
, sizeof(pcm
->name
));
602 snd_pcm_set_ops(pcm
, direction
, &pcm_ops
);
603 snd_pcm_set_managed_buffer_all(pcm
, SNDRV_DMA_TYPE_VMALLOC
, NULL
, 0, 0);
607 release_adapter(adpt
);
611 static int audio_create_sound_card(void)
614 struct sound_adapter
*adpt
;
616 list_for_each_entry(adpt
, &adpt_list
, list
) {
617 if (!adpt
->registered
)
622 ret
= snd_card_register(adpt
->card
);
624 release_adapter(adpt
);
627 adpt
->registered
= true;
632 * audio_disconnect_channel - function to disconnect a channel
633 * @iface: pointer to interface instance
634 * @channel_id: channel index
636 * This frees allocated memory and removes the sound card from ALSA
638 * Returns 0 on success or error code otherwise.
640 static int audio_disconnect_channel(struct most_interface
*iface
,
643 struct channel
*channel
;
644 struct sound_adapter
*adpt
= iface
->priv
;
646 channel
= get_channel(iface
, channel_id
);
650 list_del(&channel
->list
);
653 if (list_empty(&adpt
->dev_list
))
654 release_adapter(adpt
);
659 * audio_rx_completion - completion handler for rx channels
660 * @mbo: pointer to buffer object that has completed
662 * This searches for the channel this MBO belongs to and copy the data from MBO
665 * Returns 0 on success or error code otherwise.
667 static int audio_rx_completion(struct mbo
*mbo
)
669 struct channel
*channel
= get_channel(mbo
->ifp
, mbo
->hdm_channel_id
);
670 bool period_elapsed
= false;
674 if (channel
->is_stream_running
)
675 period_elapsed
= copy_data(channel
, mbo
);
678 snd_pcm_period_elapsed(channel
->substream
);
683 * audio_tx_completion - completion handler for tx channels
684 * @iface: pointer to interface instance
685 * @channel_id: channel index/ID
687 * This searches the channel that belongs to this combination of interface
688 * pointer and channel ID and wakes a process sitting in the wait queue of
691 * Returns 0 on success or error code otherwise.
693 static int audio_tx_completion(struct most_interface
*iface
, int channel_id
)
695 struct channel
*channel
= get_channel(iface
, channel_id
);
700 wake_up_interruptible(&channel
->playback_waitq
);
705 * Initialization of the struct most_component
707 static struct most_component comp
= {
710 .probe_channel
= audio_probe_channel
,
711 .disconnect_channel
= audio_disconnect_channel
,
712 .rx_completion
= audio_rx_completion
,
713 .tx_completion
= audio_tx_completion
,
714 .cfg_complete
= audio_create_sound_card
,
717 static int __init
audio_init(void)
721 INIT_LIST_HEAD(&adpt_list
);
723 ret
= most_register_component(&comp
);
725 pr_err("Failed to register %s\n", comp
.name
);
728 ret
= most_register_configfs_subsys(&comp
);
730 pr_err("Failed to register %s configfs subsys\n", comp
.name
);
731 most_deregister_component(&comp
);
736 static void __exit
audio_exit(void)
738 most_deregister_configfs_subsys(&comp
);
739 most_deregister_component(&comp
);
742 module_init(audio_init
);
743 module_exit(audio_exit
);
745 MODULE_LICENSE("GPL");
746 MODULE_AUTHOR("Christian Gromm <christian.gromm@microchip.com>");
747 MODULE_DESCRIPTION("Sound Component Module for Mostcore");