From 7f30830b7b82e5225c38a48b387e44f3defe40e2 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 8 May 2012 16:52:23 +0200 Subject: ALSA: hda - Always resume the codec immediately This is a fix for the problem in commit 785f857d1c, the pop noise issue on some machines with ALC269. The problem was the uninitialized state after the resume due to the delayed resume of the codec chips. In that commit, we tried to fix by forcibly putting the codec to D3 at suspend. But, this still also leaves the uninitialized state after resume, and it _might_ be still problematic with some BIOS. Since the commit turned out to regress another issues, we reverted it in the end. Now, in this fix, try to fix by turning on the codec immediately at the resume path. We need to take care of the power-saving in this case. When the device is woken up at the power-saved state, it should go power-saving again after the resume. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'sound/pci/hda/hda_intel.c') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 6e958bf94191..c19e71a94e1b 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2351,17 +2351,6 @@ static void azx_power_notify(struct hda_bus *bus) * power management */ -static int snd_hda_codecs_inuse(struct hda_bus *bus) -{ - struct hda_codec *codec; - - list_for_each_entry(codec, &bus->codec_list, list) { - if (snd_hda_codec_needs_resume(codec)) - return 1; - } - return 0; -} - static int azx_suspend(struct pci_dev *pci, pm_message_t state) { struct snd_card *card = pci_get_drvdata(pci); @@ -2408,8 +2397,7 @@ static int azx_resume(struct pci_dev *pci) return -EIO; azx_init_pci(chip); - if (snd_hda_codecs_inuse(chip->bus)) - azx_init_chip(chip, 1); + azx_init_chip(chip, 1); snd_hda_resume(chip->bus); snd_power_change_state(card, SNDRV_CTL_POWER_D0); -- cgit v1.2.3-59-g8ed1b From 5ae763b1bc573e7ef5d9a96c71c8b3e3a865ad8c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 8 May 2012 10:34:08 +0200 Subject: ALSA: hda - Add the support for Creative SoundCore3D The controller is compatible with HD-audio 1.0a with some specific restrictions. - The BDLE entries can't be over 4k boundary - No position-buffer and no MSI Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'sound/pci/hda/hda_intel.c') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index c19e71a94e1b..a70d7e5443aa 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -497,6 +497,7 @@ enum { AZX_DRIVER_NVIDIA, AZX_DRIVER_TERA, AZX_DRIVER_CTX, + AZX_DRIVER_CTHDA, AZX_DRIVER_GENERIC, AZX_NUM_DRIVERS, /* keep this as last entry */ }; @@ -518,6 +519,7 @@ enum { #define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */ #define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */ #define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */ +#define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ /* quirks for ATI SB / AMD Hudson */ #define AZX_DCAPS_PRESET_ATI_SB \ @@ -533,6 +535,9 @@ enum { (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI |\ AZX_DCAPS_ALIGN_BUFSIZE) +#define AZX_DCAPS_PRESET_CTHDA \ + (AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_4K_BDLE_BOUNDARY) + static char *driver_short_names[] __devinitdata = { [AZX_DRIVER_ICH] = "HDA Intel", [AZX_DRIVER_PCH] = "HDA Intel PCH", @@ -546,6 +551,7 @@ static char *driver_short_names[] __devinitdata = { [AZX_DRIVER_NVIDIA] = "HDA NVidia", [AZX_DRIVER_TERA] = "HDA Teradici", [AZX_DRIVER_CTX] = "HDA Creative", + [AZX_DRIVER_CTHDA] = "HDA Creative", [AZX_DRIVER_GENERIC] = "HD-Audio Generic", }; @@ -1283,7 +1289,8 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) /* * set up a BDL entry */ -static int setup_bdle(struct snd_pcm_substream *substream, +static int setup_bdle(struct azx *chip, + struct snd_pcm_substream *substream, struct azx_dev *azx_dev, u32 **bdlp, int ofs, int size, int with_ioc) { @@ -1302,6 +1309,12 @@ static int setup_bdle(struct snd_pcm_substream *substream, bdl[1] = cpu_to_le32(upper_32_bits(addr)); /* program the size field of the BDL entry */ chunk = snd_pcm_sgbuf_get_chunk_size(substream, ofs, size); + /* one BDLE cannot cross 4K boundary on CTHDA chips */ + if (chip->driver_caps & AZX_DCAPS_4K_BDLE_BOUNDARY) { + u32 remain = 0x1000 - (ofs & 0xfff); + if (chunk > remain) + chunk = remain; + } bdl[2] = cpu_to_le32(chunk); /* program the IOC to enable interrupt * only when the whole fragment is processed @@ -1354,7 +1367,7 @@ static int azx_setup_periods(struct azx *chip, bdl_pos_adj[chip->dev_index]); pos_adj = 0; } else { - ofs = setup_bdle(substream, azx_dev, + ofs = setup_bdle(chip, substream, azx_dev, &bdl, ofs, pos_adj, !substream->runtime->no_period_wakeup); if (ofs < 0) @@ -1364,10 +1377,10 @@ static int azx_setup_periods(struct azx *chip, pos_adj = 0; for (i = 0; i < periods; i++) { if (i == periods - 1 && pos_adj) - ofs = setup_bdle(substream, azx_dev, &bdl, ofs, + ofs = setup_bdle(chip, substream, azx_dev, &bdl, ofs, period_bytes - pos_adj, 0); else - ofs = setup_bdle(substream, azx_dev, &bdl, ofs, + ofs = setup_bdle(chip, substream, azx_dev, &bdl, ofs, period_bytes, !substream->runtime->no_period_wakeup); if (ofs < 0) @@ -3116,6 +3129,11 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB }, #endif + /* CTHDA chips */ + { PCI_DEVICE(0x1102, 0x0010), + .driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA }, + { PCI_DEVICE(0x1102, 0x0012), + .driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA }, /* Vortex86MX */ { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC }, /* VMware HDAudio */ -- cgit v1.2.3-59-g8ed1b