cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

opl4_mixer.c (2203B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * OPL4 mixer functions
      4 * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
      5 */
      6
      7#include "opl4_local.h"
      8#include <sound/control.h>
      9
     10static int snd_opl4_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
     11{
     12	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
     13	uinfo->count = 2;
     14	uinfo->value.integer.min = 0;
     15	uinfo->value.integer.max = 7;
     16	return 0;
     17}
     18
     19static int snd_opl4_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
     20{
     21	struct snd_opl4 *opl4 = snd_kcontrol_chip(kcontrol);
     22	unsigned long flags;
     23	u8 reg = kcontrol->private_value;
     24	u8 value;
     25
     26	spin_lock_irqsave(&opl4->reg_lock, flags);
     27	value = snd_opl4_read(opl4, reg);
     28	spin_unlock_irqrestore(&opl4->reg_lock, flags);
     29	ucontrol->value.integer.value[0] = 7 - (value & 7);
     30	ucontrol->value.integer.value[1] = 7 - ((value >> 3) & 7);
     31	return 0;
     32}
     33
     34static int snd_opl4_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
     35{
     36	struct snd_opl4 *opl4 = snd_kcontrol_chip(kcontrol);
     37	unsigned long flags;
     38	u8 reg = kcontrol->private_value;
     39	u8 value, old_value;
     40
     41	value = (7 - (ucontrol->value.integer.value[0] & 7)) |
     42		((7 - (ucontrol->value.integer.value[1] & 7)) << 3);
     43	spin_lock_irqsave(&opl4->reg_lock, flags);
     44	old_value = snd_opl4_read(opl4, reg);
     45	snd_opl4_write(opl4, reg, value);
     46	spin_unlock_irqrestore(&opl4->reg_lock, flags);
     47	return value != old_value;
     48}
     49
     50static const struct snd_kcontrol_new snd_opl4_controls[] = {
     51	{
     52		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
     53		.name = "FM Playback Volume",
     54		.info = snd_opl4_ctl_info,
     55		.get = snd_opl4_ctl_get,
     56		.put = snd_opl4_ctl_put,
     57		.private_value = OPL4_REG_MIX_CONTROL_FM
     58	},
     59	{
     60		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
     61		.name = "Wavetable Playback Volume",
     62		.info = snd_opl4_ctl_info,
     63		.get = snd_opl4_ctl_get,
     64		.put = snd_opl4_ctl_put,
     65		.private_value = OPL4_REG_MIX_CONTROL_PCM
     66	}
     67};
     68
     69int snd_opl4_create_mixer(struct snd_opl4 *opl4)
     70{
     71	struct snd_card *card = opl4->card;
     72	int i, err;
     73
     74	strcat(card->mixername, ",OPL4");
     75
     76	for (i = 0; i < 2; ++i) {
     77		err = snd_ctl_add(card, snd_ctl_new1(&snd_opl4_controls[i], opl4));
     78		if (err < 0)
     79			return err;
     80	}
     81	return 0;
     82}