linux/sound/pci/es1968.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  Driver for ESS Maestro 1/2/2E Sound Card (started 21.8.99)
 *  Copyright (c) by Matze Braun <[email protected]>.
 *                   Takashi Iwai <[email protected]>
 *                  
 *  Most of the driver code comes from Zach Brown([email protected])
 *	Alan Cox OSS Driver
 *  Rewritted from card-es1938.c source.
 *
 *  TODO:
 *   Perhaps Synth
 *
 *  Notes from Zach Brown about the driver code
 *
 *  Hardware Description
 *
 *	A working Maestro setup contains the Maestro chip wired to a 
 *	codec or 2.  In the Maestro we have the APUs, the ASSP, and the
 *	Wavecache.  The APUs can be though of as virtual audio routing
 *	channels.  They can take data from a number of sources and perform
 *	basic encodings of the data.  The wavecache is a storehouse for
 *	PCM data.  Typically it deals with PCI and interracts with the
 *	APUs.  The ASSP is a wacky DSP like device that ESS is loth
 *	to release docs on.  Thankfully it isn't required on the Maestro
 *	until you start doing insane things like FM emulation and surround
 *	encoding.  The codecs are almost always AC-97 compliant codecs, 
 *	but it appears that early Maestros may have had PT101 (an ESS
 *	part?) wired to them.  The only real difference in the Maestro
 *	families is external goop like docking capability, memory for
 *	the ASSP, and initialization differences.
 *
 *  Driver Operation
 *
 *	We only drive the APU/Wavecache as typical DACs and drive the
 *	mixers in the codecs.  There are 64 APUs.  We assign 6 to each
 *	/dev/dsp? device.  2 channels for output, and 4 channels for
 *	input.
 *
 *	Each APU can do a number of things, but we only really use
 *	3 basic functions.  For playback we use them to convert PCM
 *	data fetched over PCI by the wavecahche into analog data that
 *	is handed to the codec.  One APU for mono, and a pair for stereo.
 *	When in stereo, the combination of smarts in the APU and Wavecache
 *	decide which wavecache gets the left or right channel.
 *
 *	For record we still use the old overly mono system.  For each in
 *	coming channel the data comes in from the codec, through a 'input'
 *	APU, through another rate converter APU, and then into memory via
 *	the wavecache and PCI.  If its stereo, we mash it back into LRLR in
 *	software.  The pass between the 2 APUs is supposedly what requires us
 *	to have a 512 byte buffer sitting around in wavecache/memory.
 *
 *	The wavecache makes our life even more fun.  First off, it can
 *	only address the first 28 bits of PCI address space, making it
 *	useless on quite a few architectures.  Secondly, its insane.
 *	It claims to fetch from 4 regions of PCI space, each 4 meg in length.
 *	But that doesn't really work.  You can only use 1 region.  So all our
 *	allocations have to be in 4meg of each other.  Booo.  Hiss.
 *	So we have a module parameter, dsps_order, that is the order of
 *	the number of dsps to provide.  All their buffer space is allocated
 *	on open time.  The sonicvibes OSS routines we inherited really want
 *	power of 2 buffers, so we have all those next to each other, then
 *	512 byte regions for the recording wavecaches.  This ends up
 *	wasting quite a bit of memory.  The only fixes I can see would be 
 *	getting a kernel allocator that could work in zones, or figuring out
 *	just how to coerce the WP into doing what we want.
 *
 *	The indirection of the various registers means we have to spinlock
 *	nearly all register accesses.  We have the main register indirection
 *	like the wave cache, maestro registers, etc.  Then we have beasts
 *	like the APU interface that is indirect registers gotten at through
 *	the main maestro indirection.  Ouch.  We spinlock around the actual
 *	ports on a per card basis.  This means spinlock activity at each IO
 *	operation, but the only IO operation clusters are in non critical 
 *	paths and it makes the code far easier to follow.  Interrupts are
 *	blocked while holding the locks because the int handler has to
 *	get at some of them :(.  The mixer interface doesn't, however.
 *	We also have an OSS state lock that is thrown around in a few
 *	places.
 */

#include <linux/io.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/gameport.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/input.h>

#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/mpu401.h>
#include <sound/ac97_codec.h>
#include <sound/initval.h>

#ifdef CONFIG_SND_ES1968_RADIO
#include <media/drv-intf/tea575x.h>
#endif

#define CARD_NAME
#define DRIVER_NAME

MODULE_DESCRIPTION();
MODULE_LICENSE();

#if IS_REACHABLE(CONFIG_GAMEPORT)
#define SUPPORT_JOYSTICK
#endif

static int index[SNDRV_CARDS] =;	/* Index 1-MAX */
static char *id[SNDRV_CARDS] =;	/* ID for this card */
static bool enable[SNDRV_CARDS] =;	/* Enable this card */
static int total_bufsize[SNDRV_CARDS] =;
static int pcm_substreams_p[SNDRV_CARDS] =;
static int pcm_substreams_c[SNDRV_CARDS] =;
static int clock[SNDRV_CARDS];
static int use_pm[SNDRV_CARDS] =;
static int enable_mpu[SNDRV_CARDS] =;
#ifdef SUPPORT_JOYSTICK
static bool joystick[SNDRV_CARDS];
#endif
static int radio_nr[SNDRV_CARDS] =;

module_param_array();
MODULE_PARM_DESC();
module_param_array();
MODULE_PARM_DESC();
module_param_array();
MODULE_PARM_DESC();
module_param_array();
MODULE_PARM_DESC();
module_param_array();
MODULE_PARM_DESC();
module_param_array();
MODULE_PARM_DESC();
module_param_array();
MODULE_PARM_DESC();
module_param_array();
MODULE_PARM_DESC();
module_param_array();
MODULE_PARM_DESC();
#ifdef SUPPORT_JOYSTICK
module_param_array();
MODULE_PARM_DESC();
#endif
module_param_array();
MODULE_PARM_DESC();



#define NR_APUS
#define NR_APU_REGS

/* NEC Versas ? */
#define NEC_VERSA_SUBID1
#define NEC_VERSA_SUBID2

/* Mode Flags */
#define ESS_FMT_STEREO
#define ESS_FMT_16BIT

#define DAC_RUNNING
#define ADC_RUNNING

/* Values for the ESM_LEGACY_AUDIO_CONTROL */

#define ESS_DISABLE_AUDIO
#define ESS_ENABLE_SERIAL_IRQ
#define IO_ADRESS_ALIAS
#define MPU401_IRQ_ENABLE
#define MPU401_IO_ENABLE
#define GAME_IO_ENABLE
#define FM_IO_ENABLE
#define SB_IO_ENABLE

/* Values for the ESM_CONFIG_A */

#define PIC_SNOOP1
#define PIC_SNOOP2
#define SAFEGUARD
#define DMA_CLEAR
#define DMA_DDMA
#define DMA_TDMA
#define DMA_PCPCI
#define POST_WRITE
#define PCI_TIMING
#define SWAP_LR
#define SUBTR_DECODE

/* Values for the ESM_CONFIG_B */

#define SPDIF_CONFB
#define HWV_CONFB
#define DEBOUNCE
#define GPIO_CONFB
#define CHI_CONFB
#define IDMA_CONFB
#define MIDI_FIX
#define IRQ_TO_ISA

/* Values for Ring Bus Control B */
#define RINGB_2CODEC_ID_MASK
#define RINGB_DIS_VALIDATION
#define RINGB_EN_SPDIF
#define RINGB_EN_2CODEC
#define RINGB_SING_BIT_DUAL

/* ****Port Addresses**** */

/*   Write & Read */
#define ESM_INDEX
#define ESM_DATA

/*   AC97 + RingBus */
#define ESM_AC97_INDEX
#define ESM_AC97_DATA
#define ESM_RING_BUS_DEST
#define ESM_RING_BUS_CONTR_A
#define ESM_RING_BUS_CONTR_B
#define ESM_RING_BUS_SDO

/*   WaveCache*/
#define WC_INDEX
#define WC_DATA
#define WC_CONTROL

/*   ASSP*/
#define ASSP_INDEX
#define ASSP_MEMORY
#define ASSP_DATA
#define ASSP_CONTROL_A
#define ASSP_CONTROL_B
#define ASSP_CONTROL_C
#define ASSP_HOSTW_INDEX
#define ASSP_HOSTW_DATA
#define ASSP_HOSTW_IRQ
/* Midi */
#define ESM_MPU401_PORT
/* Others */
#define ESM_PORT_HOST_IRQ

#define IDR0_DATA_PORT
#define IDR1_CRAM_POINTER
#define IDR2_CRAM_DATA
#define IDR3_WAVE_DATA
#define IDR4_WAVE_PTR_LOW
#define IDR5_WAVE_PTR_HI
#define IDR6_TIMER_CTRL
#define IDR7_WAVE_ROMRAM

#define WRITEABLE_MAP
#define READABLE_MAP

/* PCI Register */

#define ESM_LEGACY_AUDIO_CONTROL
#define ESM_ACPI_COMMAND
#define ESM_CONFIG_A
#define ESM_CONFIG_B
#define ESM_DDMA

/* Bob Bits */
#define ESM_BOB_ENABLE
#define ESM_BOB_START

/* Host IRQ Control Bits */
#define ESM_RESET_MAESTRO
#define ESM_RESET_DIRECTSOUND
#define ESM_HIRQ_ClkRun
#define ESM_HIRQ_HW_VOLUME
#define ESM_HIRQ_HARPO
#define ESM_HIRQ_ASSP
#define ESM_HIRQ_DSIE
#define ESM_HIRQ_MPU401
#define ESM_HIRQ_SB

/* Host IRQ Status Bits */
#define ESM_MPU401_IRQ
#define ESM_SB_IRQ
#define ESM_SOUND_IRQ
#define ESM_ASSP_IRQ
#define ESM_HWVOL_IRQ

#define ESS_SYSCLK
#define ESM_BOB_FREQ
#define ESM_BOB_FREQ_MAX

#define ESM_FREQ_ESM1
#define ESM_FREQ_ESM2

/* APU Modes: reg 0x00, bit 4-7 */
#define ESM_APU_MODE_SHIFT
#define ESM_APU_MODE_MASK
#define ESM_APU_OFF
#define ESM_APU_16BITLINEAR
#define ESM_APU_16BITSTEREO
#define ESM_APU_8BITLINEAR
#define ESM_APU_8BITSTEREO
#define ESM_APU_8BITDIFF
#define ESM_APU_DIGITALDELAY
#define ESM_APU_DUALTAP
#define ESM_APU_CORRELATOR
#define ESM_APU_INPUTMIXER
#define ESM_APU_WAVETABLE
#define ESM_APU_SRCONVERTOR
#define ESM_APU_16BITPINGPONG
#define ESM_APU_RESERVED1
#define ESM_APU_RESERVED2
#define ESM_APU_RESERVED3

/* reg 0x00 */
#define ESM_APU_FILTER_Q_SHIFT
#define ESM_APU_FILTER_Q_MASK
/* APU Filtey Q Control */
#define ESM_APU_FILTER_LESSQ
#define ESM_APU_FILTER_MOREQ

#define ESM_APU_FILTER_TYPE_SHIFT
#define ESM_APU_FILTER_TYPE_MASK
#define ESM_APU_ENV_TYPE_SHIFT
#define ESM_APU_ENV_TYPE_MASK
#define ESM_APU_ENV_STATE_SHIFT
#define ESM_APU_ENV_STATE_MASK
#define ESM_APU_END_CURVE
#define ESM_APU_INT_ON_LOOP
#define ESM_APU_DMA_ENABLE

/* reg 0x02 */
#define ESM_APU_SUBMIX_GROUP_SHIRT
#define ESM_APU_SUBMIX_GROUP_MASK
#define ESM_APU_SUBMIX_MODE
#define ESM_APU_6dB
#define ESM_APU_DUAL_EFFECT
#define ESM_APU_EFFECT_CHANNELS_SHIFT
#define ESM_APU_EFFECT_CHANNELS_MASK

/* reg 0x03 */
#define ESM_APU_STEP_SIZE_MASK

/* reg 0x04 */
#define ESM_APU_PHASE_SHIFT
#define ESM_APU_PHASE_MASK
#define ESM_APU_WAVE64K_PAGE_SHIFT
#define ESM_APU_WAVE64K_PAGE_MASK

/* reg 0x05 - wave start offset */
/* reg 0x06 - wave end offset */
/* reg 0x07 - wave loop length */

/* reg 0x08 */
#define ESM_APU_EFFECT_GAIN_SHIFT
#define ESM_APU_EFFECT_GAIN_MASK
#define ESM_APU_TREMOLO_DEPTH_SHIFT
#define ESM_APU_TREMOLO_DEPTH_MASK
#define ESM_APU_TREMOLO_RATE_SHIFT
#define ESM_APU_TREMOLO_RATE_MASK

/* reg 0x09 */
/* bit 0-7 amplitude dest? */
#define ESM_APU_AMPLITUDE_NOW_SHIFT
#define ESM_APU_AMPLITUDE_NOW_MASK

/* reg 0x0a */
#define ESM_APU_POLAR_PAN_SHIFT
#define ESM_APU_POLAR_PAN_MASK
/* Polar Pan Control */
#define ESM_APU_PAN_CENTER_CIRCLE
#define ESM_APU_PAN_MIDDLE_RADIUS
#define ESM_APU_PAN_OUTSIDE_RADIUS

#define ESM_APU_FILTER_TUNING_SHIFT
#define ESM_APU_FILTER_TUNING_MASK

/* reg 0x0b */
#define ESM_APU_DATA_SRC_A_SHIFT
#define ESM_APU_DATA_SRC_A_MASK
#define ESM_APU_INV_POL_A
#define ESM_APU_DATA_SRC_B_SHIFT
#define ESM_APU_DATA_SRC_B_MASK
#define ESM_APU_INV_POL_B

#define ESM_APU_VIBRATO_RATE_SHIFT
#define ESM_APU_VIBRATO_RATE_MASK
#define ESM_APU_VIBRATO_DEPTH_SHIFT
#define ESM_APU_VIBRATO_DEPTH_MASK
#define ESM_APU_VIBRATO_PHASE_SHIFT
#define ESM_APU_VIBRATO_PHASE_MASK

/* reg 0x0c */
#define ESM_APU_RADIUS_SELECT

/* APU Filter Control */
#define ESM_APU_FILTER_2POLE_LOPASS
#define ESM_APU_FILTER_2POLE_BANDPASS
#define ESM_APU_FILTER_2POLE_HIPASS
#define ESM_APU_FILTER_1POLE_LOPASS
#define ESM_APU_FILTER_1POLE_HIPASS
#define ESM_APU_FILTER_OFF

/* APU ATFP Type */
#define ESM_APU_ATFP_AMPLITUDE
#define ESM_APU_ATFP_TREMELO
#define ESM_APU_ATFP_FILTER
#define ESM_APU_ATFP_PAN

/* APU ATFP Flags */
#define ESM_APU_ATFP_FLG_OFF
#define ESM_APU_ATFP_FLG_WAIT
#define ESM_APU_ATFP_FLG_DONE
#define ESM_APU_ATFP_FLG_INPROCESS


/* capture mixing buffer size */
#define ESM_MEM_ALIGN
#define ESM_MIXBUF_SIZE

#define ESM_MODE_PLAY
#define ESM_MODE_CAPTURE


/* APU use in the driver */
enum snd_enum_apu_type {};

/* chip type */
enum {};

/* DMA Hack! */
struct esm_memory {};

/* Playback Channel */
struct esschan {};

struct es1968 {};

static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id);

