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

pcsp_mixer.c (4130B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * PC-Speaker driver for Linux
      4 *
      5 * Mixer implementation.
      6 * Copyright (C) 2001-2008  Stas Sergeev
      7 */
      8
      9#include <sound/core.h>
     10#include <sound/control.h>
     11#include "pcsp.h"
     12
     13
     14static int pcsp_enable_info(struct snd_kcontrol *kcontrol,
     15			    struct snd_ctl_elem_info *uinfo)
     16{
     17	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
     18	uinfo->count = 1;
     19	uinfo->value.integer.min = 0;
     20	uinfo->value.integer.max = 1;
     21	return 0;
     22}
     23
     24static int pcsp_enable_get(struct snd_kcontrol *kcontrol,
     25			   struct snd_ctl_elem_value *ucontrol)
     26{
     27	struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
     28	ucontrol->value.integer.value[0] = chip->enable;
     29	return 0;
     30}
     31
     32static int pcsp_enable_put(struct snd_kcontrol *kcontrol,
     33			   struct snd_ctl_elem_value *ucontrol)
     34{
     35	struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
     36	int changed = 0;
     37	int enab = ucontrol->value.integer.value[0];
     38	if (enab != chip->enable) {
     39		chip->enable = enab;
     40		changed = 1;
     41	}
     42	return changed;
     43}
     44
     45static int pcsp_treble_info(struct snd_kcontrol *kcontrol,
     46			    struct snd_ctl_elem_info *uinfo)
     47{
     48	struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
     49	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
     50	uinfo->count = 1;
     51	uinfo->value.enumerated.items = chip->max_treble + 1;
     52	if (uinfo->value.enumerated.item > chip->max_treble)
     53		uinfo->value.enumerated.item = chip->max_treble;
     54	sprintf(uinfo->value.enumerated.name, "%lu",
     55		(unsigned long)PCSP_CALC_RATE(uinfo->value.enumerated.item));
     56	return 0;
     57}
     58
     59static int pcsp_treble_get(struct snd_kcontrol *kcontrol,
     60			   struct snd_ctl_elem_value *ucontrol)
     61{
     62	struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
     63	ucontrol->value.enumerated.item[0] = chip->treble;
     64	return 0;
     65}
     66
     67static int pcsp_treble_put(struct snd_kcontrol *kcontrol,
     68			   struct snd_ctl_elem_value *ucontrol)
     69{
     70	struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
     71	int changed = 0;
     72	int treble = ucontrol->value.enumerated.item[0];
     73	if (treble != chip->treble) {
     74		chip->treble = treble;
     75#if PCSP_DEBUG
     76		printk(KERN_INFO "PCSP: rate set to %li\n", PCSP_RATE());
     77#endif
     78		changed = 1;
     79	}
     80	return changed;
     81}
     82
     83static int pcsp_pcspkr_info(struct snd_kcontrol *kcontrol,
     84			    struct snd_ctl_elem_info *uinfo)
     85{
     86	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
     87	uinfo->count = 1;
     88	uinfo->value.integer.min = 0;
     89	uinfo->value.integer.max = 1;
     90	return 0;
     91}
     92
     93static int pcsp_pcspkr_get(struct snd_kcontrol *kcontrol,
     94			   struct snd_ctl_elem_value *ucontrol)
     95{
     96	struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
     97	ucontrol->value.integer.value[0] = chip->pcspkr;
     98	return 0;
     99}
    100
    101static int pcsp_pcspkr_put(struct snd_kcontrol *kcontrol,
    102			   struct snd_ctl_elem_value *ucontrol)
    103{
    104	struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
    105	int changed = 0;
    106	int spkr = ucontrol->value.integer.value[0];
    107	if (spkr != chip->pcspkr) {
    108		chip->pcspkr = spkr;
    109		changed = 1;
    110	}
    111	return changed;
    112}
    113
    114#define PCSP_MIXER_CONTROL(ctl_type, ctl_name) \
    115{ \
    116	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER, \
    117	.name =		ctl_name, \
    118	.info =		pcsp_##ctl_type##_info, \
    119	.get =		pcsp_##ctl_type##_get, \
    120	.put =		pcsp_##ctl_type##_put, \
    121}
    122
    123static const struct snd_kcontrol_new snd_pcsp_controls_pcm[] = {
    124	PCSP_MIXER_CONTROL(enable, "Master Playback Switch"),
    125	PCSP_MIXER_CONTROL(treble, "BaseFRQ Playback Volume"),
    126};
    127
    128static const struct snd_kcontrol_new snd_pcsp_controls_spkr[] = {
    129	PCSP_MIXER_CONTROL(pcspkr, "Beep Playback Switch"),
    130};
    131
    132static int snd_pcsp_ctls_add(struct snd_pcsp *chip,
    133			     const struct snd_kcontrol_new *ctls, int num)
    134{
    135	int i, err;
    136	struct snd_card *card = chip->card;
    137	for (i = 0; i < num; i++) {
    138		err = snd_ctl_add(card, snd_ctl_new1(ctls + i, chip));
    139		if (err < 0)
    140			return err;
    141	}
    142	return 0;
    143}
    144
    145int snd_pcsp_new_mixer(struct snd_pcsp *chip, int nopcm)
    146{
    147	int err;
    148	struct snd_card *card = chip->card;
    149
    150	if (!nopcm) {
    151		err = snd_pcsp_ctls_add(chip, snd_pcsp_controls_pcm,
    152			ARRAY_SIZE(snd_pcsp_controls_pcm));
    153		if (err < 0)
    154			return err;
    155	}
    156	err = snd_pcsp_ctls_add(chip, snd_pcsp_controls_spkr,
    157		ARRAY_SIZE(snd_pcsp_controls_spkr));
    158	if (err < 0)
    159		return err;
    160
    161	strcpy(card->mixername, "PC-Speaker");
    162
    163	return 0;
    164}