linux/sound/pci/emu10k1/emufx.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  Copyright (c) by Jaroslav Kysela <[email protected]>
 *                   James Courtier-Dutton <[email protected]>
 *                   Oswald Buddenhagen <[email protected]>
 *                   Creative Labs, Inc.
 *
 *  Routines for effect processor FX8010
 */

#include <linux/pci.h>
#include <linux/capability.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/init.h>
#include <linux/mutex.h>
#include <linux/moduleparam.h>
#include <linux/nospec.h>

#include <sound/core.h>
#include <sound/tlv.h>
#include <sound/emu10k1.h>

#if 0		/* for testing purposes - digital out -> capture */
#define EMU10K1_CAPTURE_DIGITAL_OUT
#endif
#if 0		/* for testing purposes - set S/PDIF to AC3 output */
#define EMU10K1_SET_AC3_IEC958
#endif
#if 0		/* for testing purposes - feed the front signal to Center/LFE outputs */
#define EMU10K1_CENTER_LFE_FROM_FRONT
#endif

static bool high_res_gpr_volume;
module_param(high_res_gpr_volume, bool, 0444);
MODULE_PARM_DESC();

/*
 *  Tables
 */ 

// Playback channel labels; corresponds with the public FXBUS_* defines.
// Unlike the tables below, this is not determined by the hardware.
const char * const snd_emu10k1_fxbus[32] =;

// Physical inputs; corresponds with the public EXTIN_* defines.
const char * const snd_emu10k1_sblive_ins[16] =;

// Physical inputs; corresponds with the public A_EXTIN_* defines.
const char * const snd_emu10k1_audigy_ins[16] =;

// Physical outputs; corresponds with the public EXTOUT_* defines.
const char * const snd_emu10k1_sblive_outs[32] =;

// Physical outputs; corresponds with the public A_EXTOUT_* defines.
const char * const snd_emu10k1_audigy_outs[32] =;

// On the SB Live! 5.1, FXBUS2[1] and FXBUS2[2] are occupied by EXTOUT_ACENTER
// and EXTOUT_ALFE, so we can't connect inputs to them for multitrack recording.
//
// Since only 14 of the 16 EXTINs are used, this is not a big problem.
// We route AC97 to FX capture 14 and 15, SPDIF_CD to FX capture 0 and 3,
// and the rest of the EXTINs to the corresponding FX capture channel.
// Multitrack recorders will still see the center/LFE output signal
// on the second and third "input" channel.
const s8 snd_emu10k1_sblive51_fxbus2_map[16] =;

static const u32 bass_table[41][5] =;

static const u32 treble_table[41][5] =;

/* dB gain = (float) 20 * log10( float(db_table_value) / 0x8000000 ) */
static const u32 db_table[101] =;

/* EMU10k1/EMU10k2 DSP control db gain */
static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1);
static const DECLARE_TLV_DB_LINEAR(snd_emu10k1_db_linear, TLV_DB_GAIN_MUTE, 0);

/* EMU10K1 bass/treble db gain */
static const DECLARE_TLV_DB_SCALE(snd_emu10k1_bass_treble_db_scale, -1200, 60, 0);

static const u32 onoff_table[2] =;

/*
 *   controls
 */

static int snd_emu10k1_gpr_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
{}

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

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

/*
 *   Interrupt handler
 */

static void snd_emu10k1_fx8010_interrupt(struct snd_emu10k1 *emu)
{}

int snd_emu10k1_fx8010_register_irq_handler(struct snd_emu10k1 *emu,
					    snd_fx8010_irq_handler_t *handler,
					    unsigned char gpr_running,
					    void *private_data,
					    struct snd_emu10k1_fx8010_irq *irq)
{}

int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu,
					      struct snd_emu10k1_fx8010_irq *irq)
{}

/*************************************************************************
 * EMU10K1 effect manager
 *************************************************************************/

static void snd_emu10k1_write_op(struct snd_emu10k1_fx8010_code *icode,
				 unsigned int *ptr,
				 u32 op, u32 r, u32 a, u32 x, u32 y)
{}

#define OP(icode, ptr, op, r, a, x, y)

static void snd_emu10k1_audigy_write_op(struct snd_emu10k1_fx8010_code *icode,
					unsigned int *ptr,
					u32 op, u32 r, u32 a, u32 x, u32 y)
{}

#define A_OP(icode, ptr, op, r, a, x, y)

static void snd_emu10k1_efx_write(struct snd_emu10k1 *emu, unsigned int pc, unsigned int data)
{}

unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc)
{}

static int snd_emu10k1_gpr_poke(struct snd_emu10k1 *emu,
				struct snd_emu10k1_fx8010_code *icode,
				bool in_kernel)
{}

static int snd_emu10k1_gpr_peek(struct snd_emu10k1 *emu,
				struct snd_emu10k1_fx8010_code *icode)
{}

static int snd_emu10k1_tram_poke(struct snd_emu10k1 *emu,
				 struct snd_emu10k1_fx8010_code *icode,
				 bool in_kernel)
{}

static int snd_emu10k1_tram_peek(struct snd_emu10k1 *emu,
				 struct snd_emu10k1_fx8010_code *icode)
{}

static int snd_emu10k1_code_poke(struct snd_emu10k1 *emu,
				 struct snd_emu10k1_fx8010_code *icode,
				 bool in_kernel)
{}

static int snd_emu10k1_code_peek(struct snd_emu10k1 *emu,
				 struct snd_emu10k1_fx8010_code *icode)
{}

static struct snd_emu10k1_fx8010_ctl *
snd_emu10k1_look_for_ctl(struct snd_emu10k1 *emu,
			 struct emu10k1_ctl_elem_id *_id)
{}

