2
* This software module makes it possible to use Open Sound System for Linux
3
* (the _professional_ version) as a low level driver source for ALSA.
5
* Copyright (C) 2004 Hannu Savolainen (hannu@voimakentta.net).
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License.
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
19
* !!!!!!!!!!!!!!!!!!!! Important !!!!!!!!!!!!!!!!!!
21
* If this file doesn't compile, you must not try to resolve the problem
22
* without perfect understanding of internals of Linux kernel, ALSA and
25
* Instead you need to check that you are using the version of this file
26
* that matches the versions of ALSA, OSS and Linux you are currently using.
31
MODULE_AUTHOR ("Hannu Savolainen <hannu@opensound.com>");
32
MODULE_LICENSE ("GPL v2");
33
MODULE_DESCRIPTION ("OSS mixer low level driver interface for ALSA");
46
if (*s >= 'A' && *s <= 'Z')
54
get_mixer_info (snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
59
dev = ext.dev = kcontrol->private_value >> 16;
60
ix = ext.ctrl = kcontrol->private_value & 0xffff;;
62
oss_mixer_ext (dev, OSS_DEV_MIXER, SNDCTL_MIX_EXTINFO, (caddr_t) & ext);
66
case MIXT_STEREOSLIDER:
68
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
70
uinfo->value.integer.min = ext.minvalue;
71
uinfo->value.integer.max = ext.maxvalue;
77
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
79
uinfo->value.integer.min = ext.minvalue;
80
uinfo->value.integer.max = ext.maxvalue;
85
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
87
uinfo->value.integer.min = 0;
88
uinfo->value.integer.max = 1;
93
static const char *texts[] = {
94
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
95
"10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
96
"20", "21", "22", "23", "24", "25", "26", "27", "28", "29",
99
oss_mixer_enuminfo enumdef;
100
uinfo->value.enumerated.items = ext.maxvalue;
102
if (uinfo->value.enumerated.item < 0)
103
uinfo->value.enumerated.item = 0;
104
if (uinfo->value.enumerated.item >= ext.maxvalue)
105
uinfo->value.enumerated.item = ext.maxvalue - 1;
106
if (uinfo->value.enumerated.item > 31)
107
uinfo->value.enumerated.item = 31;
108
strcpy (uinfo->value.enumerated.name,
109
texts[uinfo->value.enumerated.item]);
111
enumdef.dev = ext.dev;
112
enumdef.ctrl = ext.ctrl;
114
(dev, OSS_DEV_MIXER, SNDCTL_MIX_ENUMINFO,
115
(caddr_t) & enumdef) >= 0)
120
&enumdef.strings[enumdef.
121
strindex[uinfo->value.enumerated.item]];
122
strcpy (uinfo->value.enumerated.name, text);
125
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
127
uinfo->value.enumerated.items = ext.maxvalue;
132
printk ("cuckoo: mixer_info(%d/%d) - unknown type %d\n", dev, ix,
134
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
136
uinfo->value.integer.min = ext.minvalue;
137
uinfo->value.integer.max = ext.maxvalue;
145
mixer_get (snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
151
dev = ext.dev = kcontrol->private_value >> 16;
152
ix = ext.ctrl = kcontrol->private_value & 0xffff;;
154
oss_mixer_ext (dev, OSS_DEV_MIXER, SNDCTL_MIX_EXTINFO,
155
(caddr_t) & ext)) < 0)
160
val.timestamp = ext.timestamp;
162
oss_mixer_ext (dev, OSS_DEV_MIXER, SNDCTL_MIX_READ,
163
(caddr_t) & val)) < 0)
169
case MIXT_STEREOSLIDER:
170
ucontrol->value.integer.value[0] = val.value & 0xff; // Left
171
ucontrol->value.integer.value[1] = (val.value >> 8) & 0xff; // Right
174
case MIXT_MONOSLIDER:
177
ucontrol->value.integer.value[0] = val.value & 0xff;
182
ucontrol->value.integer.value[0] = !!val.value;
186
ucontrol->value.integer.value[0] = val.value;
190
printk ("cuckoo: mixer_get(%d/%d) - unknown type %d\n", dev, ix,
192
ucontrol->value.integer.value[0] = val.value & 0xff;
200
mixer_put (snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
206
dev = ext.dev = kcontrol->private_value >> 16;
207
ix = ext.ctrl = kcontrol->private_value & 0xffff;;
209
oss_mixer_ext (dev, OSS_DEV_MIXER, SNDCTL_MIX_EXTINFO,
210
(caddr_t) & ext)) < 0)
215
val.timestamp = ext.timestamp;
219
case MIXT_STEREOSLIDER:
220
val.value = ucontrol->value.integer.value[0] | // Left
221
ucontrol->value.integer.value[1] << 8; // Right
223
oss_mixer_ext (dev, OSS_DEV_MIXER, SNDCTL_MIX_WRITE,
224
(caddr_t) & val)) < 0)
228
case MIXT_MONOSLIDER:
230
val.value = ucontrol->value.integer.value[0];
232
oss_mixer_ext (dev, OSS_DEV_MIXER, SNDCTL_MIX_WRITE,
233
(caddr_t) & val)) < 0)
239
val.value = !!ucontrol->value.integer.value[0];
241
oss_mixer_ext (dev, OSS_DEV_MIXER, SNDCTL_MIX_WRITE,
242
(caddr_t) & val)) < 0)
247
val.value = ucontrol->value.integer.value[0];
249
oss_mixer_ext (dev, OSS_DEV_MIXER, SNDCTL_MIX_WRITE,
250
(caddr_t) & val)) < 0)
259
printk ("cuckoo: mixer_put(%d/%d) - unknown type %d\n", dev, ix,
261
val.value = ucontrol->value.integer.value[0];
263
oss_mixer_ext (dev, OSS_DEV_MIXER, SNDCTL_MIX_WRITE,
264
(caddr_t) & val)) < 0)
272
add_control (cuckoo_t * chip, int dev, int ix, oss_mixext * ext, char *name)
275
snd_kcontrol_new_t my_control;
277
// Upshift the name if it's an single part one
280
for (i = 0; i < strlen (name); i++)
284
for (i = 0; i < strlen (name); i++)
285
if (name[i] >= 'a' && name[i] <= 'z')
290
memset (&my_control, 0, sizeof (my_control));
292
my_control.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
293
my_control.name = name;
294
my_control.index = 0;
295
my_control.access = 0;
297
if (ext->flags & MIXF_READABLE)
298
my_control.access |= SNDRV_CTL_ELEM_ACCESS_READ;
299
if (ext->flags & MIXF_WRITEABLE)
300
my_control.access |= SNDRV_CTL_ELEM_ACCESS_WRITE;
301
if ((ext->flags & 0x3) == MIXF_READABLE) /* Read only */
302
my_control.access |= SNDRV_CTL_ELEM_ACCESS_VOLATILE;
304
my_control.private_value = (dev << 16) | ix;
305
my_control.info = get_mixer_info;
306
my_control.get = mixer_get;
307
my_control.put = mixer_put;
314
case MIXT_STEREOSLIDER:
316
case MIXT_MONOSLIDER:
320
snd_ctl_add (chip->card, snd_ctl_new1 (&my_control, chip))) < 0)
322
printk ("cuckoo: snd_ctl_add(%s) failed, err=%d\n", ext->extname,
331
install_mixer_instances (cuckoo_t * chip, int cardno)
334
mixer_operations_t **cuckoo_mixer_devs = mixer_devs_p;
336
for (dev = 0; dev < num_mixers; dev++)
337
if (cuckoo_mixer_devs[dev]->card_number == cardno)
344
oss_mixer_ext (dev, OSS_DEV_MIXER, SNDCTL_MIX_NREXT,
345
(ioctl_arg) & nrext);
350
sz = nrext * (sizeof (char *) + 32); // 32 characters / name (average)
352
for (i = 0; i < nrext; i++)
356
oss_mixext_root *root = NULL;
360
oss_mixer_ext (dev, OSS_DEV_MIXER, SNDCTL_MIX_EXTINFO,
366
root = (oss_mixext_root *) & ext.data;
377
add_control (chip, dev, i, &ext, ext.extname);
389
EXPORT_SYMBOL (install_mixer_instances);