static const struct pci_device_id snd_es1968_ids[] =;

MODULE_DEVICE_TABLE(pci, snd_es1968_ids);

/* *********************
   * Low Level Funcs!  *
   *********************/

/* no spinlock */
static void __maestro_write(struct es1968 *chip, u16 reg, u16 data)
{}

static inline void maestro_write(struct es1968 *chip, u16 reg, u16 data)
{}

/* no spinlock */
static u16 __maestro_read(struct es1968 *chip, u16 reg)
{}

static inline u16 maestro_read(struct es1968 *chip, u16 reg)
{}

/* Wait for the codec bus to be free */
static int snd_es1968_ac97_wait(struct es1968 *chip)
{}

static int snd_es1968_ac97_wait_poll(struct es1968 *chip)
{}

static void snd_es1968_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
{}

static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
{}

/* no spinlock */
static void apu_index_set(struct es1968 *chip, u16 index)
{}

/* no spinlock */
static void apu_data_set(struct es1968 *chip, u16 data)
{}

/* no spinlock */
static void __apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 data)
{}

static void apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 data)
{}

static u16 __apu_get_register(struct es1968 *chip, u16 channel, u8 reg)
{}

static u16 apu_get_register(struct es1968 *chip, u16 channel, u8 reg)
{}

