.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Driver for A2 audio system used in SGI machines |
---|
3 | 4 | * Copyright (c) 2008 Thomas Bogendoerfer <tsbogend@alpha.fanken.de> |
---|
4 | 5 | * |
---|
5 | 6 | * Based on OSS code from Ladislav Michl <ladis@linux-mips.org>, which |
---|
6 | 7 | * was based on code from Ulf Carlsson |
---|
7 | | - * |
---|
8 | | - * This program is free software; you can redistribute it and/or modify |
---|
9 | | - * it under the terms of the GNU General Public License version 2 as |
---|
10 | | - * published by the Free Software Foundation. |
---|
11 | | - * |
---|
12 | | - * This program is distributed in the hope that it will be useful, |
---|
13 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
14 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
15 | | - * GNU General Public License for more details. |
---|
16 | | - * |
---|
17 | | - * You should have received a copy of the GNU General Public License |
---|
18 | | - * along with this program; if not, write to the Free Software |
---|
19 | | - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
---|
20 | | - * |
---|
21 | 8 | */ |
---|
22 | 9 | #include <linux/kernel.h> |
---|
23 | 10 | #include <linux/init.h> |
---|
.. | .. |
---|
454 | 441 | hal2->adc.pbus.pbus->pbdma_ctrl = HPC3_PDMACTRL_LD; |
---|
455 | 442 | } |
---|
456 | 443 | |
---|
457 | | -static int hal2_alloc_dmabuf(struct hal2_codec *codec) |
---|
| 444 | +static int hal2_alloc_dmabuf(struct snd_hal2 *hal2, struct hal2_codec *codec, |
---|
| 445 | + enum dma_data_direction buffer_dir) |
---|
458 | 446 | { |
---|
| 447 | + struct device *dev = hal2->card->dev; |
---|
459 | 448 | struct hal2_desc *desc; |
---|
460 | 449 | dma_addr_t desc_dma, buffer_dma; |
---|
461 | 450 | int count = H2_BUF_SIZE / H2_BLOCK_SIZE; |
---|
462 | 451 | int i; |
---|
463 | 452 | |
---|
464 | | - codec->buffer = dma_alloc_attrs(NULL, H2_BUF_SIZE, &buffer_dma, |
---|
465 | | - GFP_KERNEL, DMA_ATTR_NON_CONSISTENT); |
---|
| 453 | + codec->buffer = dma_alloc_noncoherent(dev, H2_BUF_SIZE, &buffer_dma, |
---|
| 454 | + buffer_dir, GFP_KERNEL); |
---|
466 | 455 | if (!codec->buffer) |
---|
467 | 456 | return -ENOMEM; |
---|
468 | | - desc = dma_alloc_attrs(NULL, count * sizeof(struct hal2_desc), |
---|
469 | | - &desc_dma, GFP_KERNEL, DMA_ATTR_NON_CONSISTENT); |
---|
| 457 | + desc = dma_alloc_noncoherent(dev, count * sizeof(struct hal2_desc), |
---|
| 458 | + &desc_dma, DMA_BIDIRECTIONAL, GFP_KERNEL); |
---|
470 | 459 | if (!desc) { |
---|
471 | | - dma_free_attrs(NULL, H2_BUF_SIZE, codec->buffer, buffer_dma, |
---|
472 | | - DMA_ATTR_NON_CONSISTENT); |
---|
| 460 | + dma_free_noncoherent(dev, H2_BUF_SIZE, codec->buffer, buffer_dma, |
---|
| 461 | + buffer_dir); |
---|
473 | 462 | return -ENOMEM; |
---|
474 | 463 | } |
---|
475 | 464 | codec->buffer_dma = buffer_dma; |
---|
.. | .. |
---|
482 | 471 | desc_dma : desc_dma + (i + 1) * sizeof(struct hal2_desc); |
---|
483 | 472 | desc++; |
---|
484 | 473 | } |
---|
485 | | - dma_cache_sync(NULL, codec->desc, count * sizeof(struct hal2_desc), |
---|
486 | | - DMA_TO_DEVICE); |
---|
| 474 | + dma_sync_single_for_device(dev, codec->desc_dma, |
---|
| 475 | + count * sizeof(struct hal2_desc), |
---|
| 476 | + DMA_BIDIRECTIONAL); |
---|
487 | 477 | codec->desc_count = count; |
---|
488 | 478 | return 0; |
---|
489 | 479 | } |
---|
490 | 480 | |
---|
491 | | -static void hal2_free_dmabuf(struct hal2_codec *codec) |
---|
| 481 | +static void hal2_free_dmabuf(struct snd_hal2 *hal2, struct hal2_codec *codec, |
---|
| 482 | + enum dma_data_direction buffer_dir) |
---|
492 | 483 | { |
---|
493 | | - dma_free_attrs(NULL, codec->desc_count * sizeof(struct hal2_desc), |
---|
494 | | - codec->desc, codec->desc_dma, DMA_ATTR_NON_CONSISTENT); |
---|
495 | | - dma_free_attrs(NULL, H2_BUF_SIZE, codec->buffer, codec->buffer_dma, |
---|
496 | | - DMA_ATTR_NON_CONSISTENT); |
---|
| 484 | + struct device *dev = hal2->card->dev; |
---|
| 485 | + |
---|
| 486 | + dma_free_noncoherent(dev, codec->desc_count * sizeof(struct hal2_desc), |
---|
| 487 | + codec->desc, codec->desc_dma, DMA_BIDIRECTIONAL); |
---|
| 488 | + dma_free_noncoherent(dev, H2_BUF_SIZE, codec->buffer, codec->buffer_dma, |
---|
| 489 | + buffer_dir); |
---|
497 | 490 | } |
---|
498 | 491 | |
---|
499 | 492 | static const struct snd_pcm_hardware hal2_pcm_hw = { |
---|
500 | 493 | .info = (SNDRV_PCM_INFO_MMAP | |
---|
501 | 494 | SNDRV_PCM_INFO_MMAP_VALID | |
---|
502 | 495 | SNDRV_PCM_INFO_INTERLEAVED | |
---|
503 | | - SNDRV_PCM_INFO_BLOCK_TRANSFER), |
---|
| 496 | + SNDRV_PCM_INFO_BLOCK_TRANSFER | |
---|
| 497 | + SNDRV_PCM_INFO_SYNC_APPLPTR), |
---|
504 | 498 | .formats = SNDRV_PCM_FMTBIT_S16_BE, |
---|
505 | 499 | .rates = SNDRV_PCM_RATE_8000_48000, |
---|
506 | 500 | .rate_min = 8000, |
---|
.. | .. |
---|
514 | 508 | .periods_max = 1024, |
---|
515 | 509 | }; |
---|
516 | 510 | |
---|
517 | | -static int hal2_pcm_hw_params(struct snd_pcm_substream *substream, |
---|
518 | | - struct snd_pcm_hw_params *params) |
---|
519 | | -{ |
---|
520 | | - int err; |
---|
521 | | - |
---|
522 | | - err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); |
---|
523 | | - if (err < 0) |
---|
524 | | - return err; |
---|
525 | | - |
---|
526 | | - return 0; |
---|
527 | | -} |
---|
528 | | - |
---|
529 | | -static int hal2_pcm_hw_free(struct snd_pcm_substream *substream) |
---|
530 | | -{ |
---|
531 | | - return snd_pcm_lib_free_pages(substream); |
---|
532 | | -} |
---|
533 | | - |
---|
534 | 511 | static int hal2_playback_open(struct snd_pcm_substream *substream) |
---|
535 | 512 | { |
---|
536 | 513 | struct snd_pcm_runtime *runtime = substream->runtime; |
---|
537 | 514 | struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); |
---|
538 | | - int err; |
---|
539 | 515 | |
---|
540 | 516 | runtime->hw = hal2_pcm_hw; |
---|
541 | | - |
---|
542 | | - err = hal2_alloc_dmabuf(&hal2->dac); |
---|
543 | | - if (err) |
---|
544 | | - return err; |
---|
545 | | - return 0; |
---|
| 517 | + return hal2_alloc_dmabuf(hal2, &hal2->dac, DMA_TO_DEVICE); |
---|
546 | 518 | } |
---|
547 | 519 | |
---|
548 | 520 | static int hal2_playback_close(struct snd_pcm_substream *substream) |
---|
549 | 521 | { |
---|
550 | 522 | struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); |
---|
551 | 523 | |
---|
552 | | - hal2_free_dmabuf(&hal2->dac); |
---|
| 524 | + hal2_free_dmabuf(hal2, &hal2->dac, DMA_TO_DEVICE); |
---|
553 | 525 | return 0; |
---|
554 | 526 | } |
---|
555 | 527 | |
---|
.. | .. |
---|
563 | 535 | dac->sample_rate = hal2_compute_rate(dac, runtime->rate); |
---|
564 | 536 | memset(&dac->pcm_indirect, 0, sizeof(dac->pcm_indirect)); |
---|
565 | 537 | dac->pcm_indirect.hw_buffer_size = H2_BUF_SIZE; |
---|
| 538 | + dac->pcm_indirect.hw_queue_size = H2_BUF_SIZE / 2; |
---|
| 539 | + dac->pcm_indirect.hw_io = dac->buffer_dma; |
---|
566 | 540 | dac->pcm_indirect.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); |
---|
567 | 541 | dac->substream = substream; |
---|
568 | 542 | hal2_setup_dac(hal2); |
---|
.. | .. |
---|
575 | 549 | |
---|
576 | 550 | switch (cmd) { |
---|
577 | 551 | case SNDRV_PCM_TRIGGER_START: |
---|
578 | | - hal2->dac.pcm_indirect.hw_io = hal2->dac.buffer_dma; |
---|
579 | | - hal2->dac.pcm_indirect.hw_data = 0; |
---|
580 | | - substream->ops->ack(substream); |
---|
581 | 552 | hal2_start_dac(hal2); |
---|
582 | 553 | break; |
---|
583 | 554 | case SNDRV_PCM_TRIGGER_STOP: |
---|
.. | .. |
---|
606 | 577 | unsigned char *buf = hal2->dac.buffer + rec->hw_data; |
---|
607 | 578 | |
---|
608 | 579 | memcpy(buf, substream->runtime->dma_area + rec->sw_data, bytes); |
---|
609 | | - dma_cache_sync(NULL, buf, bytes, DMA_TO_DEVICE); |
---|
| 580 | + dma_sync_single_for_device(hal2->card->dev, |
---|
| 581 | + hal2->dac.buffer_dma + rec->hw_data, bytes, |
---|
| 582 | + DMA_TO_DEVICE); |
---|
610 | 583 | |
---|
611 | 584 | } |
---|
612 | 585 | |
---|
.. | .. |
---|
615 | 588 | struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); |
---|
616 | 589 | struct hal2_codec *dac = &hal2->dac; |
---|
617 | 590 | |
---|
618 | | - dac->pcm_indirect.hw_queue_size = H2_BUF_SIZE / 2; |
---|
619 | 591 | return snd_pcm_indirect_playback_transfer(substream, |
---|
620 | 592 | &dac->pcm_indirect, |
---|
621 | 593 | hal2_playback_transfer); |
---|
.. | .. |
---|
625 | 597 | { |
---|
626 | 598 | struct snd_pcm_runtime *runtime = substream->runtime; |
---|
627 | 599 | struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); |
---|
628 | | - struct hal2_codec *adc = &hal2->adc; |
---|
629 | | - int err; |
---|
630 | 600 | |
---|
631 | 601 | runtime->hw = hal2_pcm_hw; |
---|
632 | | - |
---|
633 | | - err = hal2_alloc_dmabuf(adc); |
---|
634 | | - if (err) |
---|
635 | | - return err; |
---|
636 | | - return 0; |
---|
| 602 | + return hal2_alloc_dmabuf(hal2, &hal2->adc, DMA_FROM_DEVICE); |
---|
637 | 603 | } |
---|
638 | 604 | |
---|
639 | 605 | static int hal2_capture_close(struct snd_pcm_substream *substream) |
---|
640 | 606 | { |
---|
641 | 607 | struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); |
---|
642 | 608 | |
---|
643 | | - hal2_free_dmabuf(&hal2->adc); |
---|
| 609 | + hal2_free_dmabuf(hal2, &hal2->adc, DMA_FROM_DEVICE); |
---|
644 | 610 | return 0; |
---|
645 | 611 | } |
---|
646 | 612 | |
---|
.. | .. |
---|
655 | 621 | memset(&adc->pcm_indirect, 0, sizeof(adc->pcm_indirect)); |
---|
656 | 622 | adc->pcm_indirect.hw_buffer_size = H2_BUF_SIZE; |
---|
657 | 623 | adc->pcm_indirect.hw_queue_size = H2_BUF_SIZE / 2; |
---|
| 624 | + adc->pcm_indirect.hw_io = adc->buffer_dma; |
---|
658 | 625 | adc->pcm_indirect.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); |
---|
659 | 626 | adc->substream = substream; |
---|
660 | 627 | hal2_setup_adc(hal2); |
---|
.. | .. |
---|
667 | 634 | |
---|
668 | 635 | switch (cmd) { |
---|
669 | 636 | case SNDRV_PCM_TRIGGER_START: |
---|
670 | | - hal2->adc.pcm_indirect.hw_io = hal2->adc.buffer_dma; |
---|
671 | | - hal2->adc.pcm_indirect.hw_data = 0; |
---|
672 | | - printk(KERN_DEBUG "buffer_dma %x\n", hal2->adc.buffer_dma); |
---|
673 | 637 | hal2_start_adc(hal2); |
---|
674 | 638 | break; |
---|
675 | 639 | case SNDRV_PCM_TRIGGER_STOP: |
---|
.. | .. |
---|
697 | 661 | struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); |
---|
698 | 662 | unsigned char *buf = hal2->adc.buffer + rec->hw_data; |
---|
699 | 663 | |
---|
700 | | - dma_cache_sync(NULL, buf, bytes, DMA_FROM_DEVICE); |
---|
| 664 | + dma_sync_single_for_cpu(hal2->card->dev, |
---|
| 665 | + hal2->adc.buffer_dma + rec->hw_data, bytes, |
---|
| 666 | + DMA_FROM_DEVICE); |
---|
701 | 667 | memcpy(substream->runtime->dma_area + rec->sw_data, buf, bytes); |
---|
702 | 668 | } |
---|
703 | 669 | |
---|
.. | .. |
---|
714 | 680 | static const struct snd_pcm_ops hal2_playback_ops = { |
---|
715 | 681 | .open = hal2_playback_open, |
---|
716 | 682 | .close = hal2_playback_close, |
---|
717 | | - .ioctl = snd_pcm_lib_ioctl, |
---|
718 | | - .hw_params = hal2_pcm_hw_params, |
---|
719 | | - .hw_free = hal2_pcm_hw_free, |
---|
720 | 683 | .prepare = hal2_playback_prepare, |
---|
721 | 684 | .trigger = hal2_playback_trigger, |
---|
722 | 685 | .pointer = hal2_playback_pointer, |
---|
.. | .. |
---|
726 | 689 | static const struct snd_pcm_ops hal2_capture_ops = { |
---|
727 | 690 | .open = hal2_capture_open, |
---|
728 | 691 | .close = hal2_capture_close, |
---|
729 | | - .ioctl = snd_pcm_lib_ioctl, |
---|
730 | | - .hw_params = hal2_pcm_hw_params, |
---|
731 | | - .hw_free = hal2_pcm_hw_free, |
---|
732 | 692 | .prepare = hal2_capture_prepare, |
---|
733 | 693 | .trigger = hal2_capture_trigger, |
---|
734 | 694 | .pointer = hal2_capture_pointer, |
---|
.. | .. |
---|
753 | 713 | &hal2_playback_ops); |
---|
754 | 714 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, |
---|
755 | 715 | &hal2_capture_ops); |
---|
756 | | - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, |
---|
757 | | - snd_dma_continuous_data(GFP_KERNEL), |
---|
758 | | - 0, 1024 * 1024); |
---|
| 716 | + snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, |
---|
| 717 | + NULL, 0, 1024 * 1024); |
---|
759 | 718 | |
---|
760 | 719 | return 0; |
---|
761 | 720 | } |
---|
.. | .. |
---|
769 | 728 | return 0; |
---|
770 | 729 | } |
---|
771 | 730 | |
---|
772 | | -static struct snd_device_ops hal2_ops = { |
---|
| 731 | +static const struct snd_device_ops hal2_ops = { |
---|
773 | 732 | .dev_free = hal2_dev_free, |
---|
774 | 733 | }; |
---|
775 | 734 | |
---|