diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-07-20 07:41:35 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-07-20 07:41:35 -0400 |
commit | bc5304b6fb6c572452b538512761a126f0e0b0d8 (patch) | |
tree | 4b95742936811a8aa51c72578ef9f73a4a62310b /sound/pci/ctxfi | |
parent | 6847e154e3cd74fca6084124c097980a7634285a (diff) |
ALSA: ctxfi - Native timer support for emu20k2
Added the native timer support for emu20k2, which gives much more
accurate update timing than the system timer.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/ctxfi')
-rw-r--r-- | sound/pci/ctxfi/ct20k2reg.h | 9 | ||||
-rw-r--r-- | sound/pci/ctxfi/cthw20k2.c | 55 |
2 files changed, 55 insertions, 9 deletions
diff --git a/sound/pci/ctxfi/ct20k2reg.h b/sound/pci/ctxfi/ct20k2reg.h index 2d07986f57cc..e0394e3996e8 100644 --- a/sound/pci/ctxfi/ct20k2reg.h +++ b/sound/pci/ctxfi/ct20k2reg.h | |||
@@ -11,9 +11,12 @@ | |||
11 | 11 | ||
12 | 12 | ||
13 | /* Timer Registers */ | 13 | /* Timer Registers */ |
14 | #define TIMER_TIMR 0x1B7004 | 14 | #define WC 0x1b7000 |
15 | #define INTERRUPT_GIP 0x1B7010 | 15 | #define TIMR 0x1b7004 |
16 | #define INTERRUPT_GIE 0x1B7014 | 16 | # define TIMR_IE (1<<15) |
17 | # define TIMR_IP (1<<14) | ||
18 | #define GIP 0x1b7010 | ||
19 | #define GIE 0x1b7014 | ||
17 | 20 | ||
18 | /* I2C Registers */ | 21 | /* I2C Registers */ |
19 | #define I2C_IF_ADDRESS 0x1B9000 | 22 | #define I2C_IF_ADDRESS 0x1B9000 |
diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c index dec46d04b041..0c4db2dcab07 100644 --- a/sound/pci/ctxfi/cthw20k2.c +++ b/sound/pci/ctxfi/cthw20k2.c | |||
@@ -1112,6 +1112,26 @@ static int daio_mgr_put_ctrl_blk(void *blk) | |||
1112 | return 0; | 1112 | return 0; |
1113 | } | 1113 | } |
1114 | 1114 | ||
1115 | /* Timer interrupt */ | ||
1116 | static int set_timer_irq(struct hw *hw, int enable) | ||
1117 | { | ||
1118 | hw_write_20kx(hw, GIE, enable ? IT_INT : 0); | ||
1119 | return 0; | ||
1120 | } | ||
1121 | |||
1122 | static int set_timer_tick(struct hw *hw, unsigned int ticks) | ||
1123 | { | ||
1124 | if (ticks) | ||
1125 | ticks |= TIMR_IE | TIMR_IP; | ||
1126 | hw_write_20kx(hw, TIMR, ticks); | ||
1127 | return 0; | ||
1128 | } | ||
1129 | |||
1130 | static unsigned int get_wc(struct hw *hw) | ||
1131 | { | ||
1132 | return hw_read_20kx(hw, WC); | ||
1133 | } | ||
1134 | |||
1115 | /* Card hardware initialization block */ | 1135 | /* Card hardware initialization block */ |
1116 | struct dac_conf { | 1136 | struct dac_conf { |
1117 | unsigned int msr; /* master sample rate in rsrs */ | 1137 | unsigned int msr; /* master sample rate in rsrs */ |
@@ -1841,6 +1861,22 @@ static int hw_have_digit_io_switch(struct hw *hw) | |||
1841 | return 0; | 1861 | return 0; |
1842 | } | 1862 | } |
1843 | 1863 | ||
1864 | static irqreturn_t ct_20k2_interrupt(int irq, void *dev_id) | ||
1865 | { | ||
1866 | struct hw *hw = dev_id; | ||
1867 | unsigned int status; | ||
1868 | |||
1869 | status = hw_read_20kx(hw, GIP); | ||
1870 | if (!status) | ||
1871 | return IRQ_NONE; | ||
1872 | |||
1873 | if (hw->irq_callback) | ||
1874 | hw->irq_callback(hw->irq_callback_data, status); | ||
1875 | |||
1876 | hw_write_20kx(hw, GIP, status); | ||
1877 | return IRQ_HANDLED; | ||
1878 | } | ||
1879 | |||
1844 | static int hw_card_start(struct hw *hw) | 1880 | static int hw_card_start(struct hw *hw) |
1845 | { | 1881 | { |
1846 | int err = 0; | 1882 | int err = 0; |
@@ -1879,12 +1915,15 @@ static int hw_card_start(struct hw *hw) | |||
1879 | set_field(&gctl, GCTL_UAA, 0); | 1915 | set_field(&gctl, GCTL_UAA, 0); |
1880 | hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl); | 1916 | hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl); |
1881 | 1917 | ||
1882 | /*if ((err = request_irq(pci->irq, ct_atc_interrupt, IRQF_SHARED, | 1918 | if (hw->irq < 0) { |
1883 | atc->chip_details->nm_card, hw))) { | 1919 | err = request_irq(pci->irq, ct_20k2_interrupt, IRQF_SHARED, |
1884 | goto error3; | 1920 | "ctxfi", hw); |
1921 | if (err < 0) { | ||
1922 | printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq); | ||
1923 | goto error2; | ||
1924 | } | ||
1925 | hw->irq = pci->irq; | ||
1885 | } | 1926 | } |
1886 | hw->irq = pci->irq; | ||
1887 | */ | ||
1888 | 1927 | ||
1889 | pci_set_master(pci); | 1928 | pci_set_master(pci); |
1890 | 1929 | ||
@@ -1972,7 +2011,7 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) | |||
1972 | hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl); | 2011 | hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl); |
1973 | 2012 | ||
1974 | /* Reset all global pending interrupts */ | 2013 | /* Reset all global pending interrupts */ |
1975 | hw_write_20kx(hw, INTERRUPT_GIE, 0); | 2014 | hw_write_20kx(hw, GIE, 0); |
1976 | /* Reset all SRC pending interrupts */ | 2015 | /* Reset all SRC pending interrupts */ |
1977 | hw_write_20kx(hw, SRC_IP, 0); | 2016 | hw_write_20kx(hw, SRC_IP, 0); |
1978 | 2017 | ||
@@ -2149,6 +2188,10 @@ static struct hw ct20k2_preset __devinitdata = { | |||
2149 | .daio_mgr_set_imapnxt = daio_mgr_set_imapnxt, | 2188 | .daio_mgr_set_imapnxt = daio_mgr_set_imapnxt, |
2150 | .daio_mgr_set_imapaddr = daio_mgr_set_imapaddr, | 2189 | .daio_mgr_set_imapaddr = daio_mgr_set_imapaddr, |
2151 | .daio_mgr_commit_write = daio_mgr_commit_write, | 2190 | .daio_mgr_commit_write = daio_mgr_commit_write, |
2191 | |||
2192 | .set_timer_irq = set_timer_irq, | ||
2193 | .set_timer_tick = set_timer_tick, | ||
2194 | .get_wc = get_wc, | ||
2152 | }; | 2195 | }; |
2153 | 2196 | ||
2154 | int __devinit create_20k2_hw_obj(struct hw **rhw) | 2197 | int __devinit create_20k2_hw_obj(struct hw **rhw) |