0001
0002
0003
0004
0005
0006
0007
0008 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0009
0010 #include <linux/module.h>
0011 #include <linux/printk.h>
0012 #include <linux/kernel.h>
0013 #include <linux/slab.h>
0014 #include <linux/init.h>
0015 #include <sound/core.h>
0016 #include <sound/pcm.h>
0017 #include <sound/pcm_params.h>
0018 #include <linux/sched.h>
0019 #include <linux/kthread.h>
0020 #include <linux/most.h>
0021
0022 #define DRIVER_NAME "sound"
0023 #define STRING_SIZE 80
0024
0025 static struct most_component comp;
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 struct channel {
0043 struct snd_pcm_substream *substream;
0044 struct snd_pcm_hardware pcm_hardware;
0045 struct most_interface *iface;
0046 struct most_channel_config *cfg;
0047 struct snd_card *card;
0048 struct list_head list;
0049 int id;
0050 unsigned int period_pos;
0051 unsigned int buffer_pos;
0052 bool is_stream_running;
0053 struct task_struct *playback_task;
0054 wait_queue_head_t playback_waitq;
0055 void (*copy_fn)(void *alsa, void *most, unsigned int bytes);
0056 };
0057
0058 struct sound_adapter {
0059 struct list_head dev_list;
0060 struct most_interface *iface;
0061 struct snd_card *card;
0062 struct list_head list;
0063 bool registered;
0064 int pcm_dev_idx;
0065 };
0066
0067 static struct list_head adpt_list;
0068
0069 #define MOST_PCM_INFO (SNDRV_PCM_INFO_MMAP | \
0070 SNDRV_PCM_INFO_MMAP_VALID | \
0071 SNDRV_PCM_INFO_BATCH | \
0072 SNDRV_PCM_INFO_INTERLEAVED | \
0073 SNDRV_PCM_INFO_BLOCK_TRANSFER)
0074
0075 static void swap_copy16(u16 *dest, const u16 *source, unsigned int bytes)
0076 {
0077 unsigned int i = 0;
0078
0079 while (i < (bytes / 2)) {
0080 dest[i] = swab16(source[i]);
0081 i++;
0082 }
0083 }
0084
0085 static void swap_copy24(u8 *dest, const u8 *source, unsigned int bytes)
0086 {
0087 unsigned int i = 0;
0088
0089 if (bytes < 2)
0090 return;
0091 while (i < bytes - 2) {
0092 dest[i] = source[i + 2];
0093 dest[i + 1] = source[i + 1];
0094 dest[i + 2] = source[i];
0095 i += 3;
0096 }
0097 }
0098
0099 static void swap_copy32(u32 *dest, const u32 *source, unsigned int bytes)
0100 {
0101 unsigned int i = 0;
0102
0103 while (i < bytes / 4) {
0104 dest[i] = swab32(source[i]);
0105 i++;
0106 }
0107 }
0108
0109 static void alsa_to_most_memcpy(void *alsa, void *most, unsigned int bytes)
0110 {
0111 memcpy(most, alsa, bytes);
0112 }
0113
0114 static void alsa_to_most_copy16(void *alsa, void *most, unsigned int bytes)
0115 {
0116 swap_copy16(most, alsa, bytes);
0117 }
0118
0119 static void alsa_to_most_copy24(void *alsa, void *most, unsigned int bytes)
0120 {
0121 swap_copy24(most, alsa, bytes);
0122 }
0123
0124 static void alsa_to_most_copy32(void *alsa, void *most, unsigned int bytes)
0125 {
0126 swap_copy32(most, alsa, bytes);
0127 }
0128
0129 static void most_to_alsa_memcpy(void *alsa, void *most, unsigned int bytes)
0130 {
0131 memcpy(alsa, most, bytes);
0132 }
0133
0134 static void most_to_alsa_copy16(void *alsa, void *most, unsigned int bytes)
0135 {
0136 swap_copy16(alsa, most, bytes);
0137 }
0138
0139 static void most_to_alsa_copy24(void *alsa, void *most, unsigned int bytes)
0140 {
0141 swap_copy24(alsa, most, bytes);
0142 }
0143
0144 static void most_to_alsa_copy32(void *alsa, void *most, unsigned int bytes)
0145 {
0146 swap_copy32(alsa, most, bytes);
0147 }
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159 static struct channel *get_channel(struct most_interface *iface,
0160 int channel_id)
0161 {
0162 struct sound_adapter *adpt = iface->priv;
0163 struct channel *channel;
0164
0165 list_for_each_entry(channel, &adpt->dev_list, list) {
0166 if ((channel->iface == iface) && (channel->id == channel_id))
0167 return channel;
0168 }
0169 return NULL;
0170 }
0171
0172
0173
0174
0175
0176
0177
0178
0179 static bool copy_data(struct channel *channel, struct mbo *mbo)
0180 {
0181 struct snd_pcm_runtime *const runtime = channel->substream->runtime;
0182 unsigned int const frame_bytes = channel->cfg->subbuffer_size;
0183 unsigned int const buffer_size = runtime->buffer_size;
0184 unsigned int frames;
0185 unsigned int fr0;
0186
0187 if (channel->cfg->direction & MOST_CH_RX)
0188 frames = mbo->processed_length / frame_bytes;
0189 else
0190 frames = mbo->buffer_length / frame_bytes;
0191 fr0 = min(buffer_size - channel->buffer_pos, frames);
0192
0193 channel->copy_fn(runtime->dma_area + channel->buffer_pos * frame_bytes,
0194 mbo->virt_address,
0195 fr0 * frame_bytes);
0196
0197 if (frames > fr0) {
0198
0199 channel->copy_fn(runtime->dma_area,
0200 mbo->virt_address + fr0 * frame_bytes,
0201 (frames - fr0) * frame_bytes);
0202 }
0203
0204 channel->buffer_pos += frames;
0205 if (channel->buffer_pos >= buffer_size)
0206 channel->buffer_pos -= buffer_size;
0207 channel->period_pos += frames;
0208 if (channel->period_pos >= runtime->period_size) {
0209 channel->period_pos -= runtime->period_size;
0210 return true;
0211 }
0212 return false;
0213 }
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225 static int playback_thread(void *data)
0226 {
0227 struct channel *const channel = data;
0228
0229 while (!kthread_should_stop()) {
0230 struct mbo *mbo = NULL;
0231 bool period_elapsed = false;
0232
0233 wait_event_interruptible(
0234 channel->playback_waitq,
0235 kthread_should_stop() ||
0236 (channel->is_stream_running &&
0237 (mbo = most_get_mbo(channel->iface, channel->id,
0238 &comp))));
0239 if (!mbo)
0240 continue;
0241
0242 if (channel->is_stream_running)
0243 period_elapsed = copy_data(channel, mbo);
0244 else
0245 memset(mbo->virt_address, 0, mbo->buffer_length);
0246
0247 most_submit_mbo(mbo);
0248 if (period_elapsed)
0249 snd_pcm_period_elapsed(channel->substream);
0250 }
0251 return 0;
0252 }
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263 static int pcm_open(struct snd_pcm_substream *substream)
0264 {
0265 struct channel *channel = substream->private_data;
0266 struct snd_pcm_runtime *runtime = substream->runtime;
0267 struct most_channel_config *cfg = channel->cfg;
0268 int ret;
0269
0270 channel->substream = substream;
0271
0272 if (cfg->direction == MOST_CH_TX) {
0273 channel->playback_task = kthread_run(playback_thread, channel,
0274 "most_audio_playback");
0275 if (IS_ERR(channel->playback_task)) {
0276 pr_err("Couldn't start thread\n");
0277 return PTR_ERR(channel->playback_task);
0278 }
0279 }
0280
0281 ret = most_start_channel(channel->iface, channel->id, &comp);
0282 if (ret) {
0283 pr_err("most_start_channel() failed!\n");
0284 if (cfg->direction == MOST_CH_TX)
0285 kthread_stop(channel->playback_task);
0286 return ret;
0287 }
0288
0289 runtime->hw = channel->pcm_hardware;
0290 return 0;
0291 }
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303 static int pcm_close(struct snd_pcm_substream *substream)
0304 {
0305 struct channel *channel = substream->private_data;
0306
0307 if (channel->cfg->direction == MOST_CH_TX)
0308 kthread_stop(channel->playback_task);
0309 most_stop_channel(channel->iface, channel->id, &comp);
0310 return 0;
0311 }
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322 static int pcm_prepare(struct snd_pcm_substream *substream)
0323 {
0324 struct channel *channel = substream->private_data;
0325 struct snd_pcm_runtime *runtime = substream->runtime;
0326 struct most_channel_config *cfg = channel->cfg;
0327 int width = snd_pcm_format_physical_width(runtime->format);
0328
0329 channel->copy_fn = NULL;
0330
0331 if (cfg->direction == MOST_CH_TX) {
0332 if (snd_pcm_format_big_endian(runtime->format) || width == 8)
0333 channel->copy_fn = alsa_to_most_memcpy;
0334 else if (width == 16)
0335 channel->copy_fn = alsa_to_most_copy16;
0336 else if (width == 24)
0337 channel->copy_fn = alsa_to_most_copy24;
0338 else if (width == 32)
0339 channel->copy_fn = alsa_to_most_copy32;
0340 } else {
0341 if (snd_pcm_format_big_endian(runtime->format) || width == 8)
0342 channel->copy_fn = most_to_alsa_memcpy;
0343 else if (width == 16)
0344 channel->copy_fn = most_to_alsa_copy16;
0345 else if (width == 24)
0346 channel->copy_fn = most_to_alsa_copy24;
0347 else if (width == 32)
0348 channel->copy_fn = most_to_alsa_copy32;
0349 }
0350
0351 if (!channel->copy_fn)
0352 return -EINVAL;
0353 channel->period_pos = 0;
0354 channel->buffer_pos = 0;
0355 return 0;
0356 }
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368 static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
0369 {
0370 struct channel *channel = substream->private_data;
0371
0372 switch (cmd) {
0373 case SNDRV_PCM_TRIGGER_START:
0374 channel->is_stream_running = true;
0375 wake_up_interruptible(&channel->playback_waitq);
0376 return 0;
0377
0378 case SNDRV_PCM_TRIGGER_STOP:
0379 channel->is_stream_running = false;
0380 return 0;
0381
0382 default:
0383 return -EINVAL;
0384 }
0385 return 0;
0386 }
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396 static snd_pcm_uframes_t pcm_pointer(struct snd_pcm_substream *substream)
0397 {
0398 struct channel *channel = substream->private_data;
0399
0400 return channel->buffer_pos;
0401 }
0402
0403
0404
0405
0406 static const struct snd_pcm_ops pcm_ops = {
0407 .open = pcm_open,
0408 .close = pcm_close,
0409 .prepare = pcm_prepare,
0410 .trigger = pcm_trigger,
0411 .pointer = pcm_pointer,
0412 };
0413
0414 static int split_arg_list(char *buf, u16 *ch_num, char **sample_res)
0415 {
0416 char *num;
0417 int ret;
0418
0419 num = strsep(&buf, "x");
0420 if (!num)
0421 goto err;
0422 ret = kstrtou16(num, 0, ch_num);
0423 if (ret)
0424 goto err;
0425 *sample_res = strsep(&buf, ".\n");
0426 if (!*sample_res)
0427 goto err;
0428 return 0;
0429
0430 err:
0431 pr_err("Bad PCM format\n");
0432 return -EINVAL;
0433 }
0434
0435 static const struct sample_resolution_info {
0436 const char *sample_res;
0437 int bytes;
0438 u64 formats;
0439 } sinfo[] = {
0440 { "8", 1, SNDRV_PCM_FMTBIT_S8 },
0441 { "16", 2, SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE },
0442 { "24", 3, SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE },
0443 { "32", 4, SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE },
0444 };
0445
0446 static int audio_set_hw_params(struct snd_pcm_hardware *pcm_hw,
0447 u16 ch_num, char *sample_res,
0448 struct most_channel_config *cfg)
0449 {
0450 int i;
0451
0452 for (i = 0; i < ARRAY_SIZE(sinfo); i++) {
0453 if (!strcmp(sample_res, sinfo[i].sample_res))
0454 goto found;
0455 }
0456 pr_err("Unsupported PCM format\n");
0457 return -EINVAL;
0458
0459 found:
0460 if (!ch_num) {
0461 pr_err("Bad number of channels\n");
0462 return -EINVAL;
0463 }
0464
0465 if (cfg->subbuffer_size != ch_num * sinfo[i].bytes) {
0466 pr_err("Audio resolution doesn't fit subbuffer size\n");
0467 return -EINVAL;
0468 }
0469
0470 pcm_hw->info = MOST_PCM_INFO;
0471 pcm_hw->rates = SNDRV_PCM_RATE_48000;
0472 pcm_hw->rate_min = 48000;
0473 pcm_hw->rate_max = 48000;
0474 pcm_hw->buffer_bytes_max = cfg->num_buffers * cfg->buffer_size;
0475 pcm_hw->period_bytes_min = cfg->buffer_size;
0476 pcm_hw->period_bytes_max = cfg->buffer_size;
0477 pcm_hw->periods_min = 1;
0478 pcm_hw->periods_max = cfg->num_buffers;
0479 pcm_hw->channels_min = ch_num;
0480 pcm_hw->channels_max = ch_num;
0481 pcm_hw->formats = sinfo[i].formats;
0482 return 0;
0483 }
0484
0485 static void release_adapter(struct sound_adapter *adpt)
0486 {
0487 struct channel *channel, *tmp;
0488
0489 list_for_each_entry_safe(channel, tmp, &adpt->dev_list, list) {
0490 list_del(&channel->list);
0491 kfree(channel);
0492 }
0493 if (adpt->card)
0494 snd_card_free(adpt->card);
0495 list_del(&adpt->list);
0496 kfree(adpt);
0497 }
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511 static int audio_probe_channel(struct most_interface *iface, int channel_id,
0512 struct most_channel_config *cfg,
0513 char *device_name, char *arg_list)
0514 {
0515 struct channel *channel;
0516 struct sound_adapter *adpt;
0517 struct snd_pcm *pcm;
0518 int playback_count = 0;
0519 int capture_count = 0;
0520 int ret;
0521 int direction;
0522 u16 ch_num;
0523 char *sample_res;
0524 char arg_list_cpy[STRING_SIZE];
0525
0526 if (cfg->data_type != MOST_CH_SYNC) {
0527 pr_err("Incompatible channel type\n");
0528 return -EINVAL;
0529 }
0530 strscpy(arg_list_cpy, arg_list, STRING_SIZE);
0531 ret = split_arg_list(arg_list_cpy, &ch_num, &sample_res);
0532 if (ret < 0)
0533 return ret;
0534
0535 list_for_each_entry(adpt, &adpt_list, list) {
0536 if (adpt->iface != iface)
0537 continue;
0538 if (adpt->registered)
0539 return -ENOSPC;
0540 adpt->pcm_dev_idx++;
0541 goto skip_adpt_alloc;
0542 }
0543 adpt = kzalloc(sizeof(*adpt), GFP_KERNEL);
0544 if (!adpt)
0545 return -ENOMEM;
0546
0547 adpt->iface = iface;
0548 INIT_LIST_HEAD(&adpt->dev_list);
0549 iface->priv = adpt;
0550 list_add_tail(&adpt->list, &adpt_list);
0551 ret = snd_card_new(iface->driver_dev, -1, "INIC", THIS_MODULE,
0552 sizeof(*channel), &adpt->card);
0553 if (ret < 0)
0554 goto err_free_adpt;
0555 snprintf(adpt->card->driver, sizeof(adpt->card->driver),
0556 "%s", DRIVER_NAME);
0557 snprintf(adpt->card->shortname, sizeof(adpt->card->shortname),
0558 "Microchip INIC");
0559 snprintf(adpt->card->longname, sizeof(adpt->card->longname),
0560 "%s at %s", adpt->card->shortname, iface->description);
0561 skip_adpt_alloc:
0562 if (get_channel(iface, channel_id)) {
0563 pr_err("channel (%s:%d) is already linked\n",
0564 iface->description, channel_id);
0565 return -EEXIST;
0566 }
0567
0568 if (cfg->direction == MOST_CH_TX) {
0569 playback_count = 1;
0570 direction = SNDRV_PCM_STREAM_PLAYBACK;
0571 } else {
0572 capture_count = 1;
0573 direction = SNDRV_PCM_STREAM_CAPTURE;
0574 }
0575 channel = kzalloc(sizeof(*channel), GFP_KERNEL);
0576 if (!channel) {
0577 ret = -ENOMEM;
0578 goto err_free_adpt;
0579 }
0580 channel->card = adpt->card;
0581 channel->cfg = cfg;
0582 channel->iface = iface;
0583 channel->id = channel_id;
0584 init_waitqueue_head(&channel->playback_waitq);
0585 list_add_tail(&channel->list, &adpt->dev_list);
0586
0587 ret = audio_set_hw_params(&channel->pcm_hardware, ch_num, sample_res,
0588 cfg);
0589 if (ret)
0590 goto err_free_adpt;
0591
0592 ret = snd_pcm_new(adpt->card, device_name, adpt->pcm_dev_idx,
0593 playback_count, capture_count, &pcm);
0594
0595 if (ret < 0)
0596 goto err_free_adpt;
0597
0598 pcm->private_data = channel;
0599 strscpy(pcm->name, device_name, sizeof(pcm->name));
0600 snd_pcm_set_ops(pcm, direction, &pcm_ops);
0601 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
0602 return 0;
0603
0604 err_free_adpt:
0605 release_adapter(adpt);
0606 return ret;
0607 }
0608
0609 static int audio_create_sound_card(void)
0610 {
0611 int ret;
0612 struct sound_adapter *adpt;
0613
0614 list_for_each_entry(adpt, &adpt_list, list) {
0615 if (!adpt->registered)
0616 goto adpt_alloc;
0617 }
0618 return -ENODEV;
0619 adpt_alloc:
0620 ret = snd_card_register(adpt->card);
0621 if (ret < 0) {
0622 release_adapter(adpt);
0623 return ret;
0624 }
0625 adpt->registered = true;
0626 return 0;
0627 }
0628
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638 static int audio_disconnect_channel(struct most_interface *iface,
0639 int channel_id)
0640 {
0641 struct channel *channel;
0642 struct sound_adapter *adpt = iface->priv;
0643
0644 channel = get_channel(iface, channel_id);
0645 if (!channel)
0646 return -EINVAL;
0647
0648 list_del(&channel->list);
0649
0650 kfree(channel);
0651 if (list_empty(&adpt->dev_list))
0652 release_adapter(adpt);
0653 return 0;
0654 }
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665 static int audio_rx_completion(struct mbo *mbo)
0666 {
0667 struct channel *channel = get_channel(mbo->ifp, mbo->hdm_channel_id);
0668 bool period_elapsed = false;
0669
0670 if (!channel)
0671 return -EINVAL;
0672 if (channel->is_stream_running)
0673 period_elapsed = copy_data(channel, mbo);
0674 most_put_mbo(mbo);
0675 if (period_elapsed)
0676 snd_pcm_period_elapsed(channel->substream);
0677 return 0;
0678 }
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691 static int audio_tx_completion(struct most_interface *iface, int channel_id)
0692 {
0693 struct channel *channel = get_channel(iface, channel_id);
0694
0695 if (!channel)
0696 return -EINVAL;
0697
0698 wake_up_interruptible(&channel->playback_waitq);
0699 return 0;
0700 }
0701
0702
0703
0704
0705 static struct most_component comp = {
0706 .mod = THIS_MODULE,
0707 .name = DRIVER_NAME,
0708 .probe_channel = audio_probe_channel,
0709 .disconnect_channel = audio_disconnect_channel,
0710 .rx_completion = audio_rx_completion,
0711 .tx_completion = audio_tx_completion,
0712 .cfg_complete = audio_create_sound_card,
0713 };
0714
0715 static int __init audio_init(void)
0716 {
0717 int ret;
0718
0719 INIT_LIST_HEAD(&adpt_list);
0720
0721 ret = most_register_component(&comp);
0722 if (ret) {
0723 pr_err("Failed to register %s\n", comp.name);
0724 return ret;
0725 }
0726 ret = most_register_configfs_subsys(&comp);
0727 if (ret) {
0728 pr_err("Failed to register %s configfs subsys\n", comp.name);
0729 most_deregister_component(&comp);
0730 }
0731 return ret;
0732 }
0733
0734 static void __exit audio_exit(void)
0735 {
0736 most_deregister_configfs_subsys(&comp);
0737 most_deregister_component(&comp);
0738 }
0739
0740 module_init(audio_init);
0741 module_exit(audio_exit);
0742
0743 MODULE_LICENSE("GPL");
0744 MODULE_AUTHOR("Christian Gromm <christian.gromm@microchip.com>");
0745 MODULE_DESCRIPTION("Sound Component Module for Mostcore");