Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/pci/emu10k1/timer.c
26424 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* Copyright (c) by Lee Revell <[email protected]>
4
* Clemens Ladisch <[email protected]>
5
* Oswald Buddenhagen <[email protected]>
6
*
7
* Routines for control of EMU10K1 chips
8
*/
9
10
#include <linux/time.h>
11
#include <sound/core.h>
12
#include <sound/emu10k1.h>
13
14
static int snd_emu10k1_timer_start(struct snd_timer *timer)
15
{
16
struct snd_emu10k1 *emu;
17
unsigned int delay;
18
19
emu = snd_timer_chip(timer);
20
delay = timer->sticks - 1;
21
if (delay < 5 ) /* minimum time is 5 ticks */
22
delay = 5;
23
snd_emu10k1_intr_enable(emu, INTE_INTERVALTIMERENB);
24
outw(delay & TIMER_RATE_MASK, emu->port + TIMER);
25
return 0;
26
}
27
28
static int snd_emu10k1_timer_stop(struct snd_timer *timer)
29
{
30
struct snd_emu10k1 *emu;
31
32
emu = snd_timer_chip(timer);
33
snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB);
34
return 0;
35
}
36
37
static unsigned long snd_emu10k1_timer_c_resolution(struct snd_timer *timer)
38
{
39
struct snd_emu10k1 *emu = snd_timer_chip(timer);
40
41
if (emu->card_capabilities->emu_model &&
42
emu->emu1010.word_clock == 44100)
43
return 22676; // 1 sample @ 44.1 kHz = 22.675736...us
44
else
45
return 20833; // 1 sample @ 48 kHz = 20.833...us
46
}
47
48
static int snd_emu10k1_timer_precise_resolution(struct snd_timer *timer,
49
unsigned long *num, unsigned long *den)
50
{
51
struct snd_emu10k1 *emu = snd_timer_chip(timer);
52
53
*num = 1;
54
if (emu->card_capabilities->emu_model)
55
*den = emu->emu1010.word_clock;
56
else
57
*den = 48000;
58
return 0;
59
}
60
61
static const struct snd_timer_hardware snd_emu10k1_timer_hw = {
62
.flags = SNDRV_TIMER_HW_AUTO,
63
.ticks = 1024,
64
.start = snd_emu10k1_timer_start,
65
.stop = snd_emu10k1_timer_stop,
66
.c_resolution = snd_emu10k1_timer_c_resolution,
67
.precise_resolution = snd_emu10k1_timer_precise_resolution,
68
};
69
70
int snd_emu10k1_timer(struct snd_emu10k1 *emu, int device)
71
{
72
struct snd_timer *timer = NULL;
73
struct snd_timer_id tid;
74
int err;
75
76
tid.dev_class = SNDRV_TIMER_CLASS_CARD;
77
tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
78
tid.card = emu->card->number;
79
tid.device = device;
80
tid.subdevice = 0;
81
err = snd_timer_new(emu->card, "EMU10K1", &tid, &timer);
82
if (err >= 0) {
83
strscpy(timer->name, "EMU10K1 timer");
84
timer->private_data = emu;
85
timer->hw = snd_emu10k1_timer_hw;
86
}
87
emu->timer = timer;
88
return err;
89
}
90
91