0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/time.h>
0015 #include <sound/core.h>
0016 #include <sound/emu10k1.h>
0017
0018 static int snd_emu10k1_timer_start(struct snd_timer *timer)
0019 {
0020 struct snd_emu10k1 *emu;
0021 unsigned long flags;
0022 unsigned int delay;
0023
0024 emu = snd_timer_chip(timer);
0025 delay = timer->sticks - 1;
0026 if (delay < 5 )
0027 delay = 5;
0028 spin_lock_irqsave(&emu->reg_lock, flags);
0029 snd_emu10k1_intr_enable(emu, INTE_INTERVALTIMERENB);
0030 outw(delay & TIMER_RATE_MASK, emu->port + TIMER);
0031 spin_unlock_irqrestore(&emu->reg_lock, flags);
0032 return 0;
0033 }
0034
0035 static int snd_emu10k1_timer_stop(struct snd_timer *timer)
0036 {
0037 struct snd_emu10k1 *emu;
0038 unsigned long flags;
0039
0040 emu = snd_timer_chip(timer);
0041 spin_lock_irqsave(&emu->reg_lock, flags);
0042 snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB);
0043 spin_unlock_irqrestore(&emu->reg_lock, flags);
0044 return 0;
0045 }
0046
0047 static int snd_emu10k1_timer_precise_resolution(struct snd_timer *timer,
0048 unsigned long *num, unsigned long *den)
0049 {
0050 *num = 1;
0051 *den = 48000;
0052 return 0;
0053 }
0054
0055 static const struct snd_timer_hardware snd_emu10k1_timer_hw = {
0056 .flags = SNDRV_TIMER_HW_AUTO,
0057 .resolution = 20833,
0058 .ticks = 1024,
0059 .start = snd_emu10k1_timer_start,
0060 .stop = snd_emu10k1_timer_stop,
0061 .precise_resolution = snd_emu10k1_timer_precise_resolution,
0062 };
0063
0064 int snd_emu10k1_timer(struct snd_emu10k1 *emu, int device)
0065 {
0066 struct snd_timer *timer = NULL;
0067 struct snd_timer_id tid;
0068 int err;
0069
0070 tid.dev_class = SNDRV_TIMER_CLASS_CARD;
0071 tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
0072 tid.card = emu->card->number;
0073 tid.device = device;
0074 tid.subdevice = 0;
0075 err = snd_timer_new(emu->card, "EMU10K1", &tid, &timer);
0076 if (err >= 0) {
0077 strcpy(timer->name, "EMU10K1 timer");
0078 timer->private_data = emu;
0079 timer->hw = snd_emu10k1_timer_hw;
0080 }
0081 emu->timer = timer;
0082 return err;
0083 }