linux/sound/pci/lola/lola_mixer.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  Support for Digigram Lola PCI-e boards
 *
 *  Copyright (c) 2011 Takashi Iwai <[email protected]>
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/vmalloc.h>
#include <linux/io.h>
#include <sound/core.h>
#include <sound/control.h>
#include <sound/pcm.h>
#include <sound/tlv.h>
#include "lola.h"

static int lola_init_pin(struct lola *chip, struct lola_pin *pin,
			 int dir, int nid)
{}

int lola_init_pins(struct lola *chip, int dir, int *nidp)
{}

void lola_free_mixer(struct lola *chip)
{}

int lola_init_mixer_widget(struct lola *chip, int nid)
{}

static int lola_mixer_set_src_gain(struct lola *chip, unsigned int id,
				   unsigned short gain, bool on)
{}

#if 0 /* not used */
static int lola_mixer_set_src_gains(struct lola *chip, unsigned int mask,
				    unsigned short *gains)
{
	int i;

	if ((chip->mixer.src_mask & mask) != mask)
		return -EINVAL;
	for (i = 0; i < LOLA_MIXER_DIM; i++) {
		if (mask & (1 << i)) {
			writew(*gains, &chip->mixer.array->src_gain[i]);
			gains++;
		}
	}
	writel(mask, &chip->mixer.array->src_gain_enable);
	lola_codec_flush(chip);
	if (chip->mixer.caps & LOLA_PEAK_METER_CAN_AGC_MASK) {
		/* update for all srcs at once */
		return lola_codec_write(chip, chip->mixer.nid,
					LOLA_VERB_SET_SOURCE_GAIN, 0x80, 0);
	}
	/* update manually */
	for (i = 0; i < LOLA_MIXER_DIM; i++) {
		if (mask & (1 << i)) {
			lola_codec_write(chip, chip->mixer.nid,
					 LOLA_VERB_SET_SOURCE_GAIN, i, 0);
		}
	}
	return 0;
}
#endif /* not used */

static int lola_mixer_set_mapping_gain(struct lola *chip,
				       unsigned int src, unsigned int dest,
				       unsigned short gain, bool on)
{}

#if 0 /* not used */
static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
				     unsigned int mask, unsigned short *gains)
{
	int i;

	if (!(chip->mixer.dest_mask & (1 << id)) ||
	    (chip->mixer.src_mask & mask) != mask)
		return -EINVAL;
	for (i = 0; i < LOLA_MIXER_DIM; i++) {
		if (mask & (1 << i)) {
			writew(*gains, &chip->mixer.array->dest_mix_gain[id][i]);
			gains++;
		}
	}
	writel(mask, &chip->mixer.array->dest_mix_gain_enable[id]);
	lola_codec_flush(chip);
	/* update for all dests at once */
	return lola_codec_write(chip, chip->mixer.nid,
				LOLA_VERB_SET_DESTINATION_GAIN, id, 0);
}
#endif /* not used */

/*
 */

static int set_analog_volume(struct lola *chip, int dir,
			     unsigned int idx, unsigned int val,
			     bool external_call);

int lola_setup_all_analog_gains(struct lola *chip, int dir, bool mute)
{}

void lola_save_mixer(struct lola *chip)
{}

void lola_restore_mixer(struct lola *chip)
{}

/*
 */

static int set_analog_volume(struct lola *chip, int dir,
			     unsigned int idx, unsigned int val,
			     bool external_call)
{}

int lola_set_src_config(struct lola *chip, unsigned int src_mask, bool update)
{}

/*
 */
static int init_mixer_values(struct lola *chip)
{}

/*
 * analog mixer control element
 */
static int lola_analog_vol_info(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_info *uinfo)
{}

static int lola_analog_vol_get(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *ucontrol)
{}

static int lola_analog_vol_put(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *ucontrol)
{}

static int lola_analog_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
			       unsigned int size, unsigned int __user *tlv)
{}

static struct snd_kcontrol_new lola_analog_mixer =;

static int create_analog_mixer(struct lola *chip, int dir, char *name)
{}

/*
 * Hardware sample rate converter on digital input
 */
