0001
0002
0003
0004
0005
0006
0007 #include "opl4_local.h"
0008 #include <sound/control.h>
0009
0010 static int snd_opl4_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
0011 {
0012 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0013 uinfo->count = 2;
0014 uinfo->value.integer.min = 0;
0015 uinfo->value.integer.max = 7;
0016 return 0;
0017 }
0018
0019 static int snd_opl4_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0020 {
0021 struct snd_opl4 *opl4 = snd_kcontrol_chip(kcontrol);
0022 unsigned long flags;
0023 u8 reg = kcontrol->private_value;
0024 u8 value;
0025
0026 spin_lock_irqsave(&opl4->reg_lock, flags);
0027 value = snd_opl4_read(opl4, reg);
0028 spin_unlock_irqrestore(&opl4->reg_lock, flags);
0029 ucontrol->value.integer.value[0] = 7 - (value & 7);
0030 ucontrol->value.integer.value[1] = 7 - ((value >> 3) & 7);
0031 return 0;
0032 }
0033
0034 static int snd_opl4_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0035 {
0036 struct snd_opl4 *opl4 = snd_kcontrol_chip(kcontrol);
0037 unsigned long flags;
0038 u8 reg = kcontrol->private_value;
0039 u8 value, old_value;
0040
0041 value = (7 - (ucontrol->value.integer.value[0] & 7)) |
0042 ((7 - (ucontrol->value.integer.value[1] & 7)) << 3);
0043 spin_lock_irqsave(&opl4->reg_lock, flags);
0044 old_value = snd_opl4_read(opl4, reg);
0045 snd_opl4_write(opl4, reg, value);
0046 spin_unlock_irqrestore(&opl4->reg_lock, flags);
0047 return value != old_value;
0048 }
0049
0050 static const struct snd_kcontrol_new snd_opl4_controls[] = {
0051 {
0052 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0053 .name = "FM Playback Volume",
0054 .info = snd_opl4_ctl_info,
0055 .get = snd_opl4_ctl_get,
0056 .put = snd_opl4_ctl_put,
0057 .private_value = OPL4_REG_MIX_CONTROL_FM
0058 },
0059 {
0060 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0061 .name = "Wavetable Playback Volume",
0062 .info = snd_opl4_ctl_info,
0063 .get = snd_opl4_ctl_get,
0064 .put = snd_opl4_ctl_put,
0065 .private_value = OPL4_REG_MIX_CONTROL_PCM
0066 }
0067 };
0068
0069 int snd_opl4_create_mixer(struct snd_opl4 *opl4)
0070 {
0071 struct snd_card *card = opl4->card;
0072 int i, err;
0073
0074 strcat(card->mixername, ",OPL4");
0075
0076 for (i = 0; i < 2; ++i) {
0077 err = snd_ctl_add(card, snd_ctl_new1(&snd_opl4_controls[i], opl4));
0078 if (err < 0)
0079 return err;
0080 }
0081 return 0;
0082 }