aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ctxfi/ctatc.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/ctatc.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/ctatc.c')
-rw-r--r--sound/pci/ctxfi/ctatc.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index 684947546d81..10b741977dd7 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -22,6 +22,7 @@
22#include "ctsrc.h" 22#include "ctsrc.h"
23#include "ctamixer.h" 23#include "ctamixer.h"
24#include "ctdaio.h" 24#include "ctdaio.h"
25#include "cttimer.h"
25#include <linux/delay.h> 26#include <linux/delay.h>
26#include <sound/pcm.h> 27#include <sound/pcm.h>
27#include <sound/control.h> 28#include <sound/control.h>
@@ -307,6 +308,8 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
307 src = apcm->src; 308 src = apcm->src;
308 } 309 }
309 310
311 ct_timer_prepare(apcm->timer);
312
310 return 0; 313 return 0;
311 314
312error1: 315error1:
@@ -389,6 +392,7 @@ static int atc_pcm_playback_start(struct ct_atc *atc, struct ct_atc_pcm *apcm)
389 src->ops->set_state(src, SRC_STATE_INIT); 392 src->ops->set_state(src, SRC_STATE_INIT);
390 src->ops->commit_write(src); 393 src->ops->commit_write(src);
391 394
395 ct_timer_start(apcm->timer);
392 return 0; 396 return 0;
393} 397}
394 398
@@ -397,6 +401,8 @@ static int atc_pcm_stop(struct ct_atc *atc, struct ct_atc_pcm *apcm)
397 struct src *src = NULL; 401 struct src *src = NULL;
398 int i = 0; 402 int i = 0;
399 403
404 ct_timer_stop(apcm->timer);
405
400 src = apcm->src; 406 src = apcm->src;
401 src->ops->set_bm(src, 0); 407 src->ops->set_bm(src, 0);
402 src->ops->set_state(src, SRC_STATE_OFF); 408 src->ops->set_state(src, SRC_STATE_OFF);
@@ -701,6 +707,8 @@ static int atc_pcm_capture_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
701 } 707 }
702 } 708 }
703 709
710 ct_timer_prepare(apcm->timer);
711
704 return 0; 712 return 0;
705} 713}
706 714
@@ -749,6 +757,7 @@ static int atc_pcm_capture_start(struct ct_atc *atc, struct ct_atc_pcm *apcm)
749 /* Enable relevant SRCs synchronously */ 757 /* Enable relevant SRCs synchronously */
750 src_mgr->commit_write(src_mgr); 758 src_mgr->commit_write(src_mgr);
751 759
760 ct_timer_start(apcm->timer);
752 return 0; 761 return 0;
753} 762}
754 763
@@ -906,6 +915,8 @@ spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
906 dao->ops->set_right_input(dao, &amixer->rsc); 915 dao->ops->set_right_input(dao, &amixer->rsc);
907 spin_unlock_irqrestore(&atc->atc_lock, flags); 916 spin_unlock_irqrestore(&atc->atc_lock, flags);
908 917
918 ct_timer_prepare(apcm->timer);
919
909 return 0; 920 return 0;
910} 921}
911 922
@@ -1100,6 +1111,11 @@ static int ct_atc_destroy(struct ct_atc *atc)
1100 if (NULL == atc) 1111 if (NULL == atc)
1101 return 0; 1112 return 0;
1102 1113
1114 if (atc->timer) {
1115 ct_timer_free(atc->timer);
1116 atc->timer = NULL;
1117 }
1118
1103 /* Stop hardware and disable all interrupts */ 1119 /* Stop hardware and disable all interrupts */
1104 if (NULL != atc->hw) 1120 if (NULL != atc->hw)
1105 ((struct hw *)atc->hw)->card_stop(atc->hw); 1121 ((struct hw *)atc->hw)->card_stop(atc->hw);
@@ -1586,6 +1602,10 @@ int ct_atc_create(struct snd_card *card, struct pci_dev *pci,
1586 /* Build topology */ 1602 /* Build topology */
1587 atc_connect_resources(atc); 1603 atc_connect_resources(atc);
1588 1604
1605 atc->timer = ct_timer_new(atc);
1606 if (!atc->timer)
1607 goto error1;
1608
1589 atc->create_alsa_devs = ct_create_alsa_devs; 1609 atc->create_alsa_devs = ct_create_alsa_devs;
1590 1610
1591 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, atc, &ops); 1611 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, atc, &ops);
@@ -1602,4 +1622,3 @@ error1:
1602 printk(KERN_ERR "ctxfi: Something wrong!!!\n"); 1622 printk(KERN_ERR "ctxfi: Something wrong!!!\n");
1603 return err; 1623 return err;
1604} 1624}
1605