linux/sound/isa/wss/wss_lib.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  Copyright (c) by Jaroslav Kysela <[email protected]>
 *  Routines for control of CS4231(A)/CS4232/InterWave & compatible chips
 *
 *  Bugs:
 *     - sometimes record brokes playback with WSS portion of
 *       Yamaha OPL3-SA3 chip
 *     - CS4231 (GUS MAX) - still trouble with occasional noises
 *			  - broken initialization?
 */

#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/io.h>
#include <sound/core.h>
#include <sound/wss.h>
#include <sound/pcm_params.h>
#include <sound/tlv.h>

#include <asm/dma.h>
#include <asm/irq.h>

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

#if 0
#define SNDRV_DEBUG_MCE
#endif

/*
 *  Some variables
 */

static const unsigned char freq_bits[14] =;

static const unsigned int rates[14] =;

static const struct snd_pcm_hw_constraint_list hw_constraints_rates =;

static int snd_wss_xrate(struct snd_pcm_runtime *runtime)
{}

static const unsigned char snd_wss_original_image[32] =;

static const unsigned char snd_opti93x_original_image[32] =;

/*
 *  Basic I/O functions
 */

static inline void wss_outb(struct snd_wss *chip, u8 offset, u8 val)
{}

static inline u8 wss_inb(struct snd_wss *chip, u8 offset)
{}

static void snd_wss_wait(struct snd_wss *chip)
{}

static void snd_wss_dout(struct snd_wss *chip, unsigned char reg,
			 unsigned char value)
{}

void snd_wss_out(struct snd_wss *chip, unsigned char reg, unsigned char value)
{}
EXPORT_SYMBOL();

unsigned char snd_wss_in(struct snd_wss *chip, unsigned char reg)
{}
EXPORT_SYMBOL();

void snd_cs4236_ext_out(struct snd_wss *chip, unsigned char reg,
			unsigned char val)
{}
EXPORT_SYMBOL();

unsigned char snd_cs4236_ext_in(struct snd_wss *chip, unsigned char reg)
{}
EXPORT_SYMBOL();

#if 0

