aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_intel.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2007-08-10 11:21:45 -0400
committerJaroslav Kysela <perex@perex.cz>2007-10-16 09:58:46 -0400
commitcb53c626e1145edf1d619bc4953f6293d3a77ace (patch)
tree715c2ef3d56a5ac7c79498800e888f562c1aa961 /sound/pci/hda/hda_intel.c
parentcca3b3718ca96dca51daf1129ac03003bcede751 (diff)
[ALSA] hda-intel - Add POWER_SAVE option
Added CONFIG_SND_HDA_POWER_SAVE kconfig. It's an experimental option to achieve an aggressive power-saving. With this option, the driver will turn on/off the power of each codec and controller chip dynamically on demand. The patch introduces a new module option 'power_save'. It specifies the second of time-out for automatic power-down. As default, it's 10 seconds. Setting 0 means to suppress the power-saving feature. The codec may have analog-input loopbacks, which are usually represented by mixer elements such as 'Mic Playback Switch' or 'CD Playback Switch'. When these are on, we cannot turn off the mixer and the codec chip has to be kept on. For bookkeeping these states, a new codec-callback is introduced. For the bus-controller side, a new callback pm_notify is introduced, which can be used to turn on/off the contoller appropriately. Note that this power-saving might cause slight click-noise at power-on/off. Also, it might take some time to wake up the codec, and might even drop some tones at the very beginning. This seems to be the side-effect of turning off the controller chip. This turn-off of the controller can be disabled by undefining HDA_POWER_SAVE_RESET_CONTOLLER in hda_intel.c. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r--sound/pci/hda/hda_intel.c158
1 files changed, 123 insertions, 35 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index ebb442dcc027..7be3a9b55330 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -75,6 +75,7 @@ MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
75module_param(enable_msi, int, 0); 75module_param(enable_msi, int, 0);
76MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); 76MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)");
77 77
78/* power_save option is defined in hda_codec.c */
78 79
79/* just for backward compatibility */ 80/* just for backward compatibility */
80static int enable; 81static int enable;
@@ -102,6 +103,18 @@ MODULE_DESCRIPTION("Intel HDA driver");
102#define SFX "hda-intel: " 103#define SFX "hda-intel: "
103 104
104/* 105/*
106 * build flags
107 */
108
109/*
110 * reset the HD-audio controller in power save mode.
111 * this may give more power-saving, but will take longer time to
112 * wake up.
113 */
114#define HDA_POWER_SAVE_RESET_CONTROLLER
115
116
117/*
105 * registers 118 * registers
106 */ 119 */
107#define ICH6_REG_GCAP 0x00 120#define ICH6_REG_GCAP 0x00
@@ -345,6 +358,7 @@ struct azx {
345 358
346 /* flags */ 359 /* flags */
347 int position_fix; 360 int position_fix;
361 unsigned int running :1;
348 unsigned int initialized :1; 362 unsigned int initialized :1;
349 unsigned int single_cmd :1; 363 unsigned int single_cmd :1;
350 unsigned int polling_mode :1; 364 unsigned int polling_mode :1;
@@ -665,6 +679,9 @@ static unsigned int azx_get_response(struct hda_codec *codec)
665 return azx_rirb_get_response(codec); 679 return azx_rirb_get_response(codec);
666} 680}
667 681
682#ifdef CONFIG_SND_HDA_POWER_SAVE
683static void azx_power_notify(struct hda_codec *codec);
684#endif
668 685
669/* reset codec link */ 686/* reset codec link */
670static int azx_reset(struct azx *chip) 687static int azx_reset(struct azx *chip)
@@ -790,19 +807,12 @@ static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev)
790 807
791 808
792/* 809/*
793 * initialize the chip 810 * reset and start the controller registers
794 */ 811 */
795static void azx_init_chip(struct azx *chip) 812static void azx_init_chip(struct azx *chip)
796{ 813{
797 unsigned char reg; 814 if (chip->initialized)
798 815 return;
799 /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44)
800 * TCSEL == Traffic Class Select Register, which sets PCI express QOS
801 * Ensuring these bits are 0 clears playback static on some HD Audio
802 * codecs
803 */
804 pci_read_config_byte (chip->pci, ICH6_PCIREG_TCSEL, &reg);
805 pci_write_config_byte(chip->pci, ICH6_PCIREG_TCSEL, reg & 0xf8);
806 816
807 /* reset controller */ 817 /* reset controller */
808 azx_reset(chip); 818 azx_reset(chip);
@@ -819,22 +829,45 @@ static void azx_init_chip(struct azx *chip)
819 azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); 829 azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
820 azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr)); 830 azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr));
821 831
832 chip->initialized = 1;
833}
834
835/*
836 * initialize the PCI registers
837 */
838/* update bits in a PCI register byte */
839static void update_pci_byte(struct pci_dev *pci, unsigned int reg,
840 unsigned char mask, unsigned char val)
841{
842 unsigned char data;
843
844 pci_read_config_byte(pci, reg, &data);
845 data &= ~mask;
846 data |= (val & mask);
847 pci_write_config_byte(pci, reg, data);
848}
849
850static void azx_init_pci(struct azx *chip)
851{
852 /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44)
853 * TCSEL == Traffic Class Select Register, which sets PCI express QOS
854 * Ensuring these bits are 0 clears playback static on some HD Audio
855 * codecs
856 */
857 update_pci_byte(chip->pci, ICH6_PCIREG_TCSEL, 0x07, 0);
858
822 switch (chip->driver_type) { 859 switch (chip->driver_type) {
823 case AZX_DRIVER_ATI: 860 case AZX_DRIVER_ATI:
824 /* For ATI SB450 azalia HD audio, we need to enable snoop */ 861 /* For ATI SB450 azalia HD audio, we need to enable snoop */
825 pci_read_config_byte(chip->pci, 862 update_pci_byte(chip->pci,
826 ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 863 ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR,
827 &reg); 864 0x07, ATI_SB450_HDAUDIO_ENABLE_SNOOP);
828 pci_write_config_byte(chip->pci,
829 ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR,
830 (reg & 0xf8) |
831 ATI_SB450_HDAUDIO_ENABLE_SNOOP);
832 break; 865 break;
833 case AZX_DRIVER_NVIDIA: 866 case AZX_DRIVER_NVIDIA:
834 /* For NVIDIA HDA, enable snoop */ 867 /* For NVIDIA HDA, enable snoop */
835 pci_read_config_byte(chip->pci,NVIDIA_HDA_TRANSREG_ADDR, &reg); 868 update_pci_byte(chip->pci,
836 pci_write_config_byte(chip->pci,NVIDIA_HDA_TRANSREG_ADDR, 869 NVIDIA_HDA_TRANSREG_ADDR,
837 (reg & 0xf0) | NVIDIA_HDA_ENABLE_COHBITS); 870 0x0f, NVIDIA_HDA_ENABLE_COHBITS);
838 break; 871 break;
839 } 872 }
840} 873}
@@ -1007,6 +1040,9 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
1007 bus_temp.pci = chip->pci; 1040 bus_temp.pci = chip->pci;
1008 bus_temp.ops.command = azx_send_cmd; 1041 bus_temp.ops.command = azx_send_cmd;
1009 bus_temp.ops.get_response = azx_get_response; 1042 bus_temp.ops.get_response = azx_get_response;
1043#ifdef CONFIG_SND_HDA_POWER_SAVE
1044 bus_temp.ops.pm_notify = azx_power_notify;
1045#endif
1010 1046
1011 err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus); 1047 err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus);
1012 if (err < 0) 1048 if (err < 0)
@@ -1128,9 +1164,11 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
1128 128); 1164 128);
1129 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 1165 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
1130 128); 1166 128);
1167 snd_hda_power_up(apcm->codec);
1131 err = hinfo->ops.open(hinfo, apcm->codec, substream); 1168 err = hinfo->ops.open(hinfo, apcm->codec, substream);
1132 if (err < 0) { 1169 if (err < 0) {
1133 azx_release_device(azx_dev); 1170 azx_release_device(azx_dev);
1171 snd_hda_power_down(apcm->codec);
1134 mutex_unlock(&chip->open_mutex); 1172 mutex_unlock(&chip->open_mutex);
1135 return err; 1173 return err;
1136 } 1174 }
@@ -1159,6 +1197,7 @@ static int azx_pcm_close(struct snd_pcm_substream *substream)
1159 spin_unlock_irqrestore(&chip->reg_lock, flags); 1197 spin_unlock_irqrestore(&chip->reg_lock, flags);
1160 azx_release_device(azx_dev); 1198 azx_release_device(azx_dev);
1161 hinfo->ops.close(hinfo, apcm->codec, substream); 1199 hinfo->ops.close(hinfo, apcm->codec, substream);
1200 snd_hda_power_down(apcm->codec);
1162 mutex_unlock(&chip->open_mutex); 1201 mutex_unlock(&chip->open_mutex);
1163 return 0; 1202 return 0;
1164} 1203}
@@ -1459,6 +1498,48 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect)
1459} 1498}
1460 1499
1461 1500
1501static void azx_stop_chip(struct azx *chip)
1502{
1503 if (chip->initialized)
1504 return;
1505
1506 /* disable interrupts */
1507 azx_int_disable(chip);
1508 azx_int_clear(chip);
1509
1510 /* disable CORB/RIRB */
1511 azx_free_cmd_io(chip);
1512
1513 /* disable position buffer */
1514 azx_writel(chip, DPLBASE, 0);
1515 azx_writel(chip, DPUBASE, 0);
1516
1517 chip->initialized = 0;
1518}
1519
1520#ifdef CONFIG_SND_HDA_POWER_SAVE
1521/* power-up/down the controller */
1522static void azx_power_notify(struct hda_codec *codec)
1523{
1524 struct azx *chip = codec->bus->private_data;
1525 struct hda_codec *c;
1526 int power_on = 0;
1527
1528 list_for_each_entry(c, &codec->bus->codec_list, list) {
1529 if (c->power_on) {
1530 power_on = 1;
1531 break;
1532 }
1533 }
1534 if (power_on)
1535 azx_init_chip(chip);
1536#ifdef HDA_POWER_SAVE_RESET_CONTROLLER
1537 else if (chip->running)
1538 azx_stop_chip(chip);
1539#endif
1540}
1541#endif /* CONFIG_SND_HDA_POWER_SAVE */
1542
1462#ifdef CONFIG_PM 1543#ifdef CONFIG_PM
1463/* 1544/*
1464 * power management 1545 * power management
@@ -1473,7 +1554,7 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
1473 for (i = 0; i < chip->pcm_devs; i++) 1554 for (i = 0; i < chip->pcm_devs; i++)
1474 snd_pcm_suspend_all(chip->pcm[i]); 1555 snd_pcm_suspend_all(chip->pcm[i]);
1475 snd_hda_suspend(chip->bus, state); 1556 snd_hda_suspend(chip->bus, state);
1476 azx_free_cmd_io(chip); 1557 azx_stop_chip(chip);
1477 if (chip->irq >= 0) { 1558 if (chip->irq >= 0) {
1478 synchronize_irq(chip->irq); 1559 synchronize_irq(chip->irq);
1479 free_irq(chip->irq, chip); 1560 free_irq(chip->irq, chip);
@@ -1506,8 +1587,12 @@ static int azx_resume(struct pci_dev *pci)
1506 chip->msi = 0; 1587 chip->msi = 0;
1507 if (azx_acquire_irq(chip, 1) < 0) 1588 if (azx_acquire_irq(chip, 1) < 0)
1508 return -EIO; 1589 return -EIO;
1590 azx_init_pci(chip);
1591#ifndef CONFIG_SND_HDA_POWER_SAVE
1592 /* the explicit resume is needed only when POWER_SAVE isn't set */
1509 azx_init_chip(chip); 1593 azx_init_chip(chip);
1510 snd_hda_resume(chip->bus); 1594 snd_hda_resume(chip->bus);
1595#endif
1511 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1596 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1512 return 0; 1597 return 0;
1513} 1598}
@@ -1521,20 +1606,9 @@ static int azx_free(struct azx *chip)
1521{ 1606{
1522 if (chip->initialized) { 1607 if (chip->initialized) {
1523 int i; 1608 int i;
1524
1525 for (i = 0; i < chip->num_streams; i++) 1609 for (i = 0; i < chip->num_streams; i++)
1526 azx_stream_stop(chip, &chip->azx_dev[i]); 1610 azx_stream_stop(chip, &chip->azx_dev[i]);
1527 1611 azx_stop_chip(chip);
1528 /* disable interrupts */
1529 azx_int_disable(chip);
1530 azx_int_clear(chip);
1531
1532 /* disable CORB/RIRB */
1533 azx_free_cmd_io(chip);
1534
1535 /* disable position buffer */
1536 azx_writel(chip, DPLBASE, 0);
1537 azx_writel(chip, DPUBASE, 0);
1538 } 1612 }
1539 1613
1540 if (chip->irq >= 0) { 1614 if (chip->irq >= 0) {
@@ -1720,10 +1794,9 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
1720 azx_init_stream(chip); 1794 azx_init_stream(chip);
1721 1795
1722 /* initialize chip */ 1796 /* initialize chip */
1797 azx_init_pci(chip);
1723 azx_init_chip(chip); 1798 azx_init_chip(chip);
1724 1799
1725 chip->initialized = 1;
1726
1727 /* codec detection */ 1800 /* codec detection */
1728 if (!chip->codec_mask) { 1801 if (!chip->codec_mask) {
1729 snd_printk(KERN_ERR SFX "no codecs found!\n"); 1802 snd_printk(KERN_ERR SFX "no codecs found!\n");
@@ -1750,6 +1823,19 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
1750 return err; 1823 return err;
1751} 1824}
1752 1825
1826static void power_down_all_codecs(struct azx *chip)
1827{
1828#ifdef CONFIG_SND_HDA_POWER_SAVE
1829 /* The codecs were powered up in snd_hda_codec_new().
1830 * Now all initialization done, so turn them down if possible
1831 */
1832 struct hda_codec *codec;
1833 list_for_each_entry(codec, &chip->bus->codec_list, list) {
1834 snd_hda_power_down(codec);
1835 }
1836#endif
1837}
1838
1753static int __devinit azx_probe(struct pci_dev *pci, 1839static int __devinit azx_probe(struct pci_dev *pci,
1754 const struct pci_device_id *pci_id) 1840 const struct pci_device_id *pci_id)
1755{ 1841{
@@ -1800,6 +1886,8 @@ static int __devinit azx_probe(struct pci_dev *pci,
1800 } 1886 }
1801 1887
1802 pci_set_drvdata(pci, card); 1888 pci_set_drvdata(pci, card);
1889 chip->running = 1;
1890 power_down_all_codecs(chip);
1803 1891
1804 return err; 1892 return err;
1805} 1893}