#include <linux/io.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/gameport.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <sound/core.h>
#include <sound/control.h>
#include <sound/pcm.h>
#include <sound/rawmidi.h>
#ifdef CHIP1371
#include <sound/ac97_codec.h>
#else
#include <sound/ak4531_codec.h>
#endif
#include <sound/initval.h>
#include <sound/asoundef.h>
#ifndef CHIP1371
#undef CHIP1370
#define CHIP1370
#endif
#ifdef CHIP1370
#define DRIVER_NAME …
#define CHIP_NAME …
#else
#define DRIVER_NAME …
#define CHIP_NAME …
#endif
MODULE_AUTHOR(…) …;
MODULE_LICENSE(…) …;
#ifdef CHIP1370
MODULE_DESCRIPTION(…) …;
#endif
#ifdef CHIP1371
MODULE_DESCRIPTION("Ensoniq/Creative AudioPCI ES1371+");
#endif
#if IS_REACHABLE(CONFIG_GAMEPORT)
#define SUPPORT_JOYSTICK
#endif
static int index[SNDRV_CARDS] = …;
static char *id[SNDRV_CARDS] = …;
static bool enable[SNDRV_CARDS] = …;
#ifdef SUPPORT_JOYSTICK
#ifdef CHIP1371
static int joystick_port[SNDRV_CARDS];
#else
static bool joystick[SNDRV_CARDS];
#endif
#endif
#ifdef CHIP1371
static int spdif[SNDRV_CARDS];
static int lineio[SNDRV_CARDS];
#endif
module_param_array(…);
MODULE_PARM_DESC(…) …;
module_param_array(…);
MODULE_PARM_DESC(…) …;
module_param_array(…);
MODULE_PARM_DESC(…) …;
#ifdef SUPPORT_JOYSTICK
#ifdef CHIP1371
module_param_hw_array(joystick_port, int, ioport, NULL, 0444);
MODULE_PARM_DESC(joystick_port, "Joystick port address.");
#else
module_param_array(…);
MODULE_PARM_DESC(…) …;
#endif
#endif
#ifdef CHIP1371
module_param_array(spdif, int, NULL, 0444);
MODULE_PARM_DESC(spdif, "S/PDIF output (-1 = none, 0 = auto, 1 = force).");
module_param_array(lineio, int, NULL, 0444);
MODULE_PARM_DESC(lineio, "Line In to Rear Out (0 = auto, 1 = force).");
#endif
#define ES1371REV_ES1373_A …
#define ES1371REV_ES1373_B …
#define ES1371REV_CT5880_A …
#define CT5880REV_CT5880_C …
#define CT5880REV_CT5880_D …
#define CT5880REV_CT5880_E …
#define ES1371REV_ES1371_B …
#define EV1938REV_EV1938_A …
#define ES1371REV_ES1373_8 …
#define ES_REG(ensoniq, x) …
#define ES_REG_CONTROL …
#define ES_1370_ADC_STOP …
#define ES_1370_XCTL1 …
#define ES_1373_BYPASS_P1 …
#define ES_1373_BYPASS_P2 …
#define ES_1373_BYPASS_R …
#define ES_1373_TEST_BIT …
#define ES_1373_RECEN_B …
#define ES_1373_SPDIF_THRU …
#define ES_1371_JOY_ASEL(o) …
#define ES_1371_JOY_ASELM …
#define ES_1371_JOY_ASELI(i) …
#define ES_1371_GPIO_IN(i) …
#define ES_1370_PCLKDIVO(o) …
#define ES_1370_PCLKDIVM …
#define ES_1370_PCLKDIVI(i) …
#define ES_1371_GPIO_OUT(o) …
#define ES_1371_GPIO_OUTM …
#define ES_MSFMTSEL …
#define ES_1370_M_SBB …
#define ES_1371_SYNC_RES …
#define ES_1370_WTSRSEL(o) …
#define ES_1370_WTSRSELM …
#define ES_1371_ADC_STOP …
#define ES_1371_PWR_INTRM …
#define ES_1370_DAC_SYNC …
#define ES_1371_M_CB …
#define ES_CCB_INTRM …
#define ES_1370_M_CB …
#define ES_1370_XCTL0 …
#define ES_1371_PDLEV(o) …
#define ES_1371_PDLEVM …
#define ES_BREQ …
#define ES_DAC1_EN …
#define ES_DAC2_EN …
#define ES_ADC_EN …
#define ES_UART_EN …
#define ES_JYSTK_EN …
#define ES_1370_CDC_EN …
#define ES_1371_XTALCKDIS …
#define ES_1370_SERR_DISABLE …
#define ES_1371_PCICLKDIS …
#define ES_REG_STATUS …
#define ES_INTR …
#define ES_1371_ST_AC97_RST …
#define ES_1373_REAR_BIT27 …
#define ES_1373_REAR_BIT26 …
#define ES_1373_REAR_BIT24 …
#define ES_1373_GPIO_INT_EN(o) …
#define ES_1373_SPDIF_EN …
#define ES_1373_SPDIF_TEST …
#define ES_1371_TEST …
#define ES_1373_GPIO_INT(i) …
#define ES_1370_CSTAT …
#define ES_1370_CBUSY …
#define ES_1370_CWRIP …
#define ES_1371_SYNC_ERR …
#define ES_1371_VC(i) …
#define ES_1370_VC(i) …
#define ES_1371_MPWR …
#define ES_MCCB …
#define ES_UART …
#define ES_DAC1 …
#define ES_DAC2 …
#define ES_ADC …
#define ES_REG_UART_DATA …
#define ES_REG_UART_STATUS …
#define ES_RXINT …
#define ES_TXINT …
#define ES_TXRDY …
#define ES_RXRDY …
#define ES_REG_UART_CONTROL …
#define ES_RXINTEN …
#define ES_TXINTENO(o) …
#define ES_TXINTENM …
#define ES_TXINTENI(i) …
#define ES_CNTRL(o) …
#define ES_CNTRLM …
#define ES_REG_UART_RES …
#define ES_TEST_MODE …
#define ES_REG_MEM_PAGE …
#define ES_MEM_PAGEO(o) …
#define ES_MEM_PAGEM …
#define ES_MEM_PAGEI(i) …
#define ES_REG_1370_CODEC …
#define ES_1370_CODEC_WRITE(a,d) …
#define ES_REG_1371_CODEC …
#define ES_1371_CODEC_RDY …
#define ES_1371_CODEC_WIP …
#define EV_1938_CODEC_MAGIC …
#define ES_1371_CODEC_PIRD …
#define ES_1371_CODEC_WRITE(a,d) …
#define ES_1371_CODEC_READS(a) …
#define ES_1371_CODEC_READ(i) …
#define ES_REG_1371_SMPRATE …
#define ES_1371_SRC_RAM_ADDRO(o) …
#define ES_1371_SRC_RAM_ADDRM …
#define ES_1371_SRC_RAM_ADDRI(i) …
#define ES_1371_SRC_RAM_WE …
#define ES_1371_SRC_RAM_BUSY …
#define ES_1371_SRC_DISABLE …
#define ES_1371_DIS_P1 …
#define ES_1371_DIS_P2 …
#define ES_1371_DIS_R1 …
#define ES_1371_SRC_RAM_DATAO(o) …
#define ES_1371_SRC_RAM_DATAM …
#define ES_1371_SRC_RAM_DATAI(i) …
#define ES_REG_1371_LEGACY …
#define ES_1371_JFAST …
#define ES_1371_HIB …
#define ES_1371_VSB …
#define ES_1371_VMPUO(o) …
#define ES_1371_VMPUM …
#define ES_1371_VMPUI(i) …
#define ES_1371_VCDCO(o) …
#define ES_1371_VCDCM …
#define ES_1371_VCDCI(i) …
#define ES_1371_FIRQ …
#define ES_1371_SDMACAP …
#define ES_1371_SPICAP …
#define ES_1371_MDMACAP …
#define ES_1371_MPICAP …
#define ES_1371_ADCAP …
#define ES_1371_SVCAP …
#define ES_1371_CDCCAP …
#define ES_1371_BACAP …
#define ES_1371_EXI(i) …
#define ES_1371_AI(i) …
#define ES_1371_WR …
#define ES_1371_LEGINT …
#define ES_REG_CHANNEL_STATUS …
#define ES_REG_SERIAL …
#define ES_1371_DAC_TEST …
#define ES_P2_END_INCO(o) …
#define ES_P2_END_INCM …
#define ES_P2_END_INCI(i) …
#define ES_P2_ST_INCO(o) …
#define ES_P2_ST_INCM …
#define ES_P2_ST_INCI(i) …
#define ES_R1_LOOP_SEL …
#define ES_P2_LOOP_SEL …
#define ES_P1_LOOP_SEL …
#define ES_P2_PAUSE …
#define ES_P1_PAUSE …
#define ES_R1_INT_EN …
#define ES_P2_INT_EN …
#define ES_P1_INT_EN …
#define ES_P1_SCT_RLD …
#define ES_P2_DAC_SEN …
#define ES_R1_MODEO(o) …
#define ES_R1_MODEM …
#define ES_R1_MODEI(i) …
#define ES_P2_MODEO(o) …
#define ES_P2_MODEM …
#define ES_P2_MODEI(i) …
#define ES_P1_MODEO(o) …
#define ES_P1_MODEM …
#define ES_P1_MODEI(i) …
#define ES_REG_DAC1_COUNT …
#define ES_REG_DAC2_COUNT …
#define ES_REG_ADC_COUNT …
#define ES_REG_CURR_COUNT(i) …
#define ES_REG_COUNTO(o) …
#define ES_REG_COUNTM …
#define ES_REG_COUNTI(i) …
#define ES_REG_DAC1_FRAME …
#define ES_REG_DAC1_SIZE …
#define ES_REG_DAC2_FRAME …
#define ES_REG_DAC2_SIZE …
#define ES_REG_ADC_FRAME …
#define ES_REG_ADC_SIZE …
#define ES_REG_FCURR_COUNTO(o) …
#define ES_REG_FCURR_COUNTM …
#define ES_REG_FCURR_COUNTI(i) …
#define ES_REG_FSIZEO(o) …
#define ES_REG_FSIZEM …
#define ES_REG_FSIZEI(i) …
#define ES_REG_PHANTOM_FRAME …
#define ES_REG_PHANTOM_COUNT …
#define ES_REG_UART_FIFO …
#define ES_REG_UF_VALID …
#define ES_REG_UF_BYTEO(o) …
#define ES_REG_UF_BYTEM …
#define ES_REG_UF_BYTEI(i) …
#define ES_PAGE_DAC …
#define ES_PAGE_ADC …
#define ES_PAGE_UART …
#define ES_PAGE_UART1 …
#define ES_SMPREG_DAC1 …
#define ES_SMPREG_DAC2 …
#define ES_SMPREG_ADC …
#define ES_SMPREG_VOL_ADC …
#define ES_SMPREG_VOL_DAC1 …
#define ES_SMPREG_VOL_DAC2 …
#define ES_SMPREG_TRUNC_N …
#define ES_SMPREG_INT_REGS …
#define ES_SMPREG_ACCUM_FRAC …
#define ES_SMPREG_VFREQ_FRAC …
#define ES_1370_SRCLOCK …
#define ES_1370_SRTODIV(x) …
#define ES_MODE_PLAY1 …
#define ES_MODE_PLAY2 …
#define ES_MODE_CAPTURE …
#define ES_MODE_OUTPUT …
#define ES_MODE_INPUT …
struct ensoniq { … };
static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id);
static const struct pci_device_id snd_audiopci_ids[] = …;
MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
#define POLL_COUNT …
#ifdef CHIP1370
static const unsigned int snd_es1370_fixed_rates[] = …;
static const struct snd_pcm_hw_constraint_list snd_es1370_hw_constraints_rates = …;
static const struct snd_ratnum es1370_clock = …;
static const struct snd_pcm_hw_constraint_ratnums snd_es1370_hw_constraints_clock = …;
#else
static const struct snd_ratden es1371_dac_clock = {
.num_min = 3000 * (1 << 15),
.num_max = 48000 * (1 << 15),
.num_step = 3000,
.den = 1 << 15,
};
static const struct snd_pcm_hw_constraint_ratdens snd_es1371_hw_constraints_dac_clock = {
.nrats = 1,
.rats = &es1371_dac_clock,
};
static const struct snd_ratnum es1371_adc_clock = {
.num = 48000 << 15,
.den_min = 32768,
.den_max = 393216,
.den_step = 1,
};
static const struct snd_pcm_hw_constraint_ratnums snd_es1371_hw_constraints_adc_clock = {
.nrats = 1,
.rats = &es1371_adc_clock,
};
#endif
static const unsigned int snd_ensoniq_sample_shift[] = …;
#ifdef CHIP1371
static unsigned int snd_es1371_wait_src_ready(struct ensoniq * ensoniq)
{
unsigned int t, r = 0;
for (t = 0; t < POLL_COUNT; t++) {
r = inl(ES_REG(ensoniq, 1371_SMPRATE));
if ((r & ES_1371_SRC_RAM_BUSY) == 0)
return r;
cond_resched();
}
dev_err(ensoniq->card->dev, "wait src ready timeout 0x%lx [0x%x]\n",
ES_REG(ensoniq, 1371_SMPRATE), r);
return 0;
}
static unsigned int snd_es1371_src_read(struct ensoniq * ensoniq, unsigned short reg)
{
unsigned int temp, i, orig, r;
temp = orig = snd_es1371_wait_src_ready(ensoniq);
r = temp & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |
ES_1371_DIS_P2 | ES_1371_DIS_R1);
r |= ES_1371_SRC_RAM_ADDRO(reg) | 0x10000;
outl(r, ES_REG(ensoniq, 1371_SMPRATE));
temp = snd_es1371_wait_src_ready(ensoniq);
if ((temp & 0x00870000) != 0x00010000) {
for (i = 0; i < POLL_COUNT; i++) {
temp = inl(ES_REG(ensoniq, 1371_SMPRATE));
if ((temp & 0x00870000) == 0x00010000)
break;
}
}
r = orig & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |
ES_1371_DIS_P2 | ES_1371_DIS_R1);
r |= ES_1371_SRC_RAM_ADDRO(reg);
outl(r, ES_REG(ensoniq, 1371_SMPRATE));
return temp;
}
static void snd_es1371_src_write(struct ensoniq * ensoniq,
unsigned short reg, unsigned short data)
{
unsigned int r;
r = snd_es1371_wait_src_ready(ensoniq) &
(ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |
ES_1371_DIS_P2 | ES_1371_DIS_R1);
r |= ES_1371_SRC_RAM_ADDRO(reg) | ES_1371_SRC_RAM_DATAO(data);
outl(r | ES_1371_SRC_RAM_WE, ES_REG(ensoniq, 1371_SMPRATE));
}
#endif
#ifdef CHIP1370
static void snd_es1370_codec_write(struct snd_ak4531 *ak4531,
unsigned short reg, unsigned short val)
{ … }
#endif
#ifdef CHIP1371
static inline bool is_ev1938(struct ensoniq *ensoniq)
{
return ensoniq->pci->device == 0x8938;
}
static void snd_es1371_codec_write(struct snd_ac97 *ac97,
unsigned short reg, unsigned short val)
{
struct ensoniq *ensoniq = ac97->private_data;
unsigned int t, x, flag;
flag = is_ev1938(ensoniq) ? EV_1938_CODEC_MAGIC : 0;
mutex_lock(&ensoniq->src_mutex);
for (t = 0; t < POLL_COUNT; t++) {
if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) {
x = snd_es1371_wait_src_ready(ensoniq);
outl((x & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |
ES_1371_DIS_P2 | ES_1371_DIS_R1)) | 0x00010000,
ES_REG(ensoniq, 1371_SMPRATE));
for (t = 0; t < POLL_COUNT; t++) {
if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==
0x00000000)
break;
}
for (t = 0; t < POLL_COUNT; t++) {
if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==
0x00010000)
break;
}
outl(ES_1371_CODEC_WRITE(reg, val) | flag,
ES_REG(ensoniq, 1371_CODEC));
snd_es1371_wait_src_ready(ensoniq);
outl(x, ES_REG(ensoniq, 1371_SMPRATE));
mutex_unlock(&ensoniq->src_mutex);
return;
}
}
mutex_unlock(&ensoniq->src_mutex);
dev_err(ensoniq->card->dev, "codec write timeout at 0x%lx [0x%x]\n",
ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
}
static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97,
unsigned short reg)
{
struct ensoniq *ensoniq = ac97->private_data;
unsigned int t, x, flag, fail = 0;
flag = is_ev1938(ensoniq) ? EV_1938_CODEC_MAGIC : 0;
__again:
mutex_lock(&ensoniq->src_mutex);
for (t = 0; t < POLL_COUNT; t++) {
if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) {
x = snd_es1371_wait_src_ready(ensoniq);
outl((x & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |
ES_1371_DIS_P2 | ES_1371_DIS_R1)) | 0x00010000,
ES_REG(ensoniq, 1371_SMPRATE));
for (t = 0; t < POLL_COUNT; t++) {
if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==
0x00000000)
break;
}
for (t = 0; t < POLL_COUNT; t++) {
if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==
0x00010000)
break;
}
outl(ES_1371_CODEC_READS(reg) | flag,
ES_REG(ensoniq, 1371_CODEC));
snd_es1371_wait_src_ready(ensoniq);
outl(x, ES_REG(ensoniq, 1371_SMPRATE));
for (t = 0; t < POLL_COUNT; t++) {
if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP))
break;
}
for (t = 0; t < POLL_COUNT; t++) {
x = inl(ES_REG(ensoniq, 1371_CODEC));
if (x & ES_1371_CODEC_RDY) {
if (is_ev1938(ensoniq)) {
for (t = 0; t < 100; t++)
inl(ES_REG(ensoniq, CONTROL));
x = inl(ES_REG(ensoniq, 1371_CODEC));
}
mutex_unlock(&ensoniq->src_mutex);
return ES_1371_CODEC_READ(x);
}
}
mutex_unlock(&ensoniq->src_mutex);
if (++fail > 10) {
dev_err(ensoniq->card->dev,
"codec read timeout (final) at 0x%lx, reg = 0x%x [0x%x]\n",
ES_REG(ensoniq, 1371_CODEC), reg,
inl(ES_REG(ensoniq, 1371_CODEC)));
return 0;
}
goto __again;
}
}
mutex_unlock(&ensoniq->src_mutex);
dev_err(ensoniq->card->dev, "codec read timeout at 0x%lx [0x%x]\n",
ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
return 0;
}
static void snd_es1371_codec_wait(struct snd_ac97 *ac97)
{
msleep(750);
snd_es1371_codec_read(ac97, AC97_RESET);
snd_es1371_codec_read(ac97, AC97_VENDOR_ID1);
snd_es1371_codec_read(ac97, AC97_VENDOR_ID2);
msleep(50);
}
static void snd_es1371_adc_rate(struct ensoniq * ensoniq, unsigned int rate)
{
unsigned int n, truncm, freq;
mutex_lock(&ensoniq->src_mutex);
n = rate / 3000;
if ((1 << n) & ((1 << 15) | (1 << 13) | (1 << 11) | (1 << 9)))
n--;
truncm = (21 * n - 1) | 1;
freq = ((48000UL << 15) / rate) * n;
if (rate >= 24000) {
if (truncm > 239)
truncm = 239;
snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N,
(((239 - truncm) >> 1) << 9) | (n << 4));
} else {
if (truncm > 119)
truncm = 119;
snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N,
0x8000 | (((119 - truncm) >> 1) << 9) | (n << 4));
}
snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_INT_REGS,
(snd_es1371_src_read(ensoniq, ES_SMPREG_ADC +
ES_SMPREG_INT_REGS) & 0x00ff) |
((freq >> 5) & 0xfc00));
snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, n << 8);
snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, n << 8);
mutex_unlock(&ensoniq->src_mutex);
}
static void snd_es1371_dac1_rate(struct ensoniq * ensoniq, unsigned int rate)
{
unsigned int freq, r;
mutex_lock(&ensoniq->src_mutex);
freq = DIV_ROUND_CLOSEST(rate << 15, 3000);
r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |
ES_1371_DIS_P2 | ES_1371_DIS_R1)) |
ES_1371_DIS_P1;
outl(r, ES_REG(ensoniq, 1371_SMPRATE));
snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS,
(snd_es1371_src_read(ensoniq, ES_SMPREG_DAC1 +
ES_SMPREG_INT_REGS) & 0x00ff) |
((freq >> 5) & 0xfc00));
snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |
ES_1371_DIS_P2 | ES_1371_DIS_R1));
outl(r, ES_REG(ensoniq, 1371_SMPRATE));
mutex_unlock(&ensoniq->src_mutex);
}
static void snd_es1371_dac2_rate(struct ensoniq * ensoniq, unsigned int rate)
{
unsigned int freq, r;
mutex_lock(&ensoniq->src_mutex);
freq = DIV_ROUND_CLOSEST(rate << 15, 3000);
r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |
ES_1371_DIS_P1 | ES_1371_DIS_R1)) |
ES_1371_DIS_P2;
outl(r, ES_REG(ensoniq, 1371_SMPRATE));
snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS,
(snd_es1371_src_read(ensoniq, ES_SMPREG_DAC2 +
ES_SMPREG_INT_REGS) & 0x00ff) |
((freq >> 5) & 0xfc00));
snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_VFREQ_FRAC,
freq & 0x7fff);
r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |
ES_1371_DIS_P1 | ES_1371_DIS_R1));
outl(r, ES_REG(ensoniq, 1371_SMPRATE));
mutex_unlock(&ensoniq->src_mutex);
}
#endif
static int snd_ensoniq_trigger(struct snd_pcm_substream *substream, int cmd)
{ … }
static int snd_ensoniq_playback1_prepare(struct snd_pcm_substream *substream)
{ … }
static int snd_ensoniq_playback2_prepare(struct snd_pcm_substream *substream)
{ … }
static int snd_ensoniq_capture_prepare(struct snd_pcm_substream *substream)
{ … }
static snd_pcm_uframes_t snd_ensoniq_playback1_pointer(struct snd_pcm_substream *substream)
{ … }
static snd_pcm_uframes_t snd_ensoniq_playback2_pointer(struct snd_pcm_substream *substream)
{ … }
static snd_pcm_uframes_t snd_ensoniq_capture_pointer(struct snd_pcm_substream *substream)
{ … }
static const struct snd_pcm_hardware snd_ensoniq_playback1 = …;
static const struct snd_pcm_hardware snd_ensoniq_playback2 = …;
static const struct snd_pcm_hardware snd_ensoniq_capture = …;
static int snd_ensoniq_playback1_open(struct snd_pcm_substream *substream)
{ … }
static int snd_ensoniq_playback2_open(struct snd_pcm_substream *substream)
{ … }
static int snd_ensoniq_capture_open(struct snd_pcm_substream *substream)
{ … }
static int snd_ensoniq_playback1_close(struct snd_pcm_substream *substream)
{ … }
static int snd_ensoniq_playback2_close(struct snd_pcm_substream *substream)
{ … }
static int snd_ensoniq_capture_close(struct snd_pcm_substream *substream)
{ … }
static const struct snd_pcm_ops snd_ensoniq_playback1_ops = …;
static const struct snd_pcm_ops snd_ensoniq_playback2_ops = …;
static const struct snd_pcm_ops snd_ensoniq_capture_ops = …;
static const struct snd_pcm_chmap_elem surround_map[] = …;
static int snd_ensoniq_pcm(struct ensoniq *ensoniq, int device)
{ … }
static int snd_ensoniq_pcm2(struct ensoniq *ensoniq, int device)
{ … }
#ifdef CHIP1371
static int snd_ens1373_spdif_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
uinfo->count = 1;
return 0;
}
static int snd_ens1373_spdif_default_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
spin_lock_irq(&ensoniq->reg_lock);
ucontrol->value.iec958.status[0] = (ensoniq->spdif_default >> 0) & 0xff;
ucontrol->value.iec958.status[1] = (ensoniq->spdif_default >> 8) & 0xff;
ucontrol->value.iec958.status[2] = (ensoniq->spdif_default >> 16) & 0xff;
ucontrol->value.iec958.status[3] = (ensoniq->spdif_default >> 24) & 0xff;
spin_unlock_irq(&ensoniq->reg_lock);
return 0;
}
static int snd_ens1373_spdif_default_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
unsigned int val;
int change;
val = ((u32)ucontrol->value.iec958.status[0] << 0) |
((u32)ucontrol->value.iec958.status[1] << 8) |
((u32)ucontrol->value.iec958.status[2] << 16) |
((u32)ucontrol->value.iec958.status[3] << 24);
spin_lock_irq(&ensoniq->reg_lock);
change = ensoniq->spdif_default != val;
ensoniq->spdif_default = val;
if (change && ensoniq->playback1_substream == NULL &&
ensoniq->playback2_substream == NULL)
outl(val, ES_REG(ensoniq, CHANNEL_STATUS));
spin_unlock_irq(&ensoniq->reg_lock);
return change;
}
static int snd_ens1373_spdif_mask_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
ucontrol->value.iec958.status[0] = 0xff;
ucontrol->value.iec958.status[1] = 0xff;
ucontrol->value.iec958.status[2] = 0xff;
ucontrol->value.iec958.status[3] = 0xff;
return 0;
}
static int snd_ens1373_spdif_stream_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
spin_lock_irq(&ensoniq->reg_lock);
ucontrol->value.iec958.status[0] = (ensoniq->spdif_stream >> 0) & 0xff;
ucontrol->value.iec958.status[1] = (ensoniq->spdif_stream >> 8) & 0xff;
ucontrol->value.iec958.status[2] = (ensoniq->spdif_stream >> 16) & 0xff;
ucontrol->value.iec958.status[3] = (ensoniq->spdif_stream >> 24) & 0xff;
spin_unlock_irq(&ensoniq->reg_lock);
return 0;
}
static int snd_ens1373_spdif_stream_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
unsigned int val;
int change;
val = ((u32)ucontrol->value.iec958.status[0] << 0) |
((u32)ucontrol->value.iec958.status[1] << 8) |
((u32)ucontrol->value.iec958.status[2] << 16) |
((u32)ucontrol->value.iec958.status[3] << 24);
spin_lock_irq(&ensoniq->reg_lock);
change = ensoniq->spdif_stream != val;
ensoniq->spdif_stream = val;
if (change && (ensoniq->playback1_substream != NULL ||
ensoniq->playback2_substream != NULL))
outl(val, ES_REG(ensoniq, CHANNEL_STATUS));
spin_unlock_irq(&ensoniq->reg_lock);
return change;
}
#define ES1371_SPDIF …
#define snd_es1371_spdif_info …
static int snd_es1371_spdif_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
spin_lock_irq(&ensoniq->reg_lock);
ucontrol->value.integer.value[0] = ensoniq->ctrl & ES_1373_SPDIF_THRU ? 1 : 0;
spin_unlock_irq(&ensoniq->reg_lock);
return 0;
}
static int snd_es1371_spdif_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
unsigned int nval1, nval2;
int change;
nval1 = ucontrol->value.integer.value[0] ? ES_1373_SPDIF_THRU : 0;
nval2 = ucontrol->value.integer.value[0] ? ES_1373_SPDIF_EN : 0;
spin_lock_irq(&ensoniq->reg_lock);
change = (ensoniq->ctrl & ES_1373_SPDIF_THRU) != nval1;
ensoniq->ctrl &= ~ES_1373_SPDIF_THRU;
ensoniq->ctrl |= nval1;
ensoniq->cssr &= ~ES_1373_SPDIF_EN;
ensoniq->cssr |= nval2;
outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
spin_unlock_irq(&ensoniq->reg_lock);
return change;
}
static const struct snd_kcontrol_new snd_es1371_mixer_spdif[] = {
ES1371_SPDIF(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH)),
{
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
.info = snd_ens1373_spdif_info,
.get = snd_ens1373_spdif_default_get,
.put = snd_ens1373_spdif_default_put,
},
{
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
.info = snd_ens1373_spdif_info,
.get = snd_ens1373_spdif_mask_get
},
{
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
.info = snd_ens1373_spdif_info,
.get = snd_ens1373_spdif_stream_get,
.put = snd_ens1373_spdif_stream_put
},
};
#define snd_es1373_rear_info …
static int snd_es1373_rear_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
int val = 0;
spin_lock_irq(&ensoniq->reg_lock);
if ((ensoniq->cssr & (ES_1373_REAR_BIT27|ES_1373_REAR_BIT26|
ES_1373_REAR_BIT24)) == ES_1373_REAR_BIT26)
val = 1;
ucontrol->value.integer.value[0] = val;
spin_unlock_irq(&ensoniq->reg_lock);
return 0;
}
static int snd_es1373_rear_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
unsigned int nval1;
int change;
nval1 = ucontrol->value.integer.value[0] ?
ES_1373_REAR_BIT26 : (ES_1373_REAR_BIT27|ES_1373_REAR_BIT24);
spin_lock_irq(&ensoniq->reg_lock);
change = (ensoniq->cssr & (ES_1373_REAR_BIT27|
ES_1373_REAR_BIT26|ES_1373_REAR_BIT24)) != nval1;
ensoniq->cssr &= ~(ES_1373_REAR_BIT27|ES_1373_REAR_BIT26|ES_1373_REAR_BIT24);
ensoniq->cssr |= nval1;
outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
spin_unlock_irq(&ensoniq->reg_lock);
return change;
}
static const struct snd_kcontrol_new snd_ens1373_rear =
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "AC97 2ch->4ch Copy Switch",
.info = snd_es1373_rear_info,
.get = snd_es1373_rear_get,
.put = snd_es1373_rear_put,
};
#define snd_es1373_line_info …
static int snd_es1373_line_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
int val = 0;
spin_lock_irq(&ensoniq->reg_lock);
if (ensoniq->ctrl & ES_1371_GPIO_OUT(4))
val = 1;
ucontrol->value.integer.value[0] = val;
spin_unlock_irq(&ensoniq->reg_lock);
return 0;
}
static int snd_es1373_line_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
int changed;
unsigned int ctrl;
spin_lock_irq(&ensoniq->reg_lock);
ctrl = ensoniq->ctrl;
if (ucontrol->value.integer.value[0])
ensoniq->ctrl |= ES_1371_GPIO_OUT(4);
else
ensoniq->ctrl &= ~ES_1371_GPIO_OUT(4);
changed = (ctrl != ensoniq->ctrl);
if (changed)
outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
spin_unlock_irq(&ensoniq->reg_lock);
return changed;
}
static const struct snd_kcontrol_new snd_ens1373_line =
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Line In->Rear Out Switch",
.info = snd_es1373_line_info,
.get = snd_es1373_line_get,
.put = snd_es1373_line_put,
};
static void snd_ensoniq_mixer_free_ac97(struct snd_ac97 *ac97)
{
struct ensoniq *ensoniq = ac97->private_data;
ensoniq->u.es1371.ac97 = NULL;
}
struct es1371_quirk {
unsigned short vid;
unsigned short did;
unsigned char rev;
};
static int es1371_quirk_lookup(struct ensoniq *ensoniq,
const struct es1371_quirk *list)
{
while (list->vid != (unsigned short)PCI_ANY_ID) {
if (ensoniq->pci->vendor == list->vid &&
ensoniq->pci->device == list->did &&
ensoniq->rev == list->rev)
return 1;
list++;
}
return 0;
}
static const struct es1371_quirk es1371_spdif_present[] = {
{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_C },
{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_D },
{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_E },
{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_ES1371, .rev = ES1371REV_CT5880_A },
{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_ES1371, .rev = ES1371REV_ES1373_8 },
{ .vid = PCI_ANY_ID, .did = PCI_ANY_ID }
};
static const struct snd_pci_quirk ens1373_line_quirk[] = {
SND_PCI_QUIRK_ID(0x1274, 0x2000),
SND_PCI_QUIRK_ID(0x1458, 0xa000),
{ }
};
static int snd_ensoniq_1371_mixer(struct ensoniq *ensoniq,
int has_spdif, int has_line)
{
struct snd_card *card = ensoniq->card;
struct snd_ac97_bus *pbus;
struct snd_ac97_template ac97;
int err;
static const struct snd_ac97_bus_ops ops = {
.write = snd_es1371_codec_write,
.read = snd_es1371_codec_read,
.wait = snd_es1371_codec_wait,
};
err = snd_ac97_bus(card, 0, &ops, NULL, &pbus);
if (err < 0)
return err;
memset(&ac97, 0, sizeof(ac97));
ac97.private_data = ensoniq;
ac97.private_free = snd_ensoniq_mixer_free_ac97;
ac97.pci = ensoniq->pci;
ac97.scaps = AC97_SCAP_AUDIO;
err = snd_ac97_mixer(pbus, &ac97, &ensoniq->u.es1371.ac97);
if (err < 0)
return err;
if (has_spdif > 0 ||
(!has_spdif && es1371_quirk_lookup(ensoniq, es1371_spdif_present))) {
struct snd_kcontrol *kctl;
int i, is_spdif = 0;
ensoniq->spdif_default = ensoniq->spdif_stream =
SNDRV_PCM_DEFAULT_CON_SPDIF;
outl(ensoniq->spdif_default, ES_REG(ensoniq, CHANNEL_STATUS));
if (ensoniq->u.es1371.ac97->ext_id & AC97_EI_SPDIF)
is_spdif++;
for (i = 0; i < ARRAY_SIZE(snd_es1371_mixer_spdif); i++) {
kctl = snd_ctl_new1(&snd_es1371_mixer_spdif[i], ensoniq);
if (!kctl)
return -ENOMEM;
kctl->id.index = is_spdif;
err = snd_ctl_add(card, kctl);
if (err < 0)
return err;
}
}
if (ensoniq->u.es1371.ac97->ext_id & AC97_EI_SDAC) {
ensoniq->cssr &= ~(ES_1373_REAR_BIT27|ES_1373_REAR_BIT24);
ensoniq->cssr |= ES_1373_REAR_BIT26;
err = snd_ctl_add(card, snd_ctl_new1(&snd_ens1373_rear, ensoniq));
if (err < 0)
return err;
}
if (has_line > 0 ||
snd_pci_quirk_lookup(ensoniq->pci, ens1373_line_quirk)) {
err = snd_ctl_add(card, snd_ctl_new1(&snd_ens1373_line,
ensoniq));
if (err < 0)
return err;
}
return 0;
}
#endif
#ifdef CHIP1370
#define ENSONIQ_CONTROL(xname, mask) …
#define snd_ensoniq_control_info …
static int snd_ensoniq_control_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{ … }
static int snd_ensoniq_control_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{ … }
static const struct snd_kcontrol_new snd_es1370_controls[2] = …;
#define ES1370_CONTROLS …
static void snd_ensoniq_mixer_free_ak4531(struct snd_ak4531 *ak4531)
{ … }
static int snd_ensoniq_1370_mixer(struct ensoniq *ensoniq)
{ … }
#endif
#ifdef SUPPORT_JOYSTICK
#ifdef CHIP1371
static int snd_ensoniq_get_joystick_port(struct ensoniq *ensoniq, int dev)
{
switch (joystick_port[dev]) {
case 0:
case 1:
case 0x200:
case 0x208:
case 0x210:
case 0x218:
return joystick_port[dev];
default:
dev_err(ensoniq->card->dev,
"invalid joystick port %#x", joystick_port[dev]);
return 0;
}
}
#else
static int snd_ensoniq_get_joystick_port(struct ensoniq *ensoniq, int dev)
{ … }
#endif
static int snd_ensoniq_create_gameport(struct ensoniq *ensoniq, int dev)
{ … }
static void snd_ensoniq_free_gameport(struct ensoniq *ensoniq)
{ … }
#else
static inline int snd_ensoniq_create_gameport(struct ensoniq *ensoniq, long port) { return -ENOSYS; }
static inline void snd_ensoniq_free_gameport(struct ensoniq *ensoniq) { }
#endif
static void snd_ensoniq_proc_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{ … }
static void snd_ensoniq_proc_init(struct ensoniq *ensoniq)
{ … }
static void snd_ensoniq_free(struct snd_card *card)
{ … }
#ifdef CHIP1371
static const struct snd_pci_quirk es1371_amplifier_hack[] = {
SND_PCI_QUIRK_ID(0x107b, 0x2150),
SND_PCI_QUIRK_ID(0x13bd, 0x100c),
SND_PCI_QUIRK_ID(0x1102, 0x5938),
SND_PCI_QUIRK_ID(0x1102, 0x8938),
{ }
};
static const struct es1371_quirk es1371_ac97_reset_hack[] = {
{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_C },
{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_D },
{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_E },
{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_ES1371, .rev = ES1371REV_CT5880_A },
{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_ES1371, .rev = ES1371REV_ES1373_8 },
{ .vid = PCI_ANY_ID, .did = PCI_ANY_ID }
};
#endif
static void snd_ensoniq_chip_init(struct ensoniq *ensoniq)
{ … }
static int snd_ensoniq_suspend(struct device *dev)
{ … }
static int snd_ensoniq_resume(struct device *dev)
{ … }
static DEFINE_SIMPLE_DEV_PM_OPS(snd_ensoniq_pm, snd_ensoniq_suspend, snd_ensoniq_resume);
static int snd_ensoniq_create(struct snd_card *card,
struct pci_dev *pci)
{ … }
static void snd_ensoniq_midi_interrupt(struct ensoniq * ensoniq)
{ … }
static int snd_ensoniq_midi_input_open(struct snd_rawmidi_substream *substream)
{ … }
static int snd_ensoniq_midi_input_close(struct snd_rawmidi_substream *substream)
{ … }
static int snd_ensoniq_midi_output_open(struct snd_rawmidi_substream *substream)
{ … }
static int snd_ensoniq_midi_output_close(struct snd_rawmidi_substream *substream)
{ … }
static void snd_ensoniq_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
{ … }
static void snd_ensoniq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
{ … }
static const struct snd_rawmidi_ops snd_ensoniq_midi_output = …;
static const struct snd_rawmidi_ops snd_ensoniq_midi_input = …;
static int snd_ensoniq_midi(struct ensoniq *ensoniq, int device)
{ … }
static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id)
{ … }
static int __snd_audiopci_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{ … }
static int snd_audiopci_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{ … }
static struct pci_driver ens137x_driver = …;
module_pci_driver(…) …;