.. | .. |
---|
| 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; |
---|