Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/sound/drivers/pcsp/pcsp_mixer.c
10817 views
1
/*
2
* PC-Speaker driver for Linux
3
*
4
* Mixer implementation.
5
* Copyright (C) 2001-2008 Stas Sergeev
6
*/
7
8
#include <sound/core.h>
9
#include <sound/control.h>
10
#include "pcsp.h"
11
12
13
static int pcsp_enable_info(struct snd_kcontrol *kcontrol,
14
struct snd_ctl_elem_info *uinfo)
15
{
16
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
17
uinfo->count = 1;
18
uinfo->value.integer.min = 0;
19
uinfo->value.integer.max = 1;
20
return 0;
21
}
22
23
static int pcsp_enable_get(struct snd_kcontrol *kcontrol,
24
struct snd_ctl_elem_value *ucontrol)
25
{
26
struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
27
ucontrol->value.integer.value[0] = chip->enable;
28
return 0;
29
}
30
31
static int pcsp_enable_put(struct snd_kcontrol *kcontrol,
32
struct snd_ctl_elem_value *ucontrol)
33
{
34
struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
35
int changed = 0;
36
int enab = ucontrol->value.integer.value[0];
37
if (enab != chip->enable) {
38
chip->enable = enab;
39
changed = 1;
40
}
41
return changed;
42
}
43
44
static int pcsp_treble_info(struct snd_kcontrol *kcontrol,
45
struct snd_ctl_elem_info *uinfo)
46
{
47
struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
48
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
49
uinfo->count = 1;
50
uinfo->value.enumerated.items = chip->max_treble + 1;
51
if (uinfo->value.enumerated.item > chip->max_treble)
52
uinfo->value.enumerated.item = chip->max_treble;
53
sprintf(uinfo->value.enumerated.name, "%lu",
54
(unsigned long)PCSP_CALC_RATE(uinfo->value.enumerated.item));
55
return 0;
56
}
57
58
static int pcsp_treble_get(struct snd_kcontrol *kcontrol,
59
struct snd_ctl_elem_value *ucontrol)
60
{
61
struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
62
ucontrol->value.enumerated.item[0] = chip->treble;
63
return 0;
64
}
65
66
static int pcsp_treble_put(struct snd_kcontrol *kcontrol,
67
struct snd_ctl_elem_value *ucontrol)
68
{
69
struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
70
int changed = 0;
71
int treble = ucontrol->value.enumerated.item[0];
72
if (treble != chip->treble) {
73
chip->treble = treble;
74
#if PCSP_DEBUG
75
printk(KERN_INFO "PCSP: rate set to %li\n", PCSP_RATE());
76
#endif
77
changed = 1;
78
}
79
return changed;
80
}
81
82
static int pcsp_pcspkr_info(struct snd_kcontrol *kcontrol,
83
struct snd_ctl_elem_info *uinfo)
84
{
85
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
86
uinfo->count = 1;
87
uinfo->value.integer.min = 0;
88
uinfo->value.integer.max = 1;
89
return 0;
90
}
91
92
static int pcsp_pcspkr_get(struct snd_kcontrol *kcontrol,
93
struct snd_ctl_elem_value *ucontrol)
94
{
95
struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
96
ucontrol->value.integer.value[0] = chip->pcspkr;
97
return 0;
98
}
99
100
static int pcsp_pcspkr_put(struct snd_kcontrol *kcontrol,
101
struct snd_ctl_elem_value *ucontrol)
102
{
103
struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
104
int changed = 0;
105
int spkr = ucontrol->value.integer.value[0];
106
if (spkr != chip->pcspkr) {
107
chip->pcspkr = spkr;
108
changed = 1;
109
}
110
return changed;
111
}
112
113
#define PCSP_MIXER_CONTROL(ctl_type, ctl_name) \
114
{ \
115
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
116
.name = ctl_name, \
117
.info = pcsp_##ctl_type##_info, \
118
.get = pcsp_##ctl_type##_get, \
119
.put = pcsp_##ctl_type##_put, \
120
}
121
122
static struct snd_kcontrol_new __devinitdata snd_pcsp_controls_pcm[] = {
123
PCSP_MIXER_CONTROL(enable, "Master Playback Switch"),
124
PCSP_MIXER_CONTROL(treble, "BaseFRQ Playback Volume"),
125
};
126
127
static struct snd_kcontrol_new __devinitdata snd_pcsp_controls_spkr[] = {
128
PCSP_MIXER_CONTROL(pcspkr, "Beep Playback Switch"),
129
};
130
131
static int __devinit snd_pcsp_ctls_add(struct snd_pcsp *chip,
132
struct snd_kcontrol_new *ctls, int num)
133
{
134
int i, err;
135
struct snd_card *card = chip->card;
136
for (i = 0; i < num; i++) {
137
err = snd_ctl_add(card, snd_ctl_new1(ctls + i, chip));
138
if (err < 0)
139
return err;
140
}
141
return 0;
142
}
143
144
int __devinit snd_pcsp_new_mixer(struct snd_pcsp *chip, int nopcm)
145
{
146
int err;
147
struct snd_card *card = chip->card;
148
149
if (!nopcm) {
150
err = snd_pcsp_ctls_add(chip, snd_pcsp_controls_pcm,
151
ARRAY_SIZE(snd_pcsp_controls_pcm));
152
if (err < 0)
153
return err;
154
}
155
err = snd_pcsp_ctls_add(chip, snd_pcsp_controls_spkr,
156
ARRAY_SIZE(snd_pcsp_controls_spkr));
157
if (err < 0)
158
return err;
159
160
strcpy(card->mixername, "PC-Speaker");
161
162
return 0;
163
}
164
165