diff options
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
| -rw-r--r-- | sound/pci/hda/hda_intel.c | 198 | 
1 files changed, 134 insertions, 64 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 21e99cfa8c4..4e9ea708027 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -128,21 +128,33 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"  			 "{ULI, M5461}}");  MODULE_DESCRIPTION("Intel HDA driver"); +#ifdef CONFIG_SND_VERBOSE_PRINTK +#define SFX	/* nop */ +#else  #define SFX	"hda-intel: " - +#endif  /*   * registers   */  #define ICH6_REG_GCAP			0x00 +#define   ICH6_GCAP_64OK	(1 << 0)   /* 64bit address support */ +#define   ICH6_GCAP_NSDO	(3 << 1)   /* # of serial data out signals */ +#define   ICH6_GCAP_BSS		(31 << 3)  /* # of bidirectional streams */ +#define   ICH6_GCAP_ISS		(15 << 8)  /* # of input streams */ +#define   ICH6_GCAP_OSS		(15 << 12) /* # of output streams */  #define ICH6_REG_VMIN			0x02  #define ICH6_REG_VMAJ			0x03  #define ICH6_REG_OUTPAY			0x04  #define ICH6_REG_INPAY			0x06  #define ICH6_REG_GCTL			0x08 +#define   ICH6_GCTL_RESET	(1 << 0)   /* controller reset */ +#define   ICH6_GCTL_FCNTRL	(1 << 1)   /* flush control */ +#define   ICH6_GCTL_UNSOL	(1 << 8)   /* accept unsol. response enable */  #define ICH6_REG_WAKEEN			0x0c  #define ICH6_REG_STATESTS		0x0e  #define ICH6_REG_GSTS			0x10 +#define   ICH6_GSTS_FSTS	(1 << 1)   /* flush status */  #define ICH6_REG_INTCTL			0x20  #define ICH6_REG_INTSTS			0x24  #define ICH6_REG_WALCLK			0x30 @@ -150,17 +162,27 @@ MODULE_DESCRIPTION("Intel HDA driver");  #define ICH6_REG_CORBLBASE		0x40  #define ICH6_REG_CORBUBASE		0x44  #define ICH6_REG_CORBWP			0x48 -#define ICH6_REG_CORBRP			0x4A +#define ICH6_REG_CORBRP			0x4a +#define   ICH6_CORBRP_RST	(1 << 15)  /* read pointer reset */  #define ICH6_REG_CORBCTL		0x4c +#define   ICH6_CORBCTL_RUN	(1 << 1)   /* enable DMA */ +#define   ICH6_CORBCTL_CMEIE	(1 << 0)   /* enable memory error irq */  #define ICH6_REG_CORBSTS		0x4d +#define   ICH6_CORBSTS_CMEI	(1 << 0)   /* memory error indication */  #define ICH6_REG_CORBSIZE		0x4e  #define ICH6_REG_RIRBLBASE		0x50  #define ICH6_REG_RIRBUBASE		0x54  #define ICH6_REG_RIRBWP			0x58 +#define   ICH6_RIRBWP_RST	(1 << 15)  /* write pointer reset */  #define ICH6_REG_RINTCNT		0x5a  #define ICH6_REG_RIRBCTL		0x5c +#define   ICH6_RBCTL_IRQ_EN	(1 << 0)   /* enable IRQ */ +#define   ICH6_RBCTL_DMA_EN	(1 << 1)   /* enable DMA */ +#define   ICH6_RBCTL_OVERRUN_EN	(1 << 2)   /* enable overrun irq */  #define ICH6_REG_RIRBSTS		0x5d +#define   ICH6_RBSTS_IRQ	(1 << 0)   /* response irq */ +#define   ICH6_RBSTS_OVERRUN	(1 << 2)   /* overrun irq */  #define ICH6_REG_RIRBSIZE		0x5e  #define ICH6_REG_IC			0x60 @@ -257,16 +279,6 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };  #define ICH6_INT_CTRL_EN	0x40000000 /* controller interrupt enable bit */  #define ICH6_INT_GLOBAL_EN	0x80000000 /* global interrupt enable bit */ -/* GCTL unsolicited response enable bit */ -#define ICH6_GCTL_UREN		(1<<8) - -/* GCTL reset bit */ -#define ICH6_GCTL_RESET		(1<<0) - -/* CORB/RIRB control, read/write pointer */ -#define ICH6_RBCTL_DMA_EN	0x02	/* enable DMA */ -#define ICH6_RBCTL_IRQ_EN	0x01	/* enable IRQ */ -#define ICH6_RBRWP_CLR		0x8000	/* read/write pointer clear */  /* below are so far hardcoded - should read registers in future */  #define ICH6_MAX_CORB_ENTRIES	256  #define ICH6_MAX_RIRB_ENTRIES	256 @@ -512,25 +524,25 @@ static void azx_init_cmd_io(struct azx *chip)  	/* set the corb write pointer to 0 */  	azx_writew(chip, CORBWP, 0);  	/* reset the corb hw read pointer */ -	azx_writew(chip, CORBRP, ICH6_RBRWP_CLR); +	azx_writew(chip, CORBRP, ICH6_CORBRP_RST);  	/* enable corb dma */ -	azx_writeb(chip, CORBCTL, ICH6_RBCTL_DMA_EN); +	azx_writeb(chip, CORBCTL, ICH6_CORBCTL_RUN);  	/* RIRB set up */  	chip->rirb.addr = chip->rb.addr + 2048;  	chip->rirb.buf = (u32 *)(chip->rb.area + 2048); +	chip->rirb.wp = chip->rirb.rp = chip->rirb.cmds = 0;  	azx_writel(chip, RIRBLBASE, (u32)chip->rirb.addr);  	azx_writel(chip, RIRBUBASE, upper_32_bits(chip->rirb.addr));  	/* set the rirb size to 256 entries (ULI requires explicitly) */  	azx_writeb(chip, RIRBSIZE, 0x02);  	/* reset the rirb hw write pointer */ -	azx_writew(chip, RIRBWP, ICH6_RBRWP_CLR); +	azx_writew(chip, RIRBWP, ICH6_RIRBWP_RST);  	/* set N=1, get RIRB response interrupt for new entry */  	azx_writew(chip, RINTCNT, 1);  	/* enable rirb dma and response irq */  	azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN | ICH6_RBCTL_IRQ_EN); -	chip->rirb.rp = chip->rirb.cmds = 0;  }  static void azx_free_cmd_io(struct azx *chip) @@ -606,6 +618,7 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)  		}  		if (!chip->rirb.cmds) {  			smp_rmb(); +			bus->rirb_error = 0;  			return chip->rirb.res; /* the last value */  		}  		if (time_after(jiffies, timeout)) @@ -619,19 +632,21 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)  	}  	if (chip->msi) { -		snd_printk(KERN_WARNING "hda_intel: No response from codec, " +		snd_printk(KERN_WARNING SFX "No response from codec, "  			   "disabling MSI: last cmd=0x%08x\n", chip->last_cmd);  		free_irq(chip->irq, chip);  		chip->irq = -1;  		pci_disable_msi(chip->pci);  		chip->msi = 0; -		if (azx_acquire_irq(chip, 1) < 0) +		if (azx_acquire_irq(chip, 1) < 0) { +			bus->rirb_error = 1;  			return -1; +		}  		goto again;  	}  	if (!chip->polling_mode) { -		snd_printk(KERN_WARNING "hda_intel: azx_get_response timeout, " +		snd_printk(KERN_WARNING SFX "azx_get_response timeout, "  			   "switching to polling mode: last cmd=0x%08x\n",  			   chip->last_cmd);  		chip->polling_mode = 1; @@ -646,14 +661,23 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)  		return -1;  	} +	/* a fatal communication error; need either to reset or to fallback +	 * to the single_cmd mode +	 */ +	bus->rirb_error = 1; +	if (bus->allow_bus_reset && !bus->response_reset && !bus->in_reset) { +		bus->response_reset = 1; +		return -1; /* give a chance to retry */ +	} +  	snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, "  		   "switching to single_cmd mode: last cmd=0x%08x\n",  		   chip->last_cmd); -	chip->rirb.rp = azx_readb(chip, RIRBWP); -	chip->rirb.cmds = 0; -	/* switch to single_cmd mode */  	chip->single_cmd = 1; +	bus->response_reset = 0; +	/* re-initialize CORB/RIRB */  	azx_free_cmd_io(chip); +	azx_init_cmd_io(chip);  	return -1;  } @@ -667,12 +691,34 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)   *       I left the codes, however, for debugging/testing purposes.   */ +/* receive a response */ +static int azx_single_wait_for_response(struct azx *chip) +{ +	int timeout = 50; + +	while (timeout--) { +		/* check IRV busy bit */ +		if (azx_readw(chip, IRS) & ICH6_IRS_VALID) { +			/* reuse rirb.res as the response return value */ +			chip->rirb.res = azx_readl(chip, IR); +			return 0; +		} +		udelay(1); +	} +	if (printk_ratelimit()) +		snd_printd(SFX "get_response timeout: IRS=0x%x\n", +			   azx_readw(chip, IRS)); +	chip->rirb.res = -1; +	return -EIO; +} +  /* send a command */  static int azx_single_send_cmd(struct hda_bus *bus, u32 val)  {  	struct azx *chip = bus->private_data;  	int timeout = 50; +	bus->rirb_error = 0;  	while (timeout--) {  		/* check ICB busy bit */  		if (!((azx_readw(chip, IRS) & ICH6_IRS_BUSY))) { @@ -682,7 +728,7 @@ static int azx_single_send_cmd(struct hda_bus *bus, u32 val)  			azx_writel(chip, IC, val);  			azx_writew(chip, IRS, azx_readw(chip, IRS) |  				   ICH6_IRS_BUSY); -			return 0; +			return azx_single_wait_for_response(chip);  		}  		udelay(1);  	} @@ -696,18 +742,7 @@ static int azx_single_send_cmd(struct hda_bus *bus, u32 val)  static unsigned int azx_single_get_response(struct hda_bus *bus)  {  	struct azx *chip = bus->private_data; -	int timeout = 50; - -	while (timeout--) { -		/* check IRV busy bit */ -		if (azx_readw(chip, IRS) & ICH6_IRS_VALID) -			return azx_readl(chip, IR); -		udelay(1); -	} -	if (printk_ratelimit()) -		snd_printd(SFX "get_response timeout: IRS=0x%x\n", -			   azx_readw(chip, IRS)); -	return (unsigned int)-1; +	return chip->rirb.res;  }  /* @@ -775,17 +810,17 @@ static int azx_reset(struct azx *chip)  	/* check to see if controller is ready */  	if (!azx_readb(chip, GCTL)) { -		snd_printd("azx_reset: controller not ready!\n"); +		snd_printd(SFX "azx_reset: controller not ready!\n");  		return -EBUSY;  	}  	/* Accept unsolicited responses */ -	azx_writel(chip, GCTL, azx_readl(chip, GCTL) | ICH6_GCTL_UREN); +	azx_writel(chip, GCTL, azx_readl(chip, GCTL) | ICH6_GCTL_UNSOL);  	/* detect codecs */  	if (!chip->codec_mask) {  		chip->codec_mask = azx_readw(chip, STATESTS); -		snd_printdd("codec_mask = 0x%x\n", chip->codec_mask); +		snd_printdd(SFX "codec_mask = 0x%x\n", chip->codec_mask);  	}  	return 0; @@ -895,8 +930,7 @@ static void azx_init_chip(struct azx *chip)  	azx_int_enable(chip);  	/* initialize the codec command I/O */ -	if (!chip->single_cmd) -		azx_init_cmd_io(chip); +	azx_init_cmd_io(chip);  	/* program the position buffer */  	azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); @@ -953,12 +987,12 @@ static void azx_init_pci(struct azx *chip)  	case AZX_DRIVER_SCH:  		pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop);  		if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) { -			pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, \ +			pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC,  				snoop & (~INTEL_SCH_HDA_DEVC_NOSNOOP));  			pci_read_config_word(chip->pci,  				INTEL_SCH_HDA_DEVC, &snoop); -			snd_printdd("HDA snoop disabled, enabling ... %s\n",\ -				(snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) \ +			snd_printdd(SFX "HDA snoop disabled, enabling ... %s\n", +				(snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)  				? "Failed" : "OK");  		}  		break; @@ -1012,7 +1046,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)  	/* clear rirb int */  	status = azx_readb(chip, RIRBSTS);  	if (status & RIRB_INT_MASK) { -		if (!chip->single_cmd && (status & RIRB_INT_RESPONSE)) +		if (status & RIRB_INT_RESPONSE)  			azx_update_rirb(chip);  		azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);  	} @@ -1098,7 +1132,7 @@ static int azx_setup_periods(struct azx *chip,  				pos_align;  		pos_adj = frames_to_bytes(runtime, pos_adj);  		if (pos_adj >= period_bytes) { -			snd_printk(KERN_WARNING "Too big adjustment %d\n", +			snd_printk(KERN_WARNING SFX "Too big adjustment %d\n",  				   bdl_pos_adj[chip->dev_index]);  			pos_adj = 0;  		} else { @@ -1122,7 +1156,7 @@ static int azx_setup_periods(struct azx *chip,  	return 0;   error: -	snd_printk(KERN_ERR "Too many BDL entries: buffer=%d, period=%d\n", +	snd_printk(KERN_ERR SFX "Too many BDL entries: buffer=%d, period=%d\n",  		   azx_dev->bufsize, period_bytes);  	return -EINVAL;  } @@ -1215,7 +1249,7 @@ static int probe_codec(struct azx *chip, int addr)  	chip->probing = 0;  	if (res == -1)  		return -EIO; -	snd_printdd("hda_intel: codec #%d probed OK\n", addr); +	snd_printdd(SFX "codec #%d probed OK\n", addr);  	return 0;  } @@ -1223,6 +1257,26 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,  				 struct hda_pcm *cpcm);  static void azx_stop_chip(struct azx *chip); +static void azx_bus_reset(struct hda_bus *bus) +{ +	struct azx *chip = bus->private_data; + +	bus->in_reset = 1; +	azx_stop_chip(chip); +	azx_init_chip(chip); +#ifdef CONFIG_PM +	if (chip->initialized) { +		int i; + +		for (i = 0; i < AZX_MAX_PCMS; i++) +			snd_pcm_suspend_all(chip->pcm[i]); +		snd_hda_suspend(chip->bus); +		snd_hda_resume(chip->bus); +	} +#endif +	bus->in_reset = 0; +} +  /*   * Codec initialization   */ @@ -1246,6 +1300,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,  	bus_temp.ops.command = azx_send_cmd;  	bus_temp.ops.get_response = azx_get_response;  	bus_temp.ops.attach_pcm = azx_attach_pcm_stream; +	bus_temp.ops.bus_reset = azx_bus_reset;  #ifdef CONFIG_SND_HDA_POWER_SAVE  	bus_temp.power_save = &power_save;  	bus_temp.ops.pm_notify = azx_power_notify; @@ -1270,8 +1325,8 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,  				/* Some BIOSen give you wrong codec addresses  				 * that don't exist  				 */ -				snd_printk(KERN_WARNING -					   "hda_intel: Codec #%d probe error; " +				snd_printk(KERN_WARNING SFX +					   "Codec #%d probe error; "  					   "disabling it...\n", c);  				chip->codec_mask &= ~(1 << c);  				/* More badly, accessing to a non-existing @@ -1487,7 +1542,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)  	bufsize = snd_pcm_lib_buffer_bytes(substream);  	period_bytes = snd_pcm_lib_period_bytes(substream); -	snd_printdd("azx_pcm_prepare: bufsize=0x%x, format=0x%x\n", +	snd_printdd(SFX "azx_pcm_prepare: bufsize=0x%x, format=0x%x\n",  		    bufsize, format_val);  	if (bufsize != azx_dev->bufsize || @@ -1830,7 +1885,7 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,  			  &pcm);  	if (err < 0)  		return err; -	strcpy(pcm->name, cpcm->name); +	strlcpy(pcm->name, cpcm->name, sizeof(pcm->name));  	apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);  	if (apcm == NULL)  		return -ENOMEM; @@ -1973,7 +2028,7 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)  	for (i = 0; i < AZX_MAX_PCMS; i++)  		snd_pcm_suspend_all(chip->pcm[i]);  	if (chip->initialized) -		snd_hda_suspend(chip->bus, state); +		snd_hda_suspend(chip->bus);  	azx_stop_chip(chip);  	if (chip->irq >= 0) {  		free_irq(chip->irq, chip); @@ -2141,6 +2196,7 @@ static struct snd_pci_quirk probe_mask_list[] __devinitdata = {  	/* including bogus ALC268 in slot#2 that conflicts with ALC888 */  	SND_PCI_QUIRK(0x17c0, 0x4085, "Medion MD96630", 0x01),  	/* forced codec slots */ +	SND_PCI_QUIRK(0x1043, 0x1262, "ASUS W5Fm", 0x103),  	SND_PCI_QUIRK(0x1046, 0x1262, "ASUS W5F", 0x103),  	{}  }; @@ -2264,14 +2320,14 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,  	synchronize_irq(chip->irq);  	gcap = azx_readw(chip, GCAP); -	snd_printdd("chipset global capabilities = 0x%x\n", gcap); +	snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap);  	/* ATI chips seems buggy about 64bit DMA addresses */  	if (chip->driver_type == AZX_DRIVER_ATI) -		gcap &= ~0x01; +		gcap &= ~ICH6_GCAP_64OK;  	/* allow 64bit DMA address if supported by H/W */ -	if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) +	if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))  		pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64));  	else {  		pci_set_dma_mask(pci, DMA_BIT_MASK(32)); @@ -2308,7 +2364,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,  	chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev),  				GFP_KERNEL);  	if (!chip->azx_dev) { -		snd_printk(KERN_ERR "cannot malloc azx_dev\n"); +		snd_printk(KERN_ERR SFX "cannot malloc azx_dev\n");  		goto errout;  	} @@ -2331,11 +2387,9 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,  		goto errout;  	}  	/* allocate CORB/RIRB */ -	if (!chip->single_cmd) { -		err = azx_alloc_cmd_io(chip); -		if (err < 0) -			goto errout; -	} +	err = azx_alloc_cmd_io(chip); +	if (err < 0) +		goto errout;  	/* initialize streams */  	azx_init_stream(chip); @@ -2358,9 +2412,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,  	}  	strcpy(card->driver, "HDA-Intel"); -	strcpy(card->shortname, driver_short_names[chip->driver_type]); -	sprintf(card->longname, "%s at 0x%lx irq %i", -		card->shortname, chip->addr, chip->irq); +	strlcpy(card->shortname, driver_short_names[chip->driver_type], +		sizeof(card->shortname)); +	snprintf(card->longname, sizeof(card->longname), +		 "%s at 0x%lx irq %i", +		 card->shortname, chip->addr, chip->irq);  	*rchip = chip;  	return 0; @@ -2513,6 +2569,20 @@ static struct pci_device_id azx_ids[] = {  	{ PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA },  	/* Teradici */  	{ PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, +	/* Creative X-Fi (CA0110-IBG) */ +#if !defined(CONFIG_SND_CTXFI) && !defined(CONFIG_SND_CTXFI_MODULE) +	/* the following entry conflicts with snd-ctxfi driver, +	 * as ctxfi driver mutates from HD-audio to native mode with +	 * a special command sequence. +	 */ +	{ PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_ANY_ID), +	  .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, +	  .class_mask = 0xffffff, +	  .driver_data = AZX_DRIVER_GENERIC }, +#else +	/* this entry seems still valid -- i.e. without emu20kx chip */ +	{ PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_GENERIC }, +#endif  	/* AMD Generic, PCI class code and Vendor ID for HD Audio */  	{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID),  	  .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,  |