linux/sound/pci/emu10k1/emu10k1x.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  Copyright (c) by Francisco Moraes <[email protected]>
 *  Driver EMU10K1X chips
 *
 *  Parts of this code were adapted from audigyls.c driver which is
 *  Copyright (c) by James Courtier-Dutton <[email protected]>
 *
 *  BUGS:
 *    --
 *
 *  TODO:
 *
 *  Chips (SB0200 model):
 *    - EMU10K1X-DBQ
 *    - STAC 9708T
 */
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/pcm.h>
#include <sound/ac97_codec.h>
#include <sound/info.h>
#include <sound/rawmidi.h>

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

// module parameters (see "Module Parameters")
static int index[SNDRV_CARDS] =;
static char *id[SNDRV_CARDS] =;
static bool enable[SNDRV_CARDS] =;

module_param_array();
MODULE_PARM_DESC();
module_param_array();
MODULE_PARM_DESC();
module_param_array();
MODULE_PARM_DESC();


// some definitions were borrowed from emu10k1 driver as they seem to be the same
/************************************************************************************************/
/* PCI function 0 registers, address = <val> + PCIBASE0						*/
/************************************************************************************************/

#define PTR
						/* NOTE: The CHANNELNUM and ADDRESS words can	*/
						/* be modified independently of each other.	*/

#define DATA

#define IPR
						/* Clear pending interrupts by writing a 1 to	*/
						/* the relevant bits and zero to the other bits	*/
#define IPR_MIDITRANSBUFEMPTY
#define IPR_MIDIRECVBUFEMPTY
#define IPR_CH_0_LOOP
#define IPR_CH_0_HALF_LOOP
#define IPR_CAP_0_LOOP
#define IPR_CAP_0_HALF_LOOP

#define INTE
#define INTE_MIDITXENABLE
#define INTE_MIDIRXENABLE
#define INTE_CH_0_LOOP
#define INTE_CH_0_HALF_LOOP
#define INTE_CAP_0_LOOP
#define INTE_CAP_0_HALF_LOOP

#define HCFG

#define HCFG_LOCKSOUNDCACHE
						/* NOTE: This should generally never be used.  	*/
#define HCFG_AUDIOENABLE
						/* Should be set to 1 when the EMU10K1 is	*/
						/* completely initialized.			*/
#define GPIO


#define AC97DATA

#define AC97ADDRESS

/********************************************************************************************************/
/* Emu10k1x pointer-offset register set, accessed through the PTR and DATA registers			*/
/********************************************************************************************************/
#define PLAYBACK_LIST_ADDR
						/* One list entry: 4 bytes for DMA address, 
						 * 4 bytes for period_size << 16.
						 * One list entry is 8 bytes long.
						 * One list entry for each period in the buffer.
						 */
#define PLAYBACK_LIST_SIZE
#define PLAYBACK_LIST_PTR
#define PLAYBACK_DMA_ADDR
#define PLAYBACK_PERIOD_SIZE
#define PLAYBACK_POINTER
#define PLAYBACK_UNKNOWN1
#define PLAYBACK_UNKNOWN2

/* Only one capture channel supported */
#define CAPTURE_DMA_ADDR
#define CAPTURE_BUFFER_SIZE
#define CAPTURE_POINTER
#define CAPTURE_UNKNOWN

/* From 0x20 - 0x3f, last samples played on each channel */

#define TRIGGER_CHANNEL
#define TRIGGER_CHANNEL_0
#define TRIGGER_CHANNEL_1
#define TRIGGER_CHANNEL_2
#define TRIGGER_CAPTURE

#define ROUTING
#define ROUTING_FRONT_LEFT
#define ROUTING_FRONT_RIGHT
#define ROUTING_REAR_LEFT
#define ROUTING_REAR_RIGHT
#define ROUTING_CENTER_LFE

#define SPCS0

#define SPCS1

#define SPCS2

