brintos

brintos / linux-shallow public Read only

0
0
Text · 52.4 KiB · 018a8d5 Raw
1788 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 *  Driver for ESS Solo-1 (ES1938, ES1946, ES1969) soundcard4 *  Copyright (c) by Jaromir Koutek <miri@punknet.cz>,5 *                   Jaroslav Kysela <perex@perex.cz>,6 *                   Thomas Sailer <sailer@ife.ee.ethz.ch>,7 *                   Abramo Bagnara <abramo@alsa-project.org>,8 *                   Markus Gruber <gruber@eikon.tum.de>9 * 10 * Rewritten from sonicvibes.c source.11 *12 *  TODO:13 *    Rewrite better spinlocks14 */15 16/*17  NOTES:18  - Capture data is written unaligned starting from dma_base + 1 so I need to19    disable mmap and to add a copy callback.20  - After several cycle of the following:21    while : ; do arecord -d1 -f cd -t raw | aplay -f cd ; done22    a "playback write error (DMA or IRQ trouble?)" may happen.23    This is due to playback interrupts not generated.24    I suspect a timing issue.25  - Sometimes the interrupt handler is invoked wrongly during playback.26    This generates some harmless "Unexpected hw_pointer: wrong interrupt27    acknowledge".28    I've seen that using small period sizes.29    Reproducible with:30    mpg123 test.mp3 &31    hdparm -t -T /dev/hda32*/33 34 35#include <linux/init.h>36#include <linux/interrupt.h>37#include <linux/pci.h>38#include <linux/slab.h>39#include <linux/gameport.h>40#include <linux/module.h>41#include <linux/delay.h>42#include <linux/dma-mapping.h>43#include <linux/io.h>44#include <sound/core.h>45#include <sound/control.h>46#include <sound/pcm.h>47#include <sound/opl3.h>48#include <sound/mpu401.h>49#include <sound/initval.h>50#include <sound/tlv.h>51 52MODULE_AUTHOR("Jaromir Koutek <miri@punknet.cz>");53MODULE_DESCRIPTION("ESS Solo-1");54MODULE_LICENSE("GPL");55 56#if IS_REACHABLE(CONFIG_GAMEPORT)57#define SUPPORT_JOYSTICK 158#endif59 60static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */61static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */62static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */63 64module_param_array(index, int, NULL, 0444);65MODULE_PARM_DESC(index, "Index value for ESS Solo-1 soundcard.");66module_param_array(id, charp, NULL, 0444);67MODULE_PARM_DESC(id, "ID string for ESS Solo-1 soundcard.");68module_param_array(enable, bool, NULL, 0444);69MODULE_PARM_DESC(enable, "Enable ESS Solo-1 soundcard.");70 71#define SLIO_REG(chip, x) ((chip)->io_port + ESSIO_REG_##x)72 73#define SLDM_REG(chip, x) ((chip)->ddma_port + ESSDM_REG_##x)74 75#define SLSB_REG(chip, x) ((chip)->sb_port + ESSSB_REG_##x)76 77#define SL_PCI_LEGACYCONTROL		0x4078#define SL_PCI_CONFIG			0x5079#define SL_PCI_DDMACONTROL		0x6080 81#define ESSIO_REG_AUDIO2DMAADDR		082#define ESSIO_REG_AUDIO2DMACOUNT	483#define ESSIO_REG_AUDIO2MODE		684#define ESSIO_REG_IRQCONTROL		785 86#define ESSDM_REG_DMAADDR		0x0087#define ESSDM_REG_DMACOUNT		0x0488#define ESSDM_REG_DMACOMMAND		0x0889#define ESSDM_REG_DMASTATUS		0x0890#define ESSDM_REG_DMAMODE		0x0b91#define ESSDM_REG_DMACLEAR		0x0d92#define ESSDM_REG_DMAMASK		0x0f93 94#define ESSSB_REG_FMLOWADDR		0x0095#define ESSSB_REG_FMHIGHADDR		0x0296#define ESSSB_REG_MIXERADDR		0x0497#define ESSSB_REG_MIXERDATA		0x0598 99#define ESSSB_IREG_AUDIO1		0x14100#define ESSSB_IREG_MICMIX		0x1a101#define ESSSB_IREG_RECSRC		0x1c102#define ESSSB_IREG_MASTER		0x32103#define ESSSB_IREG_FM			0x36104#define ESSSB_IREG_AUXACD		0x38105#define ESSSB_IREG_AUXB			0x3a106#define ESSSB_IREG_PCSPEAKER		0x3c107#define ESSSB_IREG_LINE			0x3e108#define ESSSB_IREG_SPATCONTROL		0x50109#define ESSSB_IREG_SPATLEVEL		0x52110#define ESSSB_IREG_MASTER_LEFT		0x60111#define ESSSB_IREG_MASTER_RIGHT		0x62112#define ESSSB_IREG_MPU401CONTROL	0x64113#define ESSSB_IREG_MICMIXRECORD		0x68114#define ESSSB_IREG_AUDIO2RECORD		0x69115#define ESSSB_IREG_AUXACDRECORD		0x6a116#define ESSSB_IREG_FMRECORD		0x6b117#define ESSSB_IREG_AUXBRECORD		0x6c118#define ESSSB_IREG_MONO			0x6d119#define ESSSB_IREG_LINERECORD		0x6e120#define ESSSB_IREG_MONORECORD		0x6f121#define ESSSB_IREG_AUDIO2SAMPLE		0x70122#define ESSSB_IREG_AUDIO2MODE		0x71123#define ESSSB_IREG_AUDIO2FILTER		0x72124#define ESSSB_IREG_AUDIO2TCOUNTL	0x74125#define ESSSB_IREG_AUDIO2TCOUNTH	0x76126#define ESSSB_IREG_AUDIO2CONTROL1	0x78127#define ESSSB_IREG_AUDIO2CONTROL2	0x7a128#define ESSSB_IREG_AUDIO2		0x7c129 130#define ESSSB_REG_RESET			0x06131 132#define ESSSB_REG_READDATA		0x0a133#define ESSSB_REG_WRITEDATA		0x0c134#define ESSSB_REG_READSTATUS		0x0c135 136#define ESSSB_REG_STATUS		0x0e137 138#define ESS_CMD_EXTSAMPLERATE		0xa1139#define ESS_CMD_FILTERDIV		0xa2140#define ESS_CMD_DMACNTRELOADL		0xa4141#define ESS_CMD_DMACNTRELOADH		0xa5142#define ESS_CMD_ANALOGCONTROL		0xa8143#define ESS_CMD_IRQCONTROL		0xb1144#define ESS_CMD_DRQCONTROL		0xb2145#define ESS_CMD_RECLEVEL		0xb4146#define ESS_CMD_SETFORMAT		0xb6147#define ESS_CMD_SETFORMAT2		0xb7148#define ESS_CMD_DMACONTROL		0xb8149#define ESS_CMD_DMATYPE			0xb9150#define ESS_CMD_OFFSETLEFT		0xba	151#define ESS_CMD_OFFSETRIGHT		0xbb152#define ESS_CMD_READREG			0xc0153#define ESS_CMD_ENABLEEXT		0xc6154#define ESS_CMD_PAUSEDMA		0xd0155#define ESS_CMD_ENABLEAUDIO1		0xd1156#define ESS_CMD_STOPAUDIO1		0xd3157#define ESS_CMD_AUDIO1STATUS		0xd8158#define ESS_CMD_CONTDMA			0xd4159#define ESS_CMD_TESTIRQ			0xf2160 161#define ESS_RECSRC_MIC		0162#define ESS_RECSRC_AUXACD	2163#define ESS_RECSRC_AUXB		5164#define ESS_RECSRC_LINE		6165#define ESS_RECSRC_NONE		7166 167#define DAC1 0x01168#define ADC1 0x02169#define DAC2 0x04170 171/*172 173 */174 175#define SAVED_REG_SIZE	32 /* max. number of registers to save */176 177struct es1938 {178	int irq;179 180	unsigned long io_port;181	unsigned long sb_port;182	unsigned long vc_port;183	unsigned long mpu_port;184	unsigned long game_port;185	unsigned long ddma_port;186 187	unsigned char irqmask;188	unsigned char revision;189 190	struct snd_kcontrol *hw_volume;191	struct snd_kcontrol *hw_switch;192	struct snd_kcontrol *master_volume;193	struct snd_kcontrol *master_switch;194 195	struct pci_dev *pci;196	struct snd_card *card;197	struct snd_pcm *pcm;198	struct snd_pcm_substream *capture_substream;199	struct snd_pcm_substream *playback1_substream;200	struct snd_pcm_substream *playback2_substream;201	struct snd_rawmidi *rmidi;202 203	unsigned int dma1_size;204	unsigned int dma2_size;205	unsigned int dma1_start;206	unsigned int dma2_start;207	unsigned int dma1_shift;208	unsigned int dma2_shift;209	unsigned int last_capture_dmaaddr;210	unsigned int active;211 212	spinlock_t reg_lock;213	spinlock_t mixer_lock;214        struct snd_info_entry *proc_entry;215 216#ifdef SUPPORT_JOYSTICK217	struct gameport *gameport;218#endif219	unsigned char saved_regs[SAVED_REG_SIZE];220};221 222static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id);223 224static const struct pci_device_id snd_es1938_ids[] = {225	{ PCI_VDEVICE(ESS, 0x1969), 0, },   /* Solo-1 */226	{ 0, }227};228 229MODULE_DEVICE_TABLE(pci, snd_es1938_ids);230 231#define RESET_LOOP_TIMEOUT	0x10000232#define WRITE_LOOP_TIMEOUT	0x10000233#define GET_LOOP_TIMEOUT	0x01000234 235/* -----------------------------------------------------------------236 * Write to a mixer register237 * -----------------------------------------------------------------*/238static void snd_es1938_mixer_write(struct es1938 *chip, unsigned char reg, unsigned char val)239{240	unsigned long flags;241	spin_lock_irqsave(&chip->mixer_lock, flags);242	outb(reg, SLSB_REG(chip, MIXERADDR));243	outb(val, SLSB_REG(chip, MIXERDATA));244	spin_unlock_irqrestore(&chip->mixer_lock, flags);245	dev_dbg(chip->card->dev, "Mixer reg %02x set to %02x\n", reg, val);246}247 248/* -----------------------------------------------------------------249 * Read from a mixer register250 * -----------------------------------------------------------------*/251static int snd_es1938_mixer_read(struct es1938 *chip, unsigned char reg)252{253	int data;254	unsigned long flags;255	spin_lock_irqsave(&chip->mixer_lock, flags);256	outb(reg, SLSB_REG(chip, MIXERADDR));257	data = inb(SLSB_REG(chip, MIXERDATA));258	spin_unlock_irqrestore(&chip->mixer_lock, flags);259	dev_dbg(chip->card->dev, "Mixer reg %02x now is %02x\n", reg, data);260	return data;261}262 263/* -----------------------------------------------------------------264 * Write to some bits of a mixer register (return old value)265 * -----------------------------------------------------------------*/266static int snd_es1938_mixer_bits(struct es1938 *chip, unsigned char reg,267				 unsigned char mask, unsigned char val)268{269	unsigned long flags;270	unsigned char old, new, oval;271	spin_lock_irqsave(&chip->mixer_lock, flags);272	outb(reg, SLSB_REG(chip, MIXERADDR));273	old = inb(SLSB_REG(chip, MIXERDATA));274	oval = old & mask;275	if (val != oval) {276		new = (old & ~mask) | (val & mask);277		outb(new, SLSB_REG(chip, MIXERDATA));278		dev_dbg(chip->card->dev,279			"Mixer reg %02x was %02x, set to %02x\n",280			   reg, old, new);281	}282	spin_unlock_irqrestore(&chip->mixer_lock, flags);283	return oval;284}285 286/* -----------------------------------------------------------------287 * Write command to Controller Registers288 * -----------------------------------------------------------------*/289static void snd_es1938_write_cmd(struct es1938 *chip, unsigned char cmd)290{291	int i;292	unsigned char v;293	for (i = 0; i < WRITE_LOOP_TIMEOUT; i++) {294		v = inb(SLSB_REG(chip, READSTATUS));295		if (!(v & 0x80)) {296			outb(cmd, SLSB_REG(chip, WRITEDATA));297			return;298		}299	}300	dev_err(chip->card->dev,301		"snd_es1938_write_cmd timeout (0x02%x/0x02%x)\n", cmd, v);302}303 304/* -----------------------------------------------------------------305 * Read the Read Data Buffer306 * -----------------------------------------------------------------*/307static int snd_es1938_get_byte(struct es1938 *chip)308{309	int i;310	unsigned char v;311	for (i = GET_LOOP_TIMEOUT; i; i--) {312		v = inb(SLSB_REG(chip, STATUS));313		if (v & 0x80)314			return inb(SLSB_REG(chip, READDATA));315	}316	dev_err(chip->card->dev, "get_byte timeout: status 0x02%x\n", v);317	return -ENODEV;318}319 320/* -----------------------------------------------------------------321 * Write value cmd register322 * -----------------------------------------------------------------*/323static void snd_es1938_write(struct es1938 *chip, unsigned char reg, unsigned char val)324{325	unsigned long flags;326	spin_lock_irqsave(&chip->reg_lock, flags);327	snd_es1938_write_cmd(chip, reg);328	snd_es1938_write_cmd(chip, val);329	spin_unlock_irqrestore(&chip->reg_lock, flags);330	dev_dbg(chip->card->dev, "Reg %02x set to %02x\n", reg, val);331}332 333/* -----------------------------------------------------------------334 * Read data from cmd register and return it335 * -----------------------------------------------------------------*/336static unsigned char snd_es1938_read(struct es1938 *chip, unsigned char reg)337{338	unsigned char val;339	unsigned long flags;340	spin_lock_irqsave(&chip->reg_lock, flags);341	snd_es1938_write_cmd(chip, ESS_CMD_READREG);342	snd_es1938_write_cmd(chip, reg);343	val = snd_es1938_get_byte(chip);344	spin_unlock_irqrestore(&chip->reg_lock, flags);345	dev_dbg(chip->card->dev, "Reg %02x now is %02x\n", reg, val);346	return val;347}348 349/* -----------------------------------------------------------------350 * Write data to cmd register and return old value351 * -----------------------------------------------------------------*/352static int snd_es1938_bits(struct es1938 *chip, unsigned char reg, unsigned char mask,353			   unsigned char val)354{355	unsigned long flags;356	unsigned char old, new, oval;357	spin_lock_irqsave(&chip->reg_lock, flags);358	snd_es1938_write_cmd(chip, ESS_CMD_READREG);359	snd_es1938_write_cmd(chip, reg);360	old = snd_es1938_get_byte(chip);361	oval = old & mask;362	if (val != oval) {363		snd_es1938_write_cmd(chip, reg);364		new = (old & ~mask) | (val & mask);365		snd_es1938_write_cmd(chip, new);366		dev_dbg(chip->card->dev, "Reg %02x was %02x, set to %02x\n",367			   reg, old, new);368	}369	spin_unlock_irqrestore(&chip->reg_lock, flags);370	return oval;371}372 373/* --------------------------------------------------------------------374 * Reset the chip375 * --------------------------------------------------------------------*/376static void snd_es1938_reset(struct es1938 *chip)377{378	int i;379 380	outb(3, SLSB_REG(chip, RESET));381	inb(SLSB_REG(chip, RESET));382	outb(0, SLSB_REG(chip, RESET));383	for (i = 0; i < RESET_LOOP_TIMEOUT; i++) {384		if (inb(SLSB_REG(chip, STATUS)) & 0x80) {385			if (inb(SLSB_REG(chip, READDATA)) == 0xaa)386				goto __next;387		}388	}389	dev_err(chip->card->dev, "ESS Solo-1 reset failed\n");390 391     __next:392	snd_es1938_write_cmd(chip, ESS_CMD_ENABLEEXT);393 394	/* Demand transfer DMA: 4 bytes per DMA request */395	snd_es1938_write(chip, ESS_CMD_DMATYPE, 2);396 397	/* Change behaviour of register A1398	   4x oversampling399	   2nd channel DAC asynchronous */                                                      400	snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2MODE, 0x32);401	/* enable/select DMA channel and IRQ channel */402	snd_es1938_bits(chip, ESS_CMD_IRQCONTROL, 0xf0, 0x50);403	snd_es1938_bits(chip, ESS_CMD_DRQCONTROL, 0xf0, 0x50);404	snd_es1938_write_cmd(chip, ESS_CMD_ENABLEAUDIO1);405	/* Set spatializer parameters to recommended values */406	snd_es1938_mixer_write(chip, 0x54, 0x8f);407	snd_es1938_mixer_write(chip, 0x56, 0x95);408	snd_es1938_mixer_write(chip, 0x58, 0x94);409	snd_es1938_mixer_write(chip, 0x5a, 0x80);410}411 412/* --------------------------------------------------------------------413 * Reset the FIFOs414 * --------------------------------------------------------------------*/415static void snd_es1938_reset_fifo(struct es1938 *chip)416{417	outb(2, SLSB_REG(chip, RESET));418	outb(0, SLSB_REG(chip, RESET));419}420 421static const struct snd_ratnum clocks[2] = {422	{423		.num = 793800,424		.den_min = 1,425		.den_max = 128,426		.den_step = 1,427	},428	{429		.num = 768000,430		.den_min = 1,431		.den_max = 128,432		.den_step = 1,433	}434};435 436static const struct snd_pcm_hw_constraint_ratnums hw_constraints_clocks = {437	.nrats = 2,438	.rats = clocks,439};440 441 442static void snd_es1938_rate_set(struct es1938 *chip, 443				struct snd_pcm_substream *substream,444				int mode)445{446	unsigned int bits, div0;447	struct snd_pcm_runtime *runtime = substream->runtime;448	if (runtime->rate_num == clocks[0].num)449		bits = 128 - runtime->rate_den;450	else451		bits = 256 - runtime->rate_den;452 453	/* set filter register */454	div0 = 256 - 7160000*20/(8*82*runtime->rate);455		456	if (mode == DAC2) {457		snd_es1938_mixer_write(chip, 0x70, bits);458		snd_es1938_mixer_write(chip, 0x72, div0);459	} else {460		snd_es1938_write(chip, 0xA1, bits);461		snd_es1938_write(chip, 0xA2, div0);462	}463}464 465/* --------------------------------------------------------------------466 * Configure Solo1 builtin DMA Controller467 * --------------------------------------------------------------------*/468 469static void snd_es1938_playback1_setdma(struct es1938 *chip)470{471	outb(0x00, SLIO_REG(chip, AUDIO2MODE));472	outl(chip->dma2_start, SLIO_REG(chip, AUDIO2DMAADDR));473	outw(0, SLIO_REG(chip, AUDIO2DMACOUNT));474	outw(chip->dma2_size, SLIO_REG(chip, AUDIO2DMACOUNT));475}476 477static void snd_es1938_playback2_setdma(struct es1938 *chip)478{479	/* Enable DMA controller */480	outb(0xc4, SLDM_REG(chip, DMACOMMAND));481	/* 1. Master reset */482	outb(0, SLDM_REG(chip, DMACLEAR));483	/* 2. Mask DMA */484	outb(1, SLDM_REG(chip, DMAMASK));485	outb(0x18, SLDM_REG(chip, DMAMODE));486	outl(chip->dma1_start, SLDM_REG(chip, DMAADDR));487	outw(chip->dma1_size - 1, SLDM_REG(chip, DMACOUNT));488	/* 3. Unmask DMA */489	outb(0, SLDM_REG(chip, DMAMASK));490}491 492static void snd_es1938_capture_setdma(struct es1938 *chip)493{494	/* Enable DMA controller */495	outb(0xc4, SLDM_REG(chip, DMACOMMAND));496	/* 1. Master reset */497	outb(0, SLDM_REG(chip, DMACLEAR));498	/* 2. Mask DMA */499	outb(1, SLDM_REG(chip, DMAMASK));500	outb(0x14, SLDM_REG(chip, DMAMODE));501	outl(chip->dma1_start, SLDM_REG(chip, DMAADDR));502	chip->last_capture_dmaaddr = chip->dma1_start;503	outw(chip->dma1_size - 1, SLDM_REG(chip, DMACOUNT));504	/* 3. Unmask DMA */505	outb(0, SLDM_REG(chip, DMAMASK));506}507 508/* ----------------------------------------------------------------------509 *510 *                           *** PCM part ***511 */512 513static int snd_es1938_capture_trigger(struct snd_pcm_substream *substream,514				      int cmd)515{516	struct es1938 *chip = snd_pcm_substream_chip(substream);517	int val;518	switch (cmd) {519	case SNDRV_PCM_TRIGGER_START:520	case SNDRV_PCM_TRIGGER_RESUME:521		val = 0x0f;522		chip->active |= ADC1;523		break;524	case SNDRV_PCM_TRIGGER_STOP:525	case SNDRV_PCM_TRIGGER_SUSPEND:526		val = 0x00;527		chip->active &= ~ADC1;528		break;529	default:530		return -EINVAL;531	}532	snd_es1938_write(chip, ESS_CMD_DMACONTROL, val);533	return 0;534}535 536static int snd_es1938_playback1_trigger(struct snd_pcm_substream *substream,537					int cmd)538{539	struct es1938 *chip = snd_pcm_substream_chip(substream);540	switch (cmd) {541	case SNDRV_PCM_TRIGGER_START:542	case SNDRV_PCM_TRIGGER_RESUME:543		/* According to the documentation this should be:544		   0x13 but that value may randomly swap stereo channels */545                snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL1, 0x92);546                udelay(10);547		snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL1, 0x93);548                /* This two stage init gives the FIFO -> DAC connection time to549                 * settle before first data from DMA flows in.  This should ensure550                 * no swapping of stereo channels.  Report a bug if otherwise :-) */551		outb(0x0a, SLIO_REG(chip, AUDIO2MODE));552		chip->active |= DAC2;553		break;554	case SNDRV_PCM_TRIGGER_STOP:555	case SNDRV_PCM_TRIGGER_SUSPEND:556		outb(0, SLIO_REG(chip, AUDIO2MODE));557		snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL1, 0);558		chip->active &= ~DAC2;559		break;560	default:561		return -EINVAL;562	}563	return 0;564}565 566static int snd_es1938_playback2_trigger(struct snd_pcm_substream *substream,567					int cmd)568{569	struct es1938 *chip = snd_pcm_substream_chip(substream);570	int val;571	switch (cmd) {572	case SNDRV_PCM_TRIGGER_START:573	case SNDRV_PCM_TRIGGER_RESUME:574		val = 5;575		chip->active |= DAC1;576		break;577	case SNDRV_PCM_TRIGGER_STOP:578	case SNDRV_PCM_TRIGGER_SUSPEND:579		val = 0;580		chip->active &= ~DAC1;581		break;582	default:583		return -EINVAL;584	}585	snd_es1938_write(chip, ESS_CMD_DMACONTROL, val);586	return 0;587}588 589static int snd_es1938_playback_trigger(struct snd_pcm_substream *substream,590				       int cmd)591{592	switch (substream->number) {593	case 0:594		return snd_es1938_playback1_trigger(substream, cmd);595	case 1:596		return snd_es1938_playback2_trigger(substream, cmd);597	}598	snd_BUG();599	return -EINVAL;600}601 602/* --------------------------------------------------------------------603 * First channel for Extended Mode Audio 1 ADC Operation604 * --------------------------------------------------------------------*/605static int snd_es1938_capture_prepare(struct snd_pcm_substream *substream)606{607	struct es1938 *chip = snd_pcm_substream_chip(substream);608	struct snd_pcm_runtime *runtime = substream->runtime;609	int u, is8, mono;610	unsigned int size = snd_pcm_lib_buffer_bytes(substream);611	unsigned int count = snd_pcm_lib_period_bytes(substream);612 613	chip->dma1_size = size;614	chip->dma1_start = runtime->dma_addr;615 616	mono = (runtime->channels > 1) ? 0 : 1;617	is8 = snd_pcm_format_width(runtime->format) == 16 ? 0 : 1;618	u = snd_pcm_format_unsigned(runtime->format);619 620	chip->dma1_shift = 2 - mono - is8;621 622	snd_es1938_reset_fifo(chip);623	624	/* program type */625	snd_es1938_bits(chip, ESS_CMD_ANALOGCONTROL, 0x03, (mono ? 2 : 1));626 627	/* set clock and counters */628        snd_es1938_rate_set(chip, substream, ADC1);629 630	count = 0x10000 - count;631	snd_es1938_write(chip, ESS_CMD_DMACNTRELOADL, count & 0xff);632	snd_es1938_write(chip, ESS_CMD_DMACNTRELOADH, count >> 8);633 634	/* initialize and configure ADC */635	snd_es1938_write(chip, ESS_CMD_SETFORMAT2, u ? 0x51 : 0x71);636	snd_es1938_write(chip, ESS_CMD_SETFORMAT2, 0x90 | 637		       (u ? 0x00 : 0x20) | 638		       (is8 ? 0x00 : 0x04) | 639		       (mono ? 0x40 : 0x08));640 641	//	snd_es1938_reset_fifo(chip);	642 643	/* 11. configure system interrupt controller and DMA controller */644	snd_es1938_capture_setdma(chip);645 646	return 0;647}648 649 650/* ------------------------------------------------------------------------------651 * Second Audio channel DAC Operation652 * ------------------------------------------------------------------------------*/653static int snd_es1938_playback1_prepare(struct snd_pcm_substream *substream)654{655	struct es1938 *chip = snd_pcm_substream_chip(substream);656	struct snd_pcm_runtime *runtime = substream->runtime;657	int u, is8, mono;658	unsigned int size = snd_pcm_lib_buffer_bytes(substream);659	unsigned int count = snd_pcm_lib_period_bytes(substream);660 661	chip->dma2_size = size;662	chip->dma2_start = runtime->dma_addr;663 664	mono = (runtime->channels > 1) ? 0 : 1;665	is8 = snd_pcm_format_width(runtime->format) == 16 ? 0 : 1;666	u = snd_pcm_format_unsigned(runtime->format);667 668	chip->dma2_shift = 2 - mono - is8;669 670        snd_es1938_reset_fifo(chip);671 672	/* set clock and counters */673        snd_es1938_rate_set(chip, substream, DAC2);674 675	count >>= 1;676	count = 0x10000 - count;677	snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2TCOUNTL, count & 0xff);678	snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2TCOUNTH, count >> 8);679 680	/* initialize and configure Audio 2 DAC */681	snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL2, 0x40 | (u ? 0 : 4) |682			       (mono ? 0 : 2) | (is8 ? 0 : 1));683 684	/* program DMA */685	snd_es1938_playback1_setdma(chip);686	687	return 0;688}689 690static int snd_es1938_playback2_prepare(struct snd_pcm_substream *substream)691{692	struct es1938 *chip = snd_pcm_substream_chip(substream);693	struct snd_pcm_runtime *runtime = substream->runtime;694	int u, is8, mono;695	unsigned int size = snd_pcm_lib_buffer_bytes(substream);696	unsigned int count = snd_pcm_lib_period_bytes(substream);697 698	chip->dma1_size = size;699	chip->dma1_start = runtime->dma_addr;700 701	mono = (runtime->channels > 1) ? 0 : 1;702	is8 = snd_pcm_format_width(runtime->format) == 16 ? 0 : 1;703	u = snd_pcm_format_unsigned(runtime->format);704 705	chip->dma1_shift = 2 - mono - is8;706 707	count = 0x10000 - count;708 709	/* reset */710	snd_es1938_reset_fifo(chip);711	712	snd_es1938_bits(chip, ESS_CMD_ANALOGCONTROL, 0x03, (mono ? 2 : 1));713 714	/* set clock and counters */715        snd_es1938_rate_set(chip, substream, DAC1);716	snd_es1938_write(chip, ESS_CMD_DMACNTRELOADL, count & 0xff);717	snd_es1938_write(chip, ESS_CMD_DMACNTRELOADH, count >> 8);718 719	/* initialized and configure DAC */720        snd_es1938_write(chip, ESS_CMD_SETFORMAT, u ? 0x80 : 0x00);721        snd_es1938_write(chip, ESS_CMD_SETFORMAT, u ? 0x51 : 0x71);722        snd_es1938_write(chip, ESS_CMD_SETFORMAT2, 723			 0x90 | (mono ? 0x40 : 0x08) |724			 (is8 ? 0x00 : 0x04) | (u ? 0x00 : 0x20));725 726	/* program DMA */727	snd_es1938_playback2_setdma(chip);728	729	return 0;730}731 732static int snd_es1938_playback_prepare(struct snd_pcm_substream *substream)733{734	switch (substream->number) {735	case 0:736		return snd_es1938_playback1_prepare(substream);737	case 1:738		return snd_es1938_playback2_prepare(substream);739	}740	snd_BUG();741	return -EINVAL;742}743 744/* during the incrementing of dma counters the DMA register reads sometimes745   returns garbage. To ensure a valid hw pointer, the following checks which746   should be very unlikely to fail are used:747   - is the current DMA address in the valid DMA range ?748   - is the sum of DMA address and DMA counter pointing to the last DMA byte ?749   One can argue this could differ by one byte depending on which register is750   updated first, so the implementation below allows for that.751*/752static snd_pcm_uframes_t snd_es1938_capture_pointer(struct snd_pcm_substream *substream)753{754	struct es1938 *chip = snd_pcm_substream_chip(substream);755	size_t ptr;756#if 0757	size_t old, new;758	/* This stuff is *needed*, don't ask why - AB */759	old = inw(SLDM_REG(chip, DMACOUNT));760	while ((new = inw(SLDM_REG(chip, DMACOUNT))) != old)761		old = new;762	ptr = chip->dma1_size - 1 - new;763#else764	size_t count;765	unsigned int diff;766 767	ptr = inl(SLDM_REG(chip, DMAADDR));768	count = inw(SLDM_REG(chip, DMACOUNT));769	diff = chip->dma1_start + chip->dma1_size - ptr - count;770 771	if (diff > 3 || ptr < chip->dma1_start772	      || ptr >= chip->dma1_start+chip->dma1_size)773	  ptr = chip->last_capture_dmaaddr;            /* bad, use last saved */774	else775	  chip->last_capture_dmaaddr = ptr;            /* good, remember it */776 777	ptr -= chip->dma1_start;778#endif779	return ptr >> chip->dma1_shift;780}781 782static snd_pcm_uframes_t snd_es1938_playback1_pointer(struct snd_pcm_substream *substream)783{784	struct es1938 *chip = snd_pcm_substream_chip(substream);785	size_t ptr;786#if 1787	ptr = chip->dma2_size - inw(SLIO_REG(chip, AUDIO2DMACOUNT));788#else789	ptr = inl(SLIO_REG(chip, AUDIO2DMAADDR)) - chip->dma2_start;790#endif791	return ptr >> chip->dma2_shift;792}793 794static snd_pcm_uframes_t snd_es1938_playback2_pointer(struct snd_pcm_substream *substream)795{796	struct es1938 *chip = snd_pcm_substream_chip(substream);797	size_t ptr;798	size_t old, new;799#if 1800	/* This stuff is *needed*, don't ask why - AB */801	old = inw(SLDM_REG(chip, DMACOUNT));802	while ((new = inw(SLDM_REG(chip, DMACOUNT))) != old)803		old = new;804	ptr = chip->dma1_size - 1 - new;805#else806	ptr = inl(SLDM_REG(chip, DMAADDR)) - chip->dma1_start;807#endif808	return ptr >> chip->dma1_shift;809}810 811static snd_pcm_uframes_t snd_es1938_playback_pointer(struct snd_pcm_substream *substream)812{813	switch (substream->number) {814	case 0:815		return snd_es1938_playback1_pointer(substream);816	case 1:817		return snd_es1938_playback2_pointer(substream);818	}819	snd_BUG();820	return -EINVAL;821}822 823static int snd_es1938_capture_copy(struct snd_pcm_substream *substream,824				   int channel, unsigned long pos,825				   struct iov_iter *dst, unsigned long count)826{827	struct snd_pcm_runtime *runtime = substream->runtime;828	struct es1938 *chip = snd_pcm_substream_chip(substream);829 830	if (snd_BUG_ON(pos + count > chip->dma1_size))831		return -EINVAL;832	if (pos + count < chip->dma1_size) {833		if (copy_to_iter(runtime->dma_area + pos + 1, count, dst) != count)834			return -EFAULT;835	} else {836		if (copy_to_iter(runtime->dma_area + pos + 1, count - 1, dst) != count - 1)837			return -EFAULT;838		if (copy_to_iter(runtime->dma_area, 1, dst) != 1)839			return -EFAULT;840	}841	return 0;842}843 844/* ----------------------------------------------------------------------845 * Audio1 Capture (ADC)846 * ----------------------------------------------------------------------*/847static const struct snd_pcm_hardware snd_es1938_capture =848{849	.info =			(SNDRV_PCM_INFO_INTERLEAVED |850				SNDRV_PCM_INFO_BLOCK_TRANSFER),851	.formats =		(SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |852				 SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),853	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,854	.rate_min =		6000,855	.rate_max =		48000,856	.channels_min =		1,857	.channels_max =		2,858        .buffer_bytes_max =	0x8000,       /* DMA controller screws on higher values */859	.period_bytes_min =	64,860	.period_bytes_max =	0x8000,861	.periods_min =		1,862	.periods_max =		1024,863	.fifo_size =		256,864};865 866/* -----------------------------------------------------------------------867 * Audio2 Playback (DAC)868 * -----------------------------------------------------------------------*/869static const struct snd_pcm_hardware snd_es1938_playback =870{871	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |872				 SNDRV_PCM_INFO_BLOCK_TRANSFER |873				 SNDRV_PCM_INFO_MMAP_VALID),874	.formats =		(SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |875				 SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),876	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,877	.rate_min =		6000,878	.rate_max =		48000,879	.channels_min =		1,880	.channels_max =		2,881        .buffer_bytes_max =	0x8000,       /* DMA controller screws on higher values */882	.period_bytes_min =	64,883	.period_bytes_max =	0x8000,884	.periods_min =		1,885	.periods_max =		1024,886	.fifo_size =		256,887};888 889static int snd_es1938_capture_open(struct snd_pcm_substream *substream)890{891	struct es1938 *chip = snd_pcm_substream_chip(substream);892	struct snd_pcm_runtime *runtime = substream->runtime;893 894	if (chip->playback2_substream)895		return -EAGAIN;896	chip->capture_substream = substream;897	runtime->hw = snd_es1938_capture;898	snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,899				      &hw_constraints_clocks);900	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 0, 0xff00);901	return 0;902}903 904static int snd_es1938_playback_open(struct snd_pcm_substream *substream)905{906	struct es1938 *chip = snd_pcm_substream_chip(substream);907	struct snd_pcm_runtime *runtime = substream->runtime;908 909	switch (substream->number) {910	case 0:911		chip->playback1_substream = substream;912		break;913	case 1:914		if (chip->capture_substream)915			return -EAGAIN;916		chip->playback2_substream = substream;917		break;918	default:919		snd_BUG();920		return -EINVAL;921	}922	runtime->hw = snd_es1938_playback;923	snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,924				      &hw_constraints_clocks);925	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 0, 0xff00);926	return 0;927}928 929static int snd_es1938_capture_close(struct snd_pcm_substream *substream)930{931	struct es1938 *chip = snd_pcm_substream_chip(substream);932 933	chip->capture_substream = NULL;934	return 0;935}936 937static int snd_es1938_playback_close(struct snd_pcm_substream *substream)938{939	struct es1938 *chip = snd_pcm_substream_chip(substream);940 941	switch (substream->number) {942	case 0:943		chip->playback1_substream = NULL;944		break;945	case 1:946		chip->playback2_substream = NULL;947		break;948	default:949		snd_BUG();950		return -EINVAL;951	}952	return 0;953}954 955static const struct snd_pcm_ops snd_es1938_playback_ops = {956	.open =		snd_es1938_playback_open,957	.close =	snd_es1938_playback_close,958	.prepare =	snd_es1938_playback_prepare,959	.trigger =	snd_es1938_playback_trigger,960	.pointer =	snd_es1938_playback_pointer,961};962 963static const struct snd_pcm_ops snd_es1938_capture_ops = {964	.open =		snd_es1938_capture_open,965	.close =	snd_es1938_capture_close,966	.prepare =	snd_es1938_capture_prepare,967	.trigger =	snd_es1938_capture_trigger,968	.pointer =	snd_es1938_capture_pointer,969	.copy =		snd_es1938_capture_copy,970};971 972static int snd_es1938_new_pcm(struct es1938 *chip, int device)973{974	struct snd_pcm *pcm;975	int err;976 977	err = snd_pcm_new(chip->card, "es-1938-1946", device, 2, 1, &pcm);978	if (err < 0)979		return err;980	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_es1938_playback_ops);981	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_es1938_capture_ops);982	983	pcm->private_data = chip;984	pcm->info_flags = 0;985	strcpy(pcm->name, "ESS Solo-1");986 987	snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,988				       &chip->pci->dev, 64*1024, 64*1024);989 990	chip->pcm = pcm;991	return 0;992}993 994/* -------------------------------------------------------------------995 * 996 *                       *** Mixer part ***997 */998 999static int snd_es1938_info_mux(struct snd_kcontrol *kcontrol,1000			       struct snd_ctl_elem_info *uinfo)1001{1002	static const char * const texts[8] = {1003		"Mic", "Mic Master", "CD", "AOUT",1004		"Mic1", "Mix", "Line", "Master"1005	};1006 1007	return snd_ctl_enum_info(uinfo, 1, 8, texts);1008}1009 1010static int snd_es1938_get_mux(struct snd_kcontrol *kcontrol,1011			      struct snd_ctl_elem_value *ucontrol)1012{1013	struct es1938 *chip = snd_kcontrol_chip(kcontrol);1014	ucontrol->value.enumerated.item[0] = snd_es1938_mixer_read(chip, 0x1c) & 0x07;1015	return 0;1016}1017 1018static int snd_es1938_put_mux(struct snd_kcontrol *kcontrol,1019			      struct snd_ctl_elem_value *ucontrol)1020{1021	struct es1938 *chip = snd_kcontrol_chip(kcontrol);1022	unsigned char val = ucontrol->value.enumerated.item[0];1023	1024	if (val > 7)1025		return -EINVAL;1026	return snd_es1938_mixer_bits(chip, 0x1c, 0x07, val) != val;1027}1028 1029#define snd_es1938_info_spatializer_enable	snd_ctl_boolean_mono_info1030 1031static int snd_es1938_get_spatializer_enable(struct snd_kcontrol *kcontrol,1032					     struct snd_ctl_elem_value *ucontrol)1033{1034	struct es1938 *chip = snd_kcontrol_chip(kcontrol);1035	unsigned char val = snd_es1938_mixer_read(chip, 0x50);1036	ucontrol->value.integer.value[0] = !!(val & 8);1037	return 0;1038}1039 1040static int snd_es1938_put_spatializer_enable(struct snd_kcontrol *kcontrol,1041					     struct snd_ctl_elem_value *ucontrol)1042{1043	struct es1938 *chip = snd_kcontrol_chip(kcontrol);1044	unsigned char oval, nval;1045	int change;1046	nval = ucontrol->value.integer.value[0] ? 0x0c : 0x04;1047	oval = snd_es1938_mixer_read(chip, 0x50) & 0x0c;1048	change = nval != oval;1049	if (change) {1050		snd_es1938_mixer_write(chip, 0x50, nval & ~0x04);1051		snd_es1938_mixer_write(chip, 0x50, nval);1052	}1053	return change;1054}1055 1056static int snd_es1938_info_hw_volume(struct snd_kcontrol *kcontrol,1057				     struct snd_ctl_elem_info *uinfo)1058{1059	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;1060	uinfo->count = 2;1061	uinfo->value.integer.min = 0;1062	uinfo->value.integer.max = 63;1063	return 0;1064}1065 1066static int snd_es1938_get_hw_volume(struct snd_kcontrol *kcontrol,1067				    struct snd_ctl_elem_value *ucontrol)1068{1069	struct es1938 *chip = snd_kcontrol_chip(kcontrol);1070	ucontrol->value.integer.value[0] = snd_es1938_mixer_read(chip, 0x61) & 0x3f;1071	ucontrol->value.integer.value[1] = snd_es1938_mixer_read(chip, 0x63) & 0x3f;1072	return 0;1073}1074 1075#define snd_es1938_info_hw_switch		snd_ctl_boolean_stereo_info1076 1077static int snd_es1938_get_hw_switch(struct snd_kcontrol *kcontrol,1078				    struct snd_ctl_elem_value *ucontrol)1079{1080	struct es1938 *chip = snd_kcontrol_chip(kcontrol);1081	ucontrol->value.integer.value[0] = !(snd_es1938_mixer_read(chip, 0x61) & 0x40);1082	ucontrol->value.integer.value[1] = !(snd_es1938_mixer_read(chip, 0x63) & 0x40);1083	return 0;1084}1085 1086static void snd_es1938_hwv_free(struct snd_kcontrol *kcontrol)1087{1088	struct es1938 *chip = snd_kcontrol_chip(kcontrol);1089	chip->master_volume = NULL;1090	chip->master_switch = NULL;1091	chip->hw_volume = NULL;1092	chip->hw_switch = NULL;1093}1094 1095static int snd_es1938_reg_bits(struct es1938 *chip, unsigned char reg,1096			       unsigned char mask, unsigned char val)1097{1098	if (reg < 0xa0)1099		return snd_es1938_mixer_bits(chip, reg, mask, val);1100	else1101		return snd_es1938_bits(chip, reg, mask, val);1102}1103 1104static int snd_es1938_reg_read(struct es1938 *chip, unsigned char reg)1105{1106	if (reg < 0xa0)1107		return snd_es1938_mixer_read(chip, reg);1108	else1109		return snd_es1938_read(chip, reg);1110}1111 1112#define ES1938_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv)    \1113{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \1114  .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,\1115  .name = xname, .index = xindex, \1116  .info = snd_es1938_info_single, \1117  .get = snd_es1938_get_single, .put = snd_es1938_put_single, \1118  .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24), \1119  .tlv = { .p = xtlv } }1120#define ES1938_SINGLE(xname, xindex, reg, shift, mask, invert) \1121{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \1122  .info = snd_es1938_info_single, \1123  .get = snd_es1938_get_single, .put = snd_es1938_put_single, \1124  .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }1125 1126static int snd_es1938_info_single(struct snd_kcontrol *kcontrol,1127				  struct snd_ctl_elem_info *uinfo)1128{1129	int mask = (kcontrol->private_value >> 16) & 0xff;1130 1131	uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;1132	uinfo->count = 1;1133	uinfo->value.integer.min = 0;1134	uinfo->value.integer.max = mask;1135	return 0;1136}1137 1138static int snd_es1938_get_single(struct snd_kcontrol *kcontrol,1139				 struct snd_ctl_elem_value *ucontrol)1140{1141	struct es1938 *chip = snd_kcontrol_chip(kcontrol);1142	int reg = kcontrol->private_value & 0xff;1143	int shift = (kcontrol->private_value >> 8) & 0xff;1144	int mask = (kcontrol->private_value >> 16) & 0xff;1145	int invert = (kcontrol->private_value >> 24) & 0xff;1146	int val;1147	1148	val = snd_es1938_reg_read(chip, reg);1149	ucontrol->value.integer.value[0] = (val >> shift) & mask;1150	if (invert)1151		ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];1152	return 0;1153}1154 1155static int snd_es1938_put_single(struct snd_kcontrol *kcontrol,1156				 struct snd_ctl_elem_value *ucontrol)1157{1158	struct es1938 *chip = snd_kcontrol_chip(kcontrol);1159	int reg = kcontrol->private_value & 0xff;1160	int shift = (kcontrol->private_value >> 8) & 0xff;1161	int mask = (kcontrol->private_value >> 16) & 0xff;1162	int invert = (kcontrol->private_value >> 24) & 0xff;1163	unsigned char val;1164	1165	val = (ucontrol->value.integer.value[0] & mask);1166	if (invert)1167		val = mask - val;1168	mask <<= shift;1169	val <<= shift;1170	return snd_es1938_reg_bits(chip, reg, mask, val) != val;1171}1172 1173#define ES1938_DOUBLE_TLV(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert, xtlv) \1174{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \1175  .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,\1176  .name = xname, .index = xindex, \1177  .info = snd_es1938_info_double, \1178  .get = snd_es1938_get_double, .put = snd_es1938_put_double, \1179  .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22), \1180  .tlv = { .p = xtlv } }1181#define ES1938_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \1182{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \1183  .info = snd_es1938_info_double, \1184  .get = snd_es1938_get_double, .put = snd_es1938_put_double, \1185  .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }1186 1187static int snd_es1938_info_double(struct snd_kcontrol *kcontrol,1188				  struct snd_ctl_elem_info *uinfo)1189{1190	int mask = (kcontrol->private_value >> 24) & 0xff;1191 1192	uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;1193	uinfo->count = 2;1194	uinfo->value.integer.min = 0;1195	uinfo->value.integer.max = mask;1196	return 0;1197}1198 1199static int snd_es1938_get_double(struct snd_kcontrol *kcontrol,1200				 struct snd_ctl_elem_value *ucontrol)1201{1202	struct es1938 *chip = snd_kcontrol_chip(kcontrol);1203	int left_reg = kcontrol->private_value & 0xff;1204	int right_reg = (kcontrol->private_value >> 8) & 0xff;1205	int shift_left = (kcontrol->private_value >> 16) & 0x07;1206	int shift_right = (kcontrol->private_value >> 19) & 0x07;1207	int mask = (kcontrol->private_value >> 24) & 0xff;1208	int invert = (kcontrol->private_value >> 22) & 1;1209	unsigned char left, right;1210	1211	left = snd_es1938_reg_read(chip, left_reg);1212	if (left_reg != right_reg)1213		right = snd_es1938_reg_read(chip, right_reg);1214	else1215		right = left;1216	ucontrol->value.integer.value[0] = (left >> shift_left) & mask;1217	ucontrol->value.integer.value[1] = (right >> shift_right) & mask;1218	if (invert) {1219		ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];1220		ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];1221	}1222	return 0;1223}1224 1225static int snd_es1938_put_double(struct snd_kcontrol *kcontrol,1226				 struct snd_ctl_elem_value *ucontrol)1227{1228	struct es1938 *chip = snd_kcontrol_chip(kcontrol);1229	int left_reg = kcontrol->private_value & 0xff;1230	int right_reg = (kcontrol->private_value >> 8) & 0xff;1231	int shift_left = (kcontrol->private_value >> 16) & 0x07;1232	int shift_right = (kcontrol->private_value >> 19) & 0x07;1233	int mask = (kcontrol->private_value >> 24) & 0xff;1234	int invert = (kcontrol->private_value >> 22) & 1;1235	int change;1236	unsigned char val1, val2, mask1, mask2;1237	1238	val1 = ucontrol->value.integer.value[0] & mask;1239	val2 = ucontrol->value.integer.value[1] & mask;1240	if (invert) {1241		val1 = mask - val1;1242		val2 = mask - val2;1243	}1244	val1 <<= shift_left;1245	val2 <<= shift_right;1246	mask1 = mask << shift_left;1247	mask2 = mask << shift_right;1248	if (left_reg != right_reg) {1249		change = 0;1250		if (snd_es1938_reg_bits(chip, left_reg, mask1, val1) != val1)1251			change = 1;1252		if (snd_es1938_reg_bits(chip, right_reg, mask2, val2) != val2)1253			change = 1;1254	} else {1255		change = (snd_es1938_reg_bits(chip, left_reg, mask1 | mask2, 1256					      val1 | val2) != (val1 | val2));1257	}1258	return change;1259}1260 1261static const DECLARE_TLV_DB_RANGE(db_scale_master,1262	0, 54, TLV_DB_SCALE_ITEM(-3600, 50, 1),1263	54, 63, TLV_DB_SCALE_ITEM(-900, 100, 0),1264);1265 1266static const DECLARE_TLV_DB_RANGE(db_scale_audio1,1267	0, 8, TLV_DB_SCALE_ITEM(-3300, 300, 1),1268	8, 15, TLV_DB_SCALE_ITEM(-900, 150, 0),1269);1270 1271static const DECLARE_TLV_DB_RANGE(db_scale_audio2,1272	0, 8, TLV_DB_SCALE_ITEM(-3450, 300, 1),1273	8, 15, TLV_DB_SCALE_ITEM(-1050, 150, 0),1274);1275 1276static const DECLARE_TLV_DB_RANGE(db_scale_mic,1277	0, 8, TLV_DB_SCALE_ITEM(-2400, 300, 1),1278	8, 15, TLV_DB_SCALE_ITEM(0, 150, 0),1279);1280 1281static const DECLARE_TLV_DB_RANGE(db_scale_line,1282	0, 8, TLV_DB_SCALE_ITEM(-3150, 300, 1),1283	8, 15, TLV_DB_SCALE_ITEM(-750, 150, 0),1284);1285 1286static const DECLARE_TLV_DB_SCALE(db_scale_capture, 0, 150, 0);1287 1288static const struct snd_kcontrol_new snd_es1938_controls[] = {1289ES1938_DOUBLE_TLV("Master Playback Volume", 0, 0x60, 0x62, 0, 0, 63, 0,1290		  db_scale_master),1291ES1938_DOUBLE("Master Playback Switch", 0, 0x60, 0x62, 6, 6, 1, 1),1292{1293	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,1294	.name = "Hardware Master Playback Volume",1295	.access = SNDRV_CTL_ELEM_ACCESS_READ,1296	.info = snd_es1938_info_hw_volume,1297	.get = snd_es1938_get_hw_volume,1298},1299{1300	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,1301	.access = (SNDRV_CTL_ELEM_ACCESS_READ |1302		   SNDRV_CTL_ELEM_ACCESS_TLV_READ),1303	.name = "Hardware Master Playback Switch",1304	.info = snd_es1938_info_hw_switch,1305	.get = snd_es1938_get_hw_switch,1306	.tlv = { .p = db_scale_master },1307},1308ES1938_SINGLE("Hardware Volume Split", 0, 0x64, 7, 1, 0),1309ES1938_DOUBLE_TLV("Line Playback Volume", 0, 0x3e, 0x3e, 4, 0, 15, 0,1310		  db_scale_line),1311ES1938_DOUBLE("CD Playback Volume", 0, 0x38, 0x38, 4, 0, 15, 0),1312ES1938_DOUBLE_TLV("FM Playback Volume", 0, 0x36, 0x36, 4, 0, 15, 0,1313		  db_scale_mic),1314ES1938_DOUBLE_TLV("Mono Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0,1315		  db_scale_line),1316ES1938_DOUBLE_TLV("Mic Playback Volume", 0, 0x1a, 0x1a, 4, 0, 15, 0,1317		  db_scale_mic),1318ES1938_DOUBLE_TLV("Aux Playback Volume", 0, 0x3a, 0x3a, 4, 0, 15, 0,1319		  db_scale_line),1320ES1938_DOUBLE_TLV("Capture Volume", 0, 0xb4, 0xb4, 4, 0, 15, 0,1321		  db_scale_capture),1322ES1938_SINGLE("Beep Volume", 0, 0x3c, 0, 7, 0),1323ES1938_SINGLE("Record Monitor", 0, 0xa8, 3, 1, 0),1324ES1938_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1),1325{1326	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,1327	.name = "Capture Source",1328	.info = snd_es1938_info_mux,1329	.get = snd_es1938_get_mux,1330	.put = snd_es1938_put_mux,1331},1332ES1938_DOUBLE_TLV("Mono Input Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0,1333		  db_scale_line),1334ES1938_DOUBLE_TLV("PCM Capture Volume", 0, 0x69, 0x69, 4, 0, 15, 0,1335		  db_scale_audio2),1336ES1938_DOUBLE_TLV("Mic Capture Volume", 0, 0x68, 0x68, 4, 0, 15, 0,1337		  db_scale_mic),1338ES1938_DOUBLE_TLV("Line Capture Volume", 0, 0x6e, 0x6e, 4, 0, 15, 0,1339		  db_scale_line),1340ES1938_DOUBLE_TLV("FM Capture Volume", 0, 0x6b, 0x6b, 4, 0, 15, 0,1341		  db_scale_mic),1342ES1938_DOUBLE_TLV("Mono Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0,1343		  db_scale_line),1344ES1938_DOUBLE_TLV("CD Capture Volume", 0, 0x6a, 0x6a, 4, 0, 15, 0,1345		  db_scale_line),1346ES1938_DOUBLE_TLV("Aux Capture Volume", 0, 0x6c, 0x6c, 4, 0, 15, 0,1347		  db_scale_line),1348ES1938_DOUBLE_TLV("PCM Playback Volume", 0, 0x7c, 0x7c, 4, 0, 15, 0,1349		  db_scale_audio2),1350ES1938_DOUBLE_TLV("PCM Playback Volume", 1, 0x14, 0x14, 4, 0, 15, 0,1351		  db_scale_audio1),1352ES1938_SINGLE("3D Control - Level", 0, 0x52, 0, 63, 0),1353{1354	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,1355	.name = "3D Control - Switch",1356	.info = snd_es1938_info_spatializer_enable,1357	.get = snd_es1938_get_spatializer_enable,1358	.put = snd_es1938_put_spatializer_enable,1359},1360ES1938_SINGLE("Mic Boost (+26dB)", 0, 0x7d, 3, 1, 0)1361};1362 1363 1364/* ---------------------------------------------------------------------------- */1365/* ---------------------------------------------------------------------------- */1366 1367/*1368 * initialize the chip - used by resume callback, too1369 */1370static void snd_es1938_chip_init(struct es1938 *chip)1371{1372	/* reset chip */1373	snd_es1938_reset(chip);1374 1375	/* configure native mode */1376 1377	/* enable bus master */1378	pci_set_master(chip->pci);1379 1380	/* disable legacy audio */1381	pci_write_config_word(chip->pci, SL_PCI_LEGACYCONTROL, 0x805f);1382 1383	/* set DDMA base */1384	pci_write_config_word(chip->pci, SL_PCI_DDMACONTROL, chip->ddma_port | 1);1385 1386	/* set DMA/IRQ policy */1387	pci_write_config_dword(chip->pci, SL_PCI_CONFIG, 0);1388 1389	/* enable Audio 1, Audio 2, MPU401 IRQ and HW volume IRQ*/1390	outb(0xf0, SLIO_REG(chip, IRQCONTROL));1391 1392	/* reset DMA */1393	outb(0, SLDM_REG(chip, DMACLEAR));1394}1395 1396/*1397 * PM support1398 */1399 1400static const unsigned char saved_regs[SAVED_REG_SIZE+1] = {1401	0x14, 0x1a, 0x1c, 0x3a, 0x3c, 0x3e, 0x36, 0x38,1402	0x50, 0x52, 0x60, 0x61, 0x62, 0x63, 0x64, 0x68,1403	0x69, 0x6a, 0x6b, 0x6d, 0x6e, 0x6f, 0x7c, 0x7d,1404	0xa8, 0xb4,1405};1406 1407 1408static int es1938_suspend(struct device *dev)1409{1410	struct snd_card *card = dev_get_drvdata(dev);1411	struct es1938 *chip = card->private_data;1412	const unsigned char *s;1413	unsigned char *d;1414 1415	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);1416 1417	/* save mixer-related registers */1418	for (s = saved_regs, d = chip->saved_regs; *s; s++, d++)1419		*d = snd_es1938_reg_read(chip, *s);1420 1421	outb(0x00, SLIO_REG(chip, IRQCONTROL)); /* disable irqs */1422	if (chip->irq >= 0) {1423		free_irq(chip->irq, chip);1424		chip->irq = -1;1425		card->sync_irq = -1;1426	}1427	return 0;1428}1429 1430static int es1938_resume(struct device *dev)1431{1432	struct pci_dev *pci = to_pci_dev(dev);1433	struct snd_card *card = dev_get_drvdata(dev);1434	struct es1938 *chip = card->private_data;1435	const unsigned char *s;1436	unsigned char *d;1437 1438	if (request_irq(pci->irq, snd_es1938_interrupt,1439			IRQF_SHARED, KBUILD_MODNAME, chip)) {1440		dev_err(dev, "unable to grab IRQ %d, disabling device\n",1441			pci->irq);1442		snd_card_disconnect(card);1443		return -EIO;1444	}1445	chip->irq = pci->irq;1446	card->sync_irq = chip->irq;1447	snd_es1938_chip_init(chip);1448 1449	/* restore mixer-related registers */1450	for (s = saved_regs, d = chip->saved_regs; *s; s++, d++) {1451		if (*s < 0xa0)1452			snd_es1938_mixer_write(chip, *s, *d);1453		else1454			snd_es1938_write(chip, *s, *d);1455	}1456 1457	snd_power_change_state(card, SNDRV_CTL_POWER_D0);1458	return 0;1459}1460 1461static DEFINE_SIMPLE_DEV_PM_OPS(es1938_pm, es1938_suspend, es1938_resume);1462 1463#ifdef SUPPORT_JOYSTICK1464static int snd_es1938_create_gameport(struct es1938 *chip)1465{1466	struct gameport *gp;1467 1468	chip->gameport = gp = gameport_allocate_port();1469	if (!gp) {1470		dev_err(chip->card->dev,1471			"cannot allocate memory for gameport\n");1472		return -ENOMEM;1473	}1474 1475	gameport_set_name(gp, "ES1938");1476	gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));1477	gameport_set_dev_parent(gp, &chip->pci->dev);1478	gp->io = chip->game_port;1479 1480	gameport_register_port(gp);1481 1482	return 0;1483}1484 1485static void snd_es1938_free_gameport(struct es1938 *chip)1486{1487	if (chip->gameport) {1488		gameport_unregister_port(chip->gameport);1489		chip->gameport = NULL;1490	}1491}1492#else1493static inline int snd_es1938_create_gameport(struct es1938 *chip) { return -ENOSYS; }1494static inline void snd_es1938_free_gameport(struct es1938 *chip) { }1495#endif /* SUPPORT_JOYSTICK */1496 1497static void snd_es1938_free(struct snd_card *card)1498{1499	struct es1938 *chip = card->private_data;1500 1501	/* disable irqs */1502	outb(0x00, SLIO_REG(chip, IRQCONTROL));1503	if (chip->rmidi)1504		snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0);1505 1506	snd_es1938_free_gameport(chip);1507 1508	if (chip->irq >= 0)1509		free_irq(chip->irq, chip);1510}1511 1512static int snd_es1938_create(struct snd_card *card,1513			     struct pci_dev *pci)1514{1515	struct es1938 *chip = card->private_data;1516	int err;1517 1518	/* enable PCI device */1519	err = pcim_enable_device(pci);1520	if (err < 0)1521		return err;1522        /* check, if we can restrict PCI DMA transfers to 24 bits */1523	if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(24))) {1524		dev_err(card->dev,1525			"architecture does not support 24bit PCI busmaster DMA\n");1526                return -ENXIO;1527        }1528 1529	spin_lock_init(&chip->reg_lock);1530	spin_lock_init(&chip->mixer_lock);1531	chip->card = card;1532	chip->pci = pci;1533	chip->irq = -1;1534	err = pci_request_regions(pci, "ESS Solo-1");1535	if (err < 0)1536		return err;1537	chip->io_port = pci_resource_start(pci, 0);1538	chip->sb_port = pci_resource_start(pci, 1);1539	chip->vc_port = pci_resource_start(pci, 2);1540	chip->mpu_port = pci_resource_start(pci, 3);1541	chip->game_port = pci_resource_start(pci, 4);1542	/* still use non-managed irq handler as it's re-acquired at PM resume */1543	if (request_irq(pci->irq, snd_es1938_interrupt, IRQF_SHARED,1544			KBUILD_MODNAME, chip)) {1545		dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);1546		return -EBUSY;1547	}1548	chip->irq = pci->irq;1549	card->sync_irq = chip->irq;1550	card->private_free = snd_es1938_free;1551	dev_dbg(card->dev,1552		"create: io: 0x%lx, sb: 0x%lx, vc: 0x%lx, mpu: 0x%lx, game: 0x%lx\n",1553		   chip->io_port, chip->sb_port, chip->vc_port, chip->mpu_port, chip->game_port);1554 1555	chip->ddma_port = chip->vc_port + 0x00;		/* fix from Thomas Sailer */1556 1557	snd_es1938_chip_init(chip);1558	return 0;1559}1560 1561/* --------------------------------------------------------------------1562 * Interrupt handler1563 * -------------------------------------------------------------------- */1564static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id)1565{1566	struct es1938 *chip = dev_id;1567	unsigned char status;1568	__always_unused unsigned char audiostatus;1569	int handled = 0;1570 1571	status = inb(SLIO_REG(chip, IRQCONTROL));1572#if 01573	dev_dbg(chip->card->dev,1574		"Es1938debug - interrupt status: =0x%x\n", status);1575#endif1576	1577	/* AUDIO 1 */1578	if (status & 0x10) {1579#if 01580		dev_dbg(chip->card->dev,1581		       "Es1938debug - AUDIO channel 1 interrupt\n");1582		dev_dbg(chip->card->dev,1583		       "Es1938debug - AUDIO channel 1 DMAC DMA count: %u\n",1584		       inw(SLDM_REG(chip, DMACOUNT)));1585		dev_dbg(chip->card->dev,1586		       "Es1938debug - AUDIO channel 1 DMAC DMA base: %u\n",1587		       inl(SLDM_REG(chip, DMAADDR)));1588		dev_dbg(chip->card->dev,1589		       "Es1938debug - AUDIO channel 1 DMAC DMA status: 0x%x\n",1590		       inl(SLDM_REG(chip, DMASTATUS)));1591#endif1592		/* clear irq */1593		handled = 1;1594		audiostatus = inb(SLSB_REG(chip, STATUS));1595		if (chip->active & ADC1)1596			snd_pcm_period_elapsed(chip->capture_substream);1597		else if (chip->active & DAC1)1598			snd_pcm_period_elapsed(chip->playback2_substream);1599	}1600	1601	/* AUDIO 2 */1602	if (status & 0x20) {1603#if 01604		dev_dbg(chip->card->dev,1605		       "Es1938debug - AUDIO channel 2 interrupt\n");1606		dev_dbg(chip->card->dev,1607		       "Es1938debug - AUDIO channel 2 DMAC DMA count: %u\n",1608		       inw(SLIO_REG(chip, AUDIO2DMACOUNT)));1609		dev_dbg(chip->card->dev,1610		       "Es1938debug - AUDIO channel 2 DMAC DMA base: %u\n",1611		       inl(SLIO_REG(chip, AUDIO2DMAADDR)));1612 1613#endif1614		/* clear irq */1615		handled = 1;1616		snd_es1938_mixer_bits(chip, ESSSB_IREG_AUDIO2CONTROL2, 0x80, 0);1617		if (chip->active & DAC2)1618			snd_pcm_period_elapsed(chip->playback1_substream);1619	}1620 1621	/* Hardware volume */1622	if (status & 0x40) {1623		int split = snd_es1938_mixer_read(chip, 0x64) & 0x80;1624		handled = 1;1625		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_switch->id);1626		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_volume->id);1627		if (!split) {1628			snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,1629				       &chip->master_switch->id);1630			snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,1631				       &chip->master_volume->id);1632		}1633		/* ack interrupt */1634		snd_es1938_mixer_write(chip, 0x66, 0x00);1635	}1636 1637	/* MPU401 */1638	if (status & 0x80) {1639		// the following line is evil! It switches off MIDI interrupt handling after the first interrupt received.1640		// replacing the last 0 by 0x40 works for ESS-Solo1, but just doing nothing works as well!1641		// andreas@flying-snail.de1642		// snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0); /* ack? */1643		if (chip->rmidi) {1644			handled = 1;1645			snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);1646		}1647	}1648	return IRQ_RETVAL(handled);1649}1650 1651#define ES1938_DMA_SIZE 641652 1653static int snd_es1938_mixer(struct es1938 *chip)1654{1655	struct snd_card *card;1656	unsigned int idx;1657	int err;1658 1659	card = chip->card;1660 1661	strcpy(card->mixername, "ESS Solo-1");1662 1663	for (idx = 0; idx < ARRAY_SIZE(snd_es1938_controls); idx++) {1664		struct snd_kcontrol *kctl;1665		kctl = snd_ctl_new1(&snd_es1938_controls[idx], chip);1666		switch (idx) {1667			case 0:1668				chip->master_volume = kctl;1669				kctl->private_free = snd_es1938_hwv_free;1670				break;1671			case 1:1672				chip->master_switch = kctl;1673				kctl->private_free = snd_es1938_hwv_free;1674				break;1675			case 2:1676				chip->hw_volume = kctl;1677				kctl->private_free = snd_es1938_hwv_free;1678				break;1679			case 3:1680				chip->hw_switch = kctl;1681				kctl->private_free = snd_es1938_hwv_free;1682				break;1683			}1684		err = snd_ctl_add(card, kctl);1685		if (err < 0)1686			return err;1687	}1688	return 0;1689}1690       1691 1692static int __snd_es1938_probe(struct pci_dev *pci,1693			      const struct pci_device_id *pci_id)1694{1695	static int dev;1696	struct snd_card *card;1697	struct es1938 *chip;1698	struct snd_opl3 *opl3;1699	int idx, err;1700 1701	if (dev >= SNDRV_CARDS)1702		return -ENODEV;1703	if (!enable[dev]) {1704		dev++;1705		return -ENOENT;1706	}1707 1708	err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,1709				sizeof(*chip), &card);1710	if (err < 0)1711		return err;1712	chip = card->private_data;1713 1714	for (idx = 0; idx < 5; idx++)1715		if (pci_resource_start(pci, idx) == 0 ||1716		    !(pci_resource_flags(pci, idx) & IORESOURCE_IO))1717			return -ENODEV;1718 1719	err = snd_es1938_create(card, pci);1720	if (err < 0)1721		return err;1722 1723	strcpy(card->driver, "ES1938");1724	strcpy(card->shortname, "ESS ES1938 (Solo-1)");1725	sprintf(card->longname, "%s rev %i, irq %i",1726		card->shortname,1727		chip->revision,1728		chip->irq);1729 1730	err = snd_es1938_new_pcm(chip, 0);1731	if (err < 0)1732		return err;1733	err = snd_es1938_mixer(chip);1734	if (err < 0)1735		return err;1736	if (snd_opl3_create(card,1737			    SLSB_REG(chip, FMLOWADDR),1738			    SLSB_REG(chip, FMHIGHADDR),1739			    OPL3_HW_OPL3, 1, &opl3) < 0) {1740		dev_err(card->dev, "OPL3 not detected at 0x%lx\n",1741			   SLSB_REG(chip, FMLOWADDR));1742	} else {1743		err = snd_opl3_timer_new(opl3, 0, 1);1744		if (err < 0)1745	                return err;1746		err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);1747		if (err < 0)1748	                return err;1749	}1750	if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,1751				chip->mpu_port,1752				MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK,1753				-1, &chip->rmidi) < 0) {1754		dev_err(card->dev, "unable to initialize MPU-401\n");1755	} else {1756		// this line is vital for MIDI interrupt handling on ess-solo11757		// andreas@flying-snail.de1758		snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0x40);1759	}1760 1761	snd_es1938_create_gameport(chip);1762 1763	err = snd_card_register(card);1764	if (err < 0)1765		return err;1766 1767	pci_set_drvdata(pci, card);1768	dev++;1769	return 0;1770}1771 1772static int snd_es1938_probe(struct pci_dev *pci,1773			    const struct pci_device_id *pci_id)1774{1775	return snd_card_free_on_error(&pci->dev, __snd_es1938_probe(pci, pci_id));1776}1777 1778static struct pci_driver es1938_driver = {1779	.name = KBUILD_MODNAME,1780	.id_table = snd_es1938_ids,1781	.probe = snd_es1938_probe,1782	.driver = {1783		.pm = &es1938_pm,1784	},1785};1786 1787module_pci_driver(es1938_driver);1788