aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/intel8x0.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/intel8x0.c')
-rw-r--r--sound/pci/intel8x0.c208
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;
71static int buggy_semaphore; 71static int buggy_semaphore;
72static int buggy_irq = -1; /* auto-check */ 72static int buggy_irq = -1; /* auto-check */
73static int xbox; 73static int xbox;
74static int spdif_aclink = -1;
74 75
75module_param(index, int, 0444); 76module_param(index, int, 0444);
76MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard."); 77MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard.");
@@ -86,6 +87,8 @@ module_param(buggy_irq, bool, 0444);
86MODULE_PARM_DESC(buggy_irq, "Enable workaround for buggy interrupts on some motherboards."); 87MODULE_PARM_DESC(buggy_irq, "Enable workaround for buggy interrupts on some motherboards.");
87module_param(xbox, bool, 0444); 88module_param(xbox, bool, 0444);
88MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection."); 89MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection.");
90module_param(spdif_aclink, int, 0444);
91MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link.");
89 92
90/* just for backward compatibility */ 93/* just for backward compatibility */
91static int enable; 94static 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
449static u8 igetbyte(struct intel8x0 *chip, u32 offset) 448static 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
457static u16 igetword(struct intel8x0 *chip, u32 offset) 453static 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
465static u32 igetdword(struct intel8x0 *chip, u32 offset) 458static 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
473static void iputbyte(struct intel8x0 *chip, u32 offset, u8 val) 463static 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
481static void iputword(struct intel8x0 *chip, u32 offset, u16 val) 468static 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
489static void iputdword(struct intel8x0 *chip, u32 offset, u32 val) 473static 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
501static u16 iagetword(struct intel8x0 *chip, u32 offset) 482static 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
509static void iaputword(struct intel8x0 *chip, u32 offset, u16 val) 487static 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
2940static 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 */
2946static 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
2967static int __devinit snd_intel8x0_probe(struct pci_dev *pci, 2963static 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);