diff options
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
| -rw-r--r-- | sound/pci/hda/hda_intel.c | 57 | 
1 files changed, 27 insertions, 30 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 1f350522bed..4ab8102f87e 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",  }; @@ -1285,7 +1291,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)  { @@ -1304,6 +1311,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 @@ -1356,7 +1369,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) @@ -1366,10 +1379,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) @@ -2353,17 +2366,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); @@ -2410,8 +2412,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); @@ -2565,6 +2566,8 @@ static struct snd_pci_quirk probe_mask_list[] __devinitdata = {  	/* forced codec slots */  	SND_PCI_QUIRK(0x1043, 0x1262, "ASUS W5Fm", 0x103),  	SND_PCI_QUIRK(0x1046, 0x1262, "ASUS W5F", 0x103), +	/* WinFast VP200 H (Teradici) user reported broken communication */ +	SND_PCI_QUIRK(0x3a21, 0x040d, "WinFast VP200 H", 0x101),  	{}  }; @@ -3130,6 +3133,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 */ @@ -3148,7 +3156,7 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {  MODULE_DEVICE_TABLE(pci, azx_ids);  /* pci_driver definition */ -static struct pci_driver driver = { +static struct pci_driver azx_driver = {  	.name = KBUILD_MODNAME,  	.id_table = azx_ids,  	.probe = azx_probe, @@ -3159,15 +3167,4 @@ static struct pci_driver driver = {  #endif  }; -static int __init alsa_card_azx_init(void) -{ -	return pci_register_driver(&driver); -} - -static void __exit alsa_card_azx_exit(void) -{ -	pci_unregister_driver(&driver); -} - -module_init(alsa_card_azx_init) -module_exit(alsa_card_azx_exit) +module_pci_driver(azx_driver);  |