diff options
Diffstat (limited to 'sound/pci')
31 files changed, 941 insertions, 135 deletions
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index ca25e6179d76..93422e3a3f0c 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig | |||
@@ -507,7 +507,7 @@ config SND_FM801 | |||
507 | config SND_FM801_TEA575X_BOOL | 507 | config SND_FM801_TEA575X_BOOL |
508 | bool "ForteMedia FM801 + TEA5757 tuner" | 508 | bool "ForteMedia FM801 + TEA5757 tuner" |
509 | depends on SND_FM801 | 509 | depends on SND_FM801 |
510 | depends on VIDEO_V4L1=y || VIDEO_V4L1=SND_FM801 | 510 | depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_FM801 |
511 | help | 511 | help |
512 | Say Y here to include support for soundcards based on the ForteMedia | 512 | Say Y here to include support for soundcards based on the ForteMedia |
513 | FM801 chip with a TEA5757 tuner connected to GPIO1-3 pins (Media | 513 | FM801 chip with a TEA5757 tuner connected to GPIO1-3 pins (Media |
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c index d1f242bd0ac5..8f5098f92c37 100644 --- a/sound/pci/ad1889.c +++ b/sound/pci/ad1889.c | |||
@@ -909,8 +909,8 @@ snd_ad1889_create(struct snd_card *card, | |||
909 | return err; | 909 | return err; |
910 | 910 | ||
911 | /* check PCI availability (32bit DMA) */ | 911 | /* check PCI availability (32bit DMA) */ |
912 | if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 || | 912 | if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0 || |
913 | pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) { | 913 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0) { |
914 | printk(KERN_ERR PFX "error setting 32-bit DMA mask.\n"); | 914 | printk(KERN_ERR PFX "error setting 32-bit DMA mask.\n"); |
915 | pci_disable_device(pci); | 915 | pci_disable_device(pci); |
916 | return -ENXIO; | 916 | return -ENXIO; |
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index 4edf270a7809..c551006e2920 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c | |||
@@ -2186,8 +2186,8 @@ static int __devinit snd_ali_create(struct snd_card *card, | |||
2186 | if (err < 0) | 2186 | if (err < 0) |
2187 | return err; | 2187 | return err; |
2188 | /* check, if we can restrict PCI DMA transfers to 31 bits */ | 2188 | /* check, if we can restrict PCI DMA transfers to 31 bits */ |
2189 | if (pci_set_dma_mask(pci, DMA_31BIT_MASK) < 0 || | 2189 | if (pci_set_dma_mask(pci, DMA_BIT_MASK(31)) < 0 || |
2190 | pci_set_consistent_dma_mask(pci, DMA_31BIT_MASK) < 0) { | 2190 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(31)) < 0) { |
2191 | snd_printk(KERN_ERR "architecture does not support " | 2191 | snd_printk(KERN_ERR "architecture does not support " |
2192 | "31bit PCI busmaster DMA\n"); | 2192 | "31bit PCI busmaster DMA\n"); |
2193 | pci_disable_device(pci); | 2193 | pci_disable_device(pci); |
diff --git a/sound/pci/als300.c b/sound/pci/als300.c index 009b4c8225a5..3aa35af7ca91 100644 --- a/sound/pci/als300.c +++ b/sound/pci/als300.c | |||
@@ -689,8 +689,8 @@ static int __devinit snd_als300_create(struct snd_card *card, | |||
689 | if ((err = pci_enable_device(pci)) < 0) | 689 | if ((err = pci_enable_device(pci)) < 0) |
690 | return err; | 690 | return err; |
691 | 691 | ||
692 | if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 || | 692 | if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 || |
693 | pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) { | 693 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) { |
694 | printk(KERN_ERR "error setting 28bit DMA mask\n"); | 694 | printk(KERN_ERR "error setting 28bit DMA mask\n"); |
695 | pci_disable_device(pci); | 695 | pci_disable_device(pci); |
696 | return -ENXIO; | 696 | return -ENXIO; |
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c index 542a0c65a92c..3dbacde1a5af 100644 --- a/sound/pci/als4000.c +++ b/sound/pci/als4000.c | |||
@@ -872,8 +872,8 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, | |||
872 | return err; | 872 | return err; |
873 | } | 873 | } |
874 | /* check, if we can restrict PCI DMA transfers to 24 bits */ | 874 | /* check, if we can restrict PCI DMA transfers to 24 bits */ |
875 | if (pci_set_dma_mask(pci, DMA_24BIT_MASK) < 0 || | 875 | if (pci_set_dma_mask(pci, DMA_BIT_MASK(24)) < 0 || |
876 | pci_set_consistent_dma_mask(pci, DMA_24BIT_MASK) < 0) { | 876 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(24)) < 0) { |
877 | snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n"); | 877 | snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n"); |
878 | pci_disable_device(pci); | 878 | pci_disable_device(pci); |
879 | return -ENXIO; | 879 | return -ENXIO; |
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c index 9ec122383eef..7b72c88e449d 100644 --- a/sound/pci/au88x0/au88x0.c +++ b/sound/pci/au88x0/au88x0.c | |||
@@ -151,8 +151,8 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip) | |||
151 | // check PCI availability (DMA). | 151 | // check PCI availability (DMA). |
152 | if ((err = pci_enable_device(pci)) < 0) | 152 | if ((err = pci_enable_device(pci)) < 0) |
153 | return err; | 153 | return err; |
154 | if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 || | 154 | if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0 || |
155 | pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) { | 155 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0) { |
156 | printk(KERN_ERR "error to set DMA mask\n"); | 156 | printk(KERN_ERR "error to set DMA mask\n"); |
157 | pci_disable_device(pci); | 157 | pci_disable_device(pci); |
158 | return -ENXIO; | 158 | return -ENXIO; |
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c index 8eea29fc42fe..4d34bb0d99d3 100644 --- a/sound/pci/aw2/aw2-alsa.c +++ b/sound/pci/aw2/aw2-alsa.c | |||
@@ -279,8 +279,8 @@ static int __devinit snd_aw2_create(struct snd_card *card, | |||
279 | pci_set_master(pci); | 279 | pci_set_master(pci); |
280 | 280 | ||
281 | /* check PCI availability (32bit DMA) */ | 281 | /* check PCI availability (32bit DMA) */ |
282 | if ((pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0) || | 282 | if ((pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0) || |
283 | (pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0)) { | 283 | (pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0)) { |
284 | printk(KERN_ERR "aw2: Impossible to set 32bit mask DMA\n"); | 284 | printk(KERN_ERR "aw2: Impossible to set 32bit mask DMA\n"); |
285 | pci_disable_device(pci); | 285 | pci_disable_device(pci); |
286 | return -ENXIO; | 286 | return -ENXIO; |
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index e9e9b5821d41..f290bc56178f 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c | |||
@@ -2125,8 +2125,8 @@ snd_azf3328_create(struct snd_card *card, | |||
2125 | chip->irq = -1; | 2125 | chip->irq = -1; |
2126 | 2126 | ||
2127 | /* check if we can restrict PCI DMA transfers to 24 bits */ | 2127 | /* check if we can restrict PCI DMA transfers to 24 bits */ |
2128 | if (pci_set_dma_mask(pci, DMA_24BIT_MASK) < 0 || | 2128 | if (pci_set_dma_mask(pci, DMA_BIT_MASK(24)) < 0 || |
2129 | pci_set_consistent_dma_mask(pci, DMA_24BIT_MASK) < 0) { | 2129 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(24)) < 0) { |
2130 | snd_printk(KERN_ERR "architecture does not support " | 2130 | snd_printk(KERN_ERR "architecture does not support " |
2131 | "24bit PCI busmaster DMA\n" | 2131 | "24bit PCI busmaster DMA\n" |
2132 | ); | 2132 | ); |
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index df757575798a..bfac30f7929f 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c | |||
@@ -1589,8 +1589,8 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card, | |||
1589 | err = pci_enable_device(pci); | 1589 | err = pci_enable_device(pci); |
1590 | if (err < 0) | 1590 | if (err < 0) |
1591 | return err; | 1591 | return err; |
1592 | if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 || | 1592 | if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0 || |
1593 | pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) { | 1593 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0) { |
1594 | printk(KERN_ERR "error to set 32bit mask DMA\n"); | 1594 | printk(KERN_ERR "error to set 32bit mask DMA\n"); |
1595 | pci_disable_device(pci); | 1595 | pci_disable_device(pci); |
1596 | return -ENXIO; | 1596 | return -ENXIO; |
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c index c89ed1f5bc2b..05f56e04849b 100644 --- a/sound/pci/cs5535audio/cs5535audio.c +++ b/sound/pci/cs5535audio/cs5535audio.c | |||
@@ -285,8 +285,8 @@ static int __devinit snd_cs5535audio_create(struct snd_card *card, | |||
285 | if ((err = pci_enable_device(pci)) < 0) | 285 | if ((err = pci_enable_device(pci)) < 0) |
286 | return err; | 286 | return err; |
287 | 287 | ||
288 | if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 || | 288 | if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0 || |
289 | pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) { | 289 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0) { |
290 | printk(KERN_WARNING "unable to get 32bit dma\n"); | 290 | printk(KERN_WARNING "unable to get 32bit dma\n"); |
291 | err = -ENXIO; | 291 | err = -ENXIO; |
292 | goto pcifail; | 292 | goto pcifail; |
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index 31542adc6b7e..1970f0e70f37 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c | |||
@@ -897,8 +897,8 @@ static int __devinit snd_emu10k1x_create(struct snd_card *card, | |||
897 | 897 | ||
898 | if ((err = pci_enable_device(pci)) < 0) | 898 | if ((err = pci_enable_device(pci)) < 0) |
899 | return err; | 899 | return err; |
900 | if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 || | 900 | if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 || |
901 | pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) { | 901 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) { |
902 | snd_printk(KERN_ERR "error to set 28bit mask DMA\n"); | 902 | snd_printk(KERN_ERR "error to set 28bit mask DMA\n"); |
903 | pci_disable_device(pci); | 903 | pci_disable_device(pci); |
904 | return -ENXIO; | 904 | return -ENXIO; |
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 191e1cd9997d..4b302d86f5f2 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c | |||
@@ -2493,24 +2493,17 @@ static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, un | |||
2493 | case SNDRV_EMU10K1_IOCTL_CODE_POKE: | 2493 | case SNDRV_EMU10K1_IOCTL_CODE_POKE: |
2494 | if (!capable(CAP_SYS_ADMIN)) | 2494 | if (!capable(CAP_SYS_ADMIN)) |
2495 | return -EPERM; | 2495 | return -EPERM; |
2496 | icode = kmalloc(sizeof(*icode), GFP_KERNEL); | 2496 | |
2497 | if (icode == NULL) | 2497 | icode = memdup_user(argp, sizeof(*icode)); |
2498 | return -ENOMEM; | 2498 | if (IS_ERR(icode)) |
2499 | if (copy_from_user(icode, argp, sizeof(*icode))) { | 2499 | return PTR_ERR(icode); |
2500 | kfree(icode); | ||
2501 | return -EFAULT; | ||
2502 | } | ||
2503 | res = snd_emu10k1_icode_poke(emu, icode); | 2500 | res = snd_emu10k1_icode_poke(emu, icode); |
2504 | kfree(icode); | 2501 | kfree(icode); |
2505 | return res; | 2502 | return res; |
2506 | case SNDRV_EMU10K1_IOCTL_CODE_PEEK: | 2503 | case SNDRV_EMU10K1_IOCTL_CODE_PEEK: |
2507 | icode = kmalloc(sizeof(*icode), GFP_KERNEL); | 2504 | icode = memdup_user(argp, sizeof(*icode)); |
2508 | if (icode == NULL) | 2505 | if (IS_ERR(icode)) |
2509 | return -ENOMEM; | 2506 | return PTR_ERR(icode); |
2510 | if (copy_from_user(icode, argp, sizeof(*icode))) { | ||
2511 | kfree(icode); | ||
2512 | return -EFAULT; | ||
2513 | } | ||
2514 | res = snd_emu10k1_icode_peek(emu, icode); | 2507 | res = snd_emu10k1_icode_peek(emu, icode); |
2515 | if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) { | 2508 | if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) { |
2516 | kfree(icode); | 2509 | kfree(icode); |
@@ -2519,24 +2512,16 @@ static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, un | |||
2519 | kfree(icode); | 2512 | kfree(icode); |
2520 | return res; | 2513 | return res; |
2521 | case SNDRV_EMU10K1_IOCTL_PCM_POKE: | 2514 | case SNDRV_EMU10K1_IOCTL_PCM_POKE: |
2522 | ipcm = kmalloc(sizeof(*ipcm), GFP_KERNEL); | 2515 | ipcm = memdup_user(argp, sizeof(*ipcm)); |
2523 | if (ipcm == NULL) | 2516 | if (IS_ERR(ipcm)) |
2524 | return -ENOMEM; | 2517 | return PTR_ERR(ipcm); |
2525 | if (copy_from_user(ipcm, argp, sizeof(*ipcm))) { | ||
2526 | kfree(ipcm); | ||
2527 | return -EFAULT; | ||
2528 | } | ||
2529 | res = snd_emu10k1_ipcm_poke(emu, ipcm); | 2518 | res = snd_emu10k1_ipcm_poke(emu, ipcm); |
2530 | kfree(ipcm); | 2519 | kfree(ipcm); |
2531 | return res; | 2520 | return res; |
2532 | case SNDRV_EMU10K1_IOCTL_PCM_PEEK: | 2521 | case SNDRV_EMU10K1_IOCTL_PCM_PEEK: |
2533 | ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL); | 2522 | ipcm = memdup_user(argp, sizeof(*ipcm)); |
2534 | if (ipcm == NULL) | 2523 | if (IS_ERR(ipcm)) |
2535 | return -ENOMEM; | 2524 | return PTR_ERR(ipcm); |
2536 | if (copy_from_user(ipcm, argp, sizeof(*ipcm))) { | ||
2537 | kfree(ipcm); | ||
2538 | return -EFAULT; | ||
2539 | } | ||
2540 | res = snd_emu10k1_ipcm_peek(emu, ipcm); | 2525 | res = snd_emu10k1_ipcm_peek(emu, ipcm); |
2541 | if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) { | 2526 | if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) { |
2542 | kfree(ipcm); | 2527 | kfree(ipcm); |
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index dd63b132fb8e..fbd2ac09aa34 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c | |||
@@ -1608,8 +1608,8 @@ static int __devinit snd_es1938_create(struct snd_card *card, | |||
1608 | if ((err = pci_enable_device(pci)) < 0) | 1608 | if ((err = pci_enable_device(pci)) < 0) |
1609 | return err; | 1609 | return err; |
1610 | /* check, if we can restrict PCI DMA transfers to 24 bits */ | 1610 | /* check, if we can restrict PCI DMA transfers to 24 bits */ |
1611 | if (pci_set_dma_mask(pci, DMA_24BIT_MASK) < 0 || | 1611 | if (pci_set_dma_mask(pci, DMA_BIT_MASK(24)) < 0 || |
1612 | pci_set_consistent_dma_mask(pci, DMA_24BIT_MASK) < 0) { | 1612 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(24)) < 0) { |
1613 | snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n"); | 1613 | snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n"); |
1614 | pci_disable_device(pci); | 1614 | pci_disable_device(pci); |
1615 | return -ENXIO; | 1615 | return -ENXIO; |
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index dc97e8116141..a11f453a6b6d 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c | |||
@@ -2539,8 +2539,8 @@ static int __devinit snd_es1968_create(struct snd_card *card, | |||
2539 | if ((err = pci_enable_device(pci)) < 0) | 2539 | if ((err = pci_enable_device(pci)) < 0) |
2540 | return err; | 2540 | return err; |
2541 | /* check, if we can restrict PCI DMA transfers to 28 bits */ | 2541 | /* check, if we can restrict PCI DMA transfers to 28 bits */ |
2542 | if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 || | 2542 | if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 || |
2543 | pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) { | 2543 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) { |
2544 | snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n"); | 2544 | snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n"); |
2545 | pci_disable_device(pci); | 2545 | pci_disable_device(pci); |
2546 | return -ENXIO; | 2546 | return -ENXIO; |
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index eb2a19b894a0..c710150d5065 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig | |||
@@ -139,6 +139,19 @@ config SND_HDA_CODEC_CONEXANT | |||
139 | snd-hda-codec-conexant. | 139 | snd-hda-codec-conexant. |
140 | This module is automatically loaded at probing. | 140 | This module is automatically loaded at probing. |
141 | 141 | ||
142 | config SND_HDA_CODEC_CA0110 | ||
143 | bool "Build Creative CA0110-IBG codec support" | ||
144 | depends on SND_HDA_INTEL | ||
145 | default y | ||
146 | help | ||
147 | Say Y here to include Creative CA0110-IBG codec support in | ||
148 | snd-hda-intel driver, found on some Creative X-Fi cards. | ||
149 | |||
150 | When the HD-audio driver is built as a module, the codec | ||
151 | support code is also built as another module, | ||
152 | snd-hda-codec-ca0110. | ||
153 | This module is automatically loaded at probing. | ||
154 | |||
142 | config SND_HDA_CODEC_CMEDIA | 155 | config SND_HDA_CODEC_CMEDIA |
143 | bool "Build C-Media HD-audio codec support" | 156 | bool "Build C-Media HD-audio codec support" |
144 | default y | 157 | default y |
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index 50f9d0967251..e3081d4586cc 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile | |||
@@ -13,6 +13,7 @@ snd-hda-codec-analog-objs := patch_analog.o | |||
13 | snd-hda-codec-idt-objs := patch_sigmatel.o | 13 | snd-hda-codec-idt-objs := patch_sigmatel.o |
14 | snd-hda-codec-si3054-objs := patch_si3054.o | 14 | snd-hda-codec-si3054-objs := patch_si3054.o |
15 | snd-hda-codec-atihdmi-objs := patch_atihdmi.o | 15 | snd-hda-codec-atihdmi-objs := patch_atihdmi.o |
16 | snd-hda-codec-ca0110-objs := patch_ca0110.o | ||
16 | snd-hda-codec-conexant-objs := patch_conexant.o | 17 | snd-hda-codec-conexant-objs := patch_conexant.o |
17 | snd-hda-codec-via-objs := patch_via.o | 18 | snd-hda-codec-via-objs := patch_via.o |
18 | snd-hda-codec-nvhdmi-objs := patch_nvhdmi.o | 19 | snd-hda-codec-nvhdmi-objs := patch_nvhdmi.o |
@@ -40,6 +41,9 @@ endif | |||
40 | ifdef CONFIG_SND_HDA_CODEC_ATIHDMI | 41 | ifdef CONFIG_SND_HDA_CODEC_ATIHDMI |
41 | obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-atihdmi.o | 42 | obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-atihdmi.o |
42 | endif | 43 | endif |
44 | ifdef CONFIG_SND_HDA_CODEC_CA0110 | ||
45 | obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0110.o | ||
46 | endif | ||
43 | ifdef CONFIG_SND_HDA_CODEC_CONEXANT | 47 | ifdef CONFIG_SND_HDA_CODEC_CONEXANT |
44 | obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-conexant.o | 48 | obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-conexant.o |
45 | endif | 49 | endif |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 1736ccbebc72..b649033a4c81 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -48,6 +48,7 @@ static struct hda_vendor_id hda_vendor_ids[] = { | |||
48 | { 0x1095, "Silicon Image" }, | 48 | { 0x1095, "Silicon Image" }, |
49 | { 0x10de, "Nvidia" }, | 49 | { 0x10de, "Nvidia" }, |
50 | { 0x10ec, "Realtek" }, | 50 | { 0x10ec, "Realtek" }, |
51 | { 0x1102, "Creative" }, | ||
51 | { 0x1106, "VIA" }, | 52 | { 0x1106, "VIA" }, |
52 | { 0x111d, "IDT" }, | 53 | { 0x111d, "IDT" }, |
53 | { 0x11c1, "LSI" }, | 54 | { 0x11c1, "LSI" }, |
@@ -651,19 +652,21 @@ static int get_codec_name(struct hda_codec *codec) | |||
651 | */ | 652 | */ |
652 | static void /*__devinit*/ setup_fg_nodes(struct hda_codec *codec) | 653 | static void /*__devinit*/ setup_fg_nodes(struct hda_codec *codec) |
653 | { | 654 | { |
654 | int i, total_nodes; | 655 | int i, total_nodes, function_id; |
655 | hda_nid_t nid; | 656 | hda_nid_t nid; |
656 | 657 | ||
657 | total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid); | 658 | total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid); |
658 | for (i = 0; i < total_nodes; i++, nid++) { | 659 | for (i = 0; i < total_nodes; i++, nid++) { |
659 | codec->function_id = snd_hda_param_read(codec, nid, | 660 | function_id = snd_hda_param_read(codec, nid, |
660 | AC_PAR_FUNCTION_TYPE) & 0xff; | 661 | AC_PAR_FUNCTION_TYPE) & 0xff; |
661 | switch (codec->function_id) { | 662 | switch (function_id) { |
662 | case AC_GRP_AUDIO_FUNCTION: | 663 | case AC_GRP_AUDIO_FUNCTION: |
663 | codec->afg = nid; | 664 | codec->afg = nid; |
665 | codec->function_id = function_id; | ||
664 | break; | 666 | break; |
665 | case AC_GRP_MODEM_FUNCTION: | 667 | case AC_GRP_MODEM_FUNCTION: |
666 | codec->mfg = nid; | 668 | codec->mfg = nid; |
669 | codec->function_id = function_id; | ||
667 | break; | 670 | break; |
668 | default: | 671 | default: |
669 | break; | 672 | break; |
@@ -1454,6 +1457,8 @@ _snd_hda_find_mixer_ctl(struct hda_codec *codec, | |||
1454 | memset(&id, 0, sizeof(id)); | 1457 | memset(&id, 0, sizeof(id)); |
1455 | id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 1458 | id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
1456 | id.index = idx; | 1459 | id.index = idx; |
1460 | if (snd_BUG_ON(strlen(name) >= sizeof(id.name))) | ||
1461 | return NULL; | ||
1457 | strcpy(id.name, name); | 1462 | strcpy(id.name, name); |
1458 | return snd_ctl_find_id(codec->bus->card, &id); | 1463 | return snd_ctl_find_id(codec->bus->card, &id); |
1459 | } | 1464 | } |
@@ -2274,7 +2279,11 @@ int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, | |||
2274 | err = bus->ops.command(bus, res); | 2279 | err = bus->ops.command(bus, res); |
2275 | if (!err) { | 2280 | if (!err) { |
2276 | struct hda_cache_head *c; | 2281 | struct hda_cache_head *c; |
2277 | u32 key = build_cmd_cache_key(nid, verb); | 2282 | u32 key; |
2283 | /* parm may contain the verb stuff for get/set amp */ | ||
2284 | verb = verb | (parm >> 8); | ||
2285 | parm &= 0xff; | ||
2286 | key = build_cmd_cache_key(nid, verb); | ||
2278 | c = get_alloc_hash(&codec->cmd_cache, key); | 2287 | c = get_alloc_hash(&codec->cmd_cache, key); |
2279 | if (c) | 2288 | if (c) |
2280 | c->val = parm; | 2289 | c->val = parm; |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 803b72098ed3..04f19f8cad84 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -312,6 +312,8 @@ struct azx_dev { | |||
312 | unsigned int period_bytes; /* size of the period in bytes */ | 312 | unsigned int period_bytes; /* size of the period in bytes */ |
313 | unsigned int frags; /* number for period in the play buffer */ | 313 | unsigned int frags; /* number for period in the play buffer */ |
314 | unsigned int fifo_size; /* FIFO size */ | 314 | unsigned int fifo_size; /* FIFO size */ |
315 | unsigned long start_jiffies; /* start + minimum jiffies */ | ||
316 | unsigned long min_jiffies; /* minimum jiffies before position is valid */ | ||
315 | 317 | ||
316 | void __iomem *sd_addr; /* stream descriptor pointer */ | 318 | void __iomem *sd_addr; /* stream descriptor pointer */ |
317 | 319 | ||
@@ -330,7 +332,7 @@ struct azx_dev { | |||
330 | unsigned int opened :1; | 332 | unsigned int opened :1; |
331 | unsigned int running :1; | 333 | unsigned int running :1; |
332 | unsigned int irq_pending :1; | 334 | unsigned int irq_pending :1; |
333 | unsigned int irq_ignore :1; | 335 | unsigned int start_flag: 1; /* stream full start flag */ |
334 | /* | 336 | /* |
335 | * For VIA: | 337 | * For VIA: |
336 | * A flag to ensure DMA position is 0 | 338 | * A flag to ensure DMA position is 0 |
@@ -976,7 +978,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) | |||
976 | struct azx *chip = dev_id; | 978 | struct azx *chip = dev_id; |
977 | struct azx_dev *azx_dev; | 979 | struct azx_dev *azx_dev; |
978 | u32 status; | 980 | u32 status; |
979 | int i; | 981 | int i, ok; |
980 | 982 | ||
981 | spin_lock(&chip->reg_lock); | 983 | spin_lock(&chip->reg_lock); |
982 | 984 | ||
@@ -992,18 +994,14 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) | |||
992 | azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); | 994 | azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); |
993 | if (!azx_dev->substream || !azx_dev->running) | 995 | if (!azx_dev->substream || !azx_dev->running) |
994 | continue; | 996 | continue; |
995 | /* ignore the first dummy IRQ (due to pos_adj) */ | ||
996 | if (azx_dev->irq_ignore) { | ||
997 | azx_dev->irq_ignore = 0; | ||
998 | continue; | ||
999 | } | ||
1000 | /* check whether this IRQ is really acceptable */ | 997 | /* check whether this IRQ is really acceptable */ |
1001 | if (azx_position_ok(chip, azx_dev)) { | 998 | ok = azx_position_ok(chip, azx_dev); |
999 | if (ok == 1) { | ||
1002 | azx_dev->irq_pending = 0; | 1000 | azx_dev->irq_pending = 0; |
1003 | spin_unlock(&chip->reg_lock); | 1001 | spin_unlock(&chip->reg_lock); |
1004 | snd_pcm_period_elapsed(azx_dev->substream); | 1002 | snd_pcm_period_elapsed(azx_dev->substream); |
1005 | spin_lock(&chip->reg_lock); | 1003 | spin_lock(&chip->reg_lock); |
1006 | } else if (chip->bus && chip->bus->workq) { | 1004 | } else if (ok == 0 && chip->bus && chip->bus->workq) { |
1007 | /* bogus IRQ, process it later */ | 1005 | /* bogus IRQ, process it later */ |
1008 | azx_dev->irq_pending = 1; | 1006 | azx_dev->irq_pending = 1; |
1009 | queue_work(chip->bus->workq, | 1007 | queue_work(chip->bus->workq, |
@@ -1089,7 +1087,6 @@ static int azx_setup_periods(struct azx *chip, | |||
1089 | bdl = (u32 *)azx_dev->bdl.area; | 1087 | bdl = (u32 *)azx_dev->bdl.area; |
1090 | ofs = 0; | 1088 | ofs = 0; |
1091 | azx_dev->frags = 0; | 1089 | azx_dev->frags = 0; |
1092 | azx_dev->irq_ignore = 0; | ||
1093 | pos_adj = bdl_pos_adj[chip->dev_index]; | 1090 | pos_adj = bdl_pos_adj[chip->dev_index]; |
1094 | if (pos_adj > 0) { | 1091 | if (pos_adj > 0) { |
1095 | struct snd_pcm_runtime *runtime = substream->runtime; | 1092 | struct snd_pcm_runtime *runtime = substream->runtime; |
@@ -1110,7 +1107,6 @@ static int azx_setup_periods(struct azx *chip, | |||
1110 | &bdl, ofs, pos_adj, 1); | 1107 | &bdl, ofs, pos_adj, 1); |
1111 | if (ofs < 0) | 1108 | if (ofs < 0) |
1112 | goto error; | 1109 | goto error; |
1113 | azx_dev->irq_ignore = 1; | ||
1114 | } | 1110 | } |
1115 | } else | 1111 | } else |
1116 | pos_adj = 0; | 1112 | pos_adj = 0; |
@@ -1156,6 +1152,9 @@ static void azx_stream_reset(struct azx *chip, struct azx_dev *azx_dev) | |||
1156 | while (((val = azx_sd_readb(azx_dev, SD_CTL)) & SD_CTL_STREAM_RESET) && | 1152 | while (((val = azx_sd_readb(azx_dev, SD_CTL)) & SD_CTL_STREAM_RESET) && |
1157 | --timeout) | 1153 | --timeout) |
1158 | ; | 1154 | ; |
1155 | |||
1156 | /* reset first position - may not be synced with hw at this time */ | ||
1157 | *azx_dev->posbuf = 0; | ||
1159 | } | 1158 | } |
1160 | 1159 | ||
1161 | /* | 1160 | /* |
@@ -1410,7 +1409,6 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
1410 | snd_pcm_set_sync(substream); | 1409 | snd_pcm_set_sync(substream); |
1411 | mutex_unlock(&chip->open_mutex); | 1410 | mutex_unlock(&chip->open_mutex); |
1412 | 1411 | ||
1413 | azx_stream_reset(chip, azx_dev); | ||
1414 | return 0; | 1412 | return 0; |
1415 | } | 1413 | } |
1416 | 1414 | ||
@@ -1475,6 +1473,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) | |||
1475 | unsigned int bufsize, period_bytes, format_val; | 1473 | unsigned int bufsize, period_bytes, format_val; |
1476 | int err; | 1474 | int err; |
1477 | 1475 | ||
1476 | azx_stream_reset(chip, azx_dev); | ||
1478 | format_val = snd_hda_calc_stream_format(runtime->rate, | 1477 | format_val = snd_hda_calc_stream_format(runtime->rate, |
1479 | runtime->channels, | 1478 | runtime->channels, |
1480 | runtime->format, | 1479 | runtime->format, |
@@ -1503,6 +1502,8 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) | |||
1503 | return err; | 1502 | return err; |
1504 | } | 1503 | } |
1505 | 1504 | ||
1505 | azx_dev->min_jiffies = (runtime->period_size * HZ) / | ||
1506 | (runtime->rate * 2); | ||
1506 | azx_setup_controller(chip, azx_dev); | 1507 | azx_setup_controller(chip, azx_dev); |
1507 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 1508 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
1508 | azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1; | 1509 | azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1; |
@@ -1519,13 +1520,14 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
1519 | struct azx *chip = apcm->chip; | 1520 | struct azx *chip = apcm->chip; |
1520 | struct azx_dev *azx_dev; | 1521 | struct azx_dev *azx_dev; |
1521 | struct snd_pcm_substream *s; | 1522 | struct snd_pcm_substream *s; |
1522 | int start, nsync = 0, sbits = 0; | 1523 | int rstart = 0, start, nsync = 0, sbits = 0; |
1523 | int nwait, timeout; | 1524 | int nwait, timeout; |
1524 | 1525 | ||
1525 | switch (cmd) { | 1526 | switch (cmd) { |
1527 | case SNDRV_PCM_TRIGGER_START: | ||
1528 | rstart = 1; | ||
1526 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 1529 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
1527 | case SNDRV_PCM_TRIGGER_RESUME: | 1530 | case SNDRV_PCM_TRIGGER_RESUME: |
1528 | case SNDRV_PCM_TRIGGER_START: | ||
1529 | start = 1; | 1531 | start = 1; |
1530 | break; | 1532 | break; |
1531 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 1533 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
@@ -1555,6 +1557,10 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
1555 | if (s->pcm->card != substream->pcm->card) | 1557 | if (s->pcm->card != substream->pcm->card) |
1556 | continue; | 1558 | continue; |
1557 | azx_dev = get_azx_dev(s); | 1559 | azx_dev = get_azx_dev(s); |
1560 | if (rstart) { | ||
1561 | azx_dev->start_flag = 1; | ||
1562 | azx_dev->start_jiffies = jiffies + azx_dev->min_jiffies; | ||
1563 | } | ||
1558 | if (start) | 1564 | if (start) |
1559 | azx_stream_start(chip, azx_dev); | 1565 | azx_stream_start(chip, azx_dev); |
1560 | else | 1566 | else |
@@ -1704,6 +1710,11 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) | |||
1704 | { | 1710 | { |
1705 | unsigned int pos; | 1711 | unsigned int pos; |
1706 | 1712 | ||
1713 | if (azx_dev->start_flag && | ||
1714 | time_before_eq(jiffies, azx_dev->start_jiffies)) | ||
1715 | return -1; /* bogus (too early) interrupt */ | ||
1716 | azx_dev->start_flag = 0; | ||
1717 | |||
1707 | pos = azx_get_position(chip, azx_dev); | 1718 | pos = azx_get_position(chip, azx_dev); |
1708 | if (chip->position_fix == POS_FIX_AUTO) { | 1719 | if (chip->position_fix == POS_FIX_AUTO) { |
1709 | if (!pos) { | 1720 | if (!pos) { |
@@ -1820,7 +1831,7 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, | |||
1820 | &pcm); | 1831 | &pcm); |
1821 | if (err < 0) | 1832 | if (err < 0) |
1822 | return err; | 1833 | return err; |
1823 | strcpy(pcm->name, cpcm->name); | 1834 | strlcpy(pcm->name, cpcm->name, sizeof(pcm->name)); |
1824 | apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); | 1835 | apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); |
1825 | if (apcm == NULL) | 1836 | if (apcm == NULL) |
1826 | return -ENOMEM; | 1837 | return -ENOMEM; |
@@ -2261,11 +2272,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2261 | gcap &= ~0x01; | 2272 | gcap &= ~0x01; |
2262 | 2273 | ||
2263 | /* allow 64bit DMA address if supported by H/W */ | 2274 | /* allow 64bit DMA address if supported by H/W */ |
2264 | if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_64BIT_MASK)) | 2275 | if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) |
2265 | pci_set_consistent_dma_mask(pci, DMA_64BIT_MASK); | 2276 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64)); |
2266 | else { | 2277 | else { |
2267 | pci_set_dma_mask(pci, DMA_32BIT_MASK); | 2278 | pci_set_dma_mask(pci, DMA_BIT_MASK(32)); |
2268 | pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK); | 2279 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)); |
2269 | } | 2280 | } |
2270 | 2281 | ||
2271 | /* read number of streams from GCAP register instead of using | 2282 | /* read number of streams from GCAP register instead of using |
@@ -2348,9 +2359,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2348 | } | 2359 | } |
2349 | 2360 | ||
2350 | strcpy(card->driver, "HDA-Intel"); | 2361 | strcpy(card->driver, "HDA-Intel"); |
2351 | strcpy(card->shortname, driver_short_names[chip->driver_type]); | 2362 | strlcpy(card->shortname, driver_short_names[chip->driver_type], |
2352 | sprintf(card->longname, "%s at 0x%lx irq %i", | 2363 | sizeof(card->shortname)); |
2353 | card->shortname, chip->addr, chip->irq); | 2364 | snprintf(card->longname, sizeof(card->longname), |
2365 | "%s at 0x%lx irq %i", | ||
2366 | card->shortname, chip->addr, chip->irq); | ||
2354 | 2367 | ||
2355 | *rchip = chip; | 2368 | *rchip = chip; |
2356 | return 0; | 2369 | return 0; |
@@ -2503,6 +2516,11 @@ static struct pci_device_id azx_ids[] = { | |||
2503 | { PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA }, | 2516 | { PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA }, |
2504 | /* Teradici */ | 2517 | /* Teradici */ |
2505 | { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, | 2518 | { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, |
2519 | /* Creative X-Fi (CA0110-IBG) */ | ||
2520 | { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_ANY_ID), | ||
2521 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | ||
2522 | .class_mask = 0xffffff, | ||
2523 | .driver_data = AZX_DRIVER_GENERIC }, | ||
2506 | /* AMD Generic, PCI class code and Vendor ID for HD Audio */ | 2524 | /* AMD Generic, PCI class code and Vendor ID for HD Audio */ |
2507 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID), | 2525 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID), |
2508 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | 2526 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 5bb48ee8b6c6..9bcd8ab5a27f 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -3256,7 +3256,7 @@ static const char *ad1884_slave_vols[] = { | |||
3256 | "Mic Playback Volume", | 3256 | "Mic Playback Volume", |
3257 | "CD Playback Volume", | 3257 | "CD Playback Volume", |
3258 | "Internal Mic Playback Volume", | 3258 | "Internal Mic Playback Volume", |
3259 | "Docking Mic Playback Volume" | 3259 | "Docking Mic Playback Volume", |
3260 | /* "Beep Playback Volume", */ | 3260 | /* "Beep Playback Volume", */ |
3261 | "IEC958 Playback Volume", | 3261 | "IEC958 Playback Volume", |
3262 | NULL | 3262 | NULL |
@@ -3977,6 +3977,14 @@ static int patch_ad1884a(struct hda_codec *codec) | |||
3977 | spec->input_mux = &ad1884a_laptop_capture_source; | 3977 | spec->input_mux = &ad1884a_laptop_capture_source; |
3978 | codec->patch_ops.unsol_event = ad1884a_hp_unsol_event; | 3978 | codec->patch_ops.unsol_event = ad1884a_hp_unsol_event; |
3979 | codec->patch_ops.init = ad1884a_hp_init; | 3979 | codec->patch_ops.init = ad1884a_hp_init; |
3980 | /* set the upper-limit for mixer amp to 0dB for avoiding the | ||
3981 | * possible damage by overloading | ||
3982 | */ | ||
3983 | snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT, | ||
3984 | (0x17 << AC_AMPCAP_OFFSET_SHIFT) | | ||
3985 | (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | | ||
3986 | (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | | ||
3987 | (1 << AC_AMPCAP_MUTE_SHIFT)); | ||
3980 | break; | 3988 | break; |
3981 | case AD1884A_MOBILE: | 3989 | case AD1884A_MOBILE: |
3982 | spec->mixers[0] = ad1884a_mobile_mixers; | 3990 | spec->mixers[0] = ad1884a_mobile_mixers; |
diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c new file mode 100644 index 000000000000..392d108c3558 --- /dev/null +++ b/sound/pci/hda/patch_ca0110.c | |||
@@ -0,0 +1,573 @@ | |||
1 | /* | ||
2 | * HD audio interface patch for Creative X-Fi CA0110-IBG chip | ||
3 | * | ||
4 | * Copyright (c) 2008 Takashi Iwai <tiwai@suse.de> | ||
5 | * | ||
6 | * This driver is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This driver is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/init.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/pci.h> | ||
25 | #include <sound/core.h> | ||
26 | #include "hda_codec.h" | ||
27 | #include "hda_local.h" | ||
28 | |||
29 | /* | ||
30 | */ | ||
31 | |||
32 | struct ca0110_spec { | ||
33 | struct auto_pin_cfg autocfg; | ||
34 | struct hda_multi_out multiout; | ||
35 | hda_nid_t out_pins[AUTO_CFG_MAX_OUTS]; | ||
36 | hda_nid_t dacs[AUTO_CFG_MAX_OUTS]; | ||
37 | hda_nid_t hp_dac; | ||
38 | hda_nid_t input_pins[AUTO_PIN_LAST]; | ||
39 | hda_nid_t adcs[AUTO_PIN_LAST]; | ||
40 | hda_nid_t dig_out; | ||
41 | hda_nid_t dig_in; | ||
42 | unsigned int num_inputs; | ||
43 | const char *input_labels[AUTO_PIN_LAST]; | ||
44 | struct hda_pcm pcm_rec[2]; /* PCM information */ | ||
45 | }; | ||
46 | |||
47 | /* | ||
48 | * PCM callbacks | ||
49 | */ | ||
50 | static int ca0110_playback_pcm_open(struct hda_pcm_stream *hinfo, | ||
51 | struct hda_codec *codec, | ||
52 | struct snd_pcm_substream *substream) | ||
53 | { | ||
54 | struct ca0110_spec *spec = codec->spec; | ||
55 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, | ||
56 | hinfo); | ||
57 | } | ||
58 | |||
59 | static int ca0110_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
60 | struct hda_codec *codec, | ||
61 | unsigned int stream_tag, | ||
62 | unsigned int format, | ||
63 | struct snd_pcm_substream *substream) | ||
64 | { | ||
65 | struct ca0110_spec *spec = codec->spec; | ||
66 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, | ||
67 | stream_tag, format, substream); | ||
68 | } | ||
69 | |||
70 | static int ca0110_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
71 | struct hda_codec *codec, | ||
72 | struct snd_pcm_substream *substream) | ||
73 | { | ||
74 | struct ca0110_spec *spec = codec->spec; | ||
75 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | ||
76 | } | ||
77 | |||
78 | /* | ||
79 | * Digital out | ||
80 | */ | ||
81 | static int ca0110_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, | ||
82 | struct hda_codec *codec, | ||
83 | struct snd_pcm_substream *substream) | ||
84 | { | ||
85 | struct ca0110_spec *spec = codec->spec; | ||
86 | return snd_hda_multi_out_dig_open(codec, &spec->multiout); | ||
87 | } | ||
88 | |||
89 | static int ca0110_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | ||
90 | struct hda_codec *codec, | ||
91 | struct snd_pcm_substream *substream) | ||
92 | { | ||
93 | struct ca0110_spec *spec = codec->spec; | ||
94 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | ||
95 | } | ||
96 | |||
97 | static int ca0110_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
98 | struct hda_codec *codec, | ||
99 | unsigned int stream_tag, | ||
100 | unsigned int format, | ||
101 | struct snd_pcm_substream *substream) | ||
102 | { | ||
103 | struct ca0110_spec *spec = codec->spec; | ||
104 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, | ||
105 | format, substream); | ||
106 | } | ||
107 | |||
108 | /* | ||
109 | * Analog capture | ||
110 | */ | ||
111 | static int ca0110_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
112 | struct hda_codec *codec, | ||
113 | unsigned int stream_tag, | ||
114 | unsigned int format, | ||
115 | struct snd_pcm_substream *substream) | ||
116 | { | ||
117 | struct ca0110_spec *spec = codec->spec; | ||
118 | |||
119 | snd_hda_codec_setup_stream(codec, spec->adcs[substream->number], | ||
120 | stream_tag, 0, format); | ||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | static int ca0110_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
125 | struct hda_codec *codec, | ||
126 | struct snd_pcm_substream *substream) | ||
127 | { | ||
128 | struct ca0110_spec *spec = codec->spec; | ||
129 | |||
130 | snd_hda_codec_cleanup_stream(codec, spec->adcs[substream->number]); | ||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | /* | ||
135 | */ | ||
136 | |||
137 | static char *dirstr[2] = { "Playback", "Capture" }; | ||
138 | |||
139 | static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx, | ||
140 | int chan, int dir) | ||
141 | { | ||
142 | char namestr[44]; | ||
143 | int type = dir ? HDA_INPUT : HDA_OUTPUT; | ||
144 | struct snd_kcontrol_new knew = | ||
145 | HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type); | ||
146 | sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]); | ||
147 | return snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec)); | ||
148 | } | ||
149 | |||
150 | static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx, | ||
151 | int chan, int dir) | ||
152 | { | ||
153 | char namestr[44]; | ||
154 | int type = dir ? HDA_INPUT : HDA_OUTPUT; | ||
155 | struct snd_kcontrol_new knew = | ||
156 | HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type); | ||
157 | sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]); | ||
158 | return snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec)); | ||
159 | } | ||
160 | |||
161 | #define add_out_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 0) | ||
162 | #define add_out_volume(codec, nid, pfx) _add_volume(codec, nid, pfx, 3, 0) | ||
163 | #define add_in_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 1) | ||
164 | #define add_in_volume(codec, nid, pfx) _add_volume(codec, nid, pfx, 3, 1) | ||
165 | #define add_mono_switch(codec, nid, pfx, chan) \ | ||
166 | _add_switch(codec, nid, pfx, chan, 0) | ||
167 | #define add_mono_volume(codec, nid, pfx, chan) \ | ||
168 | _add_volume(codec, nid, pfx, chan, 0) | ||
169 | |||
170 | static int ca0110_build_controls(struct hda_codec *codec) | ||
171 | { | ||
172 | struct ca0110_spec *spec = codec->spec; | ||
173 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
174 | static char *prefix[AUTO_CFG_MAX_OUTS] = { | ||
175 | "Front", "Surround", NULL, "Side", "Multi" | ||
176 | }; | ||
177 | hda_nid_t mutenid; | ||
178 | int i, err; | ||
179 | |||
180 | for (i = 0; i < spec->multiout.num_dacs; i++) { | ||
181 | if (get_wcaps(codec, spec->out_pins[i]) & AC_WCAP_OUT_AMP) | ||
182 | mutenid = spec->out_pins[i]; | ||
183 | else | ||
184 | mutenid = spec->multiout.dac_nids[i]; | ||
185 | if (!prefix[i]) { | ||
186 | err = add_mono_switch(codec, mutenid, | ||
187 | "Center", 1); | ||
188 | if (err < 0) | ||
189 | return err; | ||
190 | err = add_mono_switch(codec, mutenid, | ||
191 | "LFE", 1); | ||
192 | if (err < 0) | ||
193 | return err; | ||
194 | err = add_mono_volume(codec, spec->multiout.dac_nids[i], | ||
195 | "Center", 1); | ||
196 | if (err < 0) | ||
197 | return err; | ||
198 | err = add_mono_volume(codec, spec->multiout.dac_nids[i], | ||
199 | "LFE", 1); | ||
200 | if (err < 0) | ||
201 | return err; | ||
202 | } else { | ||
203 | err = add_out_switch(codec, mutenid, | ||
204 | prefix[i]); | ||
205 | if (err < 0) | ||
206 | return err; | ||
207 | err = add_out_volume(codec, spec->multiout.dac_nids[i], | ||
208 | prefix[i]); | ||
209 | if (err < 0) | ||
210 | return err; | ||
211 | } | ||
212 | } | ||
213 | if (cfg->hp_outs) { | ||
214 | if (get_wcaps(codec, cfg->hp_pins[0]) & AC_WCAP_OUT_AMP) | ||
215 | mutenid = cfg->hp_pins[0]; | ||
216 | else | ||
217 | mutenid = spec->multiout.dac_nids[i]; | ||
218 | |||
219 | err = add_out_switch(codec, mutenid, "Headphone"); | ||
220 | if (err < 0) | ||
221 | return err; | ||
222 | if (spec->hp_dac) { | ||
223 | err = add_out_volume(codec, spec->hp_dac, "Headphone"); | ||
224 | if (err < 0) | ||
225 | return err; | ||
226 | } | ||
227 | } | ||
228 | for (i = 0; i < spec->num_inputs; i++) { | ||
229 | const char *label = spec->input_labels[i]; | ||
230 | if (get_wcaps(codec, spec->input_pins[i]) & AC_WCAP_IN_AMP) | ||
231 | mutenid = spec->input_pins[i]; | ||
232 | else | ||
233 | mutenid = spec->adcs[i]; | ||
234 | err = add_in_switch(codec, mutenid, label); | ||
235 | if (err < 0) | ||
236 | return err; | ||
237 | err = add_in_volume(codec, spec->adcs[i], label); | ||
238 | if (err < 0) | ||
239 | return err; | ||
240 | } | ||
241 | |||
242 | if (spec->dig_out) { | ||
243 | err = snd_hda_create_spdif_out_ctls(codec, spec->dig_out); | ||
244 | if (err < 0) | ||
245 | return err; | ||
246 | err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); | ||
247 | if (err < 0) | ||
248 | return err; | ||
249 | spec->multiout.share_spdif = 1; | ||
250 | } | ||
251 | if (spec->dig_in) { | ||
252 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in); | ||
253 | if (err < 0) | ||
254 | return err; | ||
255 | err = add_in_volume(codec, spec->dig_in, "IEC958"); | ||
256 | } | ||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | /* | ||
261 | */ | ||
262 | static struct hda_pcm_stream ca0110_pcm_analog_playback = { | ||
263 | .substreams = 1, | ||
264 | .channels_min = 2, | ||
265 | .channels_max = 8, | ||
266 | .ops = { | ||
267 | .open = ca0110_playback_pcm_open, | ||
268 | .prepare = ca0110_playback_pcm_prepare, | ||
269 | .cleanup = ca0110_playback_pcm_cleanup | ||
270 | }, | ||
271 | }; | ||
272 | |||
273 | static struct hda_pcm_stream ca0110_pcm_analog_capture = { | ||
274 | .substreams = 1, | ||
275 | .channels_min = 2, | ||
276 | .channels_max = 2, | ||
277 | .ops = { | ||
278 | .prepare = ca0110_capture_pcm_prepare, | ||
279 | .cleanup = ca0110_capture_pcm_cleanup | ||
280 | }, | ||
281 | }; | ||
282 | |||
283 | static struct hda_pcm_stream ca0110_pcm_digital_playback = { | ||
284 | .substreams = 1, | ||
285 | .channels_min = 2, | ||
286 | .channels_max = 2, | ||
287 | .ops = { | ||
288 | .open = ca0110_dig_playback_pcm_open, | ||
289 | .close = ca0110_dig_playback_pcm_close, | ||
290 | .prepare = ca0110_dig_playback_pcm_prepare | ||
291 | }, | ||
292 | }; | ||
293 | |||
294 | static struct hda_pcm_stream ca0110_pcm_digital_capture = { | ||
295 | .substreams = 1, | ||
296 | .channels_min = 2, | ||
297 | .channels_max = 2, | ||
298 | }; | ||
299 | |||
300 | static int ca0110_build_pcms(struct hda_codec *codec) | ||
301 | { | ||
302 | struct ca0110_spec *spec = codec->spec; | ||
303 | struct hda_pcm *info = spec->pcm_rec; | ||
304 | |||
305 | codec->pcm_info = info; | ||
306 | codec->num_pcms = 0; | ||
307 | |||
308 | info->name = "CA0110 Analog"; | ||
309 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ca0110_pcm_analog_playback; | ||
310 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dacs[0]; | ||
311 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = | ||
312 | spec->multiout.max_channels; | ||
313 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0110_pcm_analog_capture; | ||
314 | info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_inputs; | ||
315 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0]; | ||
316 | codec->num_pcms++; | ||
317 | |||
318 | if (!spec->dig_out && !spec->dig_in) | ||
319 | return 0; | ||
320 | |||
321 | info++; | ||
322 | info->name = "CA0110 Digital"; | ||
323 | info->pcm_type = HDA_PCM_TYPE_SPDIF; | ||
324 | if (spec->dig_out) { | ||
325 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = | ||
326 | ca0110_pcm_digital_playback; | ||
327 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dig_out; | ||
328 | } | ||
329 | if (spec->dig_in) { | ||
330 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = | ||
331 | ca0110_pcm_digital_capture; | ||
332 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in; | ||
333 | } | ||
334 | codec->num_pcms++; | ||
335 | |||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac) | ||
340 | { | ||
341 | if (pin) { | ||
342 | snd_hda_codec_write(codec, pin, 0, | ||
343 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); | ||
344 | if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP) | ||
345 | snd_hda_codec_write(codec, pin, 0, | ||
346 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
347 | AMP_OUT_UNMUTE); | ||
348 | } | ||
349 | if (dac) | ||
350 | snd_hda_codec_write(codec, dac, 0, | ||
351 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO); | ||
352 | } | ||
353 | |||
354 | static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc) | ||
355 | { | ||
356 | if (pin) { | ||
357 | snd_hda_codec_write(codec, pin, 0, | ||
358 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80); | ||
359 | if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP) | ||
360 | snd_hda_codec_write(codec, pin, 0, | ||
361 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
362 | AMP_IN_UNMUTE(0)); | ||
363 | } | ||
364 | if (adc) | ||
365 | snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
366 | AMP_IN_UNMUTE(0)); | ||
367 | } | ||
368 | |||
369 | static int ca0110_init(struct hda_codec *codec) | ||
370 | { | ||
371 | struct ca0110_spec *spec = codec->spec; | ||
372 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
373 | int i; | ||
374 | |||
375 | for (i = 0; i < spec->multiout.num_dacs; i++) | ||
376 | init_output(codec, spec->out_pins[i], | ||
377 | spec->multiout.dac_nids[i]); | ||
378 | init_output(codec, cfg->hp_pins[0], spec->hp_dac); | ||
379 | init_output(codec, cfg->dig_out_pins[0], spec->dig_out); | ||
380 | |||
381 | for (i = 0; i < spec->num_inputs; i++) | ||
382 | init_input(codec, spec->input_pins[i], spec->adcs[i]); | ||
383 | init_input(codec, cfg->dig_in_pin, spec->dig_in); | ||
384 | return 0; | ||
385 | } | ||
386 | |||
387 | static void ca0110_free(struct hda_codec *codec) | ||
388 | { | ||
389 | kfree(codec->spec); | ||
390 | } | ||
391 | |||
392 | static struct hda_codec_ops ca0110_patch_ops = { | ||
393 | .build_controls = ca0110_build_controls, | ||
394 | .build_pcms = ca0110_build_pcms, | ||
395 | .init = ca0110_init, | ||
396 | .free = ca0110_free, | ||
397 | }; | ||
398 | |||
399 | |||
400 | static void parse_line_outs(struct hda_codec *codec) | ||
401 | { | ||
402 | struct ca0110_spec *spec = codec->spec; | ||
403 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
404 | int i, n; | ||
405 | unsigned int def_conf; | ||
406 | hda_nid_t nid; | ||
407 | |||
408 | n = 0; | ||
409 | for (i = 0; i < cfg->line_outs; i++) { | ||
410 | nid = cfg->line_out_pins[i]; | ||
411 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
412 | if (!def_conf) | ||
413 | continue; /* invalid pin */ | ||
414 | if (snd_hda_get_connections(codec, nid, &spec->dacs[i], 1) != 1) | ||
415 | continue; | ||
416 | spec->out_pins[n++] = nid; | ||
417 | } | ||
418 | spec->multiout.dac_nids = spec->dacs; | ||
419 | spec->multiout.num_dacs = n; | ||
420 | spec->multiout.max_channels = n * 2; | ||
421 | } | ||
422 | |||
423 | static void parse_hp_out(struct hda_codec *codec) | ||
424 | { | ||
425 | struct ca0110_spec *spec = codec->spec; | ||
426 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
427 | int i; | ||
428 | unsigned int def_conf; | ||
429 | hda_nid_t nid, dac; | ||
430 | |||
431 | if (!cfg->hp_outs) | ||
432 | return; | ||
433 | nid = cfg->hp_pins[0]; | ||
434 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
435 | if (!def_conf) { | ||
436 | cfg->hp_outs = 0; | ||
437 | return; | ||
438 | } | ||
439 | if (snd_hda_get_connections(codec, nid, &dac, 1) != 1) | ||
440 | return; | ||
441 | |||
442 | for (i = 0; i < cfg->line_outs; i++) | ||
443 | if (dac == spec->dacs[i]) | ||
444 | break; | ||
445 | if (i >= cfg->line_outs) { | ||
446 | spec->hp_dac = dac; | ||
447 | spec->multiout.hp_nid = dac; | ||
448 | } | ||
449 | } | ||
450 | |||
451 | static void parse_input(struct hda_codec *codec) | ||
452 | { | ||
453 | struct ca0110_spec *spec = codec->spec; | ||
454 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
455 | hda_nid_t nid, pin; | ||
456 | int n, i, j; | ||
457 | |||
458 | n = 0; | ||
459 | nid = codec->start_nid; | ||
460 | for (i = 0; i < codec->num_nodes; i++, nid++) { | ||
461 | unsigned int wcaps = get_wcaps(codec, nid); | ||
462 | unsigned int type = (wcaps & AC_WCAP_TYPE) >> | ||
463 | AC_WCAP_TYPE_SHIFT; | ||
464 | if (type != AC_WID_AUD_IN) | ||
465 | continue; | ||
466 | if (snd_hda_get_connections(codec, nid, &pin, 1) != 1) | ||
467 | continue; | ||
468 | if (pin == cfg->dig_in_pin) { | ||
469 | spec->dig_in = nid; | ||
470 | continue; | ||
471 | } | ||
472 | for (j = 0; j < AUTO_PIN_LAST; j++) | ||
473 | if (cfg->input_pins[j] == pin) | ||
474 | break; | ||
475 | if (j >= AUTO_PIN_LAST) | ||
476 | continue; | ||
477 | spec->input_pins[n] = pin; | ||
478 | spec->input_labels[n] = auto_pin_cfg_labels[j]; | ||
479 | spec->adcs[n] = nid; | ||
480 | n++; | ||
481 | } | ||
482 | spec->num_inputs = n; | ||
483 | } | ||
484 | |||
485 | static void parse_digital(struct hda_codec *codec) | ||
486 | { | ||
487 | struct ca0110_spec *spec = codec->spec; | ||
488 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
489 | |||
490 | if (cfg->dig_outs && | ||
491 | snd_hda_get_connections(codec, cfg->dig_out_pins[0], | ||
492 | &spec->dig_out, 1) == 1) | ||
493 | spec->multiout.dig_out_nid = cfg->dig_out_pins[0]; | ||
494 | } | ||
495 | |||
496 | static int ca0110_parse_auto_config(struct hda_codec *codec) | ||
497 | { | ||
498 | struct ca0110_spec *spec = codec->spec; | ||
499 | int err; | ||
500 | |||
501 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); | ||
502 | if (err < 0) | ||
503 | return err; | ||
504 | |||
505 | parse_line_outs(codec); | ||
506 | parse_hp_out(codec); | ||
507 | parse_digital(codec); | ||
508 | parse_input(codec); | ||
509 | return 0; | ||
510 | } | ||
511 | |||
512 | |||
513 | int patch_ca0110(struct hda_codec *codec) | ||
514 | { | ||
515 | struct ca0110_spec *spec; | ||
516 | int err; | ||
517 | |||
518 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
519 | if (!spec) | ||
520 | return -ENOMEM; | ||
521 | codec->spec = spec; | ||
522 | |||
523 | codec->bus->needs_damn_long_delay = 1; | ||
524 | |||
525 | err = ca0110_parse_auto_config(codec); | ||
526 | if (err < 0) | ||
527 | goto error; | ||
528 | |||
529 | codec->patch_ops = ca0110_patch_ops; | ||
530 | |||
531 | return 0; | ||
532 | |||
533 | error: | ||
534 | kfree(codec->spec); | ||
535 | codec->spec = NULL; | ||
536 | return err; | ||
537 | } | ||
538 | |||
539 | |||
540 | /* | ||
541 | * patch entries | ||
542 | */ | ||
543 | static struct hda_codec_preset snd_hda_preset_ca0110[] = { | ||
544 | { .id = 0x1102000a, .name = "CA0110-IBG", .patch = patch_ca0110 }, | ||
545 | { .id = 0x1102000b, .name = "CA0110-IBG", .patch = patch_ca0110 }, | ||
546 | { .id = 0x1102000d, .name = "SB0880 X-Fi", .patch = patch_ca0110 }, | ||
547 | {} /* terminator */ | ||
548 | }; | ||
549 | |||
550 | MODULE_ALIAS("snd-hda-codec-id:1102000a"); | ||
551 | MODULE_ALIAS("snd-hda-codec-id:1102000b"); | ||
552 | MODULE_ALIAS("snd-hda-codec-id:1102000d"); | ||
553 | |||
554 | MODULE_LICENSE("GPL"); | ||
555 | MODULE_DESCRIPTION("Creative CA0110-IBG HD-audio codec"); | ||
556 | |||
557 | static struct hda_codec_preset_list ca0110_list = { | ||
558 | .preset = snd_hda_preset_ca0110, | ||
559 | .owner = THIS_MODULE, | ||
560 | }; | ||
561 | |||
562 | static int __init patch_ca0110_init(void) | ||
563 | { | ||
564 | return snd_hda_add_codec_preset(&ca0110_list); | ||
565 | } | ||
566 | |||
567 | static void __exit patch_ca0110_exit(void) | ||
568 | { | ||
569 | snd_hda_delete_codec_preset(&ca0110_list); | ||
570 | } | ||
571 | |||
572 | module_init(patch_ca0110_init) | ||
573 | module_exit(patch_ca0110_exit) | ||
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 1f2ad76ca94b..56ce19e68cb5 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -350,12 +350,20 @@ static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
350 | } | 350 | } |
351 | 351 | ||
352 | #ifdef CONFIG_SND_JACK | 352 | #ifdef CONFIG_SND_JACK |
353 | static void conexant_free_jack_priv(struct snd_jack *jack) | ||
354 | { | ||
355 | struct conexant_jack *jacks = jack->private_data; | ||
356 | jacks->nid = 0; | ||
357 | jacks->jack = NULL; | ||
358 | } | ||
359 | |||
353 | static int conexant_add_jack(struct hda_codec *codec, | 360 | static int conexant_add_jack(struct hda_codec *codec, |
354 | hda_nid_t nid, int type) | 361 | hda_nid_t nid, int type) |
355 | { | 362 | { |
356 | struct conexant_spec *spec; | 363 | struct conexant_spec *spec; |
357 | struct conexant_jack *jack; | 364 | struct conexant_jack *jack; |
358 | const char *name; | 365 | const char *name; |
366 | int err; | ||
359 | 367 | ||
360 | spec = codec->spec; | 368 | spec = codec->spec; |
361 | snd_array_init(&spec->jacks, sizeof(*jack), 32); | 369 | snd_array_init(&spec->jacks, sizeof(*jack), 32); |
@@ -368,7 +376,12 @@ static int conexant_add_jack(struct hda_codec *codec, | |||
368 | jack->nid = nid; | 376 | jack->nid = nid; |
369 | jack->type = type; | 377 | jack->type = type; |
370 | 378 | ||
371 | return snd_jack_new(codec->bus->card, name, type, &jack->jack); | 379 | err = snd_jack_new(codec->bus->card, name, type, &jack->jack); |
380 | if (err < 0) | ||
381 | return err; | ||
382 | jack->jack->private_data = jack; | ||
383 | jack->jack->private_free = conexant_free_jack_priv; | ||
384 | return 0; | ||
372 | } | 385 | } |
373 | 386 | ||
374 | static void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid) | 387 | static void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid) |
@@ -455,8 +468,10 @@ static void conexant_free(struct hda_codec *codec) | |||
455 | if (spec->jacks.list) { | 468 | if (spec->jacks.list) { |
456 | struct conexant_jack *jacks = spec->jacks.list; | 469 | struct conexant_jack *jacks = spec->jacks.list; |
457 | int i; | 470 | int i; |
458 | for (i = 0; i < spec->jacks.used; i++) | 471 | for (i = 0; i < spec->jacks.used; i++, jacks++) { |
459 | snd_device_free(codec->bus->card, &jacks[i].jack); | 472 | if (jacks->jack) |
473 | snd_device_free(codec->bus->card, jacks->jack); | ||
474 | } | ||
460 | snd_array_free(&spec->jacks); | 475 | snd_array_free(&spec->jacks); |
461 | } | 476 | } |
462 | #endif | 477 | #endif |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index ee92c73df083..a6ec87a5c066 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -188,6 +188,8 @@ enum { | |||
188 | ALC663_ASUS_MODE4, | 188 | ALC663_ASUS_MODE4, |
189 | ALC663_ASUS_MODE5, | 189 | ALC663_ASUS_MODE5, |
190 | ALC663_ASUS_MODE6, | 190 | ALC663_ASUS_MODE6, |
191 | ALC272_DELL, | ||
192 | ALC272_DELL_ZM1, | ||
191 | ALC662_AUTO, | 193 | ALC662_AUTO, |
192 | ALC662_MODEL_LAST, | 194 | ALC662_MODEL_LAST, |
193 | }; | 195 | }; |
@@ -8747,10 +8749,9 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
8747 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD), | 8749 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD), |
8748 | SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), | 8750 | SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), |
8749 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), | 8751 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), |
8750 | SND_PCI_QUIRK(0x1734, 0x1107, "FSC AMILO Xi2550", | 8752 | SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx", |
8751 | ALC883_FUJITSU_PI2515), | 8753 | ALC883_FUJITSU_PI2515), |
8752 | SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515), | 8754 | SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx", |
8753 | SND_PCI_QUIRK(0x1734, 0x113d, "Fujitsu AMILO Xa3530", | ||
8754 | ALC888_FUJITSU_XA3530), | 8755 | ALC888_FUJITSU_XA3530), |
8755 | SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), | 8756 | SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), |
8756 | SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), | 8757 | SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), |
@@ -8769,6 +8770,10 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
8769 | {} | 8770 | {} |
8770 | }; | 8771 | }; |
8771 | 8772 | ||
8773 | static hda_nid_t alc883_slave_dig_outs[] = { | ||
8774 | ALC1200_DIGOUT_NID, 0, | ||
8775 | }; | ||
8776 | |||
8772 | static hda_nid_t alc1200_slave_dig_outs[] = { | 8777 | static hda_nid_t alc1200_slave_dig_outs[] = { |
8773 | ALC883_DIGOUT_NID, 0, | 8778 | ALC883_DIGOUT_NID, 0, |
8774 | }; | 8779 | }; |
@@ -8814,6 +8819,7 @@ static struct alc_config_preset alc883_presets[] = { | |||
8814 | .dac_nids = alc883_dac_nids, | 8819 | .dac_nids = alc883_dac_nids, |
8815 | .dig_out_nid = ALC883_DIGOUT_NID, | 8820 | .dig_out_nid = ALC883_DIGOUT_NID, |
8816 | .dig_in_nid = ALC883_DIGIN_NID, | 8821 | .dig_in_nid = ALC883_DIGIN_NID, |
8822 | .slave_dig_outs = alc883_slave_dig_outs, | ||
8817 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes), | 8823 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes), |
8818 | .channel_mode = alc883_3ST_6ch_intel_modes, | 8824 | .channel_mode = alc883_3ST_6ch_intel_modes, |
8819 | .need_dac_fix = 1, | 8825 | .need_dac_fix = 1, |
@@ -12977,10 +12983,17 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = { | |||
12977 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), | 12983 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), |
12978 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", | 12984 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", |
12979 | ALC269_ASUS_EEEPC_P703), | 12985 | ALC269_ASUS_EEEPC_P703), |
12986 | SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703), | ||
12987 | SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703), | ||
12988 | SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703), | ||
12989 | SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703), | ||
12990 | SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703), | ||
12991 | SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703), | ||
12980 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", | 12992 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", |
12981 | ALC269_ASUS_EEEPC_P901), | 12993 | ALC269_ASUS_EEEPC_P901), |
12982 | SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", | 12994 | SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", |
12983 | ALC269_ASUS_EEEPC_P901), | 12995 | ALC269_ASUS_EEEPC_P901), |
12996 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901), | ||
12984 | SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), | 12997 | SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), |
12985 | SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), | 12998 | SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), |
12986 | {} | 12999 | {} |
@@ -15211,12 +15224,23 @@ static hda_nid_t alc662_dac_nids[4] = { | |||
15211 | 0x02, 0x03, 0x04 | 15224 | 0x02, 0x03, 0x04 |
15212 | }; | 15225 | }; |
15213 | 15226 | ||
15227 | static hda_nid_t alc272_dac_nids[2] = { | ||
15228 | 0x02, 0x03 | ||
15229 | }; | ||
15230 | |||
15214 | static hda_nid_t alc662_adc_nids[1] = { | 15231 | static hda_nid_t alc662_adc_nids[1] = { |
15215 | /* ADC1-2 */ | 15232 | /* ADC1-2 */ |
15216 | 0x09, | 15233 | 0x09, |
15217 | }; | 15234 | }; |
15218 | 15235 | ||
15236 | static hda_nid_t alc272_adc_nids[1] = { | ||
15237 | /* ADC1-2 */ | ||
15238 | 0x08, | ||
15239 | }; | ||
15240 | |||
15219 | static hda_nid_t alc662_capsrc_nids[1] = { 0x22 }; | 15241 | static hda_nid_t alc662_capsrc_nids[1] = { 0x22 }; |
15242 | static hda_nid_t alc272_capsrc_nids[1] = { 0x23 }; | ||
15243 | |||
15220 | 15244 | ||
15221 | /* input MUX */ | 15245 | /* input MUX */ |
15222 | /* FIXME: should be a matrix-type input source selection */ | 15246 | /* FIXME: should be a matrix-type input source selection */ |
@@ -15642,14 +15666,7 @@ static struct hda_verb alc662_init_verbs[] = { | |||
15642 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | 15666 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ |
15643 | /* Input mixer */ | 15667 | /* Input mixer */ |
15644 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 15668 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
15645 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
15646 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
15647 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
15648 | |||
15649 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 15669 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
15650 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
15651 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
15652 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
15653 | 15670 | ||
15654 | /* always trun on EAPD */ | 15671 | /* always trun on EAPD */ |
15655 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | 15672 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, |
@@ -15844,12 +15861,48 @@ static struct hda_verb alc662_ecs_init_verbs[] = { | |||
15844 | {} | 15861 | {} |
15845 | }; | 15862 | }; |
15846 | 15863 | ||
15864 | static struct hda_verb alc272_dell_zm1_init_verbs[] = { | ||
15865 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
15866 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
15867 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
15868 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
15869 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
15870 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
15871 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ | ||
15872 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
15873 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, | ||
15874 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, | ||
15875 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
15876 | {} | ||
15877 | }; | ||
15878 | |||
15879 | static struct hda_verb alc272_dell_init_verbs[] = { | ||
15880 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
15881 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
15882 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
15883 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
15884 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
15885 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
15886 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ | ||
15887 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
15888 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, | ||
15889 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, | ||
15890 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
15891 | {} | ||
15892 | }; | ||
15893 | |||
15847 | static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { | 15894 | static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { |
15848 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), | 15895 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), |
15849 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), | 15896 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), |
15850 | { } /* end */ | 15897 | { } /* end */ |
15851 | }; | 15898 | }; |
15852 | 15899 | ||
15900 | static struct snd_kcontrol_new alc272_auto_capture_mixer[] = { | ||
15901 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
15902 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
15903 | { } /* end */ | ||
15904 | }; | ||
15905 | |||
15853 | static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) | 15906 | static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) |
15854 | { | 15907 | { |
15855 | unsigned int present; | 15908 | unsigned int present; |
@@ -16361,6 +16414,8 @@ static const char *alc662_models[ALC662_MODEL_LAST] = { | |||
16361 | 16414 | ||
16362 | static struct snd_pci_quirk alc662_cfg_tbl[] = { | 16415 | static struct snd_pci_quirk alc662_cfg_tbl[] = { |
16363 | SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), | 16416 | SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), |
16417 | SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL), | ||
16418 | SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1), | ||
16364 | SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1), | 16419 | SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1), |
16365 | SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3), | 16420 | SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3), |
16366 | SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3), | 16421 | SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3), |
@@ -16373,26 +16428,36 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { | |||
16373 | SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6), | 16428 | SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6), |
16374 | SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6), | 16429 | SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6), |
16375 | SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2), | 16430 | SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2), |
16431 | SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3), | ||
16432 | SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA), | ||
16433 | SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2), | ||
16376 | SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2), | 16434 | SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2), |
16377 | SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5), | 16435 | SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5), |
16378 | SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6), | 16436 | SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6), |
16379 | SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2), | 16437 | SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2), |
16438 | SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1), | ||
16380 | SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2), | 16439 | SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2), |
16381 | SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2), | 16440 | SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2), |
16382 | SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA), | 16441 | SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA), |
16383 | /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/ | 16442 | /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/ |
16384 | SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3), | 16443 | SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3), |
16385 | SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3), | 16444 | SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3), |
16445 | SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1), | ||
16446 | SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1), | ||
16447 | SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1), | ||
16386 | SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1), | 16448 | SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1), |
16387 | SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2), | 16449 | SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2), |
16388 | SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2), | 16450 | SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2), |
16451 | SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1), | ||
16389 | SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1), | 16452 | SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1), |
16390 | SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3), | 16453 | SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3), |
16454 | SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1), | ||
16391 | SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1), | 16455 | SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1), |
16392 | SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V), | 16456 | SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V), |
16393 | /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/ | 16457 | /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/ |
16394 | SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1), | 16458 | SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1), |
16395 | SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2), | 16459 | SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2), |
16460 | SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA), | ||
16396 | SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1), | 16461 | SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1), |
16397 | SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4), | 16462 | SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4), |
16398 | SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG), | 16463 | SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG), |
@@ -16641,6 +16706,36 @@ static struct alc_config_preset alc662_presets[] = { | |||
16641 | .unsol_event = alc663_mode6_unsol_event, | 16706 | .unsol_event = alc663_mode6_unsol_event, |
16642 | .init_hook = alc663_mode6_inithook, | 16707 | .init_hook = alc663_mode6_inithook, |
16643 | }, | 16708 | }, |
16709 | [ALC272_DELL] = { | ||
16710 | .mixers = { alc663_m51va_mixer }, | ||
16711 | .cap_mixer = alc272_auto_capture_mixer, | ||
16712 | .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs }, | ||
16713 | .num_dacs = ARRAY_SIZE(alc272_dac_nids), | ||
16714 | .dac_nids = alc662_dac_nids, | ||
16715 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
16716 | .adc_nids = alc272_adc_nids, | ||
16717 | .num_adc_nids = ARRAY_SIZE(alc272_adc_nids), | ||
16718 | .capsrc_nids = alc272_capsrc_nids, | ||
16719 | .channel_mode = alc662_3ST_2ch_modes, | ||
16720 | .input_mux = &alc663_m51va_capture_source, | ||
16721 | .unsol_event = alc663_m51va_unsol_event, | ||
16722 | .init_hook = alc663_m51va_inithook, | ||
16723 | }, | ||
16724 | [ALC272_DELL_ZM1] = { | ||
16725 | .mixers = { alc663_m51va_mixer }, | ||
16726 | .cap_mixer = alc662_auto_capture_mixer, | ||
16727 | .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs }, | ||
16728 | .num_dacs = ARRAY_SIZE(alc272_dac_nids), | ||
16729 | .dac_nids = alc662_dac_nids, | ||
16730 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
16731 | .adc_nids = alc662_adc_nids, | ||
16732 | .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), | ||
16733 | .capsrc_nids = alc662_capsrc_nids, | ||
16734 | .channel_mode = alc662_3ST_2ch_modes, | ||
16735 | .input_mux = &alc663_m51va_capture_source, | ||
16736 | .unsol_event = alc663_m51va_unsol_event, | ||
16737 | .init_hook = alc663_m51va_inithook, | ||
16738 | }, | ||
16644 | }; | 16739 | }; |
16645 | 16740 | ||
16646 | 16741 | ||
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index b5e108aa8f63..917bc5d3ac2c 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -3076,6 +3076,11 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs, | |||
3076 | unsigned int wid_caps; | 3076 | unsigned int wid_caps; |
3077 | 3077 | ||
3078 | for (i = 0; i < num_outs && i < ARRAY_SIZE(chname); i++) { | 3078 | for (i = 0; i < num_outs && i < ARRAY_SIZE(chname); i++) { |
3079 | if (type == AUTO_PIN_HP_OUT && !spec->hp_detect) { | ||
3080 | wid_caps = get_wcaps(codec, pins[i]); | ||
3081 | if (wid_caps & AC_WCAP_UNSOL_CAP) | ||
3082 | spec->hp_detect = 1; | ||
3083 | } | ||
3079 | nid = dac_nids[i]; | 3084 | nid = dac_nids[i]; |
3080 | if (!nid) | 3085 | if (!nid) |
3081 | continue; | 3086 | continue; |
@@ -3119,11 +3124,6 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs, | |||
3119 | err = create_controls_idx(codec, name, idx, nid, 3); | 3124 | err = create_controls_idx(codec, name, idx, nid, 3); |
3120 | if (err < 0) | 3125 | if (err < 0) |
3121 | return err; | 3126 | return err; |
3122 | if (type == AUTO_PIN_HP_OUT && !spec->hp_detect) { | ||
3123 | wid_caps = get_wcaps(codec, pins[i]); | ||
3124 | if (wid_caps & AC_WCAP_UNSOL_CAP) | ||
3125 | spec->hp_detect = 1; | ||
3126 | } | ||
3127 | } | 3127 | } |
3128 | } | 3128 | } |
3129 | return 0; | 3129 | return 0; |
@@ -3851,6 +3851,15 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask, | |||
3851 | AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */ | 3851 | AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */ |
3852 | } | 3852 | } |
3853 | 3853 | ||
3854 | #ifdef CONFIG_SND_JACK | ||
3855 | static void stac92xx_free_jack_priv(struct snd_jack *jack) | ||
3856 | { | ||
3857 | struct sigmatel_jack *jacks = jack->private_data; | ||
3858 | jacks->nid = 0; | ||
3859 | jacks->jack = NULL; | ||
3860 | } | ||
3861 | #endif | ||
3862 | |||
3854 | static int stac92xx_add_jack(struct hda_codec *codec, | 3863 | static int stac92xx_add_jack(struct hda_codec *codec, |
3855 | hda_nid_t nid, int type) | 3864 | hda_nid_t nid, int type) |
3856 | { | 3865 | { |
@@ -3860,6 +3869,7 @@ static int stac92xx_add_jack(struct hda_codec *codec, | |||
3860 | int def_conf = snd_hda_codec_get_pincfg(codec, nid); | 3869 | int def_conf = snd_hda_codec_get_pincfg(codec, nid); |
3861 | int connectivity = get_defcfg_connect(def_conf); | 3870 | int connectivity = get_defcfg_connect(def_conf); |
3862 | char name[32]; | 3871 | char name[32]; |
3872 | int err; | ||
3863 | 3873 | ||
3864 | if (connectivity && connectivity != AC_JACK_PORT_FIXED) | 3874 | if (connectivity && connectivity != AC_JACK_PORT_FIXED) |
3865 | return 0; | 3875 | return 0; |
@@ -3876,10 +3886,15 @@ static int stac92xx_add_jack(struct hda_codec *codec, | |||
3876 | snd_hda_get_jack_connectivity(def_conf), | 3886 | snd_hda_get_jack_connectivity(def_conf), |
3877 | snd_hda_get_jack_location(def_conf)); | 3887 | snd_hda_get_jack_location(def_conf)); |
3878 | 3888 | ||
3879 | return snd_jack_new(codec->bus->card, name, type, &jack->jack); | 3889 | err = snd_jack_new(codec->bus->card, name, type, &jack->jack); |
3880 | #else | 3890 | if (err < 0) { |
3881 | return 0; | 3891 | jack->nid = 0; |
3892 | return err; | ||
3893 | } | ||
3894 | jack->jack->private_data = jack; | ||
3895 | jack->jack->private_free = stac92xx_free_jack_priv; | ||
3882 | #endif | 3896 | #endif |
3897 | return 0; | ||
3883 | } | 3898 | } |
3884 | 3899 | ||
3885 | static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid, | 3900 | static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid, |
@@ -4138,8 +4153,10 @@ static void stac92xx_free_jacks(struct hda_codec *codec) | |||
4138 | if (!codec->bus->shutdown && spec->jacks.list) { | 4153 | if (!codec->bus->shutdown && spec->jacks.list) { |
4139 | struct sigmatel_jack *jacks = spec->jacks.list; | 4154 | struct sigmatel_jack *jacks = spec->jacks.list; |
4140 | int i; | 4155 | int i; |
4141 | for (i = 0; i < spec->jacks.used; i++) | 4156 | for (i = 0; i < spec->jacks.used; i++, jacks++) { |
4142 | snd_device_free(codec->bus->card, &jacks[i].jack); | 4157 | if (jacks->jack) |
4158 | snd_device_free(codec->bus->card, jacks->jack); | ||
4159 | } | ||
4143 | } | 4160 | } |
4144 | snd_array_free(&spec->jacks); | 4161 | snd_array_free(&spec->jacks); |
4145 | #endif | 4162 | #endif |
@@ -4413,6 +4430,24 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) | |||
4413 | if (spec->num_pwrs > 0) | 4430 | if (spec->num_pwrs > 0) |
4414 | stac92xx_pin_sense(codec, event->nid); | 4431 | stac92xx_pin_sense(codec, event->nid); |
4415 | stac92xx_report_jack(codec, event->nid); | 4432 | stac92xx_report_jack(codec, event->nid); |
4433 | |||
4434 | switch (codec->subsystem_id) { | ||
4435 | case 0x103c308f: | ||
4436 | if (event->nid == 0xb) { | ||
4437 | int pin = AC_PINCTL_IN_EN; | ||
4438 | |||
4439 | if (get_pin_presence(codec, 0xa) | ||
4440 | && get_pin_presence(codec, 0xb)) | ||
4441 | pin |= AC_PINCTL_VREF_80; | ||
4442 | if (!get_pin_presence(codec, 0xb)) | ||
4443 | pin |= AC_PINCTL_VREF_80; | ||
4444 | |||
4445 | /* toggle VREF state based on mic + hp pin | ||
4446 | * status | ||
4447 | */ | ||
4448 | stac92xx_auto_set_pinctl(codec, 0x0a, pin); | ||
4449 | } | ||
4450 | } | ||
4416 | break; | 4451 | break; |
4417 | case STAC_VREF_EVENT: | 4452 | case STAC_VREF_EVENT: |
4418 | data = snd_hda_codec_read(codec, codec->afg, 0, | 4453 | data = snd_hda_codec_read(codec, codec->afg, 0, |
@@ -4895,6 +4930,7 @@ again: | |||
4895 | switch (codec->vendor_id) { | 4930 | switch (codec->vendor_id) { |
4896 | case 0x111d7604: | 4931 | case 0x111d7604: |
4897 | case 0x111d7605: | 4932 | case 0x111d7605: |
4933 | case 0x111d76d5: | ||
4898 | if (spec->board_config == STAC_92HD83XXX_PWR_REF) | 4934 | if (spec->board_config == STAC_92HD83XXX_PWR_REF) |
4899 | break; | 4935 | break; |
4900 | spec->num_pwrs = 0; | 4936 | spec->num_pwrs = 0; |
@@ -5707,6 +5743,7 @@ static struct hda_codec_preset snd_hda_preset_sigmatel[] = { | |||
5707 | { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, | 5743 | { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, |
5708 | { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx}, | 5744 | { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx}, |
5709 | { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx}, | 5745 | { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx}, |
5746 | { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx}, | ||
5710 | { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, | 5747 | { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, |
5711 | { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, | 5748 | { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, |
5712 | { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, | 5749 | { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, |
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 3dd63f1cda53..0d0cdbdb4486 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c | |||
@@ -2533,8 +2533,8 @@ static int __devinit snd_ice1712_create(struct snd_card *card, | |||
2533 | if (err < 0) | 2533 | if (err < 0) |
2534 | return err; | 2534 | return err; |
2535 | /* check, if we can restrict PCI DMA transfers to 28 bits */ | 2535 | /* check, if we can restrict PCI DMA transfers to 28 bits */ |
2536 | if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 || | 2536 | if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 || |
2537 | pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) { | 2537 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) { |
2538 | snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n"); | 2538 | snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n"); |
2539 | pci_disable_device(pci); | 2539 | pci_disable_device(pci); |
2540 | return -ENXIO; | 2540 | return -ENXIO; |
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 57648810eaf1..5dced5b79387 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
@@ -355,6 +355,9 @@ struct ichdev { | |||
355 | unsigned int fragsize1; | 355 | unsigned int fragsize1; |
356 | unsigned int position; | 356 | unsigned int position; |
357 | unsigned int pos_shift; | 357 | unsigned int pos_shift; |
358 | unsigned int last_pos; | ||
359 | unsigned long last_pos_jiffies; | ||
360 | unsigned int jiffy_to_bytes; | ||
358 | int frags; | 361 | int frags; |
359 | int lvi; | 362 | int lvi; |
360 | int lvi_frag; | 363 | int lvi_frag; |
@@ -838,7 +841,10 @@ static int snd_intel8x0_pcm_trigger(struct snd_pcm_substream *substream, int cmd | |||
838 | ichdev->suspended = 0; | 841 | ichdev->suspended = 0; |
839 | /* fallthru */ | 842 | /* fallthru */ |
840 | case SNDRV_PCM_TRIGGER_START: | 843 | case SNDRV_PCM_TRIGGER_START: |
844 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
841 | val = ICH_IOCE | ICH_STARTBM; | 845 | val = ICH_IOCE | ICH_STARTBM; |
846 | ichdev->last_pos = ichdev->position; | ||
847 | ichdev->last_pos_jiffies = jiffies; | ||
842 | break; | 848 | break; |
843 | case SNDRV_PCM_TRIGGER_SUSPEND: | 849 | case SNDRV_PCM_TRIGGER_SUSPEND: |
844 | ichdev->suspended = 1; | 850 | ichdev->suspended = 1; |
@@ -849,9 +855,6 @@ static int snd_intel8x0_pcm_trigger(struct snd_pcm_substream *substream, int cmd | |||
849 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 855 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
850 | val = ICH_IOCE; | 856 | val = ICH_IOCE; |
851 | break; | 857 | break; |
852 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
853 | val = ICH_IOCE | ICH_STARTBM; | ||
854 | break; | ||
855 | default: | 858 | default: |
856 | return -EINVAL; | 859 | return -EINVAL; |
857 | } | 860 | } |
@@ -1045,6 +1048,7 @@ static int snd_intel8x0_pcm_prepare(struct snd_pcm_substream *substream) | |||
1045 | ichdev->pos_shift = (runtime->sample_bits > 16) ? 2 : 1; | 1048 | ichdev->pos_shift = (runtime->sample_bits > 16) ? 2 : 1; |
1046 | } | 1049 | } |
1047 | snd_intel8x0_setup_periods(chip, ichdev); | 1050 | snd_intel8x0_setup_periods(chip, ichdev); |
1051 | ichdev->jiffy_to_bytes = (runtime->rate * 4 * ichdev->pos_shift) / HZ; | ||
1048 | return 0; | 1052 | return 0; |
1049 | } | 1053 | } |
1050 | 1054 | ||
@@ -1053,7 +1057,7 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs | |||
1053 | struct intel8x0 *chip = snd_pcm_substream_chip(substream); | 1057 | struct intel8x0 *chip = snd_pcm_substream_chip(substream); |
1054 | struct ichdev *ichdev = get_ichdev(substream); | 1058 | struct ichdev *ichdev = get_ichdev(substream); |
1055 | size_t ptr1, ptr; | 1059 | size_t ptr1, ptr; |
1056 | int civ, timeout = 100; | 1060 | int civ, timeout = 10; |
1057 | unsigned int position; | 1061 | unsigned int position; |
1058 | 1062 | ||
1059 | spin_lock(&chip->reg_lock); | 1063 | spin_lock(&chip->reg_lock); |
@@ -1069,9 +1073,19 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs | |||
1069 | ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) | 1073 | ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) |
1070 | break; | 1074 | break; |
1071 | } while (timeout--); | 1075 | } while (timeout--); |
1072 | ptr1 <<= ichdev->pos_shift; | 1076 | if (ptr1 != 0) { |
1073 | ptr = ichdev->fragsize1 - ptr1; | 1077 | ptr1 <<= ichdev->pos_shift; |
1074 | ptr += position; | 1078 | ptr = ichdev->fragsize1 - ptr1; |
1079 | ptr += position; | ||
1080 | ichdev->last_pos = ptr; | ||
1081 | ichdev->last_pos_jiffies = jiffies; | ||
1082 | } else { | ||
1083 | ptr1 = jiffies - ichdev->last_pos_jiffies; | ||
1084 | if (ptr1) | ||
1085 | ptr1 -= 1; | ||
1086 | ptr = ichdev->last_pos + ptr1 * ichdev->jiffy_to_bytes; | ||
1087 | ptr %= ichdev->size; | ||
1088 | } | ||
1075 | spin_unlock(&chip->reg_lock); | 1089 | spin_unlock(&chip->reg_lock); |
1076 | if (ptr >= ichdev->size) | 1090 | if (ptr >= ichdev->size) |
1077 | return 0; | 1091 | return 0; |
@@ -2661,12 +2675,14 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip) | |||
2661 | struct snd_pcm_substream *subs; | 2675 | struct snd_pcm_substream *subs; |
2662 | struct ichdev *ichdev; | 2676 | struct ichdev *ichdev; |
2663 | unsigned long port; | 2677 | unsigned long port; |
2664 | unsigned long pos, t; | 2678 | unsigned long pos, pos1, t; |
2665 | struct timeval start_time, stop_time; | 2679 | int civ, timeout = 1000, attempt = 1; |
2680 | struct timespec start_time, stop_time; | ||
2666 | 2681 | ||
2667 | if (chip->ac97_bus->clock != 48000) | 2682 | if (chip->ac97_bus->clock != 48000) |
2668 | return; /* specified in module option */ | 2683 | return; /* specified in module option */ |
2669 | 2684 | ||
2685 | __again: | ||
2670 | subs = chip->pcm[0]->streams[0].substream; | 2686 | subs = chip->pcm[0]->streams[0].substream; |
2671 | if (! subs || subs->dma_buffer.bytes < INTEL8X0_TESTBUF_SIZE) { | 2687 | if (! subs || subs->dma_buffer.bytes < INTEL8X0_TESTBUF_SIZE) { |
2672 | snd_printk(KERN_WARNING "no playback buffer allocated - aborting measure ac97 clock\n"); | 2688 | snd_printk(KERN_WARNING "no playback buffer allocated - aborting measure ac97 clock\n"); |
@@ -2674,7 +2690,7 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip) | |||
2674 | } | 2690 | } |
2675 | ichdev = &chip->ichd[ICHD_PCMOUT]; | 2691 | ichdev = &chip->ichd[ICHD_PCMOUT]; |
2676 | ichdev->physbuf = subs->dma_buffer.addr; | 2692 | ichdev->physbuf = subs->dma_buffer.addr; |
2677 | ichdev->size = chip->ichd[ICHD_PCMOUT].fragsize = INTEL8X0_TESTBUF_SIZE; | 2693 | ichdev->size = ichdev->fragsize = INTEL8X0_TESTBUF_SIZE; |
2678 | ichdev->substream = NULL; /* don't process interrupts */ | 2694 | ichdev->substream = NULL; /* don't process interrupts */ |
2679 | 2695 | ||
2680 | /* set rate */ | 2696 | /* set rate */ |
@@ -2693,16 +2709,31 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip) | |||
2693 | iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE); | 2709 | iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE); |
2694 | iputdword(chip, ICHREG(ALI_DMACR), 1 << ichdev->ali_slot); | 2710 | iputdword(chip, ICHREG(ALI_DMACR), 1 << ichdev->ali_slot); |
2695 | } | 2711 | } |
2696 | do_gettimeofday(&start_time); | 2712 | do_posix_clock_monotonic_gettime(&start_time); |
2697 | spin_unlock_irq(&chip->reg_lock); | 2713 | spin_unlock_irq(&chip->reg_lock); |
2698 | msleep(50); | 2714 | msleep(50); |
2699 | spin_lock_irq(&chip->reg_lock); | 2715 | spin_lock_irq(&chip->reg_lock); |
2700 | /* check the position */ | 2716 | /* check the position */ |
2701 | pos = ichdev->fragsize1; | 2717 | do { |
2702 | pos -= igetword(chip, ichdev->reg_offset + ichdev->roff_picb) << ichdev->pos_shift; | 2718 | civ = igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV); |
2703 | pos += ichdev->position; | 2719 | pos1 = igetword(chip, ichdev->reg_offset + ichdev->roff_picb); |
2720 | if (pos1 == 0) { | ||
2721 | udelay(10); | ||
2722 | continue; | ||
2723 | } | ||
2724 | if (civ == igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV) && | ||
2725 | pos1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) | ||
2726 | break; | ||
2727 | } while (timeout--); | ||
2728 | if (pos1 == 0) { /* oops, this value is not reliable */ | ||
2729 | pos = 0; | ||
2730 | } else { | ||
2731 | pos = ichdev->fragsize1; | ||
2732 | pos -= pos1 << ichdev->pos_shift; | ||
2733 | pos += ichdev->position; | ||
2734 | } | ||
2704 | chip->in_measurement = 0; | 2735 | chip->in_measurement = 0; |
2705 | do_gettimeofday(&stop_time); | 2736 | do_posix_clock_monotonic_gettime(&stop_time); |
2706 | /* stop */ | 2737 | /* stop */ |
2707 | if (chip->device_type == DEVICE_ALI) { | 2738 | if (chip->device_type == DEVICE_ALI) { |
2708 | iputdword(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 16)); | 2739 | iputdword(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 16)); |
@@ -2717,19 +2748,37 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip) | |||
2717 | iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS); | 2748 | iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS); |
2718 | spin_unlock_irq(&chip->reg_lock); | 2749 | spin_unlock_irq(&chip->reg_lock); |
2719 | 2750 | ||
2751 | if (pos == 0) { | ||
2752 | snd_printk(KERN_ERR "intel8x0: measure - unreliable DMA position..\n"); | ||
2753 | __retry: | ||
2754 | if (attempt < 2) { | ||
2755 | attempt++; | ||
2756 | goto __again; | ||
2757 | } | ||
2758 | return; | ||
2759 | } | ||
2760 | |||
2761 | pos /= 4; | ||
2720 | t = stop_time.tv_sec - start_time.tv_sec; | 2762 | t = stop_time.tv_sec - start_time.tv_sec; |
2721 | t *= 1000000; | 2763 | t *= 1000000; |
2722 | t += stop_time.tv_usec - start_time.tv_usec; | 2764 | t += (stop_time.tv_nsec - start_time.tv_nsec) / 1000; |
2723 | printk(KERN_INFO "%s: measured %lu usecs\n", __func__, t); | 2765 | printk(KERN_INFO "%s: measured %lu usecs (%lu samples)\n", __func__, t, pos); |
2724 | if (t == 0) { | 2766 | if (t == 0) { |
2725 | snd_printk(KERN_ERR "?? calculation error..\n"); | 2767 | snd_printk(KERN_ERR "intel8x0: ?? calculation error..\n"); |
2726 | return; | 2768 | goto __retry; |
2727 | } | 2769 | } |
2728 | pos = (pos / 4) * 1000; | 2770 | pos *= 1000; |
2729 | pos = (pos / t) * 1000 + ((pos % t) * 1000) / t; | 2771 | pos = (pos / t) * 1000 + ((pos % t) * 1000) / t; |
2730 | if (pos < 40000 || pos >= 60000) | 2772 | if (pos < 40000 || pos >= 60000) { |
2731 | /* abnormal value. hw problem? */ | 2773 | /* abnormal value. hw problem? */ |
2732 | printk(KERN_INFO "intel8x0: measured clock %ld rejected\n", pos); | 2774 | printk(KERN_INFO "intel8x0: measured clock %ld rejected\n", pos); |
2775 | goto __retry; | ||
2776 | } else if (pos > 40500 && pos < 41500) | ||
2777 | /* first exception - 41000Hz reference clock */ | ||
2778 | chip->ac97_bus->clock = 41000; | ||
2779 | else if (pos > 43600 && pos < 44600) | ||
2780 | /* second exception - 44100HZ reference clock */ | ||
2781 | chip->ac97_bus->clock = 44100; | ||
2733 | else if (pos < 47500 || pos > 48500) | 2782 | else if (pos < 47500 || pos > 48500) |
2734 | /* not 48000Hz, tuning the clock.. */ | 2783 | /* not 48000Hz, tuning the clock.. */ |
2735 | chip->ac97_bus->clock = (chip->ac97_bus->clock * 48000) / pos; | 2784 | chip->ac97_bus->clock = (chip->ac97_bus->clock * 48000) / pos; |
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 70141548f251..75283fbb4b3f 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c | |||
@@ -2530,8 +2530,8 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, | |||
2530 | return -EIO; | 2530 | return -EIO; |
2531 | 2531 | ||
2532 | /* check, if we can restrict PCI DMA transfers to 28 bits */ | 2532 | /* check, if we can restrict PCI DMA transfers to 28 bits */ |
2533 | if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 || | 2533 | if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 || |
2534 | pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) { | 2534 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) { |
2535 | snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n"); | 2535 | snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n"); |
2536 | pci_disable_device(pci); | 2536 | pci_disable_device(pci); |
2537 | return -ENXIO; | 2537 | return -ENXIO; |
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index c1eb84a14c42..82bc5b9e7629 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c | |||
@@ -1291,7 +1291,7 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci, | |||
1291 | pci_set_master(pci); | 1291 | pci_set_master(pci); |
1292 | 1292 | ||
1293 | /* check if we can restrict PCI DMA transfers to 32 bits */ | 1293 | /* check if we can restrict PCI DMA transfers to 32 bits */ |
1294 | if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0) { | 1294 | if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0) { |
1295 | snd_printk(KERN_ERR "architecture does not support 32bit PCI busmaster DMA\n"); | 1295 | snd_printk(KERN_ERR "architecture does not support 32bit PCI busmaster DMA\n"); |
1296 | pci_disable_device(pci); | 1296 | pci_disable_device(pci); |
1297 | return -ENXIO; | 1297 | return -ENXIO; |
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index 80e064a3efff..833e9c7b27c7 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c | |||
@@ -1449,7 +1449,7 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, | |||
1449 | pci_set_master(pci); | 1449 | pci_set_master(pci); |
1450 | 1450 | ||
1451 | /* check if we can restrict PCI DMA transfers to 32 bits */ | 1451 | /* check if we can restrict PCI DMA transfers to 32 bits */ |
1452 | if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0) { | 1452 | if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0) { |
1453 | snd_printk(KERN_ERR "architecture does not support " | 1453 | snd_printk(KERN_ERR "architecture does not support " |
1454 | "32bit PCI busmaster DMA\n"); | 1454 | "32bit PCI busmaster DMA\n"); |
1455 | pci_disable_device(pci); | 1455 | pci_disable_device(pci); |
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c index baf6d8e3dabc..1a5ff0611072 100644 --- a/sound/pci/sis7019.c +++ b/sound/pci/sis7019.c | |||
@@ -1300,7 +1300,7 @@ static int __devinit sis_chip_create(struct snd_card *card, | |||
1300 | if (rc) | 1300 | if (rc) |
1301 | goto error_out; | 1301 | goto error_out; |
1302 | 1302 | ||
1303 | if (pci_set_dma_mask(pci, DMA_30BIT_MASK) < 0) { | 1303 | if (pci_set_dma_mask(pci, DMA_BIT_MASK(30)) < 0) { |
1304 | printk(KERN_ERR "sis7019: architecture does not support " | 1304 | printk(KERN_ERR "sis7019: architecture does not support " |
1305 | "30-bit PCI busmaster DMA"); | 1305 | "30-bit PCI busmaster DMA"); |
1306 | goto error_out_enabled; | 1306 | goto error_out_enabled; |
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c index d989215f3556..7dc60ad4772e 100644 --- a/sound/pci/sonicvibes.c +++ b/sound/pci/sonicvibes.c | |||
@@ -1264,8 +1264,8 @@ static int __devinit snd_sonicvibes_create(struct snd_card *card, | |||
1264 | if ((err = pci_enable_device(pci)) < 0) | 1264 | if ((err = pci_enable_device(pci)) < 0) |
1265 | return err; | 1265 | return err; |
1266 | /* check, if we can restrict PCI DMA transfers to 24 bits */ | 1266 | /* check, if we can restrict PCI DMA transfers to 24 bits */ |
1267 | if (pci_set_dma_mask(pci, DMA_24BIT_MASK) < 0 || | 1267 | if (pci_set_dma_mask(pci, DMA_BIT_MASK(24)) < 0 || |
1268 | pci_set_consistent_dma_mask(pci, DMA_24BIT_MASK) < 0) { | 1268 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(24)) < 0) { |
1269 | snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n"); | 1269 | snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n"); |
1270 | pci_disable_device(pci); | 1270 | pci_disable_device(pci); |
1271 | return -ENXIO; | 1271 | return -ENXIO; |
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index a9da9c184660..6d943f6f6b70 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c | |||
@@ -3559,8 +3559,8 @@ int __devinit snd_trident_create(struct snd_card *card, | |||
3559 | if ((err = pci_enable_device(pci)) < 0) | 3559 | if ((err = pci_enable_device(pci)) < 0) |
3560 | return err; | 3560 | return err; |
3561 | /* check, if we can restrict PCI DMA transfers to 30 bits */ | 3561 | /* check, if we can restrict PCI DMA transfers to 30 bits */ |
3562 | if (pci_set_dma_mask(pci, DMA_30BIT_MASK) < 0 || | 3562 | if (pci_set_dma_mask(pci, DMA_BIT_MASK(30)) < 0 || |
3563 | pci_set_consistent_dma_mask(pci, DMA_30BIT_MASK) < 0) { | 3563 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(30)) < 0) { |
3564 | snd_printk(KERN_ERR "architecture does not support 30bit PCI busmaster DMA\n"); | 3564 | snd_printk(KERN_ERR "architecture does not support 30bit PCI busmaster DMA\n"); |
3565 | pci_disable_device(pci); | 3565 | pci_disable_device(pci); |
3566 | return -ENXIO; | 3566 | return -ENXIO; |