3 * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "opl4_local.h"
21 #include <sound/control.h>
23 static int snd_opl4_ctl_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
25 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
27 uinfo
->value
.integer
.min
= 0;
28 uinfo
->value
.integer
.max
= 7;
32 static int snd_opl4_ctl_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
34 struct snd_opl4
*opl4
= snd_kcontrol_chip(kcontrol
);
36 u8 reg
= kcontrol
->private_value
;
39 spin_lock_irqsave(&opl4
->reg_lock
, flags
);
40 value
= snd_opl4_read(opl4
, reg
);
41 spin_unlock_irqrestore(&opl4
->reg_lock
, flags
);
42 ucontrol
->value
.integer
.value
[0] = 7 - (value
& 7);
43 ucontrol
->value
.integer
.value
[1] = 7 - ((value
>> 3) & 7);
47 static int snd_opl4_ctl_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
49 struct snd_opl4
*opl4
= snd_kcontrol_chip(kcontrol
);
51 u8 reg
= kcontrol
->private_value
;
54 value
= (7 - (ucontrol
->value
.integer
.value
[0] & 7)) |
55 ((7 - (ucontrol
->value
.integer
.value
[1] & 7)) << 3);
56 spin_lock_irqsave(&opl4
->reg_lock
, flags
);
57 old_value
= snd_opl4_read(opl4
, reg
);
58 snd_opl4_write(opl4
, reg
, value
);
59 spin_unlock_irqrestore(&opl4
->reg_lock
, flags
);
60 return value
!= old_value
;
63 static struct snd_kcontrol_new snd_opl4_controls
[] = {
65 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
66 .name
= "FM Playback Volume",
67 .info
= snd_opl4_ctl_info
,
68 .get
= snd_opl4_ctl_get
,
69 .put
= snd_opl4_ctl_put
,
70 .private_value
= OPL4_REG_MIX_CONTROL_FM
73 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
74 .name
= "Wavetable Playback Volume",
75 .info
= snd_opl4_ctl_info
,
76 .get
= snd_opl4_ctl_get
,
77 .put
= snd_opl4_ctl_put
,
78 .private_value
= OPL4_REG_MIX_CONTROL_PCM
82 int snd_opl4_create_mixer(struct snd_opl4
*opl4
)
84 struct snd_card
*card
= opl4
->card
;
87 strcat(card
->mixername
, ",OPL4");
89 for (i
= 0; i
< 2; ++i
) {
90 err
= snd_ctl_add(card
, snd_ctl_new1(&snd_opl4_controls
[i
], opl4
));