#define MAX_TLV_SIZE

static unsigned int *copy_tlv(const unsigned int __user *_tlv, bool in_kernel)
{}

static int copy_gctl(struct snd_emu10k1 *emu,
		     struct snd_emu10k1_fx8010_control_gpr *dst,
		     struct snd_emu10k1_fx8010_control_gpr *src,
		     int idx, bool in_kernel)
{}

static int copy_gctl_to_user(struct snd_emu10k1 *emu,
		     struct snd_emu10k1_fx8010_control_gpr *dst,
		     struct snd_emu10k1_fx8010_control_gpr *src,
		     int idx)
{}

static int copy_ctl_elem_id(const struct emu10k1_ctl_elem_id *list, int i,
			    struct emu10k1_ctl_elem_id *ret, bool in_kernel)
{}

static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu,
				       struct snd_emu10k1_fx8010_code *icode,
				       bool in_kernel)
{}

static void snd_emu10k1_ctl_private_free(struct snd_kcontrol *kctl)
{}

static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu,
				    struct snd_emu10k1_fx8010_code *icode,
				    bool in_kernel)
{}

static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu,
				    struct snd_emu10k1_fx8010_code *icode,
				    bool in_kernel)
{}

static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu,
				     struct snd_emu10k1_fx8010_code *icode)
{}

static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu,
				  struct snd_emu10k1_fx8010_code *icode,
				  bool in_kernel)
{}

static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu,
				  struct snd_emu10k1_fx8010_code *icode)
{}

static int snd_emu10k1_ipcm_poke(struct snd_emu10k1 *emu,
				 struct snd_emu10k1_fx8010_pcm_rec *ipcm)
{}

static int snd_emu10k1_ipcm_peek(struct snd_emu10k1 *emu,
				 struct snd_emu10k1_fx8010_pcm_rec *ipcm)
{}

#define SND_EMU10K1_GPR_CONTROLS
#define SND_EMU10K1_INPUTS
#define SND_EMU10K1_PLAYBACK_CHANNELS
#define SND_EMU10K1_CAPTURE_CHANNELS

#define HR_VAL(v)

static void
snd_emu10k1_init_mono_control2(struct snd_emu10k1_fx8010_control_gpr *ctl,
			       const char *name, int gpr, int defval, int defval_hr)
{}
#define snd_emu10k1_init_mono_control(ctl, name, gpr, defval)

static void
snd_emu10k1_init_stereo_control2(struct snd_emu10k1_fx8010_control_gpr *ctl,
				 const char *name, int gpr, int defval, int defval_hr)
{}
#define snd_emu10k1_init_stereo_control(ctl, name, gpr, defval)

static void
snd_emu10k1_init_mono_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
				    const char *name, int gpr, int defval)
{}

static void
snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
				      const char *name, int gpr, int defval)
{}

/*
 * Used for emu1010 - conversion from 32-bit capture inputs from the FPGA
 * to 2 x 16-bit registers in Audigy - their values are read via DMA.
 * Conversion is performed by Audigy DSP instructions of FX8010.
 */
static void snd_emu10k1_audigy_dsp_convert_32_to_2x16(
				struct snd_emu10k1_fx8010_code *icode,
				u32 *ptr, int tmp, int bit_shifter16,
				int reg_in, int reg_out)
{}

#define ENUM_GPR(name, size)

/*
 * initial DSP configuration for Audigy
 */

static int _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
{}


/*
 * initial DSP configuration for Emu10k1
 */

/* Volumes are in the [-2^31, 0] range, zero being mute. */
static void _volume(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
{}
static void _volume_add(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
{}

#define VOLUME(icode, ptr, dst, src, vol)
#define VOLUME_IN(icode, ptr, dst, src, vol)
#define VOLUME_ADD(icode, ptr, dst, src, vol)
#define VOLUME_ADDIN(icode, ptr, dst, src, vol)
#define VOLUME_OUT(icode, ptr, dst, src, vol)
#define _SWITCH(icode, ptr, dst, src, sw)
#define SWITCH(icode, ptr, dst, src, sw)
#define SWITCH_IN(icode, ptr, dst, src, sw)
#define _SWITCH_NEG(icode, ptr, dst, src)
#define SWITCH_NEG(icode, ptr, dst, src)


static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
{}

int snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
{}

void snd_emu10k1_free_efx(struct snd_emu10k1 *emu)
{}

#if 0 /* FIXME: who use them? */
int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output)
{
	if (output < 0 || output >= 6)
		return -EINVAL;
	snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
	return 0;
}

int snd_emu10k1_fx8010_tone_control_deactivate(struct snd_emu10k1 *emu, int output)
{
	if (output < 0 || output >= 6)
		return -EINVAL;
	snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
	return 0;
}
#endif

int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size)
{}

static int snd_emu10k1_fx8010_open(struct snd_hwdep * hw, struct file *file)
{}

static void copy_string(char *dst, const char *src, const char *null, int idx)
{}

static void snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu,
				   struct snd_emu10k1_fx8010_info *info)
{}

static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg)
{}

static int snd_emu10k1_fx8010_release(struct snd_hwdep * hw, struct file *file)
{}

int snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device)
{}

#ifdef CONFIG_PM_SLEEP
int snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu)
{}

void snd_emu10k1_efx_free_pm_buffer(struct snd_emu10k1 *emu)
{}

/*
 * save/restore GPR, TRAM and codes
 */
void snd_emu10k1_efx_suspend(struct snd_emu10k1 *emu)
{}

void snd_emu10k1_efx_resume(struct snd_emu10k1 *emu)
{}
#endif