diff options
author | Wai Yew CHAY <wychay@ctl.creative.com> | 2009-06-22 08:52:34 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-06-22 08:53:51 -0400 |
commit | 29959a09cc1aabd2d5f4f03afc0305de6bd29248 (patch) | |
tree | e7e4ed3d33995ab9e83ae378bb9d42fce63f8fde /sound/pci/ctxfi/cthw20k2.c | |
parent | a8f4310be59a2e7fc80fba945bcb32b18f4ad54f (diff) |
ALSA: ctxfi - Add PM support
Added the suspend/resume support to ctxfi driver.
The team tested on the following seems ok:
AMD Athlon 64 3500+ / ASUS A8N-E / 512MB DDR ATI / Radeon X1300
20k1 & 20k2 cards
Signed-off-by: Wai Yew CHAY <wychay@ctl.creative.com>
Singed-off-by: Ryan RICHARDS <ryan_richards@creativelabs.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/ctxfi/cthw20k2.c')
-rw-r--r-- | sound/pci/ctxfi/cthw20k2.c | 65 |
1 files changed, 52 insertions, 13 deletions
diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c index 4493a51c6b01..dec46d04b041 100644 --- a/sound/pci/ctxfi/cthw20k2.c +++ b/sound/pci/ctxfi/cthw20k2.c | |||
@@ -1860,16 +1860,18 @@ static int hw_card_start(struct hw *hw) | |||
1860 | goto error1; | 1860 | goto error1; |
1861 | } | 1861 | } |
1862 | 1862 | ||
1863 | err = pci_request_regions(pci, "XFi"); | 1863 | if (!hw->io_base) { |
1864 | if (err < 0) | 1864 | err = pci_request_regions(pci, "XFi"); |
1865 | goto error1; | 1865 | if (err < 0) |
1866 | goto error1; | ||
1866 | 1867 | ||
1867 | hw->io_base = pci_resource_start(hw->pci, 2); | 1868 | hw->io_base = pci_resource_start(hw->pci, 2); |
1868 | hw->mem_base = (unsigned long)ioremap(hw->io_base, | 1869 | hw->mem_base = (unsigned long)ioremap(hw->io_base, |
1869 | pci_resource_len(hw->pci, 2)); | 1870 | pci_resource_len(hw->pci, 2)); |
1870 | if (NULL == (void *)hw->mem_base) { | 1871 | if (NULL == (void *)hw->mem_base) { |
1871 | err = -ENOENT; | 1872 | err = -ENOENT; |
1872 | goto error2; | 1873 | goto error2; |
1874 | } | ||
1873 | } | 1875 | } |
1874 | 1876 | ||
1875 | /* Switch to 20k2 mode from UAA mode. */ | 1877 | /* Switch to 20k2 mode from UAA mode. */ |
@@ -1901,6 +1903,15 @@ error1: | |||
1901 | 1903 | ||
1902 | static int hw_card_stop(struct hw *hw) | 1904 | static int hw_card_stop(struct hw *hw) |
1903 | { | 1905 | { |
1906 | unsigned int data; | ||
1907 | |||
1908 | /* disable transport bus master and queueing of request */ | ||
1909 | hw_write_20kx(hw, TRANSPORT_CTL, 0x00); | ||
1910 | |||
1911 | /* disable pll */ | ||
1912 | data = hw_read_20kx(hw, PLL_ENB); | ||
1913 | hw_write_20kx(hw, PLL_ENB, (data & (~0x07))); | ||
1914 | |||
1904 | /* TODO: Disable interrupt and so on... */ | 1915 | /* TODO: Disable interrupt and so on... */ |
1905 | return 0; | 1916 | return 0; |
1906 | } | 1917 | } |
@@ -1939,11 +1950,9 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) | |||
1939 | 1950 | ||
1940 | /* Get PCI io port/memory base address and | 1951 | /* Get PCI io port/memory base address and |
1941 | * do 20kx core switch if needed. */ | 1952 | * do 20kx core switch if needed. */ |
1942 | if (!hw->io_base) { | 1953 | err = hw_card_start(hw); |
1943 | err = hw_card_start(hw); | 1954 | if (err) |
1944 | if (err) | 1955 | return err; |
1945 | return err; | ||
1946 | } | ||
1947 | 1956 | ||
1948 | /* PLL init */ | 1957 | /* PLL init */ |
1949 | err = hw_pll_init(hw, info->rsr); | 1958 | err = hw_pll_init(hw, info->rsr); |
@@ -2006,6 +2015,32 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) | |||
2006 | return 0; | 2015 | return 0; |
2007 | } | 2016 | } |
2008 | 2017 | ||
2018 | #ifdef CONFIG_PM | ||
2019 | static int hw_suspend(struct hw *hw, pm_message_t state) | ||
2020 | { | ||
2021 | struct pci_dev *pci = hw->pci; | ||
2022 | |||
2023 | hw_card_stop(hw); | ||
2024 | |||
2025 | pci_disable_device(pci); | ||
2026 | pci_save_state(pci); | ||
2027 | pci_set_power_state(pci, pci_choose_state(pci, state)); | ||
2028 | |||
2029 | return 0; | ||
2030 | } | ||
2031 | |||
2032 | static int hw_resume(struct hw *hw, struct card_conf *info) | ||
2033 | { | ||
2034 | struct pci_dev *pci = hw->pci; | ||
2035 | |||
2036 | pci_set_power_state(pci, PCI_D0); | ||
2037 | pci_restore_state(pci); | ||
2038 | |||
2039 | /* Re-initialize card hardware. */ | ||
2040 | return hw_card_init(hw, info); | ||
2041 | } | ||
2042 | #endif | ||
2043 | |||
2009 | static u32 hw_read_20kx(struct hw *hw, u32 reg) | 2044 | static u32 hw_read_20kx(struct hw *hw, u32 reg) |
2010 | { | 2045 | { |
2011 | return readl((void *)(hw->mem_base + reg)); | 2046 | return readl((void *)(hw->mem_base + reg)); |
@@ -2025,6 +2060,10 @@ static struct hw ct20k2_preset __devinitdata = { | |||
2025 | .is_adc_source_selected = hw_is_adc_input_selected, | 2060 | .is_adc_source_selected = hw_is_adc_input_selected, |
2026 | .select_adc_source = hw_adc_input_select, | 2061 | .select_adc_source = hw_adc_input_select, |
2027 | .have_digit_io_switch = hw_have_digit_io_switch, | 2062 | .have_digit_io_switch = hw_have_digit_io_switch, |
2063 | #ifdef CONFIG_PM | ||
2064 | .suspend = hw_suspend, | ||
2065 | .resume = hw_resume, | ||
2066 | #endif | ||
2028 | 2067 | ||
2029 | .src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk, | 2068 | .src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk, |
2030 | .src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk, | 2069 | .src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk, |