| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * ALSA driver for Intel ICH (i8x0) chipsets |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz> |
|---|
| 5 | 6 | * |
|---|
| 6 | | - * |
|---|
| 7 | 7 | * This code also contains alpha support for SiS 735 chipsets provided |
|---|
| 8 | 8 | * by Mike Pieper <mptei@users.sourceforge.net>. We have no datasheet |
|---|
| 9 | 9 | * for SiS735, so the code is not fully functional. |
|---|
| 10 | 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 | 11 | |
|---|
| 26 | | - * |
|---|
| 27 | 12 | */ |
|---|
| 28 | 13 | |
|---|
| 29 | 14 | #include <linux/io.h> |
|---|
| .. | .. |
|---|
| 38 | 23 | #include <sound/ac97_codec.h> |
|---|
| 39 | 24 | #include <sound/info.h> |
|---|
| 40 | 25 | #include <sound/initval.h> |
|---|
| 41 | | -/* for 440MX workaround */ |
|---|
| 42 | | -#include <asm/pgtable.h> |
|---|
| 43 | | -#ifdef CONFIG_X86 |
|---|
| 44 | | -#include <asm/set_memory.h> |
|---|
| 45 | | -#endif |
|---|
| 46 | 26 | |
|---|
| 47 | 27 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); |
|---|
| 48 | 28 | MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7012; Ali 5455"); |
|---|
| .. | .. |
|---|
| 86 | 66 | module_param(id, charp, 0444); |
|---|
| 87 | 67 | MODULE_PARM_DESC(id, "ID string for Intel i8x0 soundcard."); |
|---|
| 88 | 68 | module_param(ac97_clock, int, 0444); |
|---|
| 89 | | -MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = whitelist + auto-detect, 1 = force autodetect)."); |
|---|
| 69 | +MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = allowlist + auto-detect, 1 = force autodetect)."); |
|---|
| 90 | 70 | module_param(ac97_quirk, charp, 0444); |
|---|
| 91 | 71 | MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); |
|---|
| 92 | 72 | module_param(buggy_semaphore, bool, 0444); |
|---|
| .. | .. |
|---|
| 374 | 354 | unsigned int ali_slot; /* ALI DMA slot */ |
|---|
| 375 | 355 | struct ac97_pcm *pcm; |
|---|
| 376 | 356 | int pcm_open_flag; |
|---|
| 377 | | - unsigned int page_attr_changed: 1; |
|---|
| 357 | + unsigned int prepared:1; |
|---|
| 378 | 358 | unsigned int suspended: 1; |
|---|
| 379 | 359 | }; |
|---|
| 380 | 360 | |
|---|
| .. | .. |
|---|
| 414 | 394 | struct snd_ac97 *ac97[3]; |
|---|
| 415 | 395 | unsigned int ac97_sdin[3]; |
|---|
| 416 | 396 | unsigned int max_codecs, ncodecs; |
|---|
| 417 | | - unsigned int *codec_bit; |
|---|
| 397 | + const unsigned int *codec_bit; |
|---|
| 418 | 398 | unsigned int codec_isr_bits; |
|---|
| 419 | 399 | unsigned int codec_ready_bits; |
|---|
| 420 | 400 | |
|---|
| .. | .. |
|---|
| 724 | 704 | iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI); |
|---|
| 725 | 705 | } |
|---|
| 726 | 706 | |
|---|
| 727 | | -#ifdef __i386__ |
|---|
| 728 | | -/* |
|---|
| 729 | | - * Intel 82443MX running a 100MHz processor system bus has a hardware bug, |
|---|
| 730 | | - * which aborts PCI busmaster for audio transfer. A workaround is to set |
|---|
| 731 | | - * the pages as non-cached. For details, see the errata in |
|---|
| 732 | | - * http://download.intel.com/design/chipsets/specupdt/24505108.pdf |
|---|
| 733 | | - */ |
|---|
| 734 | | -static void fill_nocache(void *buf, int size, int nocache) |
|---|
| 735 | | -{ |
|---|
| 736 | | - size = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; |
|---|
| 737 | | - if (nocache) |
|---|
| 738 | | - set_pages_uc(virt_to_page(buf), size); |
|---|
| 739 | | - else |
|---|
| 740 | | - set_pages_wb(virt_to_page(buf), size); |
|---|
| 741 | | -} |
|---|
| 742 | | -#else |
|---|
| 743 | | -#define fill_nocache(buf, size, nocache) do { ; } while (0) |
|---|
| 744 | | -#endif |
|---|
| 745 | | - |
|---|
| 746 | 707 | /* |
|---|
| 747 | 708 | * Interrupt handler |
|---|
| 748 | 709 | */ |
|---|
| .. | .. |
|---|
| 753 | 714 | unsigned long flags; |
|---|
| 754 | 715 | int status, civ, i, step; |
|---|
| 755 | 716 | int ack = 0; |
|---|
| 717 | + |
|---|
| 718 | + if (!(ichdev->prepared || chip->in_measurement) || ichdev->suspended) |
|---|
| 719 | + return; |
|---|
| 756 | 720 | |
|---|
| 757 | 721 | spin_lock_irqsave(&chip->reg_lock, flags); |
|---|
| 758 | 722 | status = igetbyte(chip, port + ichdev->roff_sr); |
|---|
| .. | .. |
|---|
| 850 | 814 | switch (cmd) { |
|---|
| 851 | 815 | case SNDRV_PCM_TRIGGER_RESUME: |
|---|
| 852 | 816 | ichdev->suspended = 0; |
|---|
| 853 | | - /* fallthru */ |
|---|
| 817 | + fallthrough; |
|---|
| 854 | 818 | case SNDRV_PCM_TRIGGER_START: |
|---|
| 855 | 819 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
|---|
| 856 | 820 | val = ICH_IOCE | ICH_STARTBM; |
|---|
| .. | .. |
|---|
| 858 | 822 | break; |
|---|
| 859 | 823 | case SNDRV_PCM_TRIGGER_SUSPEND: |
|---|
| 860 | 824 | ichdev->suspended = 1; |
|---|
| 861 | | - /* fallthru */ |
|---|
| 825 | + fallthrough; |
|---|
| 862 | 826 | case SNDRV_PCM_TRIGGER_STOP: |
|---|
| 863 | 827 | val = 0; |
|---|
| 864 | 828 | break; |
|---|
| .. | .. |
|---|
| 883 | 847 | struct intel8x0 *chip = snd_pcm_substream_chip(substream); |
|---|
| 884 | 848 | struct ichdev *ichdev = get_ichdev(substream); |
|---|
| 885 | 849 | unsigned long port = ichdev->reg_offset; |
|---|
| 886 | | - static int fiforeg[] = { |
|---|
| 850 | + static const int fiforeg[] = { |
|---|
| 887 | 851 | ICHREG(ALI_FIFOCR1), ICHREG(ALI_FIFOCR2), ICHREG(ALI_FIFOCR3) |
|---|
| 888 | 852 | }; |
|---|
| 889 | 853 | unsigned int val, fifo; |
|---|
| .. | .. |
|---|
| 892 | 856 | switch (cmd) { |
|---|
| 893 | 857 | case SNDRV_PCM_TRIGGER_RESUME: |
|---|
| 894 | 858 | ichdev->suspended = 0; |
|---|
| 895 | | - /* fallthru */ |
|---|
| 859 | + fallthrough; |
|---|
| 896 | 860 | case SNDRV_PCM_TRIGGER_START: |
|---|
| 897 | 861 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
|---|
| 898 | 862 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
|---|
| .. | .. |
|---|
| 909 | 873 | break; |
|---|
| 910 | 874 | case SNDRV_PCM_TRIGGER_SUSPEND: |
|---|
| 911 | 875 | ichdev->suspended = 1; |
|---|
| 912 | | - /* fallthru */ |
|---|
| 876 | + fallthrough; |
|---|
| 913 | 877 | case SNDRV_PCM_TRIGGER_STOP: |
|---|
| 914 | 878 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
|---|
| 915 | 879 | /* pause */ |
|---|
| .. | .. |
|---|
| 938 | 902 | { |
|---|
| 939 | 903 | struct intel8x0 *chip = snd_pcm_substream_chip(substream); |
|---|
| 940 | 904 | struct ichdev *ichdev = get_ichdev(substream); |
|---|
| 941 | | - struct snd_pcm_runtime *runtime = substream->runtime; |
|---|
| 942 | 905 | int dbl = params_rate(hw_params) > 48000; |
|---|
| 943 | 906 | int err; |
|---|
| 944 | 907 | |
|---|
| 945 | | - if (chip->fix_nocache && ichdev->page_attr_changed) { |
|---|
| 946 | | - fill_nocache(runtime->dma_area, runtime->dma_bytes, 0); /* clear */ |
|---|
| 947 | | - ichdev->page_attr_changed = 0; |
|---|
| 948 | | - } |
|---|
| 949 | | - err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); |
|---|
| 950 | | - if (err < 0) |
|---|
| 951 | | - return err; |
|---|
| 952 | | - if (chip->fix_nocache) { |
|---|
| 953 | | - if (runtime->dma_area && ! ichdev->page_attr_changed) { |
|---|
| 954 | | - fill_nocache(runtime->dma_area, runtime->dma_bytes, 1); |
|---|
| 955 | | - ichdev->page_attr_changed = 1; |
|---|
| 956 | | - } |
|---|
| 957 | | - } |
|---|
| 958 | 908 | if (ichdev->pcm_open_flag) { |
|---|
| 959 | 909 | snd_ac97_pcm_close(ichdev->pcm); |
|---|
| 960 | 910 | ichdev->pcm_open_flag = 0; |
|---|
| 911 | + ichdev->prepared = 0; |
|---|
| 961 | 912 | } |
|---|
| 962 | 913 | err = snd_ac97_pcm_open(ichdev->pcm, params_rate(hw_params), |
|---|
| 963 | 914 | params_channels(hw_params), |
|---|
| .. | .. |
|---|
| 974 | 925 | |
|---|
| 975 | 926 | static int snd_intel8x0_hw_free(struct snd_pcm_substream *substream) |
|---|
| 976 | 927 | { |
|---|
| 977 | | - struct intel8x0 *chip = snd_pcm_substream_chip(substream); |
|---|
| 978 | 928 | struct ichdev *ichdev = get_ichdev(substream); |
|---|
| 979 | 929 | |
|---|
| 980 | 930 | if (ichdev->pcm_open_flag) { |
|---|
| 981 | 931 | snd_ac97_pcm_close(ichdev->pcm); |
|---|
| 982 | 932 | ichdev->pcm_open_flag = 0; |
|---|
| 933 | + ichdev->prepared = 0; |
|---|
| 983 | 934 | } |
|---|
| 984 | | - if (chip->fix_nocache && ichdev->page_attr_changed) { |
|---|
| 985 | | - fill_nocache(substream->runtime->dma_area, substream->runtime->dma_bytes, 0); |
|---|
| 986 | | - ichdev->page_attr_changed = 0; |
|---|
| 987 | | - } |
|---|
| 988 | | - return snd_pcm_lib_free_pages(substream); |
|---|
| 935 | + return 0; |
|---|
| 989 | 936 | } |
|---|
| 990 | 937 | |
|---|
| 991 | 938 | static void snd_intel8x0_setup_pcm_out(struct intel8x0 *chip, |
|---|
| .. | .. |
|---|
| 1058 | 1005 | ichdev->pos_shift = (runtime->sample_bits > 16) ? 2 : 1; |
|---|
| 1059 | 1006 | } |
|---|
| 1060 | 1007 | snd_intel8x0_setup_periods(chip, ichdev); |
|---|
| 1008 | + ichdev->prepared = 1; |
|---|
| 1061 | 1009 | return 0; |
|---|
| 1062 | 1010 | } |
|---|
| 1063 | 1011 | |
|---|
| .. | .. |
|---|
| 1370 | 1318 | static const struct snd_pcm_ops snd_intel8x0_playback_ops = { |
|---|
| 1371 | 1319 | .open = snd_intel8x0_playback_open, |
|---|
| 1372 | 1320 | .close = snd_intel8x0_playback_close, |
|---|
| 1373 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1374 | 1321 | .hw_params = snd_intel8x0_hw_params, |
|---|
| 1375 | 1322 | .hw_free = snd_intel8x0_hw_free, |
|---|
| 1376 | 1323 | .prepare = snd_intel8x0_pcm_prepare, |
|---|
| .. | .. |
|---|
| 1381 | 1328 | static const struct snd_pcm_ops snd_intel8x0_capture_ops = { |
|---|
| 1382 | 1329 | .open = snd_intel8x0_capture_open, |
|---|
| 1383 | 1330 | .close = snd_intel8x0_capture_close, |
|---|
| 1384 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1385 | 1331 | .hw_params = snd_intel8x0_hw_params, |
|---|
| 1386 | 1332 | .hw_free = snd_intel8x0_hw_free, |
|---|
| 1387 | 1333 | .prepare = snd_intel8x0_pcm_prepare, |
|---|
| .. | .. |
|---|
| 1392 | 1338 | static const struct snd_pcm_ops snd_intel8x0_capture_mic_ops = { |
|---|
| 1393 | 1339 | .open = snd_intel8x0_mic_open, |
|---|
| 1394 | 1340 | .close = snd_intel8x0_mic_close, |
|---|
| 1395 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1396 | 1341 | .hw_params = snd_intel8x0_hw_params, |
|---|
| 1397 | 1342 | .hw_free = snd_intel8x0_hw_free, |
|---|
| 1398 | 1343 | .prepare = snd_intel8x0_pcm_prepare, |
|---|
| .. | .. |
|---|
| 1403 | 1348 | static const struct snd_pcm_ops snd_intel8x0_capture_mic2_ops = { |
|---|
| 1404 | 1349 | .open = snd_intel8x0_mic2_open, |
|---|
| 1405 | 1350 | .close = snd_intel8x0_mic2_close, |
|---|
| 1406 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1407 | 1351 | .hw_params = snd_intel8x0_hw_params, |
|---|
| 1408 | 1352 | .hw_free = snd_intel8x0_hw_free, |
|---|
| 1409 | 1353 | .prepare = snd_intel8x0_pcm_prepare, |
|---|
| .. | .. |
|---|
| 1414 | 1358 | static const struct snd_pcm_ops snd_intel8x0_capture2_ops = { |
|---|
| 1415 | 1359 | .open = snd_intel8x0_capture2_open, |
|---|
| 1416 | 1360 | .close = snd_intel8x0_capture2_close, |
|---|
| 1417 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1418 | 1361 | .hw_params = snd_intel8x0_hw_params, |
|---|
| 1419 | 1362 | .hw_free = snd_intel8x0_hw_free, |
|---|
| 1420 | 1363 | .prepare = snd_intel8x0_pcm_prepare, |
|---|
| .. | .. |
|---|
| 1425 | 1368 | static const struct snd_pcm_ops snd_intel8x0_spdif_ops = { |
|---|
| 1426 | 1369 | .open = snd_intel8x0_spdif_open, |
|---|
| 1427 | 1370 | .close = snd_intel8x0_spdif_close, |
|---|
| 1428 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1429 | 1371 | .hw_params = snd_intel8x0_hw_params, |
|---|
| 1430 | 1372 | .hw_free = snd_intel8x0_hw_free, |
|---|
| 1431 | 1373 | .prepare = snd_intel8x0_pcm_prepare, |
|---|
| .. | .. |
|---|
| 1436 | 1378 | static const struct snd_pcm_ops snd_intel8x0_ali_playback_ops = { |
|---|
| 1437 | 1379 | .open = snd_intel8x0_playback_open, |
|---|
| 1438 | 1380 | .close = snd_intel8x0_playback_close, |
|---|
| 1439 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1440 | 1381 | .hw_params = snd_intel8x0_hw_params, |
|---|
| 1441 | 1382 | .hw_free = snd_intel8x0_hw_free, |
|---|
| 1442 | 1383 | .prepare = snd_intel8x0_pcm_prepare, |
|---|
| .. | .. |
|---|
| 1447 | 1388 | static const struct snd_pcm_ops snd_intel8x0_ali_capture_ops = { |
|---|
| 1448 | 1389 | .open = snd_intel8x0_capture_open, |
|---|
| 1449 | 1390 | .close = snd_intel8x0_capture_close, |
|---|
| 1450 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1451 | 1391 | .hw_params = snd_intel8x0_hw_params, |
|---|
| 1452 | 1392 | .hw_free = snd_intel8x0_hw_free, |
|---|
| 1453 | 1393 | .prepare = snd_intel8x0_pcm_prepare, |
|---|
| .. | .. |
|---|
| 1458 | 1398 | static const struct snd_pcm_ops snd_intel8x0_ali_capture_mic_ops = { |
|---|
| 1459 | 1399 | .open = snd_intel8x0_mic_open, |
|---|
| 1460 | 1400 | .close = snd_intel8x0_mic_close, |
|---|
| 1461 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1462 | 1401 | .hw_params = snd_intel8x0_hw_params, |
|---|
| 1463 | 1402 | .hw_free = snd_intel8x0_hw_free, |
|---|
| 1464 | 1403 | .prepare = snd_intel8x0_pcm_prepare, |
|---|
| .. | .. |
|---|
| 1469 | 1408 | static const struct snd_pcm_ops snd_intel8x0_ali_ac97spdifout_ops = { |
|---|
| 1470 | 1409 | .open = snd_intel8x0_ali_ac97spdifout_open, |
|---|
| 1471 | 1410 | .close = snd_intel8x0_ali_ac97spdifout_close, |
|---|
| 1472 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1473 | 1411 | .hw_params = snd_intel8x0_hw_params, |
|---|
| 1474 | 1412 | .hw_free = snd_intel8x0_hw_free, |
|---|
| 1475 | 1413 | .prepare = snd_intel8x0_pcm_prepare, |
|---|
| .. | .. |
|---|
| 1481 | 1419 | static struct snd_pcm_ops snd_intel8x0_ali_spdifin_ops = { |
|---|
| 1482 | 1420 | .open = snd_intel8x0_ali_spdifin_open, |
|---|
| 1483 | 1421 | .close = snd_intel8x0_ali_spdifin_close, |
|---|
| 1484 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1485 | 1422 | .hw_params = snd_intel8x0_hw_params, |
|---|
| 1486 | 1423 | .hw_free = snd_intel8x0_hw_free, |
|---|
| 1487 | 1424 | .prepare = snd_intel8x0_pcm_prepare, |
|---|
| .. | .. |
|---|
| 1492 | 1429 | static struct snd_pcm_ops snd_intel8x0_ali_spdifout_ops = { |
|---|
| 1493 | 1430 | .open = snd_intel8x0_ali_spdifout_open, |
|---|
| 1494 | 1431 | .close = snd_intel8x0_ali_spdifout_close, |
|---|
| 1495 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1496 | 1432 | .hw_params = snd_intel8x0_hw_params, |
|---|
| 1497 | 1433 | .hw_free = snd_intel8x0_hw_free, |
|---|
| 1498 | 1434 | .prepare = snd_intel8x0_pcm_prepare, |
|---|
| .. | .. |
|---|
| 1510 | 1446 | int ac97_idx; |
|---|
| 1511 | 1447 | }; |
|---|
| 1512 | 1448 | |
|---|
| 1449 | +#define intel8x0_dma_type(chip) \ |
|---|
| 1450 | + ((chip)->fix_nocache ? SNDRV_DMA_TYPE_DEV_UC : SNDRV_DMA_TYPE_DEV) |
|---|
| 1451 | + |
|---|
| 1513 | 1452 | static int snd_intel8x0_pcm1(struct intel8x0 *chip, int device, |
|---|
| 1514 | | - struct ich_pcm_table *rec) |
|---|
| 1453 | + const struct ich_pcm_table *rec) |
|---|
| 1515 | 1454 | { |
|---|
| 1516 | 1455 | struct snd_pcm *pcm; |
|---|
| 1517 | 1456 | int err; |
|---|
| .. | .. |
|---|
| 1540 | 1479 | strcpy(pcm->name, chip->card->shortname); |
|---|
| 1541 | 1480 | chip->pcm[device] = pcm; |
|---|
| 1542 | 1481 | |
|---|
| 1543 | | - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
|---|
| 1544 | | - snd_dma_pci_data(chip->pci), |
|---|
| 1545 | | - rec->prealloc_size, rec->prealloc_max_size); |
|---|
| 1482 | + snd_pcm_set_managed_buffer_all(pcm, intel8x0_dma_type(chip), |
|---|
| 1483 | + &chip->pci->dev, |
|---|
| 1484 | + rec->prealloc_size, rec->prealloc_max_size); |
|---|
| 1546 | 1485 | |
|---|
| 1547 | 1486 | if (rec->playback_ops && |
|---|
| 1548 | 1487 | rec->playback_ops->open == snd_intel8x0_playback_open) { |
|---|
| .. | .. |
|---|
| 1566 | 1505 | return 0; |
|---|
| 1567 | 1506 | } |
|---|
| 1568 | 1507 | |
|---|
| 1569 | | -static struct ich_pcm_table intel_pcms[] = { |
|---|
| 1508 | +static const struct ich_pcm_table intel_pcms[] = { |
|---|
| 1570 | 1509 | { |
|---|
| 1571 | 1510 | .playback_ops = &snd_intel8x0_playback_ops, |
|---|
| 1572 | 1511 | .capture_ops = &snd_intel8x0_capture_ops, |
|---|
| .. | .. |
|---|
| 1603 | 1542 | }, |
|---|
| 1604 | 1543 | }; |
|---|
| 1605 | 1544 | |
|---|
| 1606 | | -static struct ich_pcm_table nforce_pcms[] = { |
|---|
| 1545 | +static const struct ich_pcm_table nforce_pcms[] = { |
|---|
| 1607 | 1546 | { |
|---|
| 1608 | 1547 | .playback_ops = &snd_intel8x0_playback_ops, |
|---|
| 1609 | 1548 | .capture_ops = &snd_intel8x0_capture_ops, |
|---|
| .. | .. |
|---|
| 1626 | 1565 | }, |
|---|
| 1627 | 1566 | }; |
|---|
| 1628 | 1567 | |
|---|
| 1629 | | -static struct ich_pcm_table ali_pcms[] = { |
|---|
| 1568 | +static const struct ich_pcm_table ali_pcms[] = { |
|---|
| 1630 | 1569 | { |
|---|
| 1631 | 1570 | .playback_ops = &snd_intel8x0_ali_playback_ops, |
|---|
| 1632 | 1571 | .capture_ops = &snd_intel8x0_ali_capture_ops, |
|---|
| .. | .. |
|---|
| 1661 | 1600 | static int snd_intel8x0_pcm(struct intel8x0 *chip) |
|---|
| 1662 | 1601 | { |
|---|
| 1663 | 1602 | int i, tblsize, device, err; |
|---|
| 1664 | | - struct ich_pcm_table *tbl, *rec; |
|---|
| 1603 | + const struct ich_pcm_table *tbl, *rec; |
|---|
| 1665 | 1604 | |
|---|
| 1666 | 1605 | switch (chip->device_type) { |
|---|
| 1667 | 1606 | case DEVICE_INTEL_ICH4: |
|---|
| .. | .. |
|---|
| 2206 | 2145 | int err; |
|---|
| 2207 | 2146 | unsigned int i, codecs; |
|---|
| 2208 | 2147 | unsigned int glob_sta = 0; |
|---|
| 2209 | | - struct snd_ac97_bus_ops *ops; |
|---|
| 2210 | | - static struct snd_ac97_bus_ops standard_bus_ops = { |
|---|
| 2148 | + const struct snd_ac97_bus_ops *ops; |
|---|
| 2149 | + static const struct snd_ac97_bus_ops standard_bus_ops = { |
|---|
| 2211 | 2150 | .write = snd_intel8x0_codec_write, |
|---|
| 2212 | 2151 | .read = snd_intel8x0_codec_read, |
|---|
| 2213 | 2152 | }; |
|---|
| 2214 | | - static struct snd_ac97_bus_ops ali_bus_ops = { |
|---|
| 2153 | + static const struct snd_ac97_bus_ops ali_bus_ops = { |
|---|
| 2215 | 2154 | .write = snd_intel8x0_ali_codec_write, |
|---|
| 2216 | 2155 | .read = snd_intel8x0_ali_codec_read, |
|---|
| 2217 | 2156 | }; |
|---|
| .. | .. |
|---|
| 2396 | 2335 | } |
|---|
| 2397 | 2336 | |
|---|
| 2398 | 2337 | #ifdef CONFIG_SND_AC97_POWER_SAVE |
|---|
| 2399 | | -static struct snd_pci_quirk ich_chip_reset_mode[] = { |
|---|
| 2338 | +static const struct snd_pci_quirk ich_chip_reset_mode[] = { |
|---|
| 2400 | 2339 | SND_PCI_QUIRK(0x1014, 0x051f, "Thinkpad R32", 1), |
|---|
| 2401 | 2340 | { } /* end */ |
|---|
| 2402 | 2341 | }; |
|---|
| .. | .. |
|---|
| 2629 | 2568 | __hw_end: |
|---|
| 2630 | 2569 | if (chip->irq >= 0) |
|---|
| 2631 | 2570 | free_irq(chip->irq, chip); |
|---|
| 2632 | | - if (chip->bdbars.area) { |
|---|
| 2633 | | - if (chip->fix_nocache) |
|---|
| 2634 | | - fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 0); |
|---|
| 2571 | + if (chip->bdbars.area) |
|---|
| 2635 | 2572 | snd_dma_free_pages(&chip->bdbars); |
|---|
| 2636 | | - } |
|---|
| 2637 | 2573 | if (chip->addr) |
|---|
| 2638 | 2574 | pci_iounmap(chip->pci, chip->addr); |
|---|
| 2639 | 2575 | if (chip->bmaddr) |
|---|
| .. | .. |
|---|
| 2655 | 2591 | int i; |
|---|
| 2656 | 2592 | |
|---|
| 2657 | 2593 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); |
|---|
| 2658 | | - for (i = 0; i < chip->pcm_devs; i++) |
|---|
| 2659 | | - snd_pcm_suspend_all(chip->pcm[i]); |
|---|
| 2660 | | - /* clear nocache */ |
|---|
| 2661 | | - if (chip->fix_nocache) { |
|---|
| 2662 | | - for (i = 0; i < chip->bdbars_count; i++) { |
|---|
| 2663 | | - struct ichdev *ichdev = &chip->ichd[i]; |
|---|
| 2664 | | - if (ichdev->substream && ichdev->page_attr_changed) { |
|---|
| 2665 | | - struct snd_pcm_runtime *runtime = ichdev->substream->runtime; |
|---|
| 2666 | | - if (runtime->dma_area) |
|---|
| 2667 | | - fill_nocache(runtime->dma_area, runtime->dma_bytes, 0); |
|---|
| 2668 | | - } |
|---|
| 2669 | | - } |
|---|
| 2670 | | - } |
|---|
| 2671 | 2594 | for (i = 0; i < chip->ncodecs; i++) |
|---|
| 2672 | 2595 | snd_ac97_suspend(chip->ac97[i]); |
|---|
| 2673 | 2596 | if (chip->device_type == DEVICE_INTEL_ICH4) |
|---|
| .. | .. |
|---|
| 2676 | 2599 | if (chip->irq >= 0) { |
|---|
| 2677 | 2600 | free_irq(chip->irq, chip); |
|---|
| 2678 | 2601 | chip->irq = -1; |
|---|
| 2602 | + card->sync_irq = -1; |
|---|
| 2679 | 2603 | } |
|---|
| 2680 | 2604 | return 0; |
|---|
| 2681 | 2605 | } |
|---|
| .. | .. |
|---|
| 2696 | 2620 | return -EIO; |
|---|
| 2697 | 2621 | } |
|---|
| 2698 | 2622 | chip->irq = pci->irq; |
|---|
| 2699 | | - synchronize_irq(chip->irq); |
|---|
| 2623 | + card->sync_irq = chip->irq; |
|---|
| 2700 | 2624 | |
|---|
| 2701 | 2625 | /* re-initialize mixer stuff */ |
|---|
| 2702 | 2626 | if (chip->device_type == DEVICE_INTEL_ICH4 && !spdif_aclink) { |
|---|
| .. | .. |
|---|
| 2708 | 2632 | ICH_PCM_SPDIF_1011); |
|---|
| 2709 | 2633 | } |
|---|
| 2710 | 2634 | |
|---|
| 2711 | | - /* refill nocache */ |
|---|
| 2712 | | - if (chip->fix_nocache) |
|---|
| 2713 | | - fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 1); |
|---|
| 2714 | | - |
|---|
| 2715 | 2635 | for (i = 0; i < chip->ncodecs; i++) |
|---|
| 2716 | 2636 | snd_ac97_resume(chip->ac97[i]); |
|---|
| 2717 | | - |
|---|
| 2718 | | - /* refill nocache */ |
|---|
| 2719 | | - if (chip->fix_nocache) { |
|---|
| 2720 | | - for (i = 0; i < chip->bdbars_count; i++) { |
|---|
| 2721 | | - struct ichdev *ichdev = &chip->ichd[i]; |
|---|
| 2722 | | - if (ichdev->substream && ichdev->page_attr_changed) { |
|---|
| 2723 | | - struct snd_pcm_runtime *runtime = ichdev->substream->runtime; |
|---|
| 2724 | | - if (runtime->dma_area) |
|---|
| 2725 | | - fill_nocache(runtime->dma_area, runtime->dma_bytes, 1); |
|---|
| 2726 | | - } |
|---|
| 2727 | | - } |
|---|
| 2728 | | - } |
|---|
| 2729 | 2637 | |
|---|
| 2730 | 2638 | /* resume status */ |
|---|
| 2731 | 2639 | for (i = 0; i < chip->bdbars_count; i++) { |
|---|
| .. | .. |
|---|
| 2873 | 2781 | snd_ac97_update_power(chip->ac97[0], AC97_PCM_FRONT_DAC_RATE, 0); |
|---|
| 2874 | 2782 | } |
|---|
| 2875 | 2783 | |
|---|
| 2876 | | -static struct snd_pci_quirk intel8x0_clock_list[] = { |
|---|
| 2784 | +static const struct snd_pci_quirk intel8x0_clock_list[] = { |
|---|
| 2877 | 2785 | SND_PCI_QUIRK(0x0e11, 0x008a, "AD1885", 41000), |
|---|
| 2878 | 2786 | SND_PCI_QUIRK(0x1014, 0x0581, "AD1981B", 48000), |
|---|
| 2879 | 2787 | SND_PCI_QUIRK(0x1028, 0x00be, "AD1885", 44100), |
|---|
| .. | .. |
|---|
| 2891 | 2799 | wl = snd_pci_quirk_lookup(pci, intel8x0_clock_list); |
|---|
| 2892 | 2800 | if (!wl) |
|---|
| 2893 | 2801 | return 0; |
|---|
| 2894 | | - dev_info(chip->card->dev, "white list rate for %04x:%04x is %i\n", |
|---|
| 2802 | + dev_info(chip->card->dev, "allow list rate for %04x:%04x is %i\n", |
|---|
| 2895 | 2803 | pci->subsystem_vendor, pci->subsystem_device, wl->value); |
|---|
| 2896 | 2804 | chip->ac97_bus->clock = wl->value; |
|---|
| 2897 | 2805 | return 1; |
|---|
| .. | .. |
|---|
| 2933 | 2841 | |
|---|
| 2934 | 2842 | static void snd_intel8x0_proc_init(struct intel8x0 *chip) |
|---|
| 2935 | 2843 | { |
|---|
| 2936 | | - struct snd_info_entry *entry; |
|---|
| 2937 | | - |
|---|
| 2938 | | - if (! snd_card_proc_new(chip->card, "intel8x0", &entry)) |
|---|
| 2939 | | - snd_info_set_text_ops(entry, chip, snd_intel8x0_proc_read); |
|---|
| 2844 | + snd_card_ro_proc_new(chip->card, "intel8x0", chip, |
|---|
| 2845 | + snd_intel8x0_proc_read); |
|---|
| 2940 | 2846 | } |
|---|
| 2941 | 2847 | |
|---|
| 2942 | 2848 | static int snd_intel8x0_dev_free(struct snd_device *device) |
|---|
| .. | .. |
|---|
| 2950 | 2856 | unsigned int offset; |
|---|
| 2951 | 2857 | }; |
|---|
| 2952 | 2858 | |
|---|
| 2953 | | -static unsigned int ich_codec_bits[3] = { |
|---|
| 2859 | +static const unsigned int ich_codec_bits[3] = { |
|---|
| 2954 | 2860 | ICH_PCR, ICH_SCR, ICH_TCR |
|---|
| 2955 | 2861 | }; |
|---|
| 2956 | | -static unsigned int sis_codec_bits[3] = { |
|---|
| 2862 | +static const unsigned int sis_codec_bits[3] = { |
|---|
| 2957 | 2863 | ICH_PCR, ICH_SCR, ICH_SIS_TCR |
|---|
| 2958 | 2864 | }; |
|---|
| 2959 | 2865 | |
|---|
| .. | .. |
|---|
| 2998 | 2904 | unsigned int i; |
|---|
| 2999 | 2905 | unsigned int int_sta_masks; |
|---|
| 3000 | 2906 | struct ichdev *ichdev; |
|---|
| 3001 | | - static struct snd_device_ops ops = { |
|---|
| 2907 | + static const struct snd_device_ops ops = { |
|---|
| 3002 | 2908 | .dev_free = snd_intel8x0_dev_free, |
|---|
| 3003 | 2909 | }; |
|---|
| 3004 | 2910 | |
|---|
| 3005 | | - static unsigned int bdbars[] = { |
|---|
| 2911 | + static const unsigned int bdbars[] = { |
|---|
| 3006 | 2912 | 3, /* DEVICE_INTEL */ |
|---|
| 3007 | 2913 | 6, /* DEVICE_INTEL_ICH4 */ |
|---|
| 3008 | 2914 | 3, /* DEVICE_SIS */ |
|---|
| 3009 | 2915 | 6, /* DEVICE_ALI */ |
|---|
| 3010 | 2916 | 4, /* DEVICE_NFORCE */ |
|---|
| 3011 | 2917 | }; |
|---|
| 3012 | | - static struct ich_reg_info intel_regs[6] = { |
|---|
| 2918 | + static const struct ich_reg_info intel_regs[6] = { |
|---|
| 3013 | 2919 | { ICH_PIINT, 0 }, |
|---|
| 3014 | 2920 | { ICH_POINT, 0x10 }, |
|---|
| 3015 | 2921 | { ICH_MCINT, 0x20 }, |
|---|
| .. | .. |
|---|
| 3017 | 2923 | { ICH_P2INT, 0x50 }, |
|---|
| 3018 | 2924 | { ICH_SPINT, 0x60 }, |
|---|
| 3019 | 2925 | }; |
|---|
| 3020 | | - static struct ich_reg_info nforce_regs[4] = { |
|---|
| 2926 | + static const struct ich_reg_info nforce_regs[4] = { |
|---|
| 3021 | 2927 | { ICH_PIINT, 0 }, |
|---|
| 3022 | 2928 | { ICH_POINT, 0x10 }, |
|---|
| 3023 | 2929 | { ICH_MCINT, 0x20 }, |
|---|
| 3024 | 2930 | { ICH_NVSPINT, 0x70 }, |
|---|
| 3025 | 2931 | }; |
|---|
| 3026 | | - static struct ich_reg_info ali_regs[6] = { |
|---|
| 2932 | + static const struct ich_reg_info ali_regs[6] = { |
|---|
| 3027 | 2933 | { ALI_INT_PCMIN, 0x40 }, |
|---|
| 3028 | 2934 | { ALI_INT_PCMOUT, 0x50 }, |
|---|
| 3029 | 2935 | { ALI_INT_MICIN, 0x60 }, |
|---|
| .. | .. |
|---|
| 3031 | 2937 | { ALI_INT_SPDIFIN, 0xa0 }, |
|---|
| 3032 | 2938 | { ALI_INT_SPDIFOUT, 0xb0 }, |
|---|
| 3033 | 2939 | }; |
|---|
| 3034 | | - struct ich_reg_info *tbl; |
|---|
| 2940 | + const struct ich_reg_info *tbl; |
|---|
| 3035 | 2941 | |
|---|
| 3036 | 2942 | *r_intel8x0 = NULL; |
|---|
| 3037 | 2943 | |
|---|
| .. | .. |
|---|
| 3057 | 2963 | |
|---|
| 3058 | 2964 | chip->inside_vm = snd_intel8x0_inside_vm(pci); |
|---|
| 3059 | 2965 | |
|---|
| 2966 | + /* |
|---|
| 2967 | + * Intel 82443MX running a 100MHz processor system bus has a hardware |
|---|
| 2968 | + * bug, which aborts PCI busmaster for audio transfer. A workaround |
|---|
| 2969 | + * is to set the pages as non-cached. For details, see the errata in |
|---|
| 2970 | + * http://download.intel.com/design/chipsets/specupdt/24505108.pdf |
|---|
| 2971 | + */ |
|---|
| 3060 | 2972 | if (pci->vendor == PCI_VENDOR_ID_INTEL && |
|---|
| 3061 | 2973 | pci->device == PCI_DEVICE_ID_INTEL_440MX) |
|---|
| 3062 | 2974 | chip->fix_nocache = 1; /* enable workaround */ |
|---|
| .. | .. |
|---|
| 3128 | 3040 | |
|---|
| 3129 | 3041 | /* allocate buffer descriptor lists */ |
|---|
| 3130 | 3042 | /* the start of each lists must be aligned to 8 bytes */ |
|---|
| 3131 | | - if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), |
|---|
| 3043 | + if (snd_dma_alloc_pages(intel8x0_dma_type(chip), &pci->dev, |
|---|
| 3132 | 3044 | chip->bdbars_count * sizeof(u32) * ICH_MAX_FRAGS * 2, |
|---|
| 3133 | 3045 | &chip->bdbars) < 0) { |
|---|
| 3134 | 3046 | snd_intel8x0_free(chip); |
|---|
| .. | .. |
|---|
| 3137 | 3049 | } |
|---|
| 3138 | 3050 | /* tables must be aligned to 8 bytes here, but the kernel pages |
|---|
| 3139 | 3051 | are much bigger, so we don't care (on i386) */ |
|---|
| 3140 | | - /* workaround for 440MX */ |
|---|
| 3141 | | - if (chip->fix_nocache) |
|---|
| 3142 | | - fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 1); |
|---|
| 3143 | 3052 | int_sta_masks = 0; |
|---|
| 3144 | 3053 | for (i = 0; i < chip->bdbars_count; i++) { |
|---|
| 3145 | 3054 | ichdev = &chip->ichd[i]; |
|---|
| .. | .. |
|---|
| 3191 | 3100 | return -EBUSY; |
|---|
| 3192 | 3101 | } |
|---|
| 3193 | 3102 | chip->irq = pci->irq; |
|---|
| 3103 | + card->sync_irq = chip->irq; |
|---|
| 3194 | 3104 | |
|---|
| 3195 | 3105 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { |
|---|
| 3196 | 3106 | snd_intel8x0_free(chip); |
|---|
| .. | .. |
|---|
| 3230 | 3140 | { 0, NULL }, |
|---|
| 3231 | 3141 | }; |
|---|
| 3232 | 3142 | |
|---|
| 3233 | | -static struct snd_pci_quirk spdif_aclink_defaults[] = { |
|---|
| 3143 | +static const struct snd_pci_quirk spdif_aclink_defaults[] = { |
|---|
| 3234 | 3144 | SND_PCI_QUIRK(0x147b, 0x1c1a, "ASUS KN8", 1), |
|---|
| 3235 | 3145 | { } /* end */ |
|---|
| 3236 | 3146 | }; |
|---|
| 3237 | 3147 | |
|---|
| 3238 | | -/* look up white/black list for SPDIF over ac-link */ |
|---|
| 3148 | +/* look up allow/deny list for SPDIF over ac-link */ |
|---|
| 3239 | 3149 | static int check_default_spdif_aclink(struct pci_dev *pci) |
|---|
| 3240 | 3150 | { |
|---|
| 3241 | 3151 | const struct snd_pci_quirk *w; |
|---|