aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ctxfi/cthw20k1.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-06-05 10:11:07 -0400
committerTakashi Iwai <tiwai@suse.de>2009-06-05 10:44:13 -0400
commitb7bbf876087e0e2c0ba723a8398083c9a9ac1dfd (patch)
tree69a3e70658fc751ffc99eef5a6f047b19f61a4a2 /sound/pci/ctxfi/cthw20k1.c
parent6bc5874a1ddf98ac0fe6c4eab7d286c11cb1c748 (diff)
ALSA: ctxfi - Use native timer interrupt on emu20k1
emu20k1 has a native timer interrupt based on the audio clock, which is more accurate than the system timer (from the synchronization POV). This patch adds the code to handle this with multiple streams. The system timer is still used on emu20k2, and can be used also for emu20k1 easily by changing USE_SYSTEM_TIMER to 1 in cttimer.c. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/ctxfi/cthw20k1.c')
-rw-r--r--sound/pci/ctxfi/cthw20k1.c43
1 files changed, 40 insertions, 3 deletions
diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c
index e530a6d60422..550b30a2bcf1 100644
--- a/sound/pci/ctxfi/cthw20k1.c
+++ b/sound/pci/ctxfi/cthw20k1.c
@@ -1171,6 +1171,21 @@ static int daio_mgr_put_ctrl_blk(void *blk)
1171 return 0; 1171 return 0;
1172} 1172}
1173 1173
1174/* Timer interrupt */
1175static int set_timer_irq(struct hw *hw, int enable)
1176{
1177 hw_write_20kx(hw, GIE, enable ? IT_INT : 0);
1178 return 0;
1179}
1180
1181static int set_timer_tick(struct hw *hw, unsigned int ticks)
1182{
1183 if (ticks)
1184 ticks |= TIMR_IE | TIMR_IP;
1185 hw_write_20kx(hw, TIMR, ticks);
1186 return 0;
1187}
1188
1174/* Card hardware initialization block */ 1189/* Card hardware initialization block */
1175struct dac_conf { 1190struct dac_conf {
1176 unsigned int msr; /* master sample rate in rsrs */ 1191 unsigned int msr; /* master sample rate in rsrs */
@@ -1878,6 +1893,22 @@ static int uaa_to_xfi(struct pci_dev *pci)
1878 return 0; 1893 return 0;
1879} 1894}
1880 1895
1896static irqreturn_t ct_20k1_interrupt(int irq, void *dev_id)
1897{
1898 struct hw *hw = dev_id;
1899 unsigned int status;
1900
1901 status = hw_read_20kx(hw, GIP);
1902 if (!status)
1903 return IRQ_NONE;
1904
1905 if (hw->irq_callback)
1906 hw->irq_callback(hw->irq_callback_data, status);
1907
1908 hw_write_20kx(hw, GIP, status);
1909 return IRQ_HANDLED;
1910}
1911
1881static int hw_card_start(struct hw *hw) 1912static int hw_card_start(struct hw *hw)
1882{ 1913{
1883 int err = 0; 1914 int err = 0;
@@ -1914,12 +1945,13 @@ static int hw_card_start(struct hw *hw)
1914 hw->io_base = pci_resource_start(pci, 0); 1945 hw->io_base = pci_resource_start(pci, 0);
1915 } 1946 }
1916 1947
1917 /*if ((err = request_irq(pci->irq, ct_atc_interrupt, IRQF_SHARED, 1948 err = request_irq(pci->irq, ct_20k1_interrupt, IRQF_SHARED,
1918 atc->chip_details->nm_card, hw))) { 1949 "ctxfi", hw);
1950 if (err < 0) {
1951 printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
1919 goto error2; 1952 goto error2;
1920 } 1953 }
1921 hw->irq = pci->irq; 1954 hw->irq = pci->irq;
1922 */
1923 1955
1924 pci_set_master(pci); 1956 pci_set_master(pci);
1925 1957
@@ -1936,6 +1968,8 @@ error1:
1936static int hw_card_stop(struct hw *hw) 1968static int hw_card_stop(struct hw *hw)
1937{ 1969{
1938 /* TODO: Disable interrupt and so on... */ 1970 /* TODO: Disable interrupt and so on... */
1971 if (hw->irq >= 0)
1972 synchronize_irq(hw->irq);
1939 return 0; 1973 return 0;
1940} 1974}
1941 1975
@@ -2215,6 +2249,9 @@ int create_20k1_hw_obj(struct hw **rhw)
2215 hw->daio_mgr_set_imapaddr = daio_mgr_set_imapaddr; 2249 hw->daio_mgr_set_imapaddr = daio_mgr_set_imapaddr;
2216 hw->daio_mgr_commit_write = daio_mgr_commit_write; 2250 hw->daio_mgr_commit_write = daio_mgr_commit_write;
2217 2251
2252 hw->set_timer_irq = set_timer_irq;
2253 hw->set_timer_tick = set_timer_tick;
2254
2218 *rhw = hw; 2255 *rhw = hw;
2219 2256
2220 return 0; 2257 return 0;