aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ctxfi/cthw20k2.c
diff options
context:
space:
mode:
authorWai Yew CHAY <wychay@ctl.creative.com>2009-06-22 08:52:34 -0400
committerTakashi Iwai <tiwai@suse.de>2009-06-22 08:53:51 -0400
commit29959a09cc1aabd2d5f4f03afc0305de6bd29248 (patch)
treee7e4ed3d33995ab9e83ae378bb9d42fce63f8fde /sound/pci/ctxfi/cthw20k2.c
parenta8f4310be59a2e7fc80fba945bcb32b18f4ad54f (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.c65
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
1902static int hw_card_stop(struct hw *hw) 1904static 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
2019static 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
2032static 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
2009static u32 hw_read_20kx(struct hw *hw, u32 reg) 2044static 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,