static int lola_input_src_info(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_info *uinfo)
{}

static int lola_input_src_get(struct snd_kcontrol *kcontrol,
			      struct snd_ctl_elem_value *ucontrol)
{}

static int lola_input_src_put(struct snd_kcontrol *kcontrol,
			      struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new lola_input_src_mixer =;

/*
 * Lola16161 or Lola881 can have Hardware sample rate converters
 * on its digital input pins
 */
static int create_input_src_mixer(struct lola *chip)
{}

/*
 * src gain mixer
 */
static int lola_src_gain_info(struct snd_kcontrol *kcontrol,
			      struct snd_ctl_elem_info *uinfo)
{}

static int lola_src_gain_get(struct snd_kcontrol *kcontrol,
			     struct snd_ctl_elem_value *ucontrol)
{}

static int lola_src_gain_put(struct snd_kcontrol *kcontrol,
			     struct snd_ctl_elem_value *ucontrol)
{}

/* raw value: 0 = -84dB, 336 = 0dB, 408=18dB, incremented 1 for mute */
static const DECLARE_TLV_DB_SCALE(lola_src_gain_tlv, -8425, 25, 1);

static struct snd_kcontrol_new lola_src_gain_mixer =;

static int create_src_gain_mixer(struct lola *chip,
				 int num, int ofs, char *name)
{}

#if 0 /* not used */
/*
 * destination gain (matrix-like) mixer
 */
static int lola_dest_gain_info(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_info *uinfo)
{
	unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;

	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = src_num;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = 433;
	return 0;
}

static int lola_dest_gain_get(struct snd_kcontrol *kcontrol,
			      struct snd_ctl_elem_value *ucontrol)
{
	struct lola *chip = snd_kcontrol_chip(kcontrol);
	unsigned int src_ofs = kcontrol->private_value & 0xff;
	unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
	unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff;
	unsigned int dst, mask, i;

	dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs;
	mask = readl(&chip->mixer.array->dest_mix_gain_enable[dst]);
	for (i = 0; i < src_num; i++) {
		unsigned int src = src_ofs + i;
		unsigned short val;
		if (!(chip->mixer.src_mask & (1 << src)))
			return -EINVAL;
		if (mask & (1 << dst))
			val = readw(&chip->mixer.array->dest_mix_gain[dst][src]) + 1;
		else
			val = 0;
		ucontrol->value.integer.value[i] = val;
	}
	return 0;
}

static int lola_dest_gain_put(struct snd_kcontrol *kcontrol,
			      struct snd_ctl_elem_value *ucontrol)
{
	struct lola *chip = snd_kcontrol_chip(kcontrol);
	unsigned int src_ofs = kcontrol->private_value & 0xff;
	unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
	unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff;
	unsigned int dst, mask;
	unsigned short gains[MAX_STREAM_COUNT];
	int i, num;

	mask = 0;
	num = 0;
	for (i = 0; i < src_num; i++) {
		unsigned short val = ucontrol->value.integer.value[i];
		if (val) {
			gains[num++] = val - 1;
			mask |= 1 << i;
		}
	}
	mask <<= src_ofs;
	dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs;
	return lola_mixer_set_dest_gains(chip, dst, mask, gains);
}

static const DECLARE_TLV_DB_SCALE(lola_dest_gain_tlv, -8425, 25, 1);

static struct snd_kcontrol_new lola_dest_gain_mixer = {
	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
		   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
	.info = lola_dest_gain_info,
	.get = lola_dest_gain_get,
	.put = lola_dest_gain_put,
	.tlv.p = lola_dest_gain_tlv,
};

static int create_dest_gain_mixer(struct lola *chip,
				  int src_num, int src_ofs,
				  int num, int ofs, char *name)
{
	lola_dest_gain_mixer.count = num;
	lola_dest_gain_mixer.name = name;
	lola_dest_gain_mixer.private_value =
		src_ofs + (src_num << 8) + (ofs << 16) + (num << 24);
	return snd_ctl_add(chip->card,
			  snd_ctl_new1(&lola_dest_gain_mixer, chip));
}
#endif /* not used */

/*
 */
int lola_create_mixer(struct lola *chip)
{}