#define SPCS_CLKACCYMASK
#define SPCS_CLKACCY_1000PPM
#define SPCS_CLKACCY_50PPM
#define SPCS_CLKACCY_VARIABLE
#define SPCS_SAMPLERATEMASK
#define SPCS_SAMPLERATE_44
#define SPCS_SAMPLERATE_48
#define SPCS_SAMPLERATE_32
#define SPCS_CHANNELNUMMASK
#define SPCS_CHANNELNUM_UNSPEC
#define SPCS_CHANNELNUM_LEFT
#define SPCS_CHANNELNUM_RIGHT
#define SPCS_SOURCENUMMASK
#define SPCS_SOURCENUM_UNSPEC
#define SPCS_GENERATIONSTATUS
#define SPCS_CATEGORYCODEMASK
#define SPCS_MODEMASK
#define SPCS_EMPHASISMASK
#define SPCS_EMPHASIS_NONE
#define SPCS_EMPHASIS_50_15
#define SPCS_COPYRIGHT
#define SPCS_NOTAUDIODATA
#define SPCS_PROFESSIONAL

#define SPDIF_SELECT

/* This is the MPU port on the card                      					*/
#define MUDATA
#define MUCMD
#define MUSTAT

/* From 0x50 - 0x5f, last samples captured */

/*
 * The hardware has 3 channels for playback and 1 for capture.
 *  - channel 0 is the front channel
 *  - channel 1 is the rear channel
 *  - channel 2 is the center/lfe channel
 * Volume is controlled by the AC97 for the front and rear channels by
 * the PCM Playback Volume, Sigmatel Surround Playback Volume and 
 * Surround Playback Volume. The Sigmatel 4-Speaker Stereo switch affects
 * the front/rear channel mixing in the REAR OUT jack. When using the
 * 4-Speaker Stereo, both front and rear channels will be mixed in the
 * REAR OUT.
 * The center/lfe channel has no volume control and cannot be muted during
 * playback.
 */

struct emu10k1x_voice {};

struct emu10k1x_pcm {};

struct emu10k1x_midi {};

// definition of the chip-specific record
struct emu10k1x {};

/* hardware definition */
static const struct snd_pcm_hardware snd_emu10k1x_playback_hw =;

static const struct snd_pcm_hardware snd_emu10k1x_capture_hw =;

static unsigned int snd_emu10k1x_ptr_read(struct emu10k1x * emu, 
					  unsigned int reg, 
					  unsigned int chn)
{}

static void snd_emu10k1x_ptr_write(struct emu10k1x *emu, 
				   unsigned int reg, 
				   unsigned int chn, 
				   unsigned int data)
{}

static void snd_emu10k1x_intr_enable(struct emu10k1x *emu, unsigned int intrenb)
{}

static void snd_emu10k1x_intr_disable(struct emu10k1x *emu, unsigned int intrenb)
{}

static void snd_emu10k1x_gpio_write(struct emu10k1x *emu, unsigned int value)
{}

static void snd_emu10k1x_pcm_free_substream(struct snd_pcm_runtime *runtime)
{}

static void snd_emu10k1x_pcm_interrupt(struct emu10k1x *emu, struct emu10k1x_voice *voice)
{}

/* open callback */
static int snd_emu10k1x_playback_open(struct snd_pcm_substream *substream)
{}

/* close callback */
static int snd_emu10k1x_playback_close(struct snd_pcm_substream *substream)
{}

/* hw_params callback */
static int snd_emu10k1x_pcm_hw_params(struct snd_pcm_substream *substream,
				      struct snd_pcm_hw_params *hw_params)
{}

/* hw_free callback */
static int snd_emu10k1x_pcm_hw_free(struct snd_pcm_substream *substream)
{}

/* prepare callback */
static int snd_emu10k1x_pcm_prepare(struct snd_pcm_substream *substream)
{}

/* trigger callback */
static int snd_emu10k1x_pcm_trigger(struct snd_pcm_substream *substream,
				    int cmd)
{}

/* pointer callback */
static snd_pcm_uframes_t
snd_emu10k1x_pcm_pointer(struct snd_pcm_substream *substream)
{}

/* operators */
static const struct snd_pcm_ops snd_emu10k1x_playback_ops =;

/* open_capture callback */
static int snd_emu10k1x_pcm_open_capture(struct snd_pcm_substream *substream)
{}

/* close callback */
static int snd_emu10k1x_pcm_close_capture(struct snd_pcm_substream *substream)
{}

/* hw_params callback */
static int snd_emu10k1x_pcm_hw_params_capture(struct snd_pcm_substream *substream,
					      struct snd_pcm_hw_params *hw_params)
{}

/* hw_free callback */
static int snd_emu10k1x_pcm_hw_free_capture(struct snd_pcm_substream *substream)
{}

