| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (c) by Jaroslav Kysela <perex@perex.cz> |
|---|
| 3 | 4 | * Creative Labs, Inc. |
|---|
| .. | .. |
|---|
| 9 | 10 | * |
|---|
| 10 | 11 | * TODO: |
|---|
| 11 | 12 | * -- |
|---|
| 12 | | - * |
|---|
| 13 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 14 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 15 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 16 | | - * (at your option) any later version. |
|---|
| 17 | | - * |
|---|
| 18 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 19 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 20 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 21 | | - * GNU General Public License for more details. |
|---|
| 22 | | - * |
|---|
| 23 | | - * You should have received a copy of the GNU General Public License |
|---|
| 24 | | - * along with this program; if not, write to the Free Software |
|---|
| 25 | | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 26 | | - * |
|---|
| 27 | 13 | */ |
|---|
| 28 | 14 | |
|---|
| 29 | 15 | #include <linux/pci.h> |
|---|
| .. | .. |
|---|
| 137 | 123 | epcm->voices[0]->epcm = epcm; |
|---|
| 138 | 124 | if (voices > 1) { |
|---|
| 139 | 125 | for (i = 1; i < voices; i++) { |
|---|
| 140 | | - epcm->voices[i] = &epcm->emu->voices[epcm->voices[0]->number + i]; |
|---|
| 126 | + epcm->voices[i] = &epcm->emu->voices[(epcm->voices[0]->number + i) % NUM_G]; |
|---|
| 141 | 127 | epcm->voices[i]->epcm = epcm; |
|---|
| 142 | 128 | } |
|---|
| 143 | 129 | } |
|---|
| .. | .. |
|---|
| 583 | 569 | .fifo_size = 0, |
|---|
| 584 | 570 | }; |
|---|
| 585 | 571 | |
|---|
| 586 | | -static int snd_emu10k1_capture_hw_params(struct snd_pcm_substream *substream, |
|---|
| 587 | | - struct snd_pcm_hw_params *hw_params) |
|---|
| 588 | | -{ |
|---|
| 589 | | - return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); |
|---|
| 590 | | -} |
|---|
| 591 | | - |
|---|
| 592 | | -static int snd_emu10k1_capture_hw_free(struct snd_pcm_substream *substream) |
|---|
| 593 | | -{ |
|---|
| 594 | | - return snd_pcm_lib_free_pages(substream); |
|---|
| 595 | | -} |
|---|
| 596 | | - |
|---|
| 597 | 572 | static int snd_emu10k1_capture_prepare(struct snd_pcm_substream *substream) |
|---|
| 598 | 573 | { |
|---|
| 599 | 574 | struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream); |
|---|
| .. | .. |
|---|
| 778 | 753 | case SNDRV_PCM_TRIGGER_START: |
|---|
| 779 | 754 | snd_emu10k1_playback_invalidate_cache(emu, 1, epcm->extra); /* do we need this? */ |
|---|
| 780 | 755 | snd_emu10k1_playback_invalidate_cache(emu, 0, epcm->voices[0]); |
|---|
| 781 | | - /* fall through */ |
|---|
| 756 | + fallthrough; |
|---|
| 782 | 757 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
|---|
| 783 | 758 | case SNDRV_PCM_TRIGGER_RESUME: |
|---|
| 784 | 759 | if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE) |
|---|
| .. | .. |
|---|
| 927 | 902 | snd_emu10k1_playback_invalidate_cache(emu, 0, epcm->voices[i]); |
|---|
| 928 | 903 | } |
|---|
| 929 | 904 | snd_emu10k1_playback_invalidate_cache(emu, 1, epcm->extra); |
|---|
| 930 | | - |
|---|
| 931 | | - /* fall through */ |
|---|
| 905 | + fallthrough; |
|---|
| 932 | 906 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
|---|
| 933 | 907 | case SNDRV_PCM_TRIGGER_RESUME: |
|---|
| 934 | 908 | snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, 1, NULL); |
|---|
| .. | .. |
|---|
| 1374 | 1348 | static const struct snd_pcm_ops snd_emu10k1_playback_ops = { |
|---|
| 1375 | 1349 | .open = snd_emu10k1_playback_open, |
|---|
| 1376 | 1350 | .close = snd_emu10k1_playback_close, |
|---|
| 1377 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1378 | 1351 | .hw_params = snd_emu10k1_playback_hw_params, |
|---|
| 1379 | 1352 | .hw_free = snd_emu10k1_playback_hw_free, |
|---|
| 1380 | 1353 | .prepare = snd_emu10k1_playback_prepare, |
|---|
| 1381 | 1354 | .trigger = snd_emu10k1_playback_trigger, |
|---|
| 1382 | 1355 | .pointer = snd_emu10k1_playback_pointer, |
|---|
| 1383 | | - .page = snd_pcm_sgbuf_ops_page, |
|---|
| 1384 | 1356 | }; |
|---|
| 1385 | 1357 | |
|---|
| 1386 | 1358 | static const struct snd_pcm_ops snd_emu10k1_capture_ops = { |
|---|
| 1387 | 1359 | .open = snd_emu10k1_capture_open, |
|---|
| 1388 | 1360 | .close = snd_emu10k1_capture_close, |
|---|
| 1389 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1390 | | - .hw_params = snd_emu10k1_capture_hw_params, |
|---|
| 1391 | | - .hw_free = snd_emu10k1_capture_hw_free, |
|---|
| 1392 | 1361 | .prepare = snd_emu10k1_capture_prepare, |
|---|
| 1393 | 1362 | .trigger = snd_emu10k1_capture_trigger, |
|---|
| 1394 | 1363 | .pointer = snd_emu10k1_capture_pointer, |
|---|
| .. | .. |
|---|
| 1398 | 1367 | static const struct snd_pcm_ops snd_emu10k1_efx_playback_ops = { |
|---|
| 1399 | 1368 | .open = snd_emu10k1_efx_playback_open, |
|---|
| 1400 | 1369 | .close = snd_emu10k1_efx_playback_close, |
|---|
| 1401 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1402 | 1370 | .hw_params = snd_emu10k1_playback_hw_params, |
|---|
| 1403 | 1371 | .hw_free = snd_emu10k1_efx_playback_hw_free, |
|---|
| 1404 | 1372 | .prepare = snd_emu10k1_efx_playback_prepare, |
|---|
| 1405 | 1373 | .trigger = snd_emu10k1_efx_playback_trigger, |
|---|
| 1406 | 1374 | .pointer = snd_emu10k1_efx_playback_pointer, |
|---|
| 1407 | | - .page = snd_pcm_sgbuf_ops_page, |
|---|
| 1408 | 1375 | }; |
|---|
| 1409 | 1376 | |
|---|
| 1410 | 1377 | int snd_emu10k1_pcm(struct snd_emu10k1 *emu, int device) |
|---|
| .. | .. |
|---|
| 1426 | 1393 | strcpy(pcm->name, "ADC Capture/Standard PCM Playback"); |
|---|
| 1427 | 1394 | emu->pcm = pcm; |
|---|
| 1428 | 1395 | |
|---|
| 1396 | + /* playback substream can't use managed buffers due to alignment */ |
|---|
| 1429 | 1397 | for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next) |
|---|
| 1430 | | - if ((err = snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_SG, snd_dma_pci_data(emu->pci), 64*1024, 64*1024)) < 0) |
|---|
| 1431 | | - return err; |
|---|
| 1398 | + snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_SG, |
|---|
| 1399 | + &emu->pci->dev, |
|---|
| 1400 | + 64*1024, 64*1024); |
|---|
| 1432 | 1401 | |
|---|
| 1433 | 1402 | for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; substream; substream = substream->next) |
|---|
| 1434 | | - snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024); |
|---|
| 1403 | + snd_pcm_set_managed_buffer(substream, SNDRV_DMA_TYPE_DEV, |
|---|
| 1404 | + &emu->pci->dev, 64*1024, 64*1024); |
|---|
| 1435 | 1405 | |
|---|
| 1436 | 1406 | return 0; |
|---|
| 1437 | 1407 | } |
|---|
| .. | .. |
|---|
| 1455 | 1425 | emu->pcm_multi = pcm; |
|---|
| 1456 | 1426 | |
|---|
| 1457 | 1427 | for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next) |
|---|
| 1458 | | - if ((err = snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_SG, snd_dma_pci_data(emu->pci), 64*1024, 64*1024)) < 0) |
|---|
| 1459 | | - return err; |
|---|
| 1428 | + snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_SG, |
|---|
| 1429 | + &emu->pci->dev, |
|---|
| 1430 | + 64*1024, 64*1024); |
|---|
| 1460 | 1431 | |
|---|
| 1461 | 1432 | return 0; |
|---|
| 1462 | 1433 | } |
|---|
| .. | .. |
|---|
| 1465 | 1436 | static const struct snd_pcm_ops snd_emu10k1_capture_mic_ops = { |
|---|
| 1466 | 1437 | .open = snd_emu10k1_capture_mic_open, |
|---|
| 1467 | 1438 | .close = snd_emu10k1_capture_mic_close, |
|---|
| 1468 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1469 | | - .hw_params = snd_emu10k1_capture_hw_params, |
|---|
| 1470 | | - .hw_free = snd_emu10k1_capture_hw_free, |
|---|
| 1471 | 1439 | .prepare = snd_emu10k1_capture_prepare, |
|---|
| 1472 | 1440 | .trigger = snd_emu10k1_capture_trigger, |
|---|
| 1473 | 1441 | .pointer = snd_emu10k1_capture_pointer, |
|---|
| .. | .. |
|---|
| 1489 | 1457 | strcpy(pcm->name, "Mic Capture"); |
|---|
| 1490 | 1458 | emu->pcm_mic = pcm; |
|---|
| 1491 | 1459 | |
|---|
| 1492 | | - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024); |
|---|
| 1460 | + snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, &emu->pci->dev, |
|---|
| 1461 | + 64*1024, 64*1024); |
|---|
| 1493 | 1462 | |
|---|
| 1494 | 1463 | return 0; |
|---|
| 1495 | 1464 | } |
|---|
| .. | .. |
|---|
| 1560 | 1529 | static const struct snd_pcm_ops snd_emu10k1_capture_efx_ops = { |
|---|
| 1561 | 1530 | .open = snd_emu10k1_capture_efx_open, |
|---|
| 1562 | 1531 | .close = snd_emu10k1_capture_efx_close, |
|---|
| 1563 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1564 | | - .hw_params = snd_emu10k1_capture_hw_params, |
|---|
| 1565 | | - .hw_free = snd_emu10k1_capture_hw_free, |
|---|
| 1566 | 1532 | .prepare = snd_emu10k1_capture_prepare, |
|---|
| 1567 | 1533 | .trigger = snd_emu10k1_capture_trigger, |
|---|
| 1568 | 1534 | .pointer = snd_emu10k1_capture_pointer, |
|---|
| .. | .. |
|---|
| 1643 | 1609 | fx8010_pb_trans_copy); |
|---|
| 1644 | 1610 | } |
|---|
| 1645 | 1611 | |
|---|
| 1646 | | -static int snd_emu10k1_fx8010_playback_hw_params(struct snd_pcm_substream *substream, |
|---|
| 1647 | | - struct snd_pcm_hw_params *hw_params) |
|---|
| 1648 | | -{ |
|---|
| 1649 | | - return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); |
|---|
| 1650 | | -} |
|---|
| 1651 | | - |
|---|
| 1652 | 1612 | static int snd_emu10k1_fx8010_playback_hw_free(struct snd_pcm_substream *substream) |
|---|
| 1653 | 1613 | { |
|---|
| 1654 | 1614 | struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream); |
|---|
| .. | .. |
|---|
| 1657 | 1617 | |
|---|
| 1658 | 1618 | for (i = 0; i < pcm->channels; i++) |
|---|
| 1659 | 1619 | snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + 0x80 + pcm->etram[i], 0, 0); |
|---|
| 1660 | | - snd_pcm_lib_free_pages(substream); |
|---|
| 1661 | 1620 | return 0; |
|---|
| 1662 | 1621 | } |
|---|
| 1663 | 1622 | |
|---|
| .. | .. |
|---|
| 1753 | 1712 | { |
|---|
| 1754 | 1713 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
|---|
| 1755 | 1714 | SNDRV_PCM_INFO_RESUME | |
|---|
| 1756 | | - /* SNDRV_PCM_INFO_MMAP_VALID | */ SNDRV_PCM_INFO_PAUSE), |
|---|
| 1715 | + /* SNDRV_PCM_INFO_MMAP_VALID | */ SNDRV_PCM_INFO_PAUSE | |
|---|
| 1716 | + SNDRV_PCM_INFO_SYNC_APPLPTR), |
|---|
| 1757 | 1717 | .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, |
|---|
| 1758 | 1718 | .rates = SNDRV_PCM_RATE_48000, |
|---|
| 1759 | 1719 | .rate_min = 48000, |
|---|
| .. | .. |
|---|
| 1801 | 1761 | static const struct snd_pcm_ops snd_emu10k1_fx8010_playback_ops = { |
|---|
| 1802 | 1762 | .open = snd_emu10k1_fx8010_playback_open, |
|---|
| 1803 | 1763 | .close = snd_emu10k1_fx8010_playback_close, |
|---|
| 1804 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1805 | | - .hw_params = snd_emu10k1_fx8010_playback_hw_params, |
|---|
| 1806 | 1764 | .hw_free = snd_emu10k1_fx8010_playback_hw_free, |
|---|
| 1807 | 1765 | .prepare = snd_emu10k1_fx8010_playback_prepare, |
|---|
| 1808 | 1766 | .trigger = snd_emu10k1_fx8010_playback_trigger, |
|---|
| .. | .. |
|---|
| 1861 | 1819 | if (err < 0) |
|---|
| 1862 | 1820 | return err; |
|---|
| 1863 | 1821 | |
|---|
| 1864 | | - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024); |
|---|
| 1822 | + snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, &emu->pci->dev, |
|---|
| 1823 | + 64*1024, 64*1024); |
|---|
| 1865 | 1824 | |
|---|
| 1866 | 1825 | return 0; |
|---|
| 1867 | 1826 | } |
|---|