| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * ALSA driver for RME Digi32, Digi32/8 and Digi32 PRO audio interfaces |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 8 | 9 | * Henk Hesselink <henk@anda.nl> |
|---|
| 9 | 10 | * for writing the digi96-driver |
|---|
| 10 | 11 | * and RME for all informations. |
|---|
| 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., 675 Mass Ave, Cambridge, MA 02139, USA. |
|---|
| 25 | | - * |
|---|
| 26 | 12 | * |
|---|
| 27 | 13 | * **************************************************************************** |
|---|
| 28 | 14 | * |
|---|
| .. | .. |
|---|
| 319 | 305 | SNDRV_PCM_INFO_MMAP_VALID | |
|---|
| 320 | 306 | SNDRV_PCM_INFO_INTERLEAVED | |
|---|
| 321 | 307 | SNDRV_PCM_INFO_PAUSE | |
|---|
| 322 | | - SNDRV_PCM_INFO_SYNC_START), |
|---|
| 308 | + SNDRV_PCM_INFO_SYNC_START | |
|---|
| 309 | + SNDRV_PCM_INFO_SYNC_APPLPTR), |
|---|
| 323 | 310 | .formats = (SNDRV_PCM_FMTBIT_S16_LE | |
|---|
| 324 | 311 | SNDRV_PCM_FMTBIT_S32_LE), |
|---|
| 325 | 312 | .rates = (SNDRV_PCM_RATE_32000 | |
|---|
| .. | .. |
|---|
| 346 | 333 | SNDRV_PCM_INFO_MMAP_VALID | |
|---|
| 347 | 334 | SNDRV_PCM_INFO_INTERLEAVED | |
|---|
| 348 | 335 | SNDRV_PCM_INFO_PAUSE | |
|---|
| 349 | | - SNDRV_PCM_INFO_SYNC_START), |
|---|
| 336 | + SNDRV_PCM_INFO_SYNC_START | |
|---|
| 337 | + SNDRV_PCM_INFO_SYNC_APPLPTR), |
|---|
| 350 | 338 | .formats= SNDRV_PCM_FMTBIT_S16_LE, |
|---|
| 351 | 339 | .rates = (SNDRV_PCM_RATE_44100 | |
|---|
| 352 | 340 | SNDRV_PCM_RATE_48000), |
|---|
| .. | .. |
|---|
| 370 | 358 | SNDRV_PCM_INFO_MMAP_VALID | |
|---|
| 371 | 359 | SNDRV_PCM_INFO_INTERLEAVED | |
|---|
| 372 | 360 | SNDRV_PCM_INFO_PAUSE | |
|---|
| 373 | | - SNDRV_PCM_INFO_SYNC_START), |
|---|
| 361 | + SNDRV_PCM_INFO_SYNC_START | |
|---|
| 362 | + SNDRV_PCM_INFO_SYNC_APPLPTR), |
|---|
| 374 | 363 | .formats = (SNDRV_PCM_FMTBIT_S16_LE | |
|---|
| 375 | 364 | SNDRV_PCM_FMTBIT_S32_LE), |
|---|
| 376 | 365 | .rates = (SNDRV_PCM_RATE_32000 | |
|---|
| .. | .. |
|---|
| 397 | 386 | SNDRV_PCM_INFO_MMAP_VALID | |
|---|
| 398 | 387 | SNDRV_PCM_INFO_INTERLEAVED | |
|---|
| 399 | 388 | SNDRV_PCM_INFO_PAUSE | |
|---|
| 400 | | - SNDRV_PCM_INFO_SYNC_START), |
|---|
| 389 | + SNDRV_PCM_INFO_SYNC_START | |
|---|
| 390 | + SNDRV_PCM_INFO_SYNC_APPLPTR), |
|---|
| 401 | 391 | .formats= SNDRV_PCM_FMTBIT_S16_LE, |
|---|
| 402 | 392 | .rates = (SNDRV_PCM_RATE_44100 | |
|---|
| 403 | 393 | SNDRV_PCM_RATE_48000), |
|---|
| .. | .. |
|---|
| 672 | 662 | struct rme32 *rme32 = snd_pcm_substream_chip(substream); |
|---|
| 673 | 663 | struct snd_pcm_runtime *runtime = substream->runtime; |
|---|
| 674 | 664 | |
|---|
| 675 | | - if (rme32->fullduplex_mode) { |
|---|
| 676 | | - err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); |
|---|
| 677 | | - if (err < 0) |
|---|
| 678 | | - return err; |
|---|
| 679 | | - } else { |
|---|
| 665 | + if (!rme32->fullduplex_mode) { |
|---|
| 680 | 666 | runtime->dma_area = (void __force *)(rme32->iobase + |
|---|
| 681 | 667 | RME32_IO_DATA_BUFFER); |
|---|
| 682 | 668 | runtime->dma_addr = rme32->port + RME32_IO_DATA_BUFFER; |
|---|
| .. | .. |
|---|
| 727 | 713 | struct rme32 *rme32 = snd_pcm_substream_chip(substream); |
|---|
| 728 | 714 | struct snd_pcm_runtime *runtime = substream->runtime; |
|---|
| 729 | 715 | |
|---|
| 730 | | - if (rme32->fullduplex_mode) { |
|---|
| 731 | | - err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); |
|---|
| 732 | | - if (err < 0) |
|---|
| 733 | | - return err; |
|---|
| 734 | | - } else { |
|---|
| 716 | + if (!rme32->fullduplex_mode) { |
|---|
| 735 | 717 | runtime->dma_area = (void __force *)rme32->iobase + |
|---|
| 736 | 718 | RME32_IO_DATA_BUFFER; |
|---|
| 737 | 719 | runtime->dma_addr = rme32->port + RME32_IO_DATA_BUFFER; |
|---|
| .. | .. |
|---|
| 779 | 761 | spin_unlock_irq(&rme32->lock); |
|---|
| 780 | 762 | |
|---|
| 781 | 763 | return 0; |
|---|
| 782 | | -} |
|---|
| 783 | | - |
|---|
| 784 | | -static int snd_rme32_pcm_hw_free(struct snd_pcm_substream *substream) |
|---|
| 785 | | -{ |
|---|
| 786 | | - struct rme32 *rme32 = snd_pcm_substream_chip(substream); |
|---|
| 787 | | - if (! rme32->fullduplex_mode) |
|---|
| 788 | | - return 0; |
|---|
| 789 | | - return snd_pcm_lib_free_pages(substream); |
|---|
| 790 | 764 | } |
|---|
| 791 | 765 | |
|---|
| 792 | 766 | static void snd_rme32_pcm_start(struct rme32 * rme32, int from_pause) |
|---|
| .. | .. |
|---|
| 1104 | 1078 | snd_pcm_trigger_done(s, substream); |
|---|
| 1105 | 1079 | } |
|---|
| 1106 | 1080 | |
|---|
| 1107 | | - /* prefill playback buffer */ |
|---|
| 1108 | | - if (cmd == SNDRV_PCM_TRIGGER_START && rme32->fullduplex_mode) { |
|---|
| 1109 | | - snd_pcm_group_for_each_entry(s, substream) { |
|---|
| 1110 | | - if (s == rme32->playback_substream) { |
|---|
| 1111 | | - s->ops->ack(s); |
|---|
| 1112 | | - break; |
|---|
| 1113 | | - } |
|---|
| 1114 | | - } |
|---|
| 1115 | | - } |
|---|
| 1116 | | - |
|---|
| 1117 | 1081 | switch (cmd) { |
|---|
| 1118 | 1082 | case SNDRV_PCM_TRIGGER_START: |
|---|
| 1119 | 1083 | if (rme32->running && ! RME32_ISWORKING(rme32)) |
|---|
| .. | .. |
|---|
| 1213 | 1177 | static const struct snd_pcm_ops snd_rme32_playback_spdif_ops = { |
|---|
| 1214 | 1178 | .open = snd_rme32_playback_spdif_open, |
|---|
| 1215 | 1179 | .close = snd_rme32_playback_close, |
|---|
| 1216 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1217 | 1180 | .hw_params = snd_rme32_playback_hw_params, |
|---|
| 1218 | | - .hw_free = snd_rme32_pcm_hw_free, |
|---|
| 1219 | 1181 | .prepare = snd_rme32_playback_prepare, |
|---|
| 1220 | 1182 | .trigger = snd_rme32_pcm_trigger, |
|---|
| 1221 | 1183 | .pointer = snd_rme32_playback_pointer, |
|---|
| .. | .. |
|---|
| 1228 | 1190 | static const struct snd_pcm_ops snd_rme32_capture_spdif_ops = { |
|---|
| 1229 | 1191 | .open = snd_rme32_capture_spdif_open, |
|---|
| 1230 | 1192 | .close = snd_rme32_capture_close, |
|---|
| 1231 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1232 | 1193 | .hw_params = snd_rme32_capture_hw_params, |
|---|
| 1233 | | - .hw_free = snd_rme32_pcm_hw_free, |
|---|
| 1234 | 1194 | .prepare = snd_rme32_capture_prepare, |
|---|
| 1235 | 1195 | .trigger = snd_rme32_pcm_trigger, |
|---|
| 1236 | 1196 | .pointer = snd_rme32_capture_pointer, |
|---|
| .. | .. |
|---|
| 1242 | 1202 | static const struct snd_pcm_ops snd_rme32_playback_adat_ops = { |
|---|
| 1243 | 1203 | .open = snd_rme32_playback_adat_open, |
|---|
| 1244 | 1204 | .close = snd_rme32_playback_close, |
|---|
| 1245 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1246 | 1205 | .hw_params = snd_rme32_playback_hw_params, |
|---|
| 1247 | 1206 | .prepare = snd_rme32_playback_prepare, |
|---|
| 1248 | 1207 | .trigger = snd_rme32_pcm_trigger, |
|---|
| .. | .. |
|---|
| 1256 | 1215 | static const struct snd_pcm_ops snd_rme32_capture_adat_ops = { |
|---|
| 1257 | 1216 | .open = snd_rme32_capture_adat_open, |
|---|
| 1258 | 1217 | .close = snd_rme32_capture_close, |
|---|
| 1259 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1260 | 1218 | .hw_params = snd_rme32_capture_hw_params, |
|---|
| 1261 | 1219 | .prepare = snd_rme32_capture_prepare, |
|---|
| 1262 | 1220 | .trigger = snd_rme32_pcm_trigger, |
|---|
| .. | .. |
|---|
| 1270 | 1228 | static const struct snd_pcm_ops snd_rme32_playback_spdif_fd_ops = { |
|---|
| 1271 | 1229 | .open = snd_rme32_playback_spdif_open, |
|---|
| 1272 | 1230 | .close = snd_rme32_playback_close, |
|---|
| 1273 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1274 | 1231 | .hw_params = snd_rme32_playback_hw_params, |
|---|
| 1275 | | - .hw_free = snd_rme32_pcm_hw_free, |
|---|
| 1276 | 1232 | .prepare = snd_rme32_playback_prepare, |
|---|
| 1277 | 1233 | .trigger = snd_rme32_pcm_trigger, |
|---|
| 1278 | 1234 | .pointer = snd_rme32_playback_fd_pointer, |
|---|
| .. | .. |
|---|
| 1282 | 1238 | static const struct snd_pcm_ops snd_rme32_capture_spdif_fd_ops = { |
|---|
| 1283 | 1239 | .open = snd_rme32_capture_spdif_open, |
|---|
| 1284 | 1240 | .close = snd_rme32_capture_close, |
|---|
| 1285 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1286 | 1241 | .hw_params = snd_rme32_capture_hw_params, |
|---|
| 1287 | | - .hw_free = snd_rme32_pcm_hw_free, |
|---|
| 1288 | 1242 | .prepare = snd_rme32_capture_prepare, |
|---|
| 1289 | 1243 | .trigger = snd_rme32_pcm_trigger, |
|---|
| 1290 | 1244 | .pointer = snd_rme32_capture_fd_pointer, |
|---|
| .. | .. |
|---|
| 1294 | 1248 | static const struct snd_pcm_ops snd_rme32_playback_adat_fd_ops = { |
|---|
| 1295 | 1249 | .open = snd_rme32_playback_adat_open, |
|---|
| 1296 | 1250 | .close = snd_rme32_playback_close, |
|---|
| 1297 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1298 | 1251 | .hw_params = snd_rme32_playback_hw_params, |
|---|
| 1299 | 1252 | .prepare = snd_rme32_playback_prepare, |
|---|
| 1300 | 1253 | .trigger = snd_rme32_pcm_trigger, |
|---|
| .. | .. |
|---|
| 1305 | 1258 | static const struct snd_pcm_ops snd_rme32_capture_adat_fd_ops = { |
|---|
| 1306 | 1259 | .open = snd_rme32_capture_adat_open, |
|---|
| 1307 | 1260 | .close = snd_rme32_capture_close, |
|---|
| 1308 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1309 | 1261 | .hw_params = snd_rme32_capture_hw_params, |
|---|
| 1310 | 1262 | .prepare = snd_rme32_capture_prepare, |
|---|
| 1311 | 1263 | .trigger = snd_rme32_pcm_trigger, |
|---|
| .. | .. |
|---|
| 1364 | 1316 | return err; |
|---|
| 1365 | 1317 | rme32->port = pci_resource_start(rme32->pci, 0); |
|---|
| 1366 | 1318 | |
|---|
| 1367 | | - rme32->iobase = ioremap_nocache(rme32->port, RME32_IO_SIZE); |
|---|
| 1319 | + rme32->iobase = ioremap(rme32->port, RME32_IO_SIZE); |
|---|
| 1368 | 1320 | if (!rme32->iobase) { |
|---|
| 1369 | 1321 | dev_err(rme32->card->dev, |
|---|
| 1370 | 1322 | "unable to remap memory region 0x%lx-0x%lx\n", |
|---|
| .. | .. |
|---|
| 1378 | 1330 | return -EBUSY; |
|---|
| 1379 | 1331 | } |
|---|
| 1380 | 1332 | rme32->irq = pci->irq; |
|---|
| 1333 | + rme32->card->sync_irq = rme32->irq; |
|---|
| 1381 | 1334 | |
|---|
| 1382 | 1335 | /* read the card's revision number */ |
|---|
| 1383 | 1336 | pci_read_config_byte(pci, 8, &rme32->rev); |
|---|
| .. | .. |
|---|
| 1394 | 1347 | &snd_rme32_playback_spdif_fd_ops); |
|---|
| 1395 | 1348 | snd_pcm_set_ops(rme32->spdif_pcm, SNDRV_PCM_STREAM_CAPTURE, |
|---|
| 1396 | 1349 | &snd_rme32_capture_spdif_fd_ops); |
|---|
| 1397 | | - snd_pcm_lib_preallocate_pages_for_all(rme32->spdif_pcm, SNDRV_DMA_TYPE_CONTINUOUS, |
|---|
| 1398 | | - snd_dma_continuous_data(GFP_KERNEL), |
|---|
| 1399 | | - 0, RME32_MID_BUFFER_SIZE); |
|---|
| 1350 | + snd_pcm_set_managed_buffer_all(rme32->spdif_pcm, SNDRV_DMA_TYPE_CONTINUOUS, |
|---|
| 1351 | + NULL, 0, RME32_MID_BUFFER_SIZE); |
|---|
| 1400 | 1352 | rme32->spdif_pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX; |
|---|
| 1401 | 1353 | } else { |
|---|
| 1402 | 1354 | snd_pcm_set_ops(rme32->spdif_pcm, SNDRV_PCM_STREAM_PLAYBACK, |
|---|
| .. | .. |
|---|
| 1426 | 1378 | &snd_rme32_playback_adat_fd_ops); |
|---|
| 1427 | 1379 | snd_pcm_set_ops(rme32->adat_pcm, SNDRV_PCM_STREAM_CAPTURE, |
|---|
| 1428 | 1380 | &snd_rme32_capture_adat_fd_ops); |
|---|
| 1429 | | - snd_pcm_lib_preallocate_pages_for_all(rme32->adat_pcm, SNDRV_DMA_TYPE_CONTINUOUS, |
|---|
| 1430 | | - snd_dma_continuous_data(GFP_KERNEL), |
|---|
| 1431 | | - 0, RME32_MID_BUFFER_SIZE); |
|---|
| 1381 | + snd_pcm_set_managed_buffer_all(rme32->adat_pcm, SNDRV_DMA_TYPE_CONTINUOUS, |
|---|
| 1382 | + NULL, |
|---|
| 1383 | + 0, RME32_MID_BUFFER_SIZE); |
|---|
| 1432 | 1384 | rme32->adat_pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX; |
|---|
| 1433 | 1385 | } else { |
|---|
| 1434 | 1386 | snd_pcm_set_ops(rme32->adat_pcm, SNDRV_PCM_STREAM_PLAYBACK, |
|---|
| .. | .. |
|---|
| 1574 | 1526 | |
|---|
| 1575 | 1527 | static void snd_rme32_proc_init(struct rme32 *rme32) |
|---|
| 1576 | 1528 | { |
|---|
| 1577 | | - struct snd_info_entry *entry; |
|---|
| 1578 | | - |
|---|
| 1579 | | - if (! snd_card_proc_new(rme32->card, "rme32", &entry)) |
|---|
| 1580 | | - snd_info_set_text_ops(entry, rme32, snd_rme32_proc_read); |
|---|
| 1529 | + snd_card_ro_proc_new(rme32->card, "rme32", rme32, snd_rme32_proc_read); |
|---|
| 1581 | 1530 | } |
|---|
| 1582 | 1531 | |
|---|
| 1583 | 1532 | /* |
|---|
| .. | .. |
|---|
| 1847 | 1796 | return 0; |
|---|
| 1848 | 1797 | } |
|---|
| 1849 | 1798 | |
|---|
| 1850 | | -static struct snd_kcontrol_new snd_rme32_controls[] = { |
|---|
| 1799 | +static const struct snd_kcontrol_new snd_rme32_controls[] = { |
|---|
| 1851 | 1800 | { |
|---|
| 1852 | 1801 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
|---|
| 1853 | 1802 | .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), |
|---|