/* prepare capture callback */
static int snd_emu10k1x_pcm_prepare_capture(struct snd_pcm_substream *substream)
{}

/* trigger_capture callback */
static int snd_emu10k1x_pcm_trigger_capture(struct snd_pcm_substream *substream,
					    int cmd)
{}

/* pointer_capture callback */
static snd_pcm_uframes_t
snd_emu10k1x_pcm_pointer_capture(struct snd_pcm_substream *substream)
{}

static const struct snd_pcm_ops snd_emu10k1x_capture_ops =;

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

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

static int snd_emu10k1x_ac97(struct emu10k1x *chip)
{}

static void snd_emu10k1x_free(struct snd_card *card)
{}

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

static const struct snd_pcm_chmap_elem surround_map[] =;

static const struct snd_pcm_chmap_elem clfe_map[] =;

static int snd_emu10k1x_pcm(struct emu10k1x *emu, int device)
{}

static int snd_emu10k1x_create(struct snd_card *card,
			       struct pci_dev *pci)
{}

static void snd_emu10k1x_proc_reg_read(struct snd_info_entry *entry, 
				       struct snd_info_buffer *buffer)
{}

static void snd_emu10k1x_proc_reg_write(struct snd_info_entry *entry, 
					struct snd_info_buffer *buffer)
{}

static int snd_emu10k1x_proc_init(struct emu10k1x *emu)
{}

#define snd_emu10k1x_shared_spdif_info

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

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

static const struct snd_kcontrol_new snd_emu10k1x_shared_spdif =;

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

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

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

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

static const struct snd_kcontrol_new snd_emu10k1x_spdif_mask_control =;

static const struct snd_kcontrol_new snd_emu10k1x_spdif_control =;

static int snd_emu10k1x_mixer(struct emu10k1x *emu)
{}

#define EMU10K1X_MIDI_MODE_INPUT
#define EMU10K1X_MIDI_MODE_OUTPUT

static inline unsigned char mpu401_read(struct emu10k1x *emu, struct emu10k1x_midi *mpu, int idx)
{}

static inline void mpu401_write(struct emu10k1x *emu, struct emu10k1x_midi *mpu, int data, int idx)
{}

#define mpu401_write_data(emu, mpu, data)
#define mpu401_write_cmd(emu, mpu, data)
#define mpu401_read_data(emu, mpu)
#define mpu401_read_stat(emu, mpu)

#define mpu401_input_avail(emu,mpu)
#define mpu401_output_ready(emu,mpu)

#define MPU401_RESET
#define MPU401_ENTER_UART
#define MPU401_ACK

static void mpu401_clear_rx(struct emu10k1x *emu, struct emu10k1x_midi *mpu)
{}

/*

 */

static void do_emu10k1x_midi_interrupt(struct emu10k1x *emu,
				       struct emu10k1x_midi *midi, unsigned int status)
{}

static void snd_emu10k1x_midi_interrupt(struct emu10k1x *emu, unsigned int status)
{}

static int snd_emu10k1x_midi_cmd(struct emu10k1x * emu,
				  struct emu10k1x_midi *midi, unsigned char cmd, int ack)
{}

static int snd_emu10k1x_midi_input_open(struct snd_rawmidi_substream *substream)
{}

static int snd_emu10k1x_midi_output_open(struct snd_rawmidi_substream *substream)
{}

static int snd_emu10k1x_midi_input_close(struct snd_rawmidi_substream *substream)
{}

static int snd_emu10k1x_midi_output_close(struct snd_rawmidi_substream *substream)
{}

static void snd_emu10k1x_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
{}

static void snd_emu10k1x_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
{}

/*

 */

static const struct snd_rawmidi_ops snd_emu10k1x_midi_output =;

static const struct snd_rawmidi_ops snd_emu10k1x_midi_input =;

static void snd_emu10k1x_midi_free(struct snd_rawmidi *rmidi)
{}

static int emu10k1x_midi_init(struct emu10k1x *emu,
			      struct emu10k1x_midi *midi, int device,
			      char *name)
{}

static int snd_emu10k1x_midi(struct emu10k1x *emu)
{}

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

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

// PCI IDs
static const struct pci_device_id snd_emu10k1x_ids[] =;
MODULE_DEVICE_TABLE(pci, snd_emu10k1x_ids);

// pci_driver definition
static struct pci_driver emu10k1x_driver =;

module_pci_driver();