#if 0 /* ASSP is not supported */

static void assp_set_register(struct es1968 *chip, u32 reg, u32 value)
{
	unsigned long flags;

	spin_lock_irqsave(&chip->reg_lock, flags);
	outl(reg, chip->io_port + ASSP_INDEX);
	outl(value, chip->io_port + ASSP_DATA);
	spin_unlock_irqrestore(&chip->reg_lock, flags);
}

static u32 assp_get_register(struct es1968 *chip, u32 reg)
{
	unsigned long flags;
	u32 value;

	spin_lock_irqsave(&chip->reg_lock, flags);
	outl(reg, chip->io_port + ASSP_INDEX);
	value = inl(chip->io_port + ASSP_DATA);
	spin_unlock_irqrestore(&chip->reg_lock, flags);

	return value;
}

#endif

static void wave_set_register(struct es1968 *chip, u16 reg, u16 value)
{}

static u16 wave_get_register(struct es1968 *chip, u16 reg)
{}

/* *******************
   * Bob the Timer!  *
   *******************/

static void snd_es1968_bob_stop(struct es1968 *chip)
{}

static void snd_es1968_bob_start(struct es1968 *chip)
{}

/* call with substream spinlock */
static void snd_es1968_bob_inc(struct es1968 *chip, int freq)
{}

/* call with substream spinlock */
static void snd_es1968_bob_dec(struct es1968 *chip)
{}

static int
snd_es1968_calc_bob_rate(struct es1968 *chip, struct esschan *es,
			 struct snd_pcm_runtime *runtime)
{}


/*************
 *  PCM Part *
 *************/

static u32 snd_es1968_compute_rate(struct es1968 *chip, u32 freq)
{}

/* get current pointer */
static inline unsigned int
snd_es1968_get_dma_ptr(struct es1968 *chip, struct esschan *es)
{}

static void snd_es1968_apu_set_freq(struct es1968 *chip, int apu, int freq)
{}

/* spin lock held */
static inline void snd_es1968_trigger_apu(struct es1968 *esm, int apu, int mode)
{}

static void snd_es1968_pcm_start(struct es1968 *chip, struct esschan *es)
{}

static void snd_es1968_pcm_stop(struct es1968 *chip, struct esschan *es)
{}

/* set the wavecache control reg */
static void snd_es1968_program_wavecache(struct es1968 *chip, struct esschan *es,
					 int channel, u32 addr, int capture)
{}


static void snd_es1968_playback_setup(struct es1968 *chip, struct esschan *es,
				      struct snd_pcm_runtime *runtime)
{}


static void init_capture_apu(struct es1968 *chip, struct esschan *es, int channel,
			     unsigned int pa, unsigned int bsize,
			     int mode, int route)
{}

static void snd_es1968_capture_setup(struct es1968 *chip, struct esschan *es,
				     struct snd_pcm_runtime *runtime)
{}

/*******************
 *  ALSA Interface *
 *******************/

static int snd_es1968_pcm_prepare(struct snd_pcm_substream *substream)
{}

static int snd_es1968_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{}

static snd_pcm_uframes_t snd_es1968_pcm_pointer(struct snd_pcm_substream *substream)
{}

static const struct snd_pcm_hardware snd_es1968_playback =;

static const struct snd_pcm_hardware snd_es1968_capture =;

/* *************************
   * DMA memory management *
   *************************/

/* Because the Maestro can only take addresses relative to the PCM base address
   register :( */

static int calc_available_memory_size(struct es1968 *chip)
{}

/* allocate a new memory chunk with the specified size */
static struct esm_memory *snd_es1968_new_memory(struct es1968 *chip, int size)
{}

/* free a memory chunk */
static void snd_es1968_free_memory(struct es1968 *chip, struct esm_memory *buf)
{}

static void snd_es1968_free_dmabuf(struct es1968 *chip)
{}

static int
snd_es1968_init_dmabuf(struct es1968 *chip)
{}

/* setup the dma_areas */
/* buffer is extracted from the pre-allocated memory chunk */
static int snd_es1968_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *hw_params)
{}

/* remove dma areas if allocated */
static int snd_es1968_hw_free(struct snd_pcm_substream *substream)
{}


/*
 * allocate APU pair
 */
static int snd_es1968_alloc_apu_pair(struct es1968 *chip, int type)
{}

/*
 * release APU pair
 */
static void snd_es1968_free_apu_pair(struct es1968 *chip, int apu)
{}


/******************
 * PCM open/close *
 ******************/

static int snd_es1968_playback_open(struct snd_pcm_substream *substream)
{}

static int snd_es1968_capture_open(struct snd_pcm_substream *substream)
{}

static int snd_es1968_playback_close(struct snd_pcm_substream *substream)
{}

static int snd_es1968_capture_close(struct snd_pcm_substream *substream)
{}

static const struct snd_pcm_ops snd_es1968_playback_ops =;

static const struct snd_pcm_ops snd_es1968_capture_ops =;


/*
 * measure clock
 */
#define CLOCK_MEASURE_BUFSIZE

static void es1968_measure_clock(struct es1968 *chip)
{}


/*
 */

static void snd_es1968_pcm_free(struct snd_pcm *pcm)
{}

static int
snd_es1968_pcm(struct es1968 *chip, int device)
{}
/*
 * suppress jitter on some maestros when playing stereo
 */
static void snd_es1968_suppress_jitter(struct es1968 *chip, struct esschan *es)
{}

/*
 * update pointer
 */
static void snd_es1968_update_pcm(struct es1968 *chip, struct esschan *es)
{}

/* The hardware volume works by incrementing / decrementing 2 counters
   (without wrap around) in response to volume button presses and then
   generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7
   of a byte wide register. The meaning of bits 0 and 4 is unknown. */
static void es1968_update_hw_volume(struct work_struct *work)
{}

/*
 * interrupt handler
 */
static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id)
{}

/*
 *  Mixer stuff
 */

static int
snd_es1968_mixer(struct es1968 *chip)
{}

/*
 * reset ac97 codec
 */

static void snd_es1968_ac97_reset(struct es1968 *chip)
{}

static void snd_es1968_reset(struct es1968 *chip)
{}

/*
 * initialize maestro chip
 */
static void snd_es1968_chip_init(struct es1968 *chip)
{}

/* Enable IRQ's */
static void snd_es1968_start_irq(struct es1968 *chip)
{}

/*
 * PM support
 */
static int es1968_suspend(struct device *dev)
{}

static int es1968_resume(struct device *dev)
{}

static DEFINE_SIMPLE_DEV_PM_OPS(es1968_pm, es1968_suspend, es1968_resume);

#ifdef SUPPORT_JOYSTICK
#define JOYSTICK_ADDR
static int snd_es1968_create_gameport(struct es1968 *chip, int dev)
{}

static void snd_es1968_free_gameport(struct es1968 *chip)
{}
#else
static inline int snd_es1968_create_gameport(struct es1968 *chip, int dev) { return -ENOSYS; }
static inline void snd_es1968_free_gameport(struct es1968 *chip) { }
#endif

#ifdef CONFIG_SND_ES1968_INPUT
static int snd_es1968_input_register(struct es1968 *chip)
{}
#endif /* CONFIG_SND_ES1968_INPUT */

#ifdef CONFIG_SND_ES1968_RADIO
#define GPIO_DATA
#define IO_MASK
#define IO_DIR

/* GPIO to TEA575x maps */
struct snd_es1968_tea575x_gpio {};

static const struct snd_es1968_tea575x_gpio snd_es1968_tea575x_gpios[] =;

#define get_tea575x_gpio(chip)


static void snd_es1968_tea575x_set_pins(struct snd_tea575x *tea, u8 pins)
{}

static u8 snd_es1968_tea575x_get_pins(struct snd_tea575x *tea)
{}

static void snd_es1968_tea575x_set_direction(struct snd_tea575x *tea, bool output)
{}

static const struct snd_tea575x_ops snd_es1968_tea_ops =;
#endif

static void snd_es1968_free(struct snd_card *card)
{}

struct ess_device_list {};

static const struct ess_device_list pm_allowlist[] =;

static const struct ess_device_list mpu_denylist[] =;

static int snd_es1968_create(struct snd_card *card,
			     struct pci_dev *pci,
			     int total_bufsize,
			     int play_streams,
			     int capt_streams,
			     int chip_type,
			     int do_pm,
			     int radio_nr)
{}


/*
 */
static int __snd_es1968_probe(struct pci_dev *pci,
			      const struct pci_device_id *pci_id)
{}

static int snd_es1968_probe(struct pci_dev *pci,
			    const struct pci_device_id *pci_id)
{}

static struct pci_driver es1968_driver =;

module_pci_driver();