static void snd_wss_debug(struct snd_wss *chip)
{
	printk(KERN_DEBUG
		"CS4231 REGS:      INDEX = 0x%02x  "
		"                 STATUS = 0x%02x\n",
					wss_inb(chip, CS4231P(REGSEL)),
					wss_inb(chip, CS4231P(STATUS)));
	printk(KERN_DEBUG
		"  0x00: left input      = 0x%02x  "
		"  0x10: alt 1 (CFIG 2)  = 0x%02x\n",
					snd_wss_in(chip, 0x00),
					snd_wss_in(chip, 0x10));
	printk(KERN_DEBUG
		"  0x01: right input     = 0x%02x  "
		"  0x11: alt 2 (CFIG 3)  = 0x%02x\n",
					snd_wss_in(chip, 0x01),
					snd_wss_in(chip, 0x11));
	printk(KERN_DEBUG
		"  0x02: GF1 left input  = 0x%02x  "
		"  0x12: left line in    = 0x%02x\n",
					snd_wss_in(chip, 0x02),
					snd_wss_in(chip, 0x12));
	printk(KERN_DEBUG
		"  0x03: GF1 right input = 0x%02x  "
		"  0x13: right line in   = 0x%02x\n",
					snd_wss_in(chip, 0x03),
					snd_wss_in(chip, 0x13));
	printk(KERN_DEBUG
		"  0x04: CD left input   = 0x%02x  "
		"  0x14: timer low       = 0x%02x\n",
					snd_wss_in(chip, 0x04),
					snd_wss_in(chip, 0x14));
	printk(KERN_DEBUG
		"  0x05: CD right input  = 0x%02x  "
		"  0x15: timer high      = 0x%02x\n",
					snd_wss_in(chip, 0x05),
					snd_wss_in(chip, 0x15));
	printk(KERN_DEBUG
		"  0x06: left output     = 0x%02x  "
		"  0x16: left MIC (PnP)  = 0x%02x\n",
					snd_wss_in(chip, 0x06),
					snd_wss_in(chip, 0x16));
	printk(KERN_DEBUG
		"  0x07: right output    = 0x%02x  "
		"  0x17: right MIC (PnP) = 0x%02x\n",
					snd_wss_in(chip, 0x07),
					snd_wss_in(chip, 0x17));
	printk(KERN_DEBUG
		"  0x08: playback format = 0x%02x  "
		"  0x18: IRQ status      = 0x%02x\n",
					snd_wss_in(chip, 0x08),
					snd_wss_in(chip, 0x18));
	printk(KERN_DEBUG
		"  0x09: iface (CFIG 1)  = 0x%02x  "
		"  0x19: left line out   = 0x%02x\n",
					snd_wss_in(chip, 0x09),
					snd_wss_in(chip, 0x19));
	printk(KERN_DEBUG
		"  0x0a: pin control     = 0x%02x  "
		"  0x1a: mono control    = 0x%02x\n",
					snd_wss_in(chip, 0x0a),
					snd_wss_in(chip, 0x1a));
	printk(KERN_DEBUG
		"  0x0b: init & status   = 0x%02x  "
		"  0x1b: right line out  = 0x%02x\n",
					snd_wss_in(chip, 0x0b),
					snd_wss_in(chip, 0x1b));
	printk(KERN_DEBUG
		"  0x0c: revision & mode = 0x%02x  "
		"  0x1c: record format   = 0x%02x\n",
					snd_wss_in(chip, 0x0c),
					snd_wss_in(chip, 0x1c));
	printk(KERN_DEBUG
		"  0x0d: loopback        = 0x%02x  "
		"  0x1d: var freq (PnP)  = 0x%02x\n",
					snd_wss_in(chip, 0x0d),
					snd_wss_in(chip, 0x1d));
	printk(KERN_DEBUG
		"  0x0e: ply upr count   = 0x%02x  "
		"  0x1e: ply lwr count   = 0x%02x\n",
					snd_wss_in(chip, 0x0e),
					snd_wss_in(chip, 0x1e));
	printk(KERN_DEBUG
		"  0x0f: rec upr count   = 0x%02x  "
		"  0x1f: rec lwr count   = 0x%02x\n",
					snd_wss_in(chip, 0x0f),
					snd_wss_in(chip, 0x1f));
}

#endif

/*
 *  CS4231 detection / MCE routines
 */

static void snd_wss_busy_wait(struct snd_wss *chip)
{}

void snd_wss_mce_up(struct snd_wss *chip)
{}
EXPORT_SYMBOL();

void snd_wss_mce_down(struct snd_wss *chip)
{}
EXPORT_SYMBOL();

static unsigned int snd_wss_get_count(unsigned char format, unsigned int size)
{}

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

/*
 *  CODEC I/O
 */

static unsigned char snd_wss_get_rate(unsigned int rate)
{}

static unsigned char snd_wss_get_format(struct snd_wss *chip,
					snd_pcm_format_t format,
					int channels)
{}

static void snd_wss_calibrate_mute(struct snd_wss *chip, int mute)
{}

static void snd_wss_playback_format(struct snd_wss *chip,
				       struct snd_pcm_hw_params *params,
				       unsigned char pdfr)
{}

static void snd_wss_capture_format(struct snd_wss *chip,
				   struct snd_pcm_hw_params *params,
				   unsigned char cdfr)
{}

/*
 *  Timer interface
 */

static unsigned long snd_wss_timer_resolution(struct snd_timer *timer)
{}

static int snd_wss_timer_start(struct snd_timer *timer)
{}

static int snd_wss_timer_stop(struct snd_timer *timer)
{}

static void snd_wss_init(struct snd_wss *chip)
{}

static int snd_wss_open(struct snd_wss *chip, unsigned int mode)
{}

static void snd_wss_close(struct snd_wss *chip, unsigned int mode)
{}

/*
 *  timer open/close
 */

static int snd_wss_timer_open(struct snd_timer *timer)
{}

static int snd_wss_timer_close(struct snd_timer *timer)
{}

static const struct snd_timer_hardware snd_wss_timer_table =;

