11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds * OPL4 mixer functions
41da177e4SLinus Torvalds * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
51da177e4SLinus Torvalds */
61da177e4SLinus Torvalds
71da177e4SLinus Torvalds #include "opl4_local.h"
81da177e4SLinus Torvalds #include <sound/control.h>
91da177e4SLinus Torvalds
snd_opl4_ctl_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)10a42dd420STakashi Iwai static int snd_opl4_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
111da177e4SLinus Torvalds {
121da177e4SLinus Torvalds uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
131da177e4SLinus Torvalds uinfo->count = 2;
141da177e4SLinus Torvalds uinfo->value.integer.min = 0;
151da177e4SLinus Torvalds uinfo->value.integer.max = 7;
161da177e4SLinus Torvalds return 0;
171da177e4SLinus Torvalds }
181da177e4SLinus Torvalds
snd_opl4_ctl_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)19a42dd420STakashi Iwai static int snd_opl4_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
201da177e4SLinus Torvalds {
21a42dd420STakashi Iwai struct snd_opl4 *opl4 = snd_kcontrol_chip(kcontrol);
221da177e4SLinus Torvalds unsigned long flags;
231da177e4SLinus Torvalds u8 reg = kcontrol->private_value;
241da177e4SLinus Torvalds u8 value;
251da177e4SLinus Torvalds
261da177e4SLinus Torvalds spin_lock_irqsave(&opl4->reg_lock, flags);
271da177e4SLinus Torvalds value = snd_opl4_read(opl4, reg);
281da177e4SLinus Torvalds spin_unlock_irqrestore(&opl4->reg_lock, flags);
291da177e4SLinus Torvalds ucontrol->value.integer.value[0] = 7 - (value & 7);
301da177e4SLinus Torvalds ucontrol->value.integer.value[1] = 7 - ((value >> 3) & 7);
311da177e4SLinus Torvalds return 0;
321da177e4SLinus Torvalds }
331da177e4SLinus Torvalds
snd_opl4_ctl_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)34a42dd420STakashi Iwai static int snd_opl4_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
351da177e4SLinus Torvalds {
36a42dd420STakashi Iwai struct snd_opl4 *opl4 = snd_kcontrol_chip(kcontrol);
371da177e4SLinus Torvalds unsigned long flags;
381da177e4SLinus Torvalds u8 reg = kcontrol->private_value;
391da177e4SLinus Torvalds u8 value, old_value;
401da177e4SLinus Torvalds
411da177e4SLinus Torvalds value = (7 - (ucontrol->value.integer.value[0] & 7)) |
421da177e4SLinus Torvalds ((7 - (ucontrol->value.integer.value[1] & 7)) << 3);
431da177e4SLinus Torvalds spin_lock_irqsave(&opl4->reg_lock, flags);
441da177e4SLinus Torvalds old_value = snd_opl4_read(opl4, reg);
451da177e4SLinus Torvalds snd_opl4_write(opl4, reg, value);
461da177e4SLinus Torvalds spin_unlock_irqrestore(&opl4->reg_lock, flags);
471da177e4SLinus Torvalds return value != old_value;
481da177e4SLinus Torvalds }
491da177e4SLinus Torvalds
50*2eccd408STakashi Iwai static const struct snd_kcontrol_new snd_opl4_controls[] = {
511da177e4SLinus Torvalds {
521da177e4SLinus Torvalds .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
531da177e4SLinus Torvalds .name = "FM Playback Volume",
541da177e4SLinus Torvalds .info = snd_opl4_ctl_info,
551da177e4SLinus Torvalds .get = snd_opl4_ctl_get,
561da177e4SLinus Torvalds .put = snd_opl4_ctl_put,
571da177e4SLinus Torvalds .private_value = OPL4_REG_MIX_CONTROL_FM
581da177e4SLinus Torvalds },
591da177e4SLinus Torvalds {
601da177e4SLinus Torvalds .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
611da177e4SLinus Torvalds .name = "Wavetable Playback Volume",
621da177e4SLinus Torvalds .info = snd_opl4_ctl_info,
631da177e4SLinus Torvalds .get = snd_opl4_ctl_get,
641da177e4SLinus Torvalds .put = snd_opl4_ctl_put,
651da177e4SLinus Torvalds .private_value = OPL4_REG_MIX_CONTROL_PCM
661da177e4SLinus Torvalds }
671da177e4SLinus Torvalds };
681da177e4SLinus Torvalds
snd_opl4_create_mixer(struct snd_opl4 * opl4)69a42dd420STakashi Iwai int snd_opl4_create_mixer(struct snd_opl4 *opl4)
701da177e4SLinus Torvalds {
71a42dd420STakashi Iwai struct snd_card *card = opl4->card;
721da177e4SLinus Torvalds int i, err;
731da177e4SLinus Torvalds
741da177e4SLinus Torvalds strcat(card->mixername, ",OPL4");
751da177e4SLinus Torvalds
761da177e4SLinus Torvalds for (i = 0; i < 2; ++i) {
771da177e4SLinus Torvalds err = snd_ctl_add(card, snd_ctl_new1(&snd_opl4_controls[i], opl4));
781da177e4SLinus Torvalds if (err < 0)
791da177e4SLinus Torvalds return err;
801da177e4SLinus Torvalds }
811da177e4SLinus Torvalds return 0;
821da177e4SLinus Torvalds }
83