diff options
Diffstat (limited to 'sound/pci/intel8x0.c')
-rw-r--r-- | sound/pci/intel8x0.c | 208 |
1 files changed, 103 insertions, 105 deletions
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 30aaa6092a84..a289abfc7172 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
@@ -71,6 +71,7 @@ static char *ac97_quirk; | |||
71 | static int buggy_semaphore; | 71 | static int buggy_semaphore; |
72 | static int buggy_irq = -1; /* auto-check */ | 72 | static int buggy_irq = -1; /* auto-check */ |
73 | static int xbox; | 73 | static int xbox; |
74 | static int spdif_aclink = -1; | ||
74 | 75 | ||
75 | module_param(index, int, 0444); | 76 | module_param(index, int, 0444); |
76 | MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard."); | 77 | MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard."); |
@@ -86,6 +87,8 @@ module_param(buggy_irq, bool, 0444); | |||
86 | MODULE_PARM_DESC(buggy_irq, "Enable workaround for buggy interrupts on some motherboards."); | 87 | MODULE_PARM_DESC(buggy_irq, "Enable workaround for buggy interrupts on some motherboards."); |
87 | module_param(xbox, bool, 0444); | 88 | module_param(xbox, bool, 0444); |
88 | MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection."); | 89 | MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection."); |
90 | module_param(spdif_aclink, int, 0444); | ||
91 | MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link."); | ||
89 | 92 | ||
90 | /* just for backward compatibility */ | 93 | /* just for backward compatibility */ |
91 | static int enable; | 94 | static int enable; |
@@ -368,12 +371,8 @@ struct intel8x0 { | |||
368 | 371 | ||
369 | int irq; | 372 | int irq; |
370 | 373 | ||
371 | unsigned int mmio; | 374 | void __iomem *addr; |
372 | unsigned long addr; | 375 | void __iomem *bmaddr; |
373 | void __iomem *remap_addr; | ||
374 | unsigned int bm_mmio; | ||
375 | unsigned long bmaddr; | ||
376 | void __iomem *remap_bmaddr; | ||
377 | 376 | ||
378 | struct pci_dev *pci; | 377 | struct pci_dev *pci; |
379 | struct snd_card *card; | 378 | struct snd_card *card; |
@@ -446,72 +445,48 @@ MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids); | |||
446 | * Lowlevel I/O - busmaster | 445 | * Lowlevel I/O - busmaster |
447 | */ | 446 | */ |
448 | 447 | ||
449 | static u8 igetbyte(struct intel8x0 *chip, u32 offset) | 448 | static inline u8 igetbyte(struct intel8x0 *chip, u32 offset) |
450 | { | 449 | { |
451 | if (chip->bm_mmio) | 450 | return ioread8(chip->bmaddr + offset); |
452 | return readb(chip->remap_bmaddr + offset); | ||
453 | else | ||
454 | return inb(chip->bmaddr + offset); | ||
455 | } | 451 | } |
456 | 452 | ||
457 | static u16 igetword(struct intel8x0 *chip, u32 offset) | 453 | static inline u16 igetword(struct intel8x0 *chip, u32 offset) |
458 | { | 454 | { |
459 | if (chip->bm_mmio) | 455 | return ioread16(chip->bmaddr + offset); |
460 | return readw(chip->remap_bmaddr + offset); | ||
461 | else | ||
462 | return inw(chip->bmaddr + offset); | ||
463 | } | 456 | } |
464 | 457 | ||
465 | static u32 igetdword(struct intel8x0 *chip, u32 offset) | 458 | static inline u32 igetdword(struct intel8x0 *chip, u32 offset) |
466 | { | 459 | { |
467 | if (chip->bm_mmio) | 460 | return ioread32(chip->bmaddr + offset); |
468 | return readl(chip->remap_bmaddr + offset); | ||
469 | else | ||
470 | return inl(chip->bmaddr + offset); | ||
471 | } | 461 | } |
472 | 462 | ||
473 | static void iputbyte(struct intel8x0 *chip, u32 offset, u8 val) | 463 | static inline void iputbyte(struct intel8x0 *chip, u32 offset, u8 val) |
474 | { | 464 | { |
475 | if (chip->bm_mmio) | 465 | iowrite8(val, chip->bmaddr + offset); |
476 | writeb(val, chip->remap_bmaddr + offset); | ||
477 | else | ||
478 | outb(val, chip->bmaddr + offset); | ||
479 | } | 466 | } |
480 | 467 | ||
481 | static void iputword(struct intel8x0 *chip, u32 offset, u16 val) | 468 | static inline void iputword(struct intel8x0 *chip, u32 offset, u16 val) |
482 | { | 469 | { |
483 | if (chip->bm_mmio) | 470 | iowrite16(val, chip->bmaddr + offset); |
484 | writew(val, chip->remap_bmaddr + offset); | ||
485 | else | ||
486 | outw(val, chip->bmaddr + offset); | ||
487 | } | 471 | } |
488 | 472 | ||
489 | static void iputdword(struct intel8x0 *chip, u32 offset, u32 val) | 473 | static inline void iputdword(struct intel8x0 *chip, u32 offset, u32 val) |
490 | { | 474 | { |
491 | if (chip->bm_mmio) | 475 | iowrite32(val, chip->bmaddr + offset); |
492 | writel(val, chip->remap_bmaddr + offset); | ||
493 | else | ||
494 | outl(val, chip->bmaddr + offset); | ||
495 | } | 476 | } |
496 | 477 | ||
497 | /* | 478 | /* |
498 | * Lowlevel I/O - AC'97 registers | 479 | * Lowlevel I/O - AC'97 registers |
499 | */ | 480 | */ |
500 | 481 | ||
501 | static u16 iagetword(struct intel8x0 *chip, u32 offset) | 482 | static inline u16 iagetword(struct intel8x0 *chip, u32 offset) |
502 | { | 483 | { |
503 | if (chip->mmio) | 484 | return ioread16(chip->addr + offset); |
504 | return readw(chip->remap_addr + offset); | ||
505 | else | ||
506 | return inw(chip->addr + offset); | ||
507 | } | 485 | } |
508 | 486 | ||
509 | static void iaputword(struct intel8x0 *chip, u32 offset, u16 val) | 487 | static inline void iaputword(struct intel8x0 *chip, u32 offset, u16 val) |
510 | { | 488 | { |
511 | if (chip->mmio) | 489 | iowrite16(val, chip->addr + offset); |
512 | writew(val, chip->remap_addr + offset); | ||
513 | else | ||
514 | outw(val, chip->addr + offset); | ||
515 | } | 490 | } |
516 | 491 | ||
517 | /* | 492 | /* |
@@ -1606,10 +1581,14 @@ static int __devinit snd_intel8x0_pcm(struct intel8x0 *chip) | |||
1606 | case DEVICE_INTEL_ICH4: | 1581 | case DEVICE_INTEL_ICH4: |
1607 | tbl = intel_pcms; | 1582 | tbl = intel_pcms; |
1608 | tblsize = ARRAY_SIZE(intel_pcms); | 1583 | tblsize = ARRAY_SIZE(intel_pcms); |
1584 | if (spdif_aclink) | ||
1585 | tblsize--; | ||
1609 | break; | 1586 | break; |
1610 | case DEVICE_NFORCE: | 1587 | case DEVICE_NFORCE: |
1611 | tbl = nforce_pcms; | 1588 | tbl = nforce_pcms; |
1612 | tblsize = ARRAY_SIZE(nforce_pcms); | 1589 | tblsize = ARRAY_SIZE(nforce_pcms); |
1590 | if (spdif_aclink) | ||
1591 | tblsize--; | ||
1613 | break; | 1592 | break; |
1614 | case DEVICE_ALI: | 1593 | case DEVICE_ALI: |
1615 | tbl = ali_pcms; | 1594 | tbl = ali_pcms; |
@@ -2068,24 +2047,26 @@ static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock, | |||
2068 | }; | 2047 | }; |
2069 | 2048 | ||
2070 | chip->spdif_idx = -1; /* use PCMOUT (or disabled) */ | 2049 | chip->spdif_idx = -1; /* use PCMOUT (or disabled) */ |
2071 | switch (chip->device_type) { | 2050 | if (!spdif_aclink) { |
2072 | case DEVICE_NFORCE: | 2051 | switch (chip->device_type) { |
2073 | chip->spdif_idx = NVD_SPBAR; | 2052 | case DEVICE_NFORCE: |
2074 | break; | 2053 | chip->spdif_idx = NVD_SPBAR; |
2075 | case DEVICE_ALI: | 2054 | break; |
2076 | chip->spdif_idx = ALID_AC97SPDIFOUT; | 2055 | case DEVICE_ALI: |
2077 | break; | 2056 | chip->spdif_idx = ALID_AC97SPDIFOUT; |
2078 | case DEVICE_INTEL_ICH4: | 2057 | break; |
2079 | chip->spdif_idx = ICHD_SPBAR; | 2058 | case DEVICE_INTEL_ICH4: |
2080 | break; | 2059 | chip->spdif_idx = ICHD_SPBAR; |
2081 | }; | 2060 | break; |
2061 | }; | ||
2062 | } | ||
2082 | 2063 | ||
2083 | chip->in_ac97_init = 1; | 2064 | chip->in_ac97_init = 1; |
2084 | 2065 | ||
2085 | memset(&ac97, 0, sizeof(ac97)); | 2066 | memset(&ac97, 0, sizeof(ac97)); |
2086 | ac97.private_data = chip; | 2067 | ac97.private_data = chip; |
2087 | ac97.private_free = snd_intel8x0_mixer_free_ac97; | 2068 | ac97.private_free = snd_intel8x0_mixer_free_ac97; |
2088 | ac97.scaps = AC97_SCAP_SKIP_MODEM; | 2069 | ac97.scaps = AC97_SCAP_SKIP_MODEM | AC97_SCAP_POWER_SAVE; |
2089 | if (chip->xbox) | 2070 | if (chip->xbox) |
2090 | ac97.scaps |= AC97_SCAP_DETECT_BY_VENDOR; | 2071 | ac97.scaps |= AC97_SCAP_DETECT_BY_VENDOR; |
2091 | if (chip->device_type != DEVICE_ALI) { | 2072 | if (chip->device_type != DEVICE_ALI) { |
@@ -2201,11 +2182,11 @@ static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock, | |||
2201 | if ((igetdword(chip, ICHREG(GLOB_STA)) & ICH_SAMPLE_CAP) == ICH_SAMPLE_16_20) | 2182 | if ((igetdword(chip, ICHREG(GLOB_STA)) & ICH_SAMPLE_CAP) == ICH_SAMPLE_16_20) |
2202 | chip->smp20bit = 1; | 2183 | chip->smp20bit = 1; |
2203 | } | 2184 | } |
2204 | if (chip->device_type == DEVICE_NFORCE) { | 2185 | if (chip->device_type == DEVICE_NFORCE && !spdif_aclink) { |
2205 | /* 48kHz only */ | 2186 | /* 48kHz only */ |
2206 | chip->ichd[chip->spdif_idx].pcm->rates = SNDRV_PCM_RATE_48000; | 2187 | chip->ichd[chip->spdif_idx].pcm->rates = SNDRV_PCM_RATE_48000; |
2207 | } | 2188 | } |
2208 | if (chip->device_type == DEVICE_INTEL_ICH4) { | 2189 | if (chip->device_type == DEVICE_INTEL_ICH4 && !spdif_aclink) { |
2209 | /* use slot 10/11 for SPDIF */ | 2190 | /* use slot 10/11 for SPDIF */ |
2210 | u32 val; | 2191 | u32 val; |
2211 | val = igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_PCM_SPDIF_MASK; | 2192 | val = igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_PCM_SPDIF_MASK; |
@@ -2333,7 +2314,7 @@ static int snd_intel8x0_ich_chip_init(struct intel8x0 *chip, int probing) | |||
2333 | /* unmute the output on SIS7012 */ | 2314 | /* unmute the output on SIS7012 */ |
2334 | iputword(chip, 0x4c, igetword(chip, 0x4c) | 1); | 2315 | iputword(chip, 0x4c, igetword(chip, 0x4c) | 1); |
2335 | } | 2316 | } |
2336 | if (chip->device_type == DEVICE_NFORCE) { | 2317 | if (chip->device_type == DEVICE_NFORCE && !spdif_aclink) { |
2337 | /* enable SPDIF interrupt */ | 2318 | /* enable SPDIF interrupt */ |
2338 | unsigned int val; | 2319 | unsigned int val; |
2339 | pci_read_config_dword(chip->pci, 0x4c, &val); | 2320 | pci_read_config_dword(chip->pci, 0x4c, &val); |
@@ -2426,7 +2407,7 @@ static int snd_intel8x0_free(struct intel8x0 *chip) | |||
2426 | /* reset channels */ | 2407 | /* reset channels */ |
2427 | for (i = 0; i < chip->bdbars_count; i++) | 2408 | for (i = 0; i < chip->bdbars_count; i++) |
2428 | iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS); | 2409 | iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS); |
2429 | if (chip->device_type == DEVICE_NFORCE) { | 2410 | if (chip->device_type == DEVICE_NFORCE && !spdif_aclink) { |
2430 | /* stop the spdif interrupt */ | 2411 | /* stop the spdif interrupt */ |
2431 | unsigned int val; | 2412 | unsigned int val; |
2432 | pci_read_config_dword(chip->pci, 0x4c, &val); | 2413 | pci_read_config_dword(chip->pci, 0x4c, &val); |
@@ -2443,10 +2424,10 @@ static int snd_intel8x0_free(struct intel8x0 *chip) | |||
2443 | fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 0); | 2424 | fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 0); |
2444 | snd_dma_free_pages(&chip->bdbars); | 2425 | snd_dma_free_pages(&chip->bdbars); |
2445 | } | 2426 | } |
2446 | if (chip->remap_addr) | 2427 | if (chip->addr) |
2447 | iounmap(chip->remap_addr); | 2428 | pci_iounmap(chip->pci, chip->addr); |
2448 | if (chip->remap_bmaddr) | 2429 | if (chip->bmaddr) |
2449 | iounmap(chip->remap_bmaddr); | 2430 | pci_iounmap(chip->pci, chip->bmaddr); |
2450 | pci_release_regions(chip->pci); | 2431 | pci_release_regions(chip->pci); |
2451 | pci_disable_device(chip->pci); | 2432 | pci_disable_device(chip->pci); |
2452 | kfree(chip); | 2433 | kfree(chip); |
@@ -2520,7 +2501,7 @@ static int intel8x0_resume(struct pci_dev *pci) | |||
2520 | snd_intel8x0_chip_init(chip, 0); | 2501 | snd_intel8x0_chip_init(chip, 0); |
2521 | 2502 | ||
2522 | /* re-initialize mixer stuff */ | 2503 | /* re-initialize mixer stuff */ |
2523 | if (chip->device_type == DEVICE_INTEL_ICH4) { | 2504 | if (chip->device_type == DEVICE_INTEL_ICH4 && !spdif_aclink) { |
2524 | /* enable separate SDINs for ICH4 */ | 2505 | /* enable separate SDINs for ICH4 */ |
2525 | iputbyte(chip, ICHREG(SDM), chip->sdm_saved); | 2506 | iputbyte(chip, ICHREG(SDM), chip->sdm_saved); |
2526 | /* use slot 10/11 for SPDIF */ | 2507 | /* use slot 10/11 for SPDIF */ |
@@ -2793,35 +2774,27 @@ static int __devinit snd_intel8x0_create(struct snd_card *card, | |||
2793 | 2774 | ||
2794 | if (device_type == DEVICE_ALI) { | 2775 | if (device_type == DEVICE_ALI) { |
2795 | /* ALI5455 has no ac97 region */ | 2776 | /* ALI5455 has no ac97 region */ |
2796 | chip->bmaddr = pci_resource_start(pci, 0); | 2777 | chip->bmaddr = pci_iomap(pci, 0, 0); |
2797 | goto port_inited; | 2778 | goto port_inited; |
2798 | } | 2779 | } |
2799 | 2780 | ||
2800 | if (pci_resource_flags(pci, 2) & IORESOURCE_MEM) { /* ICH4 and Nforce */ | 2781 | if (pci_resource_flags(pci, 2) & IORESOURCE_MEM) /* ICH4 and Nforce */ |
2801 | chip->mmio = 1; | 2782 | chip->addr = pci_iomap(pci, 2, 0); |
2802 | chip->addr = pci_resource_start(pci, 2); | 2783 | else |
2803 | chip->remap_addr = ioremap_nocache(chip->addr, | 2784 | chip->addr = pci_iomap(pci, 0, 0); |
2804 | pci_resource_len(pci, 2)); | 2785 | if (!chip->addr) { |
2805 | if (chip->remap_addr == NULL) { | 2786 | snd_printk(KERN_ERR "AC'97 space ioremap problem\n"); |
2806 | snd_printk(KERN_ERR "AC'97 space ioremap problem\n"); | 2787 | snd_intel8x0_free(chip); |
2807 | snd_intel8x0_free(chip); | 2788 | return -EIO; |
2808 | return -EIO; | 2789 | } |
2809 | } | 2790 | if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) /* ICH4 */ |
2810 | } else { | 2791 | chip->bmaddr = pci_iomap(pci, 3, 0); |
2811 | chip->addr = pci_resource_start(pci, 0); | 2792 | else |
2812 | } | 2793 | chip->bmaddr = pci_iomap(pci, 1, 0); |
2813 | if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) { /* ICH4 */ | 2794 | if (!chip->bmaddr) { |
2814 | chip->bm_mmio = 1; | 2795 | snd_printk(KERN_ERR "Controller space ioremap problem\n"); |
2815 | chip->bmaddr = pci_resource_start(pci, 3); | 2796 | snd_intel8x0_free(chip); |
2816 | chip->remap_bmaddr = ioremap_nocache(chip->bmaddr, | 2797 | return -EIO; |
2817 | pci_resource_len(pci, 3)); | ||
2818 | if (chip->remap_bmaddr == NULL) { | ||
2819 | snd_printk(KERN_ERR "Controller space ioremap problem\n"); | ||
2820 | snd_intel8x0_free(chip); | ||
2821 | return -EIO; | ||
2822 | } | ||
2823 | } else { | ||
2824 | chip->bmaddr = pci_resource_start(pci, 1); | ||
2825 | } | 2798 | } |
2826 | 2799 | ||
2827 | port_inited: | 2800 | port_inited: |
@@ -2964,6 +2937,29 @@ static struct shortname_table { | |||
2964 | { 0, NULL }, | 2937 | { 0, NULL }, |
2965 | }; | 2938 | }; |
2966 | 2939 | ||
2940 | static struct snd_pci_quirk spdif_aclink_defaults[] __devinitdata = { | ||
2941 | SND_PCI_QUIRK(0x147b, 0x1c1a, "ASUS KN8", 1), | ||
2942 | { } /* end */ | ||
2943 | }; | ||
2944 | |||
2945 | /* look up white/black list for SPDIF over ac-link */ | ||
2946 | static int __devinit check_default_spdif_aclink(struct pci_dev *pci) | ||
2947 | { | ||
2948 | const struct snd_pci_quirk *w; | ||
2949 | |||
2950 | w = snd_pci_quirk_lookup(pci, spdif_aclink_defaults); | ||
2951 | if (w) { | ||
2952 | if (w->value) | ||
2953 | snd_printdd(KERN_INFO "intel8x0: Using SPDIF over " | ||
2954 | "AC-Link for %s\n", w->name); | ||
2955 | else | ||
2956 | snd_printdd(KERN_INFO "intel8x0: Using integrated " | ||
2957 | "SPDIF DMA for %s\n", w->name); | ||
2958 | return w->value; | ||
2959 | } | ||
2960 | return 0; | ||
2961 | } | ||
2962 | |||
2967 | static int __devinit snd_intel8x0_probe(struct pci_dev *pci, | 2963 | static int __devinit snd_intel8x0_probe(struct pci_dev *pci, |
2968 | const struct pci_device_id *pci_id) | 2964 | const struct pci_device_id *pci_id) |
2969 | { | 2965 | { |
@@ -2976,16 +2972,18 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci, | |||
2976 | if (card == NULL) | 2972 | if (card == NULL) |
2977 | return -ENOMEM; | 2973 | return -ENOMEM; |
2978 | 2974 | ||
2979 | switch (pci_id->driver_data) { | 2975 | if (spdif_aclink < 0) |
2980 | case DEVICE_NFORCE: | 2976 | spdif_aclink = check_default_spdif_aclink(pci); |
2981 | strcpy(card->driver, "NFORCE"); | 2977 | |
2982 | break; | 2978 | strcpy(card->driver, "ICH"); |
2983 | case DEVICE_INTEL_ICH4: | 2979 | if (!spdif_aclink) { |
2984 | strcpy(card->driver, "ICH4"); | 2980 | switch (pci_id->driver_data) { |
2985 | break; | 2981 | case DEVICE_NFORCE: |
2986 | default: | 2982 | strcpy(card->driver, "NFORCE"); |
2987 | strcpy(card->driver, "ICH"); | 2983 | break; |
2988 | break; | 2984 | case DEVICE_INTEL_ICH4: |
2985 | strcpy(card->driver, "ICH4"); | ||
2986 | } | ||
2989 | } | 2987 | } |
2990 | 2988 | ||
2991 | strcpy(card->shortname, "Intel ICH"); | 2989 | strcpy(card->shortname, "Intel ICH"); |
@@ -3025,8 +3023,8 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci, | |||
3025 | snd_intel8x0_proc_init(chip); | 3023 | snd_intel8x0_proc_init(chip); |
3026 | 3024 | ||
3027 | snprintf(card->longname, sizeof(card->longname), | 3025 | snprintf(card->longname, sizeof(card->longname), |
3028 | "%s with %s at %#lx, irq %i", card->shortname, | 3026 | "%s with %s at irq %i", card->shortname, |
3029 | snd_ac97_get_short_name(chip->ac97[0]), chip->addr, chip->irq); | 3027 | snd_ac97_get_short_name(chip->ac97[0]), chip->irq); |
3030 | 3028 | ||
3031 | if (! ac97_clock) | 3029 | if (! ac97_clock) |
3032 | intel8x0_measure_ac97_clock(chip); | 3030 | intel8x0_measure_ac97_clock(chip); |