| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (c) by Jaroslav Kysela <perex@perex.cz> |
|---|
| 3 | 4 | * Routines for control of GF1 chip (PCM things) |
|---|
| .. | .. |
|---|
| 7 | 8 | * |
|---|
| 8 | 9 | * This code emulates autoinit DMA transfer for playback, recording by GF1 |
|---|
| 9 | 10 | * chip doesn't support autoinit DMA. |
|---|
| 10 | | - * |
|---|
| 11 | | - * |
|---|
| 12 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 13 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 14 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 15 | | - * (at your option) any later version. |
|---|
| 16 | | - * |
|---|
| 17 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 18 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 19 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 20 | | - * GNU General Public License for more details. |
|---|
| 21 | | - * |
|---|
| 22 | | - * You should have received a copy of the GNU General Public License |
|---|
| 23 | | - * along with this program; if not, write to the Free Software |
|---|
| 24 | | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 25 | | - * |
|---|
| 26 | 11 | */ |
|---|
| 27 | 12 | |
|---|
| 28 | 13 | #include <asm/dma.h> |
|---|
| .. | .. |
|---|
| 438 | 423 | struct snd_gus_card *gus = snd_pcm_substream_chip(substream); |
|---|
| 439 | 424 | struct snd_pcm_runtime *runtime = substream->runtime; |
|---|
| 440 | 425 | struct gus_pcm_private *pcmp = runtime->private_data; |
|---|
| 441 | | - int err; |
|---|
| 442 | | - |
|---|
| 443 | | - if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) |
|---|
| 444 | | - return err; |
|---|
| 445 | | - if (err > 0) { /* change */ |
|---|
| 426 | + |
|---|
| 427 | + if (runtime->buffer_changed) { |
|---|
| 446 | 428 | struct snd_gf1_mem_block *block; |
|---|
| 447 | 429 | if (pcmp->memory > 0) { |
|---|
| 448 | 430 | snd_gf1_mem_free(&gus->gf1.mem_alloc, pcmp->memory); |
|---|
| .. | .. |
|---|
| 486 | 468 | struct snd_pcm_runtime *runtime = substream->runtime; |
|---|
| 487 | 469 | struct gus_pcm_private *pcmp = runtime->private_data; |
|---|
| 488 | 470 | |
|---|
| 489 | | - snd_pcm_lib_free_pages(substream); |
|---|
| 490 | 471 | if (pcmp->pvoices[0]) { |
|---|
| 491 | 472 | snd_gf1_free_voice(pcmp->gus, pcmp->pvoices[0]); |
|---|
| 492 | 473 | pcmp->pvoices[0] = NULL; |
|---|
| .. | .. |
|---|
| 589 | 570 | gus->gf1.pcm_rcntrl_reg |= 4; |
|---|
| 590 | 571 | if (snd_pcm_format_unsigned(params_format(hw_params))) |
|---|
| 591 | 572 | gus->gf1.pcm_rcntrl_reg |= 0x80; |
|---|
| 592 | | - return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); |
|---|
| 593 | | -} |
|---|
| 594 | | - |
|---|
| 595 | | -static int snd_gf1_pcm_capture_hw_free(struct snd_pcm_substream *substream) |
|---|
| 596 | | -{ |
|---|
| 597 | | - return snd_pcm_lib_free_pages(substream); |
|---|
| 573 | + return 0; |
|---|
| 598 | 574 | } |
|---|
| 599 | 575 | |
|---|
| 600 | 576 | static int snd_gf1_pcm_capture_prepare(struct snd_pcm_substream *substream) |
|---|
| .. | .. |
|---|
| 845 | 821 | static const struct snd_pcm_ops snd_gf1_pcm_playback_ops = { |
|---|
| 846 | 822 | .open = snd_gf1_pcm_playback_open, |
|---|
| 847 | 823 | .close = snd_gf1_pcm_playback_close, |
|---|
| 848 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 849 | 824 | .hw_params = snd_gf1_pcm_playback_hw_params, |
|---|
| 850 | 825 | .hw_free = snd_gf1_pcm_playback_hw_free, |
|---|
| 851 | 826 | .prepare = snd_gf1_pcm_playback_prepare, |
|---|
| .. | .. |
|---|
| 859 | 834 | static const struct snd_pcm_ops snd_gf1_pcm_capture_ops = { |
|---|
| 860 | 835 | .open = snd_gf1_pcm_capture_open, |
|---|
| 861 | 836 | .close = snd_gf1_pcm_capture_close, |
|---|
| 862 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 863 | 837 | .hw_params = snd_gf1_pcm_capture_hw_params, |
|---|
| 864 | | - .hw_free = snd_gf1_pcm_capture_hw_free, |
|---|
| 865 | 838 | .prepare = snd_gf1_pcm_capture_prepare, |
|---|
| 866 | 839 | .trigger = snd_gf1_pcm_capture_trigger, |
|---|
| 867 | 840 | .pointer = snd_gf1_pcm_capture_pointer, |
|---|
| .. | .. |
|---|
| 890 | 863 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_gf1_pcm_playback_ops); |
|---|
| 891 | 864 | |
|---|
| 892 | 865 | for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next) |
|---|
| 893 | | - snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV, |
|---|
| 894 | | - snd_dma_isa_data(), |
|---|
| 895 | | - 64*1024, gus->gf1.dma1 > 3 ? 128*1024 : 64*1024); |
|---|
| 866 | + snd_pcm_set_managed_buffer(substream, SNDRV_DMA_TYPE_DEV, |
|---|
| 867 | + card->dev, |
|---|
| 868 | + 64*1024, gus->gf1.dma1 > 3 ? 128*1024 : 64*1024); |
|---|
| 896 | 869 | |
|---|
| 897 | 870 | pcm->info_flags = 0; |
|---|
| 898 | 871 | pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; |
|---|
| .. | .. |
|---|
| 900 | 873 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_gf1_pcm_capture_ops); |
|---|
| 901 | 874 | if (gus->gf1.dma2 == gus->gf1.dma1) |
|---|
| 902 | 875 | pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX; |
|---|
| 903 | | - snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream, |
|---|
| 904 | | - SNDRV_DMA_TYPE_DEV, snd_dma_isa_data(), |
|---|
| 905 | | - 64*1024, gus->gf1.dma2 > 3 ? 128*1024 : 64*1024); |
|---|
| 876 | + snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream, |
|---|
| 877 | + SNDRV_DMA_TYPE_DEV, card->dev, |
|---|
| 878 | + 64*1024, gus->gf1.dma2 > 3 ? 128*1024 : 64*1024); |
|---|
| 906 | 879 | } |
|---|
| 907 | 880 | strcpy(pcm->name, pcm->id); |
|---|
| 908 | 881 | if (gus->interwave) { |
|---|