aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/intel8x0.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/intel8x0.c')
-rw-r--r--sound/pci/intel8x0.c57
1 files changed, 49 insertions, 8 deletions
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index d7af3e474432..7b548416dcef 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -389,6 +389,7 @@ typedef struct {
389 struct ac97_pcm *pcm; 389 struct ac97_pcm *pcm;
390 int pcm_open_flag; 390 int pcm_open_flag;
391 unsigned int page_attr_changed: 1; 391 unsigned int page_attr_changed: 1;
392 unsigned int suspended: 1;
392} ichdev_t; 393} ichdev_t;
393 394
394typedef struct _snd_intel8x0 intel8x0_t; 395typedef struct _snd_intel8x0 intel8x0_t;
@@ -862,12 +863,16 @@ static int snd_intel8x0_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
862 unsigned long port = ichdev->reg_offset; 863 unsigned long port = ichdev->reg_offset;
863 864
864 switch (cmd) { 865 switch (cmd) {
865 case SNDRV_PCM_TRIGGER_START:
866 case SNDRV_PCM_TRIGGER_RESUME: 866 case SNDRV_PCM_TRIGGER_RESUME:
867 ichdev->suspended = 0;
868 /* fallthru */
869 case SNDRV_PCM_TRIGGER_START:
867 val = ICH_IOCE | ICH_STARTBM; 870 val = ICH_IOCE | ICH_STARTBM;
868 break; 871 break;
869 case SNDRV_PCM_TRIGGER_STOP:
870 case SNDRV_PCM_TRIGGER_SUSPEND: 872 case SNDRV_PCM_TRIGGER_SUSPEND:
873 ichdev->suspended = 1;
874 /* fallthru */
875 case SNDRV_PCM_TRIGGER_STOP:
871 val = 0; 876 val = 0;
872 break; 877 break;
873 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 878 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
@@ -899,9 +904,11 @@ static int snd_intel8x0_ali_trigger(snd_pcm_substream_t *substream, int cmd)
899 904
900 val = igetdword(chip, ICHREG(ALI_DMACR)); 905 val = igetdword(chip, ICHREG(ALI_DMACR));
901 switch (cmd) { 906 switch (cmd) {
907 case SNDRV_PCM_TRIGGER_RESUME:
908 ichdev->suspended = 0;
909 /* fallthru */
902 case SNDRV_PCM_TRIGGER_START: 910 case SNDRV_PCM_TRIGGER_START:
903 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 911 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
904 case SNDRV_PCM_TRIGGER_RESUME:
905 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 912 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
906 /* clear FIFO for synchronization of channels */ 913 /* clear FIFO for synchronization of channels */
907 fifo = igetdword(chip, fiforeg[ichdev->ali_slot / 4]); 914 fifo = igetdword(chip, fiforeg[ichdev->ali_slot / 4]);
@@ -913,9 +920,11 @@ static int snd_intel8x0_ali_trigger(snd_pcm_substream_t *substream, int cmd)
913 val &= ~(1 << (ichdev->ali_slot + 16)); /* clear PAUSE flag */ 920 val &= ~(1 << (ichdev->ali_slot + 16)); /* clear PAUSE flag */
914 iputdword(chip, ICHREG(ALI_DMACR), val | (1 << ichdev->ali_slot)); /* start DMA */ 921 iputdword(chip, ICHREG(ALI_DMACR), val | (1 << ichdev->ali_slot)); /* start DMA */
915 break; 922 break;
923 case SNDRV_PCM_TRIGGER_SUSPEND:
924 ichdev->suspended = 1;
925 /* fallthru */
916 case SNDRV_PCM_TRIGGER_STOP: 926 case SNDRV_PCM_TRIGGER_STOP:
917 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 927 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
918 case SNDRV_PCM_TRIGGER_SUSPEND:
919 iputdword(chip, ICHREG(ALI_DMACR), val | (1 << (ichdev->ali_slot + 16))); /* pause */ 928 iputdword(chip, ICHREG(ALI_DMACR), val | (1 << (ichdev->ali_slot + 16))); /* pause */
920 iputbyte(chip, port + ICH_REG_OFF_CR, 0); 929 iputbyte(chip, port + ICH_REG_OFF_CR, 0);
921 while (igetbyte(chip, port + ICH_REG_OFF_CR)) 930 while (igetbyte(chip, port + ICH_REG_OFF_CR))
@@ -994,6 +1003,8 @@ static void snd_intel8x0_setup_pcm_out(intel8x0_t *chip,
994{ 1003{
995 unsigned int cnt; 1004 unsigned int cnt;
996 int dbl = runtime->rate > 48000; 1005 int dbl = runtime->rate > 48000;
1006
1007 spin_lock_irq(&chip->reg_lock);
997 switch (chip->device_type) { 1008 switch (chip->device_type) {
998 case DEVICE_ALI: 1009 case DEVICE_ALI:
999 cnt = igetdword(chip, ICHREG(ALI_SCR)); 1010 cnt = igetdword(chip, ICHREG(ALI_SCR));
@@ -1037,6 +1048,7 @@ static void snd_intel8x0_setup_pcm_out(intel8x0_t *chip,
1037 iputdword(chip, ICHREG(GLOB_CNT), cnt); 1048 iputdword(chip, ICHREG(GLOB_CNT), cnt);
1038 break; 1049 break;
1039 } 1050 }
1051 spin_unlock_irq(&chip->reg_lock);
1040} 1052}
1041 1053
1042static int snd_intel8x0_pcm_prepare(snd_pcm_substream_t * substream) 1054static int snd_intel8x0_pcm_prepare(snd_pcm_substream_t * substream)
@@ -1048,15 +1060,12 @@ static int snd_intel8x0_pcm_prepare(snd_pcm_substream_t * substream)
1048 ichdev->physbuf = runtime->dma_addr; 1060 ichdev->physbuf = runtime->dma_addr;
1049 ichdev->size = snd_pcm_lib_buffer_bytes(substream); 1061 ichdev->size = snd_pcm_lib_buffer_bytes(substream);
1050 ichdev->fragsize = snd_pcm_lib_period_bytes(substream); 1062 ichdev->fragsize = snd_pcm_lib_period_bytes(substream);
1051 spin_lock_irq(&chip->reg_lock);
1052 if (ichdev->ichd == ICHD_PCMOUT) { 1063 if (ichdev->ichd == ICHD_PCMOUT) {
1053 snd_intel8x0_setup_pcm_out(chip, runtime); 1064 snd_intel8x0_setup_pcm_out(chip, runtime);
1054 if (chip->device_type == DEVICE_INTEL_ICH4) { 1065 if (chip->device_type == DEVICE_INTEL_ICH4)
1055 ichdev->pos_shift = (runtime->sample_bits > 16) ? 2 : 1; 1066 ichdev->pos_shift = (runtime->sample_bits > 16) ? 2 : 1;
1056 }
1057 } 1067 }
1058 snd_intel8x0_setup_periods(chip, ichdev); 1068 snd_intel8x0_setup_periods(chip, ichdev);
1059 spin_unlock_irq(&chip->reg_lock);
1060 return 0; 1069 return 0;
1061} 1070}
1062 1071
@@ -1817,6 +1826,18 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
1817 }, 1826 },
1818 { 1827 {
1819 .subvendor = 0x103c, 1828 .subvendor = 0x103c,
1829 .subdevice = 0x0934,
1830 .name = "HP nx8220",
1831 .type = AC97_TUNE_MUTE_LED
1832 },
1833 {
1834 .subvendor = 0x103c,
1835 .subdevice = 0x099c,
1836 .name = "HP nx6110", /* AD1981B */
1837 .type = AC97_TUNE_HP_ONLY
1838 },
1839 {
1840 .subvendor = 0x103c,
1820 .subdevice = 0x129d, 1841 .subdevice = 0x129d,
1821 .name = "HP xw8000", 1842 .name = "HP xw8000",
1822 .type = AC97_TUNE_HP_ONLY 1843 .type = AC97_TUNE_HP_ONLY
@@ -1870,6 +1891,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
1870 .type = AC97_TUNE_HP_ONLY 1891 .type = AC97_TUNE_HP_ONLY
1871 }, 1892 },
1872 { 1893 {
1894 .subvendor = 0x10cf,
1895 .subdevice = 0x12ec,
1896 .name = "Fujitsu-Siemens 4010",
1897 .type = AC97_TUNE_HP_ONLY
1898 },
1899 {
1873 .subvendor = 0x10f1, 1900 .subvendor = 0x10f1,
1874 .subdevice = 0x2665, 1901 .subdevice = 0x2665,
1875 .name = "Fujitsu-Siemens Celsius", /* AD1981? */ 1902 .name = "Fujitsu-Siemens Celsius", /* AD1981? */
@@ -2424,6 +2451,20 @@ static int intel8x0_resume(snd_card_t *card)
2424 } 2451 }
2425 } 2452 }
2426 2453
2454 /* resume status */
2455 for (i = 0; i < chip->bdbars_count; i++) {
2456 ichdev_t *ichdev = &chip->ichd[i];
2457 unsigned long port = ichdev->reg_offset;
2458 if (! ichdev->substream || ! ichdev->suspended)
2459 continue;
2460 if (ichdev->ichd == ICHD_PCMOUT)
2461 snd_intel8x0_setup_pcm_out(chip, ichdev->substream->runtime);
2462 iputdword(chip, port + ICH_REG_OFF_BDBAR, ichdev->bdbar_addr);
2463 iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi);
2464 iputbyte(chip, port + ICH_REG_OFF_CIV, ichdev->civ);
2465 iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI);
2466 }
2467
2427 return 0; 2468 return 0;
2428} 2469}
2429#endif /* CONFIG_PM */ 2470#endif /* CONFIG_PM */