/*
 *  ok.. exported functions..
 */

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

static int snd_wss_playback_prepare(struct snd_pcm_substream *substream)
{}

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

static int snd_wss_capture_prepare(struct snd_pcm_substream *substream)
{}

void snd_wss_overrange(struct snd_wss *chip)
{}
EXPORT_SYMBOL();

irqreturn_t snd_wss_interrupt(int irq, void *dev_id)
{}
EXPORT_SYMBOL();

static snd_pcm_uframes_t snd_wss_playback_pointer(struct snd_pcm_substream *substream)
{}

static snd_pcm_uframes_t snd_wss_capture_pointer(struct snd_pcm_substream *substream)
{}

/*

 */

static int snd_ad1848_probe(struct snd_wss *chip)
{}

static int snd_wss_probe(struct snd_wss *chip)
{}

/*

 */

static const struct snd_pcm_hardware snd_wss_playback =;

static const struct snd_pcm_hardware snd_wss_capture =;

/*

 */

static int snd_wss_playback_open(struct snd_pcm_substream *substream)
{}

static int snd_wss_capture_open(struct snd_pcm_substream *substream)
{}

static int snd_wss_playback_close(struct snd_pcm_substream *substream)
{}

static int snd_wss_capture_close(struct snd_pcm_substream *substream)
{}

static void snd_wss_thinkpad_twiddle(struct snd_wss *chip, int on)
{}

#ifdef CONFIG_PM

/* lowlevel suspend callback for CS4231 */
static void snd_wss_suspend(struct snd_wss *chip)
{}

/* lowlevel resume callback for CS4231 */
static void snd_wss_resume(struct snd_wss *chip)
{}
#endif /* CONFIG_PM */

const char *snd_wss_chip_id(struct snd_wss *chip)
{}
EXPORT_SYMBOL();

static int snd_wss_new(struct snd_card *card,
			  unsigned short hardware,
			  unsigned short hwshare,
			  struct snd_wss **rchip)
{}

int snd_wss_create(struct snd_card *card,
		      unsigned long port,
		      unsigned long cport,
		      int irq, int dma1, int dma2,
		      unsigned short hardware,
		      unsigned short hwshare,
		      struct snd_wss **rchip)
{}
EXPORT_SYMBOL();

static const struct snd_pcm_ops snd_wss_playback_ops =;

static const struct snd_pcm_ops snd_wss_capture_ops =;

int snd_wss_pcm(struct snd_wss *chip, int device)
{}
EXPORT_SYMBOL();

static void snd_wss_timer_free(struct snd_timer *timer)
{}

int snd_wss_timer(struct snd_wss *chip, int device)
{}
EXPORT_SYMBOL();

/*
 *  MIXER part
 */

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

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

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

int snd_wss_info_single(struct snd_kcontrol *kcontrol,
			struct snd_ctl_elem_info *uinfo)
{}
EXPORT_SYMBOL();

int snd_wss_get_single(struct snd_kcontrol *kcontrol,
		       struct snd_ctl_elem_value *ucontrol)
{}
EXPORT_SYMBOL();

int snd_wss_put_single(struct snd_kcontrol *kcontrol,
		       struct snd_ctl_elem_value *ucontrol)
{}
EXPORT_SYMBOL();

int snd_wss_info_double(struct snd_kcontrol *kcontrol,
			struct snd_ctl_elem_info *uinfo)
{}
EXPORT_SYMBOL();

int snd_wss_get_double(struct snd_kcontrol *kcontrol,
		       struct snd_ctl_elem_value *ucontrol)
{}
EXPORT_SYMBOL();

int snd_wss_put_double(struct snd_kcontrol *kcontrol,
		       struct snd_ctl_elem_value *ucontrol)
{}
EXPORT_SYMBOL();

static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
static const DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0);

static const struct snd_kcontrol_new snd_wss_controls[] =;

int snd_wss_mixer(struct snd_wss *chip)
{}
EXPORT_SYMBOL();

const struct snd_pcm_ops *snd_wss_get_pcm_ops(int direction)
{}
EXPORT_SYMBOL();