aboutsummaryrefslogtreecommitdiff
path: root/sound/pci/ctxfi/cthw20k1.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-23 10:45:39 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-23 10:45:39 -0700
commitc488eef8154b36cce905624577183dc1fa8f6da0 (patch)
treee66d9e71e09d7213f9a35685283a5a65d11adfd1 /sound/pci/ctxfi/cthw20k1.c
parentcf9c1b92ae62ce71a8e861f02476724348defc6a (diff)
parent3f67f6693c82f1cb8edb233f9bd10fa06d27a193 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: ALSA: hda - Make jack-plug notification selectable ALSA: ctxfi - Add PM support sound: seq_midi_event: fix decoding of (N)RPN events ALSA: hda - Add digital-mic support to ALC262 auto model ALSA: hda - Fix check of input source type for realtek codecs ALSA: hda - Add quirk for Sony VAIO Z21MN ALSA: hda - Get back Input Source for ALC262 toshiba-s06 model ALSA: hda - Fix unsigned comparison in patch_sigmatel.c ALSA: via82xx: add option to disable 500ms delay in snd_via82xx_codec_wait sound: fix check for return value in snd_pcm_hw_refine ALSA: ctxfi - Allow unknown PCI SSIDs ASoC: Blackfin: update the bf5xx_i2s_resume parameters ASoC: Blackfin: keep better track of SPORT configuration state
Diffstat (limited to 'sound/pci/ctxfi/cthw20k1.c')
-rw-r--r--sound/pci/ctxfi/cthw20k1.c83
1 files changed, 66 insertions, 17 deletions
diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c
index cb69d9ddfbe..ad3e1d14446 100644
--- a/sound/pci/ctxfi/cthw20k1.c
+++ b/sound/pci/ctxfi/cthw20k1.c
@@ -1911,9 +1911,17 @@ static int hw_card_start(struct hw *hw)
goto error1;
}
- err = pci_request_regions(pci, "XFi");
- if (err < 0)
- goto error1;
+ if (!hw->io_base) {
+ err = pci_request_regions(pci, "XFi");
+ if (err < 0)
+ goto error1;
+
+ if (hw->model == CTUAA)
+ hw->io_base = pci_resource_start(pci, 5);
+ else
+ hw->io_base = pci_resource_start(pci, 0);
+
+ }
/* Switch to X-Fi mode from UAA mode if neeeded */
if (hw->model == CTUAA) {
@@ -1921,18 +1929,17 @@ static int hw_card_start(struct hw *hw)
if (err)
goto error2;
- hw->io_base = pci_resource_start(pci, 5);
- } else {
- hw->io_base = pci_resource_start(pci, 0);
}
- err = request_irq(pci->irq, ct_20k1_interrupt, IRQF_SHARED,
- "ctxfi", hw);
- if (err < 0) {
- printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
- goto error2;
+ if (hw->irq < 0) {
+ err = request_irq(pci->irq, ct_20k1_interrupt, IRQF_SHARED,
+ "ctxfi", hw);
+ if (err < 0) {
+ printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
+ goto error2;
+ }
+ hw->irq = pci->irq;
}
- hw->irq = pci->irq;
pci_set_master(pci);
@@ -1948,6 +1955,15 @@ error1:
static int hw_card_stop(struct hw *hw)
{
+ unsigned int data;
+
+ /* disable transport bus master and queueing of request */
+ hw_write_20kx(hw, TRNCTL, 0x00);
+
+ /* disable pll */
+ data = hw_read_20kx(hw, PLLCTL);
+ hw_write_20kx(hw, PLLCTL, (data & (~(0x0F<<12))));
+
/* TODO: Disable interrupt and so on... */
if (hw->irq >= 0)
synchronize_irq(hw->irq);
@@ -1987,11 +2003,9 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
struct trn_conf trn_info = {0};
/* Get PCI io port base address and do Hendrix switch if needed. */
- if (!hw->io_base) {
- err = hw_card_start(hw);
- if (err)
- return err;
- }
+ err = hw_card_start(hw);
+ if (err)
+ return err;
/* PLL init */
err = hw_pll_init(hw, info->rsr);
@@ -2064,6 +2078,37 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
return 0;
}
+#ifdef CONFIG_PM
+static int hw_suspend(struct hw *hw, pm_message_t state)
+{
+ struct pci_dev *pci = hw->pci;
+
+ hw_card_stop(hw);
+
+ if (hw->model == CTUAA) {
+ /* Switch to UAA config space. */
+ pci_write_config_dword(pci, UAA_CFG_SPACE_FLAG, 0x0);
+ }
+
+ pci_disable_device(pci);
+ pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
+
+ return 0;
+}
+
+static int hw_resume(struct hw *hw, struct card_conf *info)
+{
+ struct pci_dev *pci = hw->pci;
+
+ pci_set_power_state(pci, PCI_D0);
+ pci_restore_state(pci);
+
+ /* Re-initialize card hardware. */
+ return hw_card_init(hw, info);
+}
+#endif
+
static u32 hw_read_20kx(struct hw *hw, u32 reg)
{
u32 value;
@@ -2128,6 +2173,10 @@ static struct hw ct20k1_preset __devinitdata = {
.is_adc_source_selected = hw_is_adc_input_selected,
.select_adc_source = hw_adc_input_select,
.have_digit_io_switch = hw_have_digit_io_switch,
+#ifdef CONFIG_PM
+ .suspend = hw_suspend,
+ .resume = hw_resume,
+#endif
.src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk,
.src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk,