linux/sound/pci/maestro3.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Driver for ESS Maestro3/Allegro (ES1988) soundcards.
 * Copyright (c) 2000 by Zach Brown <[email protected]>
 *                       Takashi Iwai <[email protected]>
 *
 * Most of the hardware init stuffs are based on maestro3 driver for
 * OSS/Free by Zach Brown.  Many thanks to Zach!
 *
 * ChangeLog:
 * Aug. 27, 2001
 *     - Fixed deadlock on capture
 *     - Added Canyon3D-2 support by Rob Riggs <[email protected]>
 */
 
#define CARD_NAME
#define DRIVER_NAME

#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/vmalloc.h>
#include <linux/module.h>
#include <linux/firmware.h>
#include <linux/input.h>
#include <sound/core.h>
#include <sound/info.h>
#include <sound/control.h>
#include <sound/pcm.h>
#include <sound/mpu401.h>
#include <sound/ac97_codec.h>
#include <sound/initval.h>
#include <asm/byteorder.h>

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();
MODULE_FIRMWARE();
MODULE_FIRMWARE();

static int index[SNDRV_CARDS] =;	/* Index 0-MAX */
static char *id[SNDRV_CARDS] =;	/* ID for this card */
static bool enable[SNDRV_CARDS] =; /* all enabled */
static bool external_amp[SNDRV_CARDS] =;
static int amp_gpio[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();

#define MAX_PLAYBACKS
#define MAX_CAPTURES
#define NR_DSPS


/*
 * maestro3 registers
 */

/* Allegro PCI configuration registers */
#define PCI_LEGACY_AUDIO_CTRL
#define SOUND_BLASTER_ENABLE
#define FM_SYNTHESIS_ENABLE
#define GAME_PORT_ENABLE
#define MPU401_IO_ENABLE
#define MPU401_IRQ_ENABLE
#define ALIAS_10BIT_IO
#define SB_DMA_MASK
#define SB_DMA_0
#define SB_DMA_1
#define SB_DMA_R
#define SB_DMA_3
#define SB_IRQ_MASK
#define SB_IRQ_5
#define SB_IRQ_7
#define SB_IRQ_9
#define SB_IRQ_10
#define MIDI_IRQ_MASK
#define SERIAL_IRQ_ENABLE
#define DISABLE_LEGACY

#define PCI_ALLEGRO_CONFIG
#define SB_ADDR_240
#define MPU_ADDR_MASK
#define MPU_ADDR_330
#define MPU_ADDR_300
#define MPU_ADDR_320
#define MPU_ADDR_340
#define USE_PCI_TIMING
#define POSTED_WRITE_ENABLE
#define DMA_POLICY_MASK
#define DMA_DDMA
#define DMA_TDMA
#define DMA_PCPCI
#define DMA_WBDMA16
#define DMA_WBDMA4
#define DMA_WBDMA2
#define DMA_WBDMA1
#define DMA_SAFE_GUARD
#define HI_PERF_GP_ENABLE
#define PIC_SNOOP_MODE_0
#define PIC_SNOOP_MODE_1
#define SOUNDBLASTER_IRQ_MASK
#define RING_IN_ENABLE
#define SPDIF_TEST_MODE
#define CLK_MULT_MODE_SELECT_2
#define EEPROM_WRITE_ENABLE
#define CODEC_DIR_IN
#define HV_BUTTON_FROM_GD
#define REDUCED_DEBOUNCE
#define HV_CTRL_ENABLE
#define SPDIF_ENABLE
#define CLK_DIV_SELECT
#define CLK_DIV_BY_48
#define CLK_DIV_BY_49
#define CLK_DIV_BY_50
#define CLK_DIV_RESERVED
#define PM_CTRL_ENABLE
#define CLK_MULT_MODE_SELECT
#define CLK_MULT_MODE_SHIFT
#define CLK_MULT_MODE_0
#define CLK_MULT_MODE_1
#define CLK_MULT_MODE_2
#define CLK_MULT_MODE_3
#define INT_CLK_SELECT
#define INT_CLK_MULT_RESET

/* M3 */
#define INT_CLK_SRC_NOT_PCI
#define INT_CLK_MULT_ENABLE

#define PCI_ACPI_CONTROL
#define PCI_ACPI_D0
#define PCI_ACPI_D1
#define PCI_ACPI_D2

#define PCI_USER_CONFIG
#define EXT_PCI_MASTER_ENABLE
#define SPDIF_OUT_SELECT
#define TEST_PIN_DIR_CTRL
#define AC97_CODEC_TEST
#define TRI_STATE_BUFFER
#define IN_CLK_12MHZ_SELECT
#define MULTI_FUNC_DISABLE
#define EXT_MASTER_PAIR_SEL
#define PCI_MASTER_SUPPORT
#define STOP_CLOCK_ENABLE
#define EAPD_DRIVE_ENABLE
#define REQ_TRI_STATE_ENABLE
#define REQ_LOW_ENABLE
#define MIDI_1_ENABLE
#define MIDI_2_ENABLE
#define SB_AUDIO_SYNC
#define HV_CTRL_TEST
#define SOUNDBLASTER_TEST

#define PCI_USER_CONFIG_C

#define PCI_DDMA_CTRL
#define DDMA_ENABLE


/* Allegro registers */
#define HOST_INT_CTRL
#define SB_INT_ENABLE
#define MPU401_INT_ENABLE
#define ASSP_INT_ENABLE
#define RING_INT_ENABLE
#define HV_INT_ENABLE
#define CLKRUN_GEN_ENABLE
#define HV_CTRL_TO_PME
#define SOFTWARE_RESET_ENABLE

/*
 * should be using the above defines, probably.
 */
#define REGB_ENABLE_RESET
#define REGB_STOP_CLOCK

#define HOST_INT_STATUS
#define SB_INT_PENDING
#define MPU401_INT_PENDING
#define ASSP_INT_PENDING
#define RING_INT_PENDING
#define HV_INT_PENDING

#define HARDWARE_VOL_CTRL
#define SHADOW_MIX_REG_VOICE
#define HW_VOL_COUNTER_VOICE
#define SHADOW_MIX_REG_MASTER
#define HW_VOL_COUNTER_MASTER

#define CODEC_COMMAND
#define CODEC_READ_B

#define CODEC_STATUS
#define CODEC_BUSY_B

#define CODEC_DATA

#define RING_BUS_CTRL_A
#define RAC_PME_ENABLE
#define RAC_SDFS_ENABLE
#define LAC_PME_ENABLE
#define LAC_SDFS_ENABLE
#define SERIAL_AC_LINK_ENABLE
#define IO_SRAM_ENABLE
#define IIS_INPUT_ENABLE

#define RING_BUS_CTRL_B
#define SECOND_CODEC_ID_MASK
#define SPDIF_FUNC_ENABLE
#define SECOND_AC_ENABLE
#define SB_MODULE_INTF_ENABLE
#define SSPE_ENABLE
#define M3I_DOCK_ENABLE

#define SDO_OUT_DEST_CTRL
#define COMMAND_ADDR_OUT
#define PCM_LR_OUT_LOCAL
#define PCM_LR_OUT_REMOTE
#define PCM_LR_OUT_MUTE
#define PCM_LR_OUT_BOTH
#define LINE1_DAC_OUT_LOCAL
#define LINE1_DAC_OUT_REMOTE
#define LINE1_DAC_OUT_MUTE
#define LINE1_DAC_OUT_BOTH
#define PCM_CLS_OUT_LOCAL
#define PCM_CLS_OUT_REMOTE
#define PCM_CLS_OUT_MUTE
#define PCM_CLS_OUT_BOTH
#define PCM_RLF_OUT_LOCAL
#define PCM_RLF_OUT_REMOTE
#define PCM_RLF_OUT_MUTE
#define PCM_RLF_OUT_BOTH
#define LINE2_DAC_OUT_LOCAL
#define LINE2_DAC_OUT_REMOTE
#define LINE2_DAC_OUT_MUTE
#define LINE2_DAC_OUT_BOTH
#define HANDSET_OUT_LOCAL
#define HANDSET_OUT_REMOTE
#define HANDSET_OUT_MUTE
#define HANDSET_OUT_BOTH
#define IO_CTRL_OUT_LOCAL
#define IO_CTRL_OUT_REMOTE
#define IO_CTRL_OUT_MUTE
#define IO_CTRL_OUT_BOTH

#define SDO_IN_DEST_CTRL
#define STATUS_ADDR_IN
#define PCM_LR_IN_LOCAL
#define PCM_LR_IN_REMOTE
#define PCM_LR_RESERVED
#define PCM_LR_IN_BOTH
#define LINE1_ADC_IN_LOCAL
#define LINE1_ADC_IN_REMOTE
#define LINE1_ADC_IN_MUTE
#define MIC_ADC_IN_LOCAL
#define MIC_ADC_IN_REMOTE
#define MIC_ADC_IN_MUTE
#define LINE2_DAC_IN_LOCAL
#define LINE2_DAC_IN_REMOTE
#define LINE2_DAC_IN_MUTE
#define HANDSET_IN_LOCAL
#define HANDSET_IN_REMOTE
#define HANDSET_IN_MUTE
#define IO_STATUS_IN_LOCAL
#define IO_STATUS_IN_REMOTE

#define SPDIF_IN_CTRL
#define SPDIF_IN_ENABLE

#define GPIO_DATA
#define GPIO_DATA_MASK
#define GPIO_HV_STATUS
#define GPIO_PME_STATUS

#define GPIO_MASK
#define GPIO_DIRECTION
#define GPO_PRIMARY_AC97
#define GPI_LINEOUT_SENSE
#define GPO_SECONDARY_AC97
#define GPI_VOL_DOWN
#define GPI_VOL_UP
#define GPI_IIS_CLK
#define GPI_IIS_LRCLK
#define GPI_IIS_DATA
#define GPI_DOCKING_STATUS
#define GPI_HEADPHONE_SENSE
#define GPO_EXT_AMP_SHUTDOWN

#define GPO_EXT_AMP_M3
#define GPO_EXT_AMP_ALLEGRO

/* M3 */
#define GPO_M3_EXT_AMP_SHUTDN

#define ASSP_INDEX_PORT
#define ASSP_MEMORY_PORT
#define ASSP_DATA_PORT

#define MPU401_DATA_PORT
#define MPU401_STATUS_PORT

#define CLK_MULT_DATA_PORT

#define ASSP_CONTROL_A
#define ASSP_0_WS_ENABLE
#define ASSP_CTRL_A_RESERVED1
#define ASSP_CTRL_A_RESERVED2
#define ASSP_CLK_49MHZ_SELECT
#define FAST_PLU_ENABLE
#define ASSP_CTRL_A_RESERVED3
#define DSP_CLK_36MHZ_SELECT

#define ASSP_CONTROL_B
#define RESET_ASSP
#define RUN_ASSP
#define ENABLE_ASSP_CLOCK
#define STOP_ASSP_CLOCK
#define RESET_TOGGLE

#define ASSP_CONTROL_C
#define ASSP_HOST_INT_ENABLE
#define FM_ADDR_REMAP_DISABLE
#define HOST_WRITE_PORT_ENABLE

#define ASSP_HOST_INT_STATUS
#define DSP2HOST_REQ_PIORECORD
#define DSP2HOST_REQ_I2SRATE
#define DSP2HOST_REQ_TIMER

/*
 * ASSP control regs
 */
#define DSP_PORT_TIMER_COUNT

#define DSP_PORT_MEMORY_INDEX

#define DSP_PORT_MEMORY_TYPE
#define MEMTYPE_INTERNAL_CODE
#define MEMTYPE_INTERNAL_DATA
#define MEMTYPE_MASK

#define DSP_PORT_MEMORY_DATA

#define DSP_PORT_CONTROL_REG_A
#define DSP_PORT_CONTROL_REG_B
#define DSP_PORT_CONTROL_REG_C

#define REV_A_CODE_MEMORY_BEGIN
#define REV_A_CODE_MEMORY_END
#define REV_A_CODE_MEMORY_UNIT_LENGTH
#define REV_A_CODE_MEMORY_LENGTH

#define REV_B_CODE_MEMORY_BEGIN
#define REV_B_CODE_MEMORY_END
#define REV_B_CODE_MEMORY_UNIT_LENGTH
#define REV_B_CODE_MEMORY_LENGTH

#define REV_A_DATA_MEMORY_BEGIN
#define REV_A_DATA_MEMORY_END
#define REV_A_DATA_MEMORY_UNIT_LENGTH
#define REV_A_DATA_MEMORY_LENGTH

#define REV_B_DATA_MEMORY_BEGIN
#define REV_B_DATA_MEMORY_END
#define REV_B_DATA_MEMORY_UNIT_LENGTH
#define REV_B_DATA_MEMORY_LENGTH


#define NUM_UNITS_KERNEL_CODE
#define NUM_UNITS_KERNEL_DATA

#define NUM_UNITS_KERNEL_CODE_WITH_HSP
#define NUM_UNITS_KERNEL_DATA_WITH_HSP

/*
 * Kernel data layout
 */

#define DP_SHIFT_COUNT

#define KDATA_BASE_ADDR
#define KDATA_BASE_ADDR2

#define KDATA_TASK0
#define KDATA_TASK1
#define KDATA_TASK2
#define KDATA_TASK3
#define KDATA_TASK4
#define KDATA_TASK5
#define KDATA_TASK6
#define KDATA_TASK7
#define KDATA_TASK_ENDMARK

#define KDATA_CURRENT_TASK
#define KDATA_TASK_SWITCH

#define KDATA_INSTANCE0_POS3D
#define KDATA_INSTANCE1_POS3D
#define KDATA_INSTANCE2_POS3D
#define KDATA_INSTANCE3_POS3D
#define KDATA_INSTANCE4_POS3D
#define KDATA_INSTANCE5_POS3D
#define KDATA_INSTANCE6_POS3D
#define KDATA_INSTANCE7_POS3D
#define KDATA_INSTANCE8_POS3D
#define KDATA_INSTANCE_POS3D_ENDMARK

#define KDATA_INSTANCE0_SPKVIRT
#define KDATA_INSTANCE_SPKVIRT_ENDMARK

#define KDATA_INSTANCE0_SPDIF
#define KDATA_INSTANCE_SPDIF_ENDMARK

#define KDATA_INSTANCE0_MODEM
#define KDATA_INSTANCE_MODEM_ENDMARK

#define KDATA_INSTANCE0_SRC
#define KDATA_INSTANCE1_SRC
#define KDATA_INSTANCE_SRC_ENDMARK

#define KDATA_INSTANCE0_MINISRC
#define KDATA_INSTANCE1_MINISRC
#define KDATA_INSTANCE2_MINISRC
#define KDATA_INSTANCE3_MINISRC
#define KDATA_INSTANCE_MINISRC_ENDMARK

#define KDATA_INSTANCE0_CPYTHRU
#define KDATA_INSTANCE1_CPYTHRU
#define KDATA_INSTANCE_CPYTHRU_ENDMARK

#define KDATA_CURRENT_DMA
#define KDATA_DMA_SWITCH
#define KDATA_DMA_ACTIVE

#define KDATA_DMA_XFER0
#define KDATA_DMA_XFER1
#define KDATA_DMA_XFER2
#define KDATA_DMA_XFER3
#define KDATA_DMA_XFER4
#define KDATA_DMA_XFER5
#define KDATA_DMA_XFER6
#define KDATA_DMA_XFER7
#define KDATA_DMA_XFER8
#define KDATA_DMA_XFER_ENDMARK

#define KDATA_I2S_SAMPLE_COUNT
#define KDATA_I2S_INT_METER
#define KDATA_I2S_ACTIVE

#define KDATA_TIMER_COUNT_RELOAD
#define KDATA_TIMER_COUNT_CURRENT

#define KDATA_HALT_SYNCH_CLIENT
#define KDATA_HALT_SYNCH_DMA
#define KDATA_HALT_ACKNOWLEDGE

#define KDATA_ADC1_XFER0
#define KDATA_ADC1_XFER_ENDMARK
#define KDATA_ADC1_LEFT_VOLUME
#define KDATA_ADC1_RIGHT_VOLUME
#define KDATA_ADC1_LEFT_SUR_VOL
#define KDATA_ADC1_RIGHT_SUR_VOL

#define KDATA_ADC2_XFER0
#define KDATA_ADC2_XFER_ENDMARK
#define KDATA_ADC2_LEFT_VOLUME
#define KDATA_ADC2_RIGHT_VOLUME
#define KDATA_ADC2_LEFT_SUR_VOL
#define KDATA_ADC2_RIGHT_SUR_VOL

#define KDATA_CD_XFER0					
#define KDATA_CD_XFER_ENDMARK
#define KDATA_CD_LEFT_VOLUME
#define KDATA_CD_RIGHT_VOLUME
#define KDATA_CD_LEFT_SUR_VOL
#define KDATA_CD_RIGHT_SUR_VOL

#define KDATA_MIC_XFER0
#define KDATA_MIC_XFER_ENDMARK
#define KDATA_MIC_VOLUME
#define KDATA_MIC_SUR_VOL

#define KDATA_I2S_XFER0
#define KDATA_I2S_XFER_ENDMARK

#define KDATA_CHI_XFER0
#define KDATA_CHI_XFER_ENDMARK

#define KDATA_SPDIF_XFER
#define KDATA_SPDIF_CURRENT_FRAME
#define KDATA_SPDIF_FRAME0
#define KDATA_SPDIF_FRAME1
#define KDATA_SPDIF_FRAME2

#define KDATA_SPDIF_REQUEST
#define KDATA_SPDIF_TEMP

#define KDATA_SPDIFIN_XFER0
#define KDATA_SPDIFIN_XFER_ENDMARK
#define KDATA_SPDIFIN_INT_METER

#define KDATA_DSP_RESET_COUNT
#define KDATA_DEBUG_OUTPUT

#define KDATA_KERNEL_ISR_LIST

#define KDATA_KERNEL_ISR_CBSR1
#define KDATA_KERNEL_ISR_CBER1
#define KDATA_KERNEL_ISR_CBCR
#define KDATA_KERNEL_ISR_AR0
#define KDATA_KERNEL_ISR_AR1
#define KDATA_KERNEL_ISR_AR2
#define KDATA_KERNEL_ISR_AR3
#define KDATA_KERNEL_ISR_AR4
#define KDATA_KERNEL_ISR_AR5
#define KDATA_KERNEL_ISR_BRCR
#define KDATA_KERNEL_ISR_PASR
#define KDATA_KERNEL_ISR_PAER

#define KDATA_CLIENT_SCRATCH0
#define KDATA_CLIENT_SCRATCH1
#define KDATA_KERNEL_SCRATCH
#define KDATA_KERNEL_ISR_SCRATCH

#define KDATA_OUEUE_LEFT
#define KDATA_QUEUE_RIGHT

#define KDATA_ADC1_REQUEST
#define KDATA_ADC2_REQUEST
#define KDATA_CD_REQUEST
#define KDATA_MIC_REQUEST

#define KDATA_ADC1_MIXER_REQUEST
#define KDATA_ADC2_MIXER_REQUEST
#define KDATA_CD_MIXER_REQUEST
#define KDATA_MIC_MIXER_REQUEST
#define KDATA_MIC_SYNC_COUNTER

/*
 * second 'segment' (?) reserved for mixer
 * buffers..
 */

#define KDATA_MIXER_WORD0
#define KDATA_MIXER_WORD1
#define KDATA_MIXER_WORD2
#define KDATA_MIXER_WORD3
#define KDATA_MIXER_WORD4
#define KDATA_MIXER_WORD5
#define KDATA_MIXER_WORD6
#define KDATA_MIXER_WORD7
#define KDATA_MIXER_WORD8
#define KDATA_MIXER_WORD9
#define KDATA_MIXER_WORDA
#define KDATA_MIXER_WORDB
#define KDATA_MIXER_WORDC
#define KDATA_MIXER_WORDD
#define KDATA_MIXER_WORDE
#define KDATA_MIXER_WORDF

#define KDATA_MIXER_XFER0
#define KDATA_MIXER_XFER1
#define KDATA_MIXER_XFER2
#define KDATA_MIXER_XFER3
#define KDATA_MIXER_XFER4
#define KDATA_MIXER_XFER5
#define KDATA_MIXER_XFER6
#define KDATA_MIXER_XFER7
#define KDATA_MIXER_XFER8
#define KDATA_MIXER_XFER9
#define KDATA_MIXER_XFER_ENDMARK

#define KDATA_MIXER_TASK_NUMBER
#define KDATA_CURRENT_MIXER
#define KDATA_MIXER_ACTIVE
#define KDATA_MIXER_BANK_STATUS
#define KDATA_DAC_LEFT_VOLUME
#define KDATA_DAC_RIGHT_VOLUME

#define MAX_INSTANCE_MINISRC
#define MAX_VIRTUAL_DMA_CHANNELS
#define MAX_VIRTUAL_MIXER_CHANNELS
#define MAX_VIRTUAL_ADC1_CHANNELS

/*
 * client data area offsets
 */
#define CDATA_INSTANCE_READY

#define CDATA_HOST_SRC_ADDRL
#define CDATA_HOST_SRC_ADDRH
#define CDATA_HOST_SRC_END_PLUS_1L
#define CDATA_HOST_SRC_END_PLUS_1H
#define CDATA_HOST_SRC_CURRENTL
#define CDATA_HOST_SRC_CURRENTH

#define CDATA_IN_BUF_CONNECT
#define CDATA_OUT_BUF_CONNECT

#define CDATA_IN_BUF_BEGIN
#define CDATA_IN_BUF_END_PLUS_1
#define CDATA_IN_BUF_HEAD
#define CDATA_IN_BUF_TAIL
#define CDATA_OUT_BUF_BEGIN
#define CDATA_OUT_BUF_END_PLUS_1
#define CDATA_OUT_BUF_HEAD
#define CDATA_OUT_BUF_TAIL

#define CDATA_DMA_CONTROL
#define CDATA_RESERVED

#define CDATA_FREQUENCY
#define CDATA_LEFT_VOLUME
#define CDATA_RIGHT_VOLUME
#define CDATA_LEFT_SUR_VOL
#define CDATA_RIGHT_SUR_VOL

#define CDATA_HEADER_LEN

#define SRC3_DIRECTION_OFFSET
#define SRC3_MODE_OFFSET
#define SRC3_WORD_LENGTH_OFFSET
#define SRC3_PARAMETER_OFFSET
#define SRC3_COEFF_ADDR_OFFSET
#define SRC3_FILTAP_ADDR_OFFSET
#define SRC3_TEMP_INBUF_ADDR_OFFSET
#define SRC3_TEMP_OUTBUF_ADDR_OFFSET

#define MINISRC_IN_BUFFER_SIZE
#define MINISRC_OUT_BUFFER_SIZE
#define MINISRC_TMP_BUFFER_SIZE
#define MINISRC_BIQUAD_STAGE
#define MINISRC_COEF_LOC

#define DMACONTROL_BLOCK_MASK
#define DMAC_BLOCK0_SELECTOR
#define DMAC_BLOCK1_SELECTOR
#define DMAC_BLOCK2_SELECTOR
#define DMAC_BLOCK3_SELECTOR
#define DMAC_BLOCK4_SELECTOR
#define DMAC_BLOCK5_SELECTOR
#define DMAC_BLOCK6_SELECTOR
#define DMAC_BLOCK7_SELECTOR
#define DMAC_BLOCK8_SELECTOR
#define DMAC_BLOCK9_SELECTOR
#define DMAC_BLOCKA_SELECTOR
#define DMAC_BLOCKB_SELECTOR
#define DMAC_BLOCKC_SELECTOR
#define DMAC_BLOCKD_SELECTOR
#define DMAC_BLOCKE_SELECTOR
#define DMAC_BLOCKF_SELECTOR
#define DMACONTROL_PAGE_MASK
#define DMAC_PAGE0_SELECTOR
#define DMAC_PAGE1_SELECTOR
#define DMAC_PAGE2_SELECTOR
#define DMAC_PAGE3_SELECTOR
#define DMACONTROL_AUTOREPEAT
#define DMACONTROL_STOPPED
#define DMACONTROL_DIRECTION

/*
 * an arbitrary volume we set the internal
 * volume settings to so that the ac97 volume
 * range is a little less insane.  0x7fff is 
 * max.
 */
#define ARB_VOLUME

/*
 */

struct m3_list {};

struct m3_dma {};
    
struct snd_m3 {};

/*
 * pci ids
 */
static const struct pci_device_id snd_m3_ids[] =;

MODULE_DEVICE_TABLE(pci, snd_m3_ids);

static const struct snd_pci_quirk m3_amp_quirk_list[] =;

static const struct snd_pci_quirk m3_irda_quirk_list[] =;

/* hardware volume quirks */
static const struct snd_pci_quirk m3_hv_quirk_list[] =;

/* HP Omnibook quirks */
static const struct snd_pci_quirk m3_omnibook_quirk_list[] =;

/*
 * lowlevel functions
 */

static inline void snd_m3_outw(struct snd_m3 *chip, u16 value, unsigned long reg)
{}

static inline u16 snd_m3_inw(struct snd_m3 *chip, unsigned long reg)
{}

static inline void snd_m3_outb(struct snd_m3 *chip, u8 value, unsigned long reg)
{}

static inline u8 snd_m3_inb(struct snd_m3 *chip, unsigned long reg)
{}

/*
 * access 16bit words to the code or data regions of the dsp's memory.
 * index addresses 16bit words.
 */
static u16 snd_m3_assp_read(struct snd_m3 *chip, u16 region, u16 index)
{}

static void snd_m3_assp_write(struct snd_m3 *chip, u16 region, u16 index, u16 data)
{}

static void snd_m3_assp_halt(struct snd_m3 *chip)
{}

static void snd_m3_assp_continue(struct snd_m3 *chip)
{}


/*
 * This makes me sad. the maestro3 has lists
 * internally that must be packed.. 0 terminates,
 * apparently, or maybe all unused entries have
 * to be 0, the lists have static lengths set
 * by the binary code images.
 */

static int snd_m3_add_list(struct snd_m3 *chip, struct m3_list *list, u16 val)
{}

static void snd_m3_remove_list(struct snd_m3 *chip, struct m3_list *list, int index)
{}

static void snd_m3_inc_timer_users(struct snd_m3 *chip)
{}

static void snd_m3_dec_timer_users(struct snd_m3 *chip)
{}

/*
 * start/stop
 */

/* spinlock held! */
static int snd_m3_pcm_start(struct snd_m3 *chip, struct m3_dma *s,
			    struct snd_pcm_substream *subs)
{}

/* spinlock held! */
static int snd_m3_pcm_stop(struct snd_m3 *chip, struct m3_dma *s,
			   struct snd_pcm_substream *subs)
{}

static int
snd_m3_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
{}

/*
 * setup
 */
static void 
snd_m3_pcm_setup1(struct snd_m3 *chip, struct m3_dma *s, struct snd_pcm_substream *subs)
{}

static void snd_m3_pcm_setup2(struct snd_m3 *chip, struct m3_dma *s,
			      struct snd_pcm_runtime *runtime)
{}


static const struct play_vals {} pv[] =;


/* the mode passed should be already shifted and masked */
static void
snd_m3_playback_setup(struct snd_m3 *chip, struct m3_dma *s,
		      struct snd_pcm_substream *subs)
{}

/*
 *    Native record driver 
 */
static const struct rec_vals {} rv[] =;

static void
snd_m3_capture_setup(struct snd_m3 *chip, struct m3_dma *s, struct snd_pcm_substream *subs)
{}

static int snd_m3_pcm_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *hw_params)
{}

static int snd_m3_pcm_hw_free(struct snd_pcm_substream *substream)
{}

static int
snd_m3_pcm_prepare(struct snd_pcm_substream *subs)
{}

/*
 * get current pointer
 */
static unsigned int
snd_m3_get_pointer(struct snd_m3 *chip, struct m3_dma *s, struct snd_pcm_substream *subs)
{}

static snd_pcm_uframes_t
snd_m3_pcm_pointer(struct snd_pcm_substream *subs)
{}


/* update pointer */
/* spinlock held! */
static void snd_m3_update_ptr(struct snd_m3 *chip, struct m3_dma *s)
{}

/* The m3's 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 snd_m3_update_hw_volume(struct work_struct *work)
{}

static irqreturn_t snd_m3_interrupt(int irq, void *dev_id)
{}


/*
 */

static const struct snd_pcm_hardware snd_m3_playback =;

static const struct snd_pcm_hardware snd_m3_capture =;


/*
 */

static int
snd_m3_substream_open(struct snd_m3 *chip, struct snd_pcm_substream *subs)
{}

static void
snd_m3_substream_close(struct snd_m3 *chip, struct snd_pcm_substream *subs)
{}

static int
snd_m3_playback_open(struct snd_pcm_substream *subs)
{}

static int
snd_m3_playback_close(struct snd_pcm_substream *subs)
{}

static int
snd_m3_capture_open(struct snd_pcm_substream *subs)
{}

static int
snd_m3_capture_close(struct snd_pcm_substream *subs)
{}

/*
 * create pcm instance
 */

static const struct snd_pcm_ops snd_m3_playback_ops =;

static const struct snd_pcm_ops snd_m3_capture_ops =;

static int
snd_m3_pcm(struct snd_m3 * chip, int device)
{}


/*
 * ac97 interface
 */

/*
 * Wait for the ac97 serial bus to be free.
 * return nonzero if the bus is still busy.
 */
static int snd_m3_ac97_wait(struct snd_m3 *chip)
{}

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

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


static void snd_m3_remote_codec_config(struct snd_m3 *chip, int isremote)
{}

/* 
 * hack, returns non zero on err 
 */
static int snd_m3_try_read_vendor(struct snd_m3 *chip)
{}

static void snd_m3_ac97_reset(struct snd_m3 *chip)
{}

static int snd_m3_mixer(struct snd_m3 *chip)
{}


/*
 * initialize ASSP
 */

#define MINISRC_LPF_LEN
static const u16 minisrc_lpf[MINISRC_LPF_LEN] =;

static void snd_m3_assp_init(struct snd_m3 *chip)
{}


static int snd_m3_assp_client_init(struct snd_m3 *chip, struct m3_dma *s, int index)
{}


/* 
 * this works for the reference board, have to find
 * out about others
 *
 * this needs more magic for 4 speaker, but..
 */
static void
snd_m3_amp_enable(struct snd_m3 *chip, int enable)
{}

static void
snd_m3_hv_init(struct snd_m3 *chip)
{}

static int
snd_m3_chip_init(struct snd_m3 *chip)
{} 

static void
snd_m3_enable_ints(struct snd_m3 *chip)
{}


/*
 */

static void snd_m3_free(struct snd_card *card)
{}


/*
 * APM support
 */
static int m3_suspend(struct device *dev)
{}

static int m3_resume(struct device *dev)
{}

static DEFINE_SIMPLE_DEV_PM_OPS(m3_pm, m3_suspend, m3_resume);

#ifdef CONFIG_SND_MAESTRO3_INPUT
static int snd_m3_input_register(struct snd_m3 *chip)
{}
#endif /* CONFIG_INPUT */

/*
 */

static int
snd_m3_create(struct snd_card *card, struct pci_dev *pci,
	      int enable_amp,
	      int amp_gpio)
{}

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

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

static struct pci_driver m3_driver =;
	
module_pci_driver();