diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-10 09:19:44 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-10 09:19:44 -0700 |
commit | e7990d45bb88c2f0565b5ee4c32eefe81653faff (patch) | |
tree | 852ab6988b7226083fefa0e0e851dbff0e7ec7f2 /sound/pci/ice1712/ice1712.c | |
parent | 190a3998be3ede25d6145e187d6d321f504d28fb (diff) | |
parent | a5065eb6da55b226661456e6a7435f605df98111 (diff) | |
download | linux-e7990d45bb88c2f0565b5ee4c32eefe81653faff.tar.gz linux-e7990d45bb88c2f0565b5ee4c32eefe81653faff.tar.bz2 linux-e7990d45bb88c2f0565b5ee4c32eefe81653faff.zip |
Merge tag 'sound-fix-3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai:
"Here is a bunch of small fixes that have been collected since the
previous pull request. In addition to various misc fixes, the
following are included:
- HD-audio quirks for Dell, HP, Chromebook, and ALC28x codecs
- HD-audio AMD HDMI regression fix
- Continued PM support/fixes for ice1712 driver
- Multiplatform fixes for ASoC samsung drivers
- Addition of device id tables to a few ASoC drivers
- Bit clock polarity config and error flag fixes in ASoC fsl_sai"
* tag 'sound-fix-3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (32 commits)
ALSA: usb-audio: Suppress repetitive debug messages from retire_playback_urb()
ALSA: hda - Make full_reset boolean
ALSA: hda - add headset mic detect quirk for a Dell laptop
sound: dmasound: use module_platform_driver_probe()
ALSA: au1x00: use module_platform_driver()
ALSA: hda - Use runtime helper to check active state.
ALSA: ice1712: Fix boundary checks in PCM pointer ops
ASoC: davinci-mcasp: Fix bit clock polarity settings
ASoC: samsung: Fix build on multiplatform
ASoC: fsl_sai: Fix Bit Clock Polarity configurations
ALSA: hda - Do not assign streams in reverse order
ALSA: hda/realtek - Add eapd shutup to ALC283
ALSA: hda/realtek - Change model name alias for ChromeOS
ASoC: da732x: Print correct major id
ALSA: hda/realtek - Improve HP depop when system change power state on Chromebook
ASoC: cs42l52: Fix mask for REVID
sound/oss: Remove uncompilable DBG macro use
ALSA: ice1712: Save/restore routing and rate registers
ALSA: ice1712: restore AK4xxx volumes on resume
ASoC: alc56(23|32): fix undefined return value of probing code
...
Diffstat (limited to 'sound/pci/ice1712/ice1712.c')
-rw-r--r-- | sound/pci/ice1712/ice1712.c | 47 |
1 files changed, 42 insertions, 5 deletions
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 291672fc4a99..d9b9e4595f17 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -685,9 +685,10 @@ static snd_pcm_uframes_t snd_ice1712_playback_pointer(struct snd_pcm_substream * if (!(snd_ice1712_read(ice, ICE1712_IREG_PBK_CTRL) & 1)) return 0; ptr = runtime->buffer_size - inw(ice->ddma_port + 4); + ptr = bytes_to_frames(substream->runtime, ptr); if (ptr == runtime->buffer_size) ptr = 0; - return bytes_to_frames(substream->runtime, ptr); + return ptr; } static snd_pcm_uframes_t snd_ice1712_playback_ds_pointer(struct snd_pcm_substream *substream) @@ -704,9 +705,10 @@ static snd_pcm_uframes_t snd_ice1712_playback_ds_pointer(struct snd_pcm_substrea addr = ICE1712_DSC_ADDR0; ptr = snd_ice1712_ds_read(ice, substream->number * 2, addr) - ice->playback_con_virt_addr[substream->number]; + ptr = bytes_to_frames(substream->runtime, ptr); if (ptr == substream->runtime->buffer_size) ptr = 0; - return bytes_to_frames(substream->runtime, ptr); + return ptr; } static snd_pcm_uframes_t snd_ice1712_capture_pointer(struct snd_pcm_substream *substream) @@ -717,9 +719,10 @@ static snd_pcm_uframes_t snd_ice1712_capture_pointer(struct snd_pcm_substream *s if (!(snd_ice1712_read(ice, ICE1712_IREG_CAP_CTRL) & 1)) return 0; ptr = inl(ICEREG(ice, CONCAP_ADDR)) - ice->capture_con_virt_addr; + ptr = bytes_to_frames(substream->runtime, ptr); if (ptr == substream->runtime->buffer_size) ptr = 0; - return bytes_to_frames(substream->runtime, ptr); + return ptr; } static const struct snd_pcm_hardware snd_ice1712_playback = { @@ -1048,6 +1051,8 @@ __out: old = inb(ICEMT(ice, RATE)); if (!force && old == val) goto __out; + + ice->cur_rate = rate; outb(val, ICEMT(ice, RATE)); spin_unlock_irqrestore(&ice->reg_lock, flags); @@ -1114,9 +1119,10 @@ static snd_pcm_uframes_t snd_ice1712_playback_pro_pointer(struct snd_pcm_substre if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_PLAYBACK_START)) return 0; ptr = ice->playback_pro_size - (inw(ICEMT(ice, PLAYBACK_SIZE)) << 2); + ptr = bytes_to_frames(substream->runtime, ptr); if (ptr == substream->runtime->buffer_size) ptr = 0; - return bytes_to_frames(substream->runtime, ptr); + return ptr; } static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(struct snd_pcm_substream *substream) @@ -1127,9 +1133,10 @@ static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(struct snd_pcm_substrea if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_CAPTURE_START_SHADOW)) return 0; ptr = ice->capture_pro_size - (inw(ICEMT(ice, CAPTURE_SIZE)) << 2); + ptr = bytes_to_frames(substream->runtime, ptr); if (ptr == substream->runtime->buffer_size) ptr = 0; - return bytes_to_frames(substream->runtime, ptr); + return ptr; } static const struct snd_pcm_hardware snd_ice1712_playback_pro = { @@ -2832,6 +2839,12 @@ static int snd_ice1712_suspend(struct device *dev) snd_pcm_suspend_all(ice->pcm_ds); snd_ac97_suspend(ice->ac97); + spin_lock_irq(&ice->reg_lock); + ice->pm_saved_is_spdif_master = is_spdif_master(ice); + ice->pm_saved_spdif_ctrl = inw(ICEMT(ice, ROUTE_SPDOUT)); + ice->pm_saved_route = inw(ICEMT(ice, ROUTE_PSDOUT03)); + spin_unlock_irq(&ice->reg_lock); + if (ice->pm_suspend) ice->pm_suspend(ice); @@ -2846,6 +2859,7 @@ static int snd_ice1712_resume(struct device *dev) struct pci_dev *pci = to_pci_dev(dev); struct snd_card *card = dev_get_drvdata(dev); struct snd_ice1712 *ice = card->private_data; + int rate; if (!ice->pm_suspend_enabled) return 0; @@ -2860,14 +2874,37 @@ static int snd_ice1712_resume(struct device *dev) pci_set_master(pci); + if (ice->cur_rate) + rate = ice->cur_rate; + else + rate = PRO_RATE_DEFAULT; + if (snd_ice1712_chip_init(ice) < 0) { snd_card_disconnect(card); return -EIO; } + ice->cur_rate = rate; + if (ice->pm_resume) ice->pm_resume(ice); + if (ice->pm_saved_is_spdif_master) { + /* switching to external clock via SPDIF */ + spin_lock_irq(&ice->reg_lock); + outb(inb(ICEMT(ice, RATE)) | ICE1712_SPDIF_MASTER, + ICEMT(ice, RATE)); + spin_unlock_irq(&ice->reg_lock); + snd_ice1712_set_input_clock_source(ice, 1); + } else { + /* internal on-card clock */ + snd_ice1712_set_pro_rate(ice, rate, 1); + snd_ice1712_set_input_clock_source(ice, 0); + } + + outw(ice->pm_saved_spdif_ctrl, ICEMT(ice, ROUTE_SPDOUT)); + outw(ice->pm_saved_route, ICEMT(ice, ROUTE_PSDOUT03)); + if (ice->ac97) snd_ac97_resume(ice->ac97); |