Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * OPL4 mixer functions
0004  * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
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 }