diff options
Diffstat (limited to 'sound/pci/ctxfi/cthw20k1.c')
-rw-r--r-- | sound/pci/ctxfi/cthw20k1.c | 83 |
1 files changed, 66 insertions, 17 deletions
diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c index cb69d9ddfbe3..ad3e1d144464 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) | |||
1911 | goto error1; | 1911 | goto error1; |
1912 | } | 1912 | } |
1913 | 1913 | ||
1914 | err = pci_request_regions(pci, "XFi"); | 1914 | if (!hw->io_base) { |
1915 | if (err < 0) | 1915 | err = pci_request_regions(pci, "XFi"); |
1916 | goto error1; | 1916 | if (err < 0) |
1917 | goto error1; | ||
1918 | |||
1919 | if (hw->model == CTUAA) | ||
1920 | hw->io_base = pci_resource_start(pci, 5); | ||
1921 | else | ||
1922 | hw->io_base = pci_resource_start(pci, 0); | ||
1923 | |||
1924 | } | ||
1917 | 1925 | ||
1918 | /* Switch to X-Fi mode from UAA mode if neeeded */ | 1926 | /* Switch to X-Fi mode from UAA mode if neeeded */ |
1919 | if (hw->model == CTUAA) { | 1927 | if (hw->model == CTUAA) { |
@@ -1921,18 +1929,17 @@ static int hw_card_start(struct hw *hw) | |||
1921 | if (err) | 1929 | if (err) |
1922 | goto error2; | 1930 | goto error2; |
1923 | 1931 | ||
1924 | hw->io_base = pci_resource_start(pci, 5); | ||
1925 | } else { | ||
1926 | hw->io_base = pci_resource_start(pci, 0); | ||
1927 | } | 1932 | } |
1928 | 1933 | ||
1929 | err = request_irq(pci->irq, ct_20k1_interrupt, IRQF_SHARED, | 1934 | if (hw->irq < 0) { |
1930 | "ctxfi", hw); | 1935 | err = request_irq(pci->irq, ct_20k1_interrupt, IRQF_SHARED, |
1931 | if (err < 0) { | 1936 | "ctxfi", hw); |
1932 | printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq); | 1937 | if (err < 0) { |
1933 | goto error2; | 1938 | printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq); |
1939 | goto error2; | ||
1940 | } | ||
1941 | hw->irq = pci->irq; | ||
1934 | } | 1942 | } |
1935 | hw->irq = pci->irq; | ||
1936 | 1943 | ||
1937 | pci_set_master(pci); | 1944 | pci_set_master(pci); |
1938 | 1945 | ||
@@ -1948,6 +1955,15 @@ error1: | |||
1948 | 1955 | ||
1949 | static int hw_card_stop(struct hw *hw) | 1956 | static int hw_card_stop(struct hw *hw) |
1950 | { | 1957 | { |
1958 | unsigned int data; | ||
1959 | |||
1960 | /* disable transport bus master and queueing of request */ | ||
1961 | hw_write_20kx(hw, TRNCTL, 0x00); | ||
1962 | |||
1963 | /* disable pll */ | ||
1964 | data = hw_read_20kx(hw, PLLCTL); | ||
1965 | hw_write_20kx(hw, PLLCTL, (data & (~(0x0F<<12)))); | ||
1966 | |||
1951 | /* TODO: Disable interrupt and so on... */ | 1967 | /* TODO: Disable interrupt and so on... */ |
1952 | if (hw->irq >= 0) | 1968 | if (hw->irq >= 0) |
1953 | synchronize_irq(hw->irq); | 1969 | synchronize_irq(hw->irq); |
@@ -1987,11 +2003,9 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) | |||
1987 | struct trn_conf trn_info = {0}; | 2003 | struct trn_conf trn_info = {0}; |
1988 | 2004 | ||
1989 | /* Get PCI io port base address and do Hendrix switch if needed. */ | 2005 | /* Get PCI io port base address and do Hendrix switch if needed. */ |
1990 | if (!hw->io_base) { | 2006 | err = hw_card_start(hw); |
1991 | err = hw_card_start(hw); | 2007 | if (err) |
1992 | if (err) | 2008 | return err; |
1993 | return err; | ||
1994 | } | ||
1995 | 2009 | ||
1996 | /* PLL init */ | 2010 | /* PLL init */ |
1997 | err = hw_pll_init(hw, info->rsr); | 2011 | err = hw_pll_init(hw, info->rsr); |
@@ -2064,6 +2078,37 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) | |||
2064 | return 0; | 2078 | return 0; |
2065 | } | 2079 | } |
2066 | 2080 | ||
2081 | #ifdef CONFIG_PM | ||
2082 | static int hw_suspend(struct hw *hw, pm_message_t state) | ||
2083 | { | ||
2084 | struct pci_dev *pci = hw->pci; | ||
2085 | |||
2086 | hw_card_stop(hw); | ||
2087 | |||
2088 | if (hw->model == CTUAA) { | ||
2089 | /* Switch to UAA config space. */ | ||
2090 | pci_write_config_dword(pci, UAA_CFG_SPACE_FLAG, 0x0); | ||
2091 | } | ||
2092 | |||
2093 | pci_disable_device(pci); | ||
2094 | pci_save_state(pci); | ||
2095 | pci_set_power_state(pci, pci_choose_state(pci, state)); | ||
2096 | |||
2097 | return 0; | ||
2098 | } | ||
2099 | |||
2100 | static int hw_resume(struct hw *hw, struct card_conf *info) | ||
2101 | { | ||
2102 | struct pci_dev *pci = hw->pci; | ||
2103 | |||
2104 | pci_set_power_state(pci, PCI_D0); | ||
2105 | pci_restore_state(pci); | ||
2106 | |||
2107 | /* Re-initialize card hardware. */ | ||
2108 | return hw_card_init(hw, info); | ||
2109 | } | ||
2110 | #endif | ||
2111 | |||
2067 | static u32 hw_read_20kx(struct hw *hw, u32 reg) | 2112 | static u32 hw_read_20kx(struct hw *hw, u32 reg) |
2068 | { | 2113 | { |
2069 | u32 value; | 2114 | u32 value; |
@@ -2128,6 +2173,10 @@ static struct hw ct20k1_preset __devinitdata = { | |||
2128 | .is_adc_source_selected = hw_is_adc_input_selected, | 2173 | .is_adc_source_selected = hw_is_adc_input_selected, |
2129 | .select_adc_source = hw_adc_input_select, | 2174 | .select_adc_source = hw_adc_input_select, |
2130 | .have_digit_io_switch = hw_have_digit_io_switch, | 2175 | .have_digit_io_switch = hw_have_digit_io_switch, |
2176 | #ifdef CONFIG_PM | ||
2177 | .suspend = hw_suspend, | ||
2178 | .resume = hw_resume, | ||
2179 | #endif | ||
2131 | 2180 | ||
2132 | .src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk, | 2181 | .src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk, |
2133 | .src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk, | 2182 | .src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk, |