15455Sdg// SPDX-License-Identifier: GPL-2.0-or-later
21541Srgrimes/*
31541Srgrimes *  Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
41549Srgrimes *  Driver EMU10K1X chips
51549Srgrimes *
61549Srgrimes *  Parts of this code were adapted from audigyls.c driver which is
71549Srgrimes *  Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
81541Srgrimes *
91549Srgrimes *  BUGS:
101541Srgrimes *    --
111541Srgrimes *
121541Srgrimes *  TODO:
131541Srgrimes *
141541Srgrimes *  Chips (SB0200 model):
151541Srgrimes *    - EMU10K1X-DBQ
161541Srgrimes *    - STAC 9708T
171541Srgrimes */
181541Srgrimes#include <linux/init.h>
191541Srgrimes#include <linux/interrupt.h>
201541Srgrimes#include <linux/pci.h>
211541Srgrimes#include <linux/dma-mapping.h>
2258705Scharnier#include <linux/slab.h>
231541Srgrimes#include <linux/module.h>
241541Srgrimes#include <sound/core.h>
251541Srgrimes#include <sound/initval.h>
261541Srgrimes#include <sound/pcm.h>
271541Srgrimes#include <sound/ac97_codec.h>
281541Srgrimes#include <sound/info.h>
291541Srgrimes#include <sound/rawmidi.h>
301541Srgrimes
311541SrgrimesMODULE_AUTHOR("Francisco Moraes <fmoraes@nc.rr.com>");
321541SrgrimesMODULE_DESCRIPTION("EMU10K1X");
331541SrgrimesMODULE_LICENSE("GPL");
341541Srgrimes
351541Srgrimes// module parameters (see "Module Parameters")
361541Srgrimesstatic int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
371541Srgrimesstatic char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
381541Srgrimesstatic bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
391541Srgrimes
401541Srgrimesmodule_param_array(index, int, NULL, 0444);
411817SdgMODULE_PARM_DESC(index, "Index value for the EMU10K1X soundcard.");
421541Srgrimesmodule_param_array(id, charp, NULL, 0444);
431541SrgrimesMODULE_PARM_DESC(id, "ID string for the EMU10K1X soundcard.");
441541Srgrimesmodule_param_array(enable, bool, NULL, 0444);
451541SrgrimesMODULE_PARM_DESC(enable, "Enable the EMU10K1X soundcard.");
461541Srgrimes
471541Srgrimes
485455Sdg// some definitions were borrowed from emu10k1 driver as they seem to be the same
491541Srgrimes/************************************************************************************************/
501541Srgrimes/* PCI function 0 registers, address = <val> + PCIBASE0						*/
511541Srgrimes/************************************************************************************************/
521541Srgrimes
531541Srgrimes#define PTR			0x00		/* Indexed register set pointer register	*/
545455Sdg						/* NOTE: The CHANNELNUM and ADDRESS words can	*/
555455Sdg						/* be modified independently of each other.	*/
565455Sdg
571541Srgrimes#define DATA			0x04		/* Indexed register set data register		*/
585455Sdg
591541Srgrimes#define IPR			0x08		/* Global interrupt pending register		*/
601541Srgrimes						/* Clear pending interrupts by writing a 1 to	*/
611541Srgrimes						/* the relevant bits and zero to the other bits	*/
621541Srgrimes#define IPR_MIDITRANSBUFEMPTY   0x00000001	/* MIDI UART transmit buffer empty		*/
631541Srgrimes#define IPR_MIDIRECVBUFEMPTY    0x00000002	/* MIDI UART receive buffer empty		*/
641541Srgrimes#define IPR_CH_0_LOOP           0x00000800      /* Channel 0 loop                               */
651541Srgrimes#define IPR_CH_0_HALF_LOOP      0x00000100      /* Channel 0 half loop                          */
661541Srgrimes#define IPR_CAP_0_LOOP          0x00080000      /* Channel capture loop                         */
671541Srgrimes#define IPR_CAP_0_HALF_LOOP     0x00010000      /* Channel capture half loop                    */
681541Srgrimes
691541Srgrimes#define INTE			0x0c		/* Interrupt enable register			*/
701541Srgrimes#define INTE_MIDITXENABLE       0x00000001	/* Enable MIDI transmit-buffer-empty interrupts	*/
711541Srgrimes#define INTE_MIDIRXENABLE       0x00000002	/* Enable MIDI receive-buffer-empty interrupts	*/
721541Srgrimes#define INTE_CH_0_LOOP          0x00000800      /* Channel 0 loop                               */
73116226Sobrien#define INTE_CH_0_HALF_LOOP     0x00000100      /* Channel 0 half loop                          */
74116226Sobrien#define INTE_CAP_0_LOOP         0x00080000      /* Channel capture loop                         */
75116226Sobrien#define INTE_CAP_0_HALF_LOOP    0x00010000      /* Channel capture half loop                    */
76116226Sobrien
771541Srgrimes#define HCFG			0x14		/* Hardware config register			*/
781541Srgrimes
7976949Sjhb#define HCFG_LOCKSOUNDCACHE	0x00000008	/* 1 = Cancel bustmaster accesses to soundcache */
8076166Smarkm						/* NOTE: This should generally never be used.  	*/
8176166Smarkm#define HCFG_AUDIOENABLE	0x00000001	/* 0 = CODECs transmit zero-valued samples	*/
821549Srgrimes						/* Should be set to 1 when the EMU10K1 is	*/
831549Srgrimes						/* completely initialized.			*/
8476949Sjhb#define GPIO			0x18		/* Defaults: 00001080-Analog, 00001000-SPDIF.   */
8512662Sdg
8676949Sjhb
871541Srgrimes#define AC97DATA		0x1c		/* AC97 register set data register (16 bit)	*/
881541Srgrimes
8912662Sdg#define AC97ADDRESS		0x1e		/* AC97 register set address register (8 bit)	*/
9012662Sdg
9112662Sdg/********************************************************************************************************/
9212662Sdg/* Emu10k1x pointer-offset register set, accessed through the PTR and DATA registers			*/
931541Srgrimes/********************************************************************************************************/
941541Srgrimes#define PLAYBACK_LIST_ADDR	0x00		/* Base DMA address of a list of pointers to each period/size */
954207Sdg						/* One list entry: 4 bytes for DMA address,
969507Sdg						 * 4 bytes for period_size << 16.
979507Sdg						 * One list entry is 8 bytes long.
9812662Sdg						 * One list entry for each period in the buffer.
991541Srgrimes						 */
100120722Salc#define PLAYBACK_LIST_SIZE	0x01		/* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000  */
101120722Salc#define PLAYBACK_LIST_PTR	0x02		/* Pointer to the current period being played */
102120722Salc#define PLAYBACK_DMA_ADDR	0x04		/* Playback DMA address */
103120722Salc#define PLAYBACK_PERIOD_SIZE	0x05		/* Playback period size */
104120722Salc#define PLAYBACK_POINTER	0x06		/* Playback period pointer. Sample currently in DAC */
105120722Salc#define PLAYBACK_UNKNOWN1       0x07
106120722Salc#define PLAYBACK_UNKNOWN2       0x08
107120722Salc
108120722Salc/* Only one capture channel supported */
109120722Salc#define CAPTURE_DMA_ADDR	0x10		/* Capture DMA address */
110120722Salc#define CAPTURE_BUFFER_SIZE	0x11		/* Capture buffer size */
11192727Salfred#define CAPTURE_POINTER		0x12		/* Capture buffer pointer. Sample currently in ADC */
112120722Salc#define CAPTURE_UNKNOWN         0x13
1131549Srgrimes
11432585Sdyson/* From 0x20 - 0x3f, last samples played on each channel */
11532585Sdyson
1161549Srgrimes#define TRIGGER_CHANNEL         0x40            /* Trigger channel playback                     */
1171549Srgrimes#define TRIGGER_CHANNEL_0       0x00000001      /* Trigger channel 0                            */
11834202Sdyson#define TRIGGER_CHANNEL_1       0x00000002      /* Trigger channel 1                            */
11934202Sdyson#define TRIGGER_CHANNEL_2       0x00000004      /* Trigger channel 2                            */
12034202Sdyson#define TRIGGER_CAPTURE         0x00000100      /* Trigger capture channel                      */
12134202Sdyson
12234202Sdyson#define ROUTING                 0x41            /* Setup sound routing ?                        */
12334202Sdyson#define ROUTING_FRONT_LEFT      0x00000001
12434202Sdyson#define ROUTING_FRONT_RIGHT     0x00000002
12534202Sdyson#define ROUTING_REAR_LEFT       0x00000004
12634202Sdyson#define ROUTING_REAR_RIGHT      0x00000008
12792588Sgreen#define ROUTING_CENTER_LFE      0x00010000
12834202Sdyson
12934202Sdyson#define SPCS0			0x42		/* SPDIF output Channel Status 0 register	*/
13034202Sdyson
13142957Sdillon#define SPCS1			0x43		/* SPDIF output Channel Status 1 register	*/
13234202Sdyson
13334202Sdyson#define SPCS2			0x44		/* SPDIF output Channel Status 2 register	*/
134100456Salc
13538799Sdfr#define SPCS_CLKACCYMASK	0x30000000	/* Clock accuracy				*/
13634202Sdyson#define SPCS_CLKACCY_1000PPM	0x00000000	/* 1000 parts per million			*/
137100456Salc#define SPCS_CLKACCY_50PPM	0x10000000	/* 50 parts per million				*/
13834202Sdyson#define SPCS_CLKACCY_VARIABLE	0x20000000	/* Variable accuracy				*/
13934202Sdyson#define SPCS_SAMPLERATEMASK	0x0f000000	/* Sample rate					*/
14034202Sdyson#define SPCS_SAMPLERATE_44	0x00000000	/* 44.1kHz sample rate				*/
14142957Sdillon#define SPCS_SAMPLERATE_48	0x02000000	/* 48kHz sample rate				*/
14234202Sdyson#define SPCS_SAMPLERATE_32	0x03000000	/* 32kHz sample rate				*/
14334202Sdyson#define SPCS_CHANNELNUMMASK	0x00f00000	/* Channel number				*/
14492588Sgreen#define SPCS_CHANNELNUM_UNSPEC	0x00000000	/* Unspecified channel number			*/
14534202Sdyson#define SPCS_CHANNELNUM_LEFT	0x00100000	/* Left channel					*/
14692588Sgreen#define SPCS_CHANNELNUM_RIGHT	0x00200000	/* Right channel				*/
14734202Sdyson#define SPCS_SOURCENUMMASK	0x000f0000	/* Source number				*/
14834202Sdyson#define SPCS_SOURCENUM_UNSPEC	0x00000000	/* Unspecified source number			*/
14934202Sdyson#define SPCS_GENERATIONSTATUS	0x00008000	/* Originality flag (see IEC-958 spec)		*/
15034202Sdyson#define SPCS_CATEGORYCODEMASK	0x00007f00	/* Category code (see IEC-958 spec)		*/
15134202Sdyson#define SPCS_MODEMASK		0x000000c0	/* Mode (see IEC-958 spec)			*/
15234202Sdyson#define SPCS_EMPHASISMASK	0x00000038	/* Emphasis					*/
153116695Salc#define SPCS_EMPHASIS_NONE	0x00000000	/* No emphasis					*/
15434202Sdyson#define SPCS_EMPHASIS_50_15	0x00000008	/* 50/15 usec 2 channel				*/
155113761Salc#define SPCS_COPYRIGHT		0x00000004	/* Copyright asserted flag -- do not modify	*/
15634202Sdyson#define SPCS_NOTAUDIODATA	0x00000002	/* 0 = Digital audio, 1 = not audio		*/
157113761Salc#define SPCS_PROFESSIONAL	0x00000001	/* 0 = Consumer (IEC-958), 1 = pro (AES3-1992)	*/
158100456Salc
15934202Sdyson#define SPDIF_SELECT		0x45		/* Enables SPDIF or Analogue outputs 0-Analogue, 0x700-SPDIF */
160100456Salc
16134202Sdyson/* This is the MPU port on the card                      					*/
162113761Salc#define MUDATA		0x47
16334202Sdyson#define MUCMD		0x48
16434202Sdyson#define MUSTAT		MUCMD
16534202Sdyson
16634202Sdyson/* From 0x50 - 0x5f, last samples captured */
16734202Sdyson
16834202Sdyson/*
16934202Sdyson * The hardware has 3 channels for playback and 1 for capture.
17079224Sdillon *  - channel 0 is the front channel
17134202Sdyson *  - channel 1 is the rear channel
17234202Sdyson *  - channel 2 is the center/lfe channel
173123879Salc * Volume is controlled by the AC97 for the front and rear channels by
174123879Salc * the PCM Playback Volume, Sigmatel Surround Playback Volume and
17534202Sdyson * Surround Playback Volume. The Sigmatel 4-Speaker Stereo switch affects
17634202Sdyson * the front/rear channel mixing in the REAR OUT jack. When using the
17734202Sdyson * 4-Speaker Stereo, both front and rear channels will be mixed in the
17834202Sdyson * REAR OUT.
17934202Sdyson * The center/lfe channel has no volume control and cannot be muted during
1801541Srgrimes * playback.
18151488Sdillon */
18251488Sdillon
18351488Sdillonstruct emu10k1x_voice {
18451488Sdillon	struct emu10k1x *emu;
18551488Sdillon	int number;
18651488Sdillon	int use;
18751488Sdillon
18851488Sdillon	struct emu10k1x_pcm *epcm;
18951488Sdillon};
1901541Srgrimes
1911541Srgrimesstruct emu10k1x_pcm {
19258634Scharnier	struct emu10k1x *emu;
1931541Srgrimes	struct snd_pcm_substream *substream;
1941541Srgrimes	struct emu10k1x_voice *voice;
1951541Srgrimes	unsigned short running;
1961541Srgrimes};
1971541Srgrimes
1981541Srgrimesstruct emu10k1x_midi {
1991541Srgrimes	struct emu10k1x *emu;
2001541Srgrimes	struct snd_rawmidi *rmidi;
2011541Srgrimes	struct snd_rawmidi_substream *substream_input;
2021541Srgrimes	struct snd_rawmidi_substream *substream_output;
2031541Srgrimes	unsigned int midi_mode;
2041541Srgrimes	spinlock_t input_lock;
20579224Sdillon	spinlock_t output_lock;
2061541Srgrimes	spinlock_t open_lock;
2071541Srgrimes	int tx_enable, rx_enable;
20876827Salfred	int port;
20976827Salfred	int ipr_tx, ipr_rx;
2101541Srgrimes	void (*interrupt)(struct emu10k1x *emu, unsigned int status);
2115455Sdg};
212116650Salc
21394977Salc// definition of the chip-specific record
21432702Sdysonstruct emu10k1x {
2155455Sdg	struct snd_card *card;
2165455Sdg	struct pci_dev *pci;
21734202Sdyson
21832702Sdyson	unsigned long port;
21934202Sdyson	int irq;
2201541Srgrimes
22134202Sdyson	unsigned char revision;		/* chip revision */
22294977Salc	unsigned int serial;            /* serial number */
22395021Salc	unsigned short model;		/* subsystem id */
2241541Srgrimes
2255455Sdg	spinlock_t emu_lock;
2261541Srgrimes	spinlock_t voice_lock;
2271541Srgrimes
2285455Sdg	struct snd_ac97 *ac97;
2295455Sdg	struct snd_pcm *pcm;
2301541Srgrimes
23151488Sdillon	struct emu10k1x_voice voices[3];
23295021Salc	struct emu10k1x_voice capture_voice;
23395021Salc	u32 spdif_bits[3]; // SPDIF out setup
23495021Salc
23595021Salc	struct snd_dma_buffer *dma_buffer;
23695021Salc
23794977Salc	struct emu10k1x_midi midi;
23894977Salc};
23994977Salc
240123879Salc/* hardware definition */
24194977Salcstatic const struct snd_pcm_hardware snd_emu10k1x_playback_hw = {
24294977Salc	.info =			(SNDRV_PCM_INFO_MMAP |
24394977Salc				 SNDRV_PCM_INFO_INTERLEAVED |
24494977Salc				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
24595021Salc				 SNDRV_PCM_INFO_MMAP_VALID),
24632585Sdyson	.formats =		SNDRV_PCM_FMTBIT_S16_LE,
24732585Sdyson	.rates =		SNDRV_PCM_RATE_48000,
24832585Sdyson	.rate_min =		48000,
24932585Sdyson	.rate_max =		48000,
25032585Sdyson	.channels_min =		2,
25132585Sdyson	.channels_max =		2,
25232585Sdyson	.buffer_bytes_max =	(32*1024),
25332585Sdyson	.period_bytes_min =	64,
25432585Sdyson	.period_bytes_max =	(16*1024),
25534202Sdyson	.periods_min =		2,
25632585Sdyson	.periods_max =		8,
25734202Sdyson	.fifo_size =		0,
258123879Salc};
25995764Salc
26032585Sdysonstatic const struct snd_pcm_hardware snd_emu10k1x_capture_hw = {
26132585Sdyson	.info =			(SNDRV_PCM_INFO_MMAP |
26232585Sdyson				 SNDRV_PCM_INFO_INTERLEAVED |
26332585Sdyson				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
26432585Sdyson				 SNDRV_PCM_INFO_MMAP_VALID),
26594981Salc	.formats =		SNDRV_PCM_FMTBIT_S16_LE,
26694981Salc	.rates =		SNDRV_PCM_RATE_48000,
26794981Salc	.rate_min =		48000,
26832585Sdyson	.rate_max =		48000,
26934202Sdyson	.channels_min =		2,
27034202Sdyson	.channels_max =		2,
2711541Srgrimes	.buffer_bytes_max =	(32*1024),
2727695Sdg	.period_bytes_min =	64,
27334202Sdyson	.period_bytes_max =	(16*1024),
27432702Sdyson	.periods_min =		2,
27534202Sdyson	.periods_max =		2,
27620054Sdyson	.fifo_size =		0,
27737563Sbde};
27820054Sdyson
27920054Sdysonstatic unsigned int snd_emu10k1x_ptr_read(struct emu10k1x * emu,
28020449Sdyson					  unsigned int reg,
28132286Sdyson					  unsigned int chn)
28232286Sdyson{
28332286Sdyson	unsigned long flags;
28432286Sdyson	unsigned int regptr, val;
28586236Sdillon
28686236Sdillon	regptr = (reg << 16) | chn;
28786236Sdillon
28886236Sdillon	spin_lock_irqsave(&emu->emu_lock, flags);
28995701Salc	outl(regptr, emu->port + PTR);
29095701Salc	val = inl(emu->port + DATA);
29132286Sdyson	spin_unlock_irqrestore(&emu->emu_lock, flags);
292123879Salc	return val;
293120183Salc}
294123879Salc
29586236Sdillonstatic void snd_emu10k1x_ptr_write(struct emu10k1x *emu,
29638135Sdfr				   unsigned int reg,
29732286Sdyson				   unsigned int chn,
29892588Sgreen				   unsigned int data)
2991541Srgrimes{
3001541Srgrimes	unsigned int regptr;
3011541Srgrimes	unsigned long flags;
3021541Srgrimes
30334202Sdyson	regptr = (reg << 16) | chn;
3041541Srgrimes
3055455Sdg	spin_lock_irqsave(&emu->emu_lock, flags);
3065455Sdg	outl(regptr, emu->port + PTR);
3071541Srgrimes	outl(data, emu->port + DATA);
30834202Sdyson	spin_unlock_irqrestore(&emu->emu_lock, flags);
30934202Sdyson}
3101541Srgrimes
31142957Sdillonstatic void snd_emu10k1x_intr_enable(struct emu10k1x *emu, unsigned int intrenb)
31242957Sdillon{
31342957Sdillon	unsigned long flags;
31434202Sdyson	unsigned int intr_enable;
31534202Sdyson
31632585Sdyson	spin_lock_irqsave(&emu->emu_lock, flags);
31732585Sdyson	intr_enable = inl(emu->port + INTE) | intrenb;
31842957Sdillon	outl(intr_enable, emu->port + INTE);
31942957Sdillon	spin_unlock_irqrestore(&emu->emu_lock, flags);
32042957Sdillon}
32142957Sdillon
32234202Sdysonstatic void snd_emu10k1x_intr_disable(struct emu10k1x *emu, unsigned int intrenb)
32334202Sdyson{
32441322Sdg	unsigned long flags;
32598849Sken	unsigned int intr_enable;
32698849Sken
327111977Sken	spin_lock_irqsave(&emu->emu_lock, flags);
328111977Sken	intr_enable = inl(emu->port + INTE) & ~intrenb;
329111977Sken	outl(intr_enable, emu->port + INTE);
330111977Sken	spin_unlock_irqrestore(&emu->emu_lock, flags);
331111977Sken}
332111977Sken
333111977Skenstatic void snd_emu10k1x_gpio_write(struct emu10k1x *emu, unsigned int value)
33498849Sken{
335105466Salc	unsigned long flags;
33698849Sken
337111977Sken	spin_lock_irqsave(&emu->emu_lock, flags);
338111977Sken	outl(value, emu->port + GPIO);
33998849Sken	spin_unlock_irqrestore(&emu->emu_lock, flags);
34098849Sken}
34198849Sken
342105466Salcstatic void snd_emu10k1x_pcm_free_substream(struct snd_pcm_runtime *runtime)
343116552Salc{
34498849Sken	kfree(runtime->private_data);
34598849Sken}
34698849Sken
3471541Srgrimesstatic void snd_emu10k1x_pcm_interrupt(struct emu10k1x *emu, struct emu10k1x_voice *voice)
34842957Sdillon{
34942957Sdillon	struct emu10k1x_pcm *epcm;
35042957Sdillon
35142957Sdillon	epcm = voice->epcm;
35242957Sdillon	if (!epcm)
35358634Scharnier		return;
35442957Sdillon	if (epcm->substream == NULL)
35542957Sdillon		return;
35642957Sdillon#if 0
35742957Sdillon	dev_info(emu->card->dev,
35842957Sdillon		 "IRQ: position = 0x%x, period = 0x%x, size = 0x%x\n",
35942957Sdillon		   epcm->substream->ops->pointer(epcm->substream),
36042957Sdillon		   snd_pcm_lib_period_bytes(epcm->substream),
36142957Sdillon		   snd_pcm_lib_buffer_bytes(epcm->substream));
3621541Srgrimes#endif
36342957Sdillon	snd_pcm_period_elapsed(epcm->substream);
364100742Salc}
36534202Sdyson
366108068Salc/* open callback */
367108068Salcstatic int snd_emu10k1x_playback_open(struct snd_pcm_substream *substream)
368108068Salc{
36942957Sdillon	struct emu10k1x *chip = snd_pcm_substream_chip(substream);
370123879Salc	struct emu10k1x_pcm *epcm;
37134202Sdyson	struct snd_pcm_runtime *runtime = substream->runtime;
3721541Srgrimes	int err;
3731541Srgrimes
37492029Seivind	err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
3757695Sdg	if (err < 0)
37641322Sdg		return err;
37779263Sdillon	err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64);
37841322Sdg	if (err < 0)
37916268Sdyson                return err;
38051488Sdillon
38134202Sdyson	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
382100742Salc	if (epcm == NULL)
38334202Sdyson		return -ENOMEM;
38490935Ssilby	epcm->emu = chip;
3855455Sdg	epcm->substream = substream;
3865455Sdg
38743086Sdillon	runtime->private_data = epcm;
38842957Sdillon	runtime->private_free = snd_emu10k1x_pcm_free_substream;
38942957Sdillon
39042957Sdillon	runtime->hw = snd_emu10k1x_playback_hw;
39142957Sdillon
39242957Sdillon	return 0;
39342957Sdillon}
39438799Sdfr
395100742Salc/* close callback */
39634202Sdysonstatic int snd_emu10k1x_playback_close(struct snd_pcm_substream *substream)
39734202Sdyson{
3985455Sdg	return 0;
3995455Sdg}
40033936Sdyson
4011541Srgrimes/* hw_params callback */
4021541Srgrimesstatic int snd_emu10k1x_pcm_hw_params(struct snd_pcm_substream *substream,
40342957Sdillon				      struct snd_pcm_hw_params *hw_params)
40442957Sdillon{
40551488Sdillon	struct snd_pcm_runtime *runtime = substream->runtime;
40651488Sdillon	struct emu10k1x_pcm *epcm = runtime->private_data;
40742957Sdillon
40851488Sdillon	if (! epcm->voice) {
40934202Sdyson		epcm->voice = &epcm->emu->voices[substream->pcm->device];
41034202Sdyson		epcm->voice->use = 1;
4118585Sdg		epcm->voice->epcm = epcm;
4128585Sdg	}
41310988Sdyson
4141541Srgrimes	return 0;
4155455Sdg}
4161541Srgrimes
41751488Sdillon/* hw_free callback */
41851488Sdillonstatic int snd_emu10k1x_pcm_hw_free(struct snd_pcm_substream *substream)
41951488Sdillon{
42051488Sdillon	struct snd_pcm_runtime *runtime = substream->runtime;
42151488Sdillon	struct emu10k1x_pcm *epcm;
42234202Sdyson
42334202Sdyson	if (runtime->private_data == NULL)
42490935Ssilby		return 0;
4251541Srgrimes
4261541Srgrimes	epcm = runtime->private_data;
4271541Srgrimes
42832585Sdyson	if (epcm->voice) {
4295455Sdg		epcm->voice->use = 0;
43042957Sdillon		epcm->voice->epcm = NULL;
43151488Sdillon		epcm->voice = NULL;
43251488Sdillon	}
43351488Sdillon
43451488Sdillon	return 0;
43551488Sdillon}
43651488Sdillon
43751488Sdillon/* prepare callback */
43842957Sdillonstatic int snd_emu10k1x_pcm_prepare(struct snd_pcm_substream *substream)
43951488Sdillon{
4401541Srgrimes	struct emu10k1x *emu = snd_pcm_substream_chip(substream);
4411549Srgrimes	struct snd_pcm_runtime *runtime = substream->runtime;
44215819Sdyson	struct emu10k1x_pcm *epcm = runtime->private_data;
44349338Salc	int voice = epcm->voice->number;
4441541Srgrimes	u32 *table_base = (u32 *)(emu->dma_buffer->area+1024*voice);
44549338Salc	u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
44615819Sdyson	int i;
44715819Sdyson
44832702Sdyson	for(i = 0; i < runtime->periods; i++) {
44934202Sdyson		*table_base++=runtime->dma_addr+(i*period_size_bytes);
45032702Sdyson		*table_base++=period_size_bytes<<16;
45132702Sdyson	}
45232702Sdyson
45334202Sdyson	snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_ADDR, voice, emu->dma_buffer->addr+1024*voice);
45432702Sdyson	snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_SIZE, voice, (runtime->periods - 1) << 19);
45532702Sdyson	snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_PTR, voice, 0);
45615819Sdyson	snd_emu10k1x_ptr_write(emu, PLAYBACK_POINTER, voice, 0);
457119357Salc	snd_emu10k1x_ptr_write(emu, PLAYBACK_UNKNOWN1, voice, 0);
458119357Salc	snd_emu10k1x_ptr_write(emu, PLAYBACK_UNKNOWN2, voice, 0);
459119357Salc	snd_emu10k1x_ptr_write(emu, PLAYBACK_DMA_ADDR, voice, runtime->dma_addr);
460119357Salc
461119357Salc	snd_emu10k1x_ptr_write(emu, PLAYBACK_PERIOD_SIZE, voice, frames_to_bytes(runtime, runtime->period_size)<<16);
462119357Salc
463119357Salc	return 0;
464119357Salc}
46515819Sdyson
46651488Sdillon/* trigger callback */
46751488Sdillonstatic int snd_emu10k1x_pcm_trigger(struct snd_pcm_substream *substream,
46815819Sdyson				    int cmd)
46915819Sdyson{
47051488Sdillon	struct emu10k1x *emu = snd_pcm_substream_chip(substream);
47115819Sdyson	struct snd_pcm_runtime *runtime = substream->runtime;
472100413Salc	struct emu10k1x_pcm *epcm = runtime->private_data;
47346349Salc	int channel = epcm->voice->number;
47446349Salc	int result = 0;
47546349Salc
47646349Salc	/*
47746349Salc	dev_dbg(emu->card->dev,
47892029Seivind		"trigger - emu10k1x = 0x%x, cmd = %i, pointer = %d\n",
47924678Speter		(int)emu, cmd, (int)substream->ops->pointer(substream));
48015819Sdyson	*/
48115819Sdyson
48292029Seivind	switch (cmd) {
48392029Seivind	case SNDRV_PCM_TRIGGER_START:
48415819Sdyson		if(runtime->periods == 2)
48515819Sdyson			snd_emu10k1x_intr_enable(emu, (INTE_CH_0_LOOP | INTE_CH_0_HALF_LOOP) << channel);
48616058Sdyson		else
48761081Sdillon			snd_emu10k1x_intr_enable(emu, INTE_CH_0_LOOP << channel);
48816058Sdyson		epcm->running = 1;
48915819Sdyson		snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0)|(TRIGGER_CHANNEL_0<<channel));
49015819Sdyson		break;
491125838Salc	case SNDRV_PCM_TRIGGER_STOP:
49215819Sdyson		epcm->running = 0;
49315819Sdyson		snd_emu10k1x_intr_disable(emu, (INTE_CH_0_LOOP | INTE_CH_0_HALF_LOOP) << channel);
49415819Sdyson		snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0) & ~(TRIGGER_CHANNEL_0<<channel));
49515819Sdyson		break;
49615819Sdyson	default:
49715819Sdyson		result = -EINVAL;
498100413Salc		break;
49915819Sdyson	}
50015819Sdyson	return result;
50115819Sdyson}
502119357Salc
503119357Salc/* pointer callback */
5041541Srgrimesstatic snd_pcm_uframes_t
5055455Sdgsnd_emu10k1x_pcm_pointer(struct snd_pcm_substream *substream)
5065455Sdg{
5075455Sdg	struct emu10k1x *emu = snd_pcm_substream_chip(substream);
5085455Sdg	struct snd_pcm_runtime *runtime = substream->runtime;
5095455Sdg	struct emu10k1x_pcm *epcm = runtime->private_data;
5105455Sdg	int channel = epcm->voice->number;
5115455Sdg	snd_pcm_uframes_t ptr = 0, ptr1 = 0, ptr2= 0,ptr3 = 0,ptr4 = 0;
5125455Sdg
5135455Sdg	if (!epcm->running)
5145455Sdg		return 0;
51542957Sdillon
51642957Sdillon	ptr3 = snd_emu10k1x_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
51795701Salc	ptr1 = snd_emu10k1x_ptr_read(emu, PLAYBACK_POINTER, channel);
51895701Salc	ptr4 = snd_emu10k1x_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
51995701Salc
5201549Srgrimes	if(ptr4 == 0 && ptr1 == frames_to_bytes(runtime, runtime->buffer_size))
5213449Sphk		return 0;
52234202Sdyson
5231541Srgrimes	if (ptr3 != ptr4)
5241541Srgrimes		ptr1 = snd_emu10k1x_ptr_read(emu, PLAYBACK_POINTER, channel);
52551488Sdillon	ptr2 = bytes_to_frames(runtime, ptr1);
52651488Sdillon	ptr2 += (ptr4 >> 3) * runtime->period_size;
52795701Salc	ptr = ptr2;
52895701Salc
52995701Salc	if (ptr >= runtime->buffer_size)
53051488Sdillon		ptr -= runtime->buffer_size;
53151488Sdillon
53251488Sdillon	return ptr;
53351488Sdillon}
5345455Sdg
53542957Sdillon/* operators */
53642957Sdillonstatic const struct snd_pcm_ops snd_emu10k1x_playback_ops = {
5371541Srgrimes	.open =        snd_emu10k1x_playback_open,
53834202Sdyson	.close =       snd_emu10k1x_playback_close,
5391541Srgrimes	.hw_params =   snd_emu10k1x_pcm_hw_params,
5401549Srgrimes	.hw_free =     snd_emu10k1x_pcm_hw_free,
54134202Sdyson	.prepare =     snd_emu10k1x_pcm_prepare,
5429507Sdg	.trigger =     snd_emu10k1x_pcm_trigger,
54310988Sdyson	.pointer =     snd_emu10k1x_pcm_pointer,
5441541Srgrimes};
5451541Srgrimes
54617312Sdyson/* open_capture callback */
54717312Sdysonstatic int snd_emu10k1x_pcm_open_capture(struct snd_pcm_substream *substream)
54817312Sdyson{
54917312Sdyson	struct emu10k1x *chip = snd_pcm_substream_chip(substream);
55017312Sdyson	struct emu10k1x_pcm *epcm;
5515455Sdg	struct snd_pcm_runtime *runtime = substream->runtime;
5525455Sdg	int err;
5535455Sdg
5541541Srgrimes	err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
55534202Sdyson	if (err < 0)
55692029Seivind		return err;
55734202Sdyson	err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64);
55817312Sdyson	if (err < 0)
5597695Sdg		return err;
5608876Srgrimes
5611549Srgrimes	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
56242957Sdillon	if (epcm == NULL)
5631541Srgrimes		return -ENOMEM;
5641541Srgrimes
5655455Sdg	epcm->emu = chip;
5665455Sdg	epcm->substream = substream;
5675455Sdg
5688876Srgrimes	runtime->private_data = epcm;
5699507Sdg	runtime->private_free = snd_emu10k1x_pcm_free_substream;
5705455Sdg
5718876Srgrimes	runtime->hw = snd_emu10k1x_capture_hw;
5725455Sdg
5739507Sdg	return 0;
5745455Sdg}
5755455Sdg
5761541Srgrimes/* close callback */
5774207Sdgstatic int snd_emu10k1x_pcm_close_capture(struct snd_pcm_substream *substream)
57837843Sdg{
57937843Sdg	return 0;
5801549Srgrimes}
5814207Sdg
5821549Srgrimes/* hw_params callback */
5834207Sdgstatic int snd_emu10k1x_pcm_hw_params_capture(struct snd_pcm_substream *substream,
5845455Sdg					      struct snd_pcm_hw_params *hw_params)
5855455Sdg{
5865455Sdg	struct snd_pcm_runtime *runtime = substream->runtime;
5874207Sdg	struct emu10k1x_pcm *epcm = runtime->private_data;
58834202Sdyson
58932585Sdyson	if (! epcm->voice) {
590100456Salc		if (epcm->emu->capture_voice.use)
59134202Sdyson			return -EBUSY;
592100456Salc		epcm->voice = &epcm->emu->capture_voice;
59334202Sdyson		epcm->voice->epcm = epcm;
59434202Sdyson		epcm->voice->use = 1;
5954207Sdg	}
5961541Srgrimes
59734202Sdyson	return 0;
598100456Salc}
59934202Sdyson
600100456Salc/* hw_free callback */
60134202Sdysonstatic int snd_emu10k1x_pcm_hw_free_capture(struct snd_pcm_substream *substream)
6021549Srgrimes{
6031549Srgrimes	struct snd_pcm_runtime *runtime = substream->runtime;
6041549Srgrimes
6051549Srgrimes	struct emu10k1x_pcm *epcm;
6061541Srgrimes
6071541Srgrimes	if (runtime->private_data == NULL)
60851488Sdillon		return 0;
6091541Srgrimes	epcm = runtime->private_data;
61042957Sdillon
61142957Sdillon	if (epcm->voice) {
6121541Srgrimes		epcm->voice->use = 0;
61334202Sdyson		epcm->voice->epcm = NULL;
61434202Sdyson		epcm->voice = NULL;
6151541Srgrimes	}
6161541Srgrimes
6175455Sdg	return 0;
6185455Sdg}
6191541Srgrimes
62034202Sdyson/* prepare capture callback */
62134202Sdysonstatic int snd_emu10k1x_pcm_prepare_capture(struct snd_pcm_substream *substream)
6221541Srgrimes{
6231541Srgrimes	struct emu10k1x *emu = snd_pcm_substream_chip(substream);
6245455Sdg	struct snd_pcm_runtime *runtime = substream->runtime;
6255455Sdg
6261541Srgrimes	snd_emu10k1x_ptr_write(emu, CAPTURE_DMA_ADDR, 0, runtime->dma_addr);
62734202Sdyson	snd_emu10k1x_ptr_write(emu, CAPTURE_BUFFER_SIZE, 0, frames_to_bytes(runtime, runtime->buffer_size)<<16); // buffer size in bytes
62834202Sdyson	snd_emu10k1x_ptr_write(emu, CAPTURE_POINTER, 0, 0);
629113761Salc	snd_emu10k1x_ptr_write(emu, CAPTURE_UNKNOWN, 0, 0);
6301541Srgrimes
63134202Sdyson	return 0;
63234202Sdyson}
63334202Sdyson
634116695Salc/* trigger_capture callback */
6351541Srgrimesstatic int snd_emu10k1x_pcm_trigger_capture(struct snd_pcm_substream *substream,
63634202Sdyson					    int cmd)
6371541Srgrimes{
63846349Salc	struct emu10k1x *emu = snd_pcm_substream_chip(substream);
63946349Salc	struct snd_pcm_runtime *runtime = substream->runtime;
64046349Salc	struct emu10k1x_pcm *epcm = runtime->private_data;
64134202Sdyson	int result = 0;
642102382Salc
64346349Salc	switch (cmd) {
64446349Salc	case SNDRV_PCM_TRIGGER_START:
64544250Salc		snd_emu10k1x_intr_enable(emu, INTE_CAP_0_LOOP |
64617312Sdyson					 INTE_CAP_0_HALF_LOOP);
64746349Salc		snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0)|TRIGGER_CAPTURE);
64842957Sdillon		epcm->running = 1;
6495455Sdg		break;
650116667Salc	case SNDRV_PCM_TRIGGER_STOP:
651116667Salc		epcm->running = 0;
652116667Salc		snd_emu10k1x_intr_disable(emu, INTE_CAP_0_LOOP |
653116667Salc					  INTE_CAP_0_HALF_LOOP);
654116667Salc		snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0) & ~(TRIGGER_CAPTURE));
65534202Sdyson		break;
656116667Salc	default:
65734202Sdyson		result = -EINVAL;
6581541Srgrimes		break;
6591541Srgrimes	}
66042957Sdillon	return result;
66142408Seivind}
66242408Seivind
6631541Srgrimes/* pointer_capture callback */
6641541Srgrimesstatic snd_pcm_uframes_t
6655455Sdgsnd_emu10k1x_pcm_pointer_capture(struct snd_pcm_substream *substream)
6665455Sdg{
6671541Srgrimes	struct emu10k1x *emu = snd_pcm_substream_chip(substream);
6681541Srgrimes	struct snd_pcm_runtime *runtime = substream->runtime;
6691541Srgrimes	struct emu10k1x_pcm *epcm = runtime->private_data;
6705455Sdg	snd_pcm_uframes_t ptr;
6715455Sdg
6725455Sdg	if (!epcm->running)
6731541Srgrimes		return 0;
67434202Sdyson
6755455Sdg	ptr = bytes_to_frames(runtime, snd_emu10k1x_ptr_read(emu, CAPTURE_POINTER, 0));
6765455Sdg	if (ptr >= runtime->buffer_size)
6771541Srgrimes		ptr -= runtime->buffer_size;
6785455Sdg
6791541Srgrimes	return ptr;
68042957Sdillon}
68142957Sdillon
68242957Sdillonstatic const struct snd_pcm_ops snd_emu10k1x_capture_ops = {
68342957Sdillon	.open =        snd_emu10k1x_pcm_open_capture,
68442957Sdillon	.close =       snd_emu10k1x_pcm_close_capture,
68542957Sdillon	.hw_params =   snd_emu10k1x_pcm_hw_params_capture,
68642957Sdillon	.hw_free =     snd_emu10k1x_pcm_hw_free_capture,
68742957Sdillon	.prepare =     snd_emu10k1x_pcm_prepare_capture,
6881541Srgrimes	.trigger =     snd_emu10k1x_pcm_trigger_capture,
689116650Salc	.pointer =     snd_emu10k1x_pcm_pointer_capture,
690116596Salc};
69114316Sdyson
69214316Sdysonstatic unsigned short snd_emu10k1x_ac97_read(struct snd_ac97 *ac97,
69314316Sdyson					     unsigned short reg)
69434202Sdyson{
69514316Sdyson	struct emu10k1x *emu = ac97->private_data;
69614316Sdyson	unsigned long flags;
69714316Sdyson	unsigned short val;
69834202Sdyson
69914316Sdyson	spin_lock_irqsave(&emu->emu_lock, flags);
70058705Scharnier	outb(reg, emu->port + AC97ADDRESS);
70114316Sdyson	val = inw(emu->port + AC97DATA);
70234202Sdyson	spin_unlock_irqrestore(&emu->emu_lock, flags);
70314316Sdyson	return val;
70414316Sdyson}
70514316Sdyson
70634202Sdysonstatic void snd_emu10k1x_ac97_write(struct snd_ac97 *ac97,
70734202Sdyson				    unsigned short reg, unsigned short val)
708116650Salc{
70914316Sdyson	struct emu10k1x *emu = ac97->private_data;
71014316Sdyson	unsigned long flags;
71114316Sdyson
712116596Salc	spin_lock_irqsave(&emu->emu_lock, flags);
713116658Salc	outb(reg, emu->port + AC97ADDRESS);
71414316Sdyson	outw(val, emu->port + AC97DATA);
71514316Sdyson	spin_unlock_irqrestore(&emu->emu_lock, flags);
71614316Sdyson}
717106981Salc
71834202Sdysonstatic int snd_emu10k1x_ac97(struct emu10k1x *chip)
71914316Sdyson{
72042957Sdillon	struct snd_ac97_bus *pbus;
72142957Sdillon	struct snd_ac97_template ac97;
72242957Sdillon	int err;
72314316Sdyson	static const struct snd_ac97_bus_ops ops = {
72434202Sdyson		.write = snd_emu10k1x_ac97_write,
725116658Salc		.read = snd_emu10k1x_ac97_read,
726116658Salc	};
72734202Sdyson
72834202Sdyson	err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus);
72934202Sdyson	if (err < 0)
73014316Sdyson		return err;
73114316Sdyson	pbus->no_vra = 1; /* we don't need VRA */
73214316Sdyson
73314316Sdyson	memset(&ac97, 0, sizeof(ac97));
734120903Salc	ac97.private_data = chip;
735120903Salc	ac97.scaps = AC97_SCAP_NO_SPDIF;
73614316Sdyson	return snd_ac97_mixer(pbus, &ac97, &chip->ac97);
73734202Sdyson}
73834202Sdyson
73934202Sdysonstatic void snd_emu10k1x_free(struct snd_card *card)
74034202Sdyson{
74134202Sdyson	struct emu10k1x *chip = card->private_data;
74214316Sdyson
74342957Sdillon	snd_emu10k1x_ptr_write(chip, TRIGGER_CHANNEL, 0, 0);
74442957Sdillon	// disable interrupts
74542957Sdillon	outl(0, chip->port + INTE);
74642957Sdillon	// disable audio
74734202Sdyson	outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG);
748113761Salc}
7491541Srgrimes
7505455Sdgstatic irqreturn_t snd_emu10k1x_interrupt(int irq, void *dev_id)
7511541Srgrimes{
75234202Sdyson	unsigned int status;
75334202Sdyson
754116658Salc	struct emu10k1x *chip = dev_id;
755116695Salc	struct emu10k1x_voice *pvoice = chip->voices;
756116695Salc	int i;
757116658Salc	int mask;
7585455Sdg
7595455Sdg	status = inl(chip->port + IPR);
7601541Srgrimes
7611541Srgrimes	if (! status)
7621541Srgrimes		return IRQ_NONE;
7631541Srgrimes
7645455Sdg	// capture interrupt
7655455Sdg	if (status & (IPR_CAP_0_LOOP | IPR_CAP_0_HALF_LOOP)) {
7661541Srgrimes		struct emu10k1x_voice *cap_voice = &chip->capture_voice;
76792588Sgreen		if (cap_voice->use)
76834202Sdyson			snd_emu10k1x_pcm_interrupt(chip, cap_voice);
7695455Sdg		else
77012767Sdyson			snd_emu10k1x_intr_disable(chip,
7715455Sdg						  INTE_CAP_0_LOOP |
7721541Srgrimes						  INTE_CAP_0_HALF_LOOP);
7731541Srgrimes	}
7745455Sdg
7755455Sdg	mask = IPR_CH_0_LOOP|IPR_CH_0_HALF_LOOP;
7761541Srgrimes	for (i = 0; i < 3; i++) {
7771541Srgrimes		if (status & mask) {
7781541Srgrimes			if (pvoice->use)
77944098Sdillon				snd_emu10k1x_pcm_interrupt(chip, pvoice);
78044098Sdillon			else
78144098Sdillon				snd_emu10k1x_intr_disable(chip, mask);
78244098Sdillon		}
78344098Sdillon		pvoice++;
78444098Sdillon		mask <<= 1;
78544098Sdillon	}
78644098Sdillon
78774237Sdillon	if (status & (IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY)) {
78874237Sdillon		if (chip->midi.interrupt)
78974237Sdillon			chip->midi.interrupt(chip, status);
79074237Sdillon		else
79174237Sdillon			snd_emu10k1x_intr_disable(chip, INTE_MIDITXENABLE|INTE_MIDIRXENABLE);
79274237Sdillon	}
793116695Salc
79444098Sdillon	// acknowledge the interrupt if necessary
79544098Sdillon	outl(status, chip->port + IPR);
7969507Sdg
797122383Smini	/* dev_dbg(chip->card->dev, "interrupt %08x\n", status); */
7985455Sdg	return IRQ_HANDLED;
7995455Sdg}
8005455Sdg
8015455Sdgstatic const struct snd_pcm_chmap_elem surround_map[] = {
8021541Srgrimes	{ .channels = 2,
80334202Sdyson	  .map = { SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
80434202Sdyson	{ }
80534202Sdyson};
8061541Srgrimes
807116695Salcstatic const struct snd_pcm_chmap_elem clfe_map[] = {
8081541Srgrimes	{ .channels = 2,
8095455Sdg	  .map = { SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE } },
8105455Sdg	{ }
8115455Sdg};
8121541Srgrimes
8131541Srgrimesstatic int snd_emu10k1x_pcm(struct emu10k1x *emu, int device)
81434202Sdyson{
81534202Sdyson	struct snd_pcm *pcm;
8165455Sdg	const struct snd_pcm_chmap_elem *map = NULL;
8171541Srgrimes	int err;
81892588Sgreen	int capture = 0;
8191541Srgrimes
82034202Sdyson	if (device == 0)
82134202Sdyson		capture = 1;
82234202Sdyson
82334202Sdyson	err = snd_pcm_new(emu->card, "emu10k1x", device, 1, capture, &pcm);
8241541Srgrimes	if (err < 0)
8251541Srgrimes		return err;
8261541Srgrimes
8275455Sdg	pcm->private_data = emu;
8285455Sdg
8295455Sdg	switch(device) {
8305455Sdg	case 0:
8315455Sdg		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1x_playback_ops);
8325455Sdg		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1x_capture_ops);
8331541Srgrimes		break;
8341541Srgrimes	case 1:
8351541Srgrimes	case 2:
8361541Srgrimes		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1x_playback_ops);
8371541Srgrimes		break;
8385455Sdg	}
8395455Sdg
8405455Sdg	pcm->info_flags = 0;
8415455Sdg	switch(device) {
8421541Srgrimes	case 0:
8431541Srgrimes		strcpy(pcm->name, "EMU10K1X Front");
8447411Sdg		map = snd_pcm_std_chmaps;
845108068Salc		break;
84638799Sdfr	case 1:
84785517Sdillon		strcpy(pcm->name, "EMU10K1X Rear");
84854467Sdillon		map = surround_map;
8497411Sdg		break;
8507411Sdg	case 2:
85154467Sdillon		strcpy(pcm->name, "EMU10K1X Center/LFE");
85254467Sdillon		map = clfe_map;
85342957Sdillon		break;
85454467Sdillon	}
85554467Sdillon	emu->pcm = pcm;
85654467Sdillon
85754467Sdillon	snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
85854467Sdillon				       &emu->pci->dev, 32*1024, 32*1024);
85954467Sdillon
86054467Sdillon	return snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, map, 2,
86142957Sdillon				     1 << 2, NULL);
86242957Sdillon}
8637411Sdg
86473212Sdillonstatic int snd_emu10k1x_create(struct snd_card *card,
86573212Sdillon			       struct pci_dev *pci)
86673212Sdillon{
86773212Sdillon	struct emu10k1x *chip = card->private_data;
86873212Sdillon	int err;
86973212Sdillon	int ch;
870108068Salc
87124666Sdyson	err = pcim_enable_device(pci);
87268884Sdillon	if (err < 0)
87343138Sdillon		return err;
87468884Sdillon
87542957Sdillon	if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(28)) < 0) {
87668884Sdillon		dev_err(card->dev, "error to set 28bit mask DMA\n");
8777411Sdg		return -ENXIO;
8787411Sdg	}
8797695Sdg
88043119Sdillon	chip->card = card;
88143119Sdillon	chip->pci = pci;
88243119Sdillon	chip->irq = -1;
88348922Salc
88448922Salc	spin_lock_init(&chip->emu_lock);
88546349Salc	spin_lock_init(&chip->voice_lock);
88646349Salc
88746349Salc	err = pci_request_regions(pci, "EMU10K1X");
88846349Salc	if (err < 0)
88946349Salc		return err;
89046349Salc	chip->port = pci_resource_start(pci, 0);
89146349Salc
89246349Salc	if (devm_request_irq(&pci->dev, pci->irq, snd_emu10k1x_interrupt,
893120764Salc			     IRQF_SHARED, KBUILD_MODNAME, chip)) {
894120764Salc		dev_err(card->dev, "cannot grab irq %d\n", pci->irq);
89560755Speter		return -EBUSY;
89632702Sdyson	}
897120722Salc	chip->irq = pci->irq;
89832702Sdyson	card->sync_irq = chip->irq;
899123879Salc	card->private_free = snd_emu10k1x_free;
90099920Salc
90146349Salc	chip->dma_buffer = snd_devm_alloc_pages(&pci->dev, SNDRV_DMA_TYPE_DEV,
902101634Salc						4 * 1024);
90316058Sdyson	if (!chip->dma_buffer)
9041541Srgrimes		return -ENOMEM;
9055455Sdg
9065455Sdg	pci_set_master(pci);
9071541Srgrimes	/* read revision & serial */
90824666Sdyson	chip->revision = pci->revision;
9091541Srgrimes	pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
91034202Sdyson	pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
9111541Srgrimes	dev_info(card->dev, "Model %04x Rev %08x Serial %08x\n", chip->model,
91240700Sdg		   chip->revision, chip->serial);
9135455Sdg
91434202Sdyson	outl(0, chip->port + INTE);
9151549Srgrimes
916101654Salc	for(ch = 0; ch < 3; ch++) {
91799920Salc		chip->voices[ch].emu = chip;
918113868Sjhb		chip->voices[ch].number = ch;
919113868Sjhb	}
920113868Sjhb
9211549Srgrimes	/*
9221549Srgrimes	 *  Init to 0x02109204 :
9231549Srgrimes	 *  Clock accuracy    = 0     (1000ppm)
9241549Srgrimes	 *  Sample Rate       = 2     (48kHz)
9251549Srgrimes	 *  Audio Channel     = 1     (Left of 2)
9261549Srgrimes	 *  Source Number     = 0     (Unspecified)
927113868Sjhb	 *  Generation Status = 1     (Original for Cat Code 12)
9281541Srgrimes	 *  Cat Code          = 12    (Digital Signal Mixer)
9291541Srgrimes	 *  Mode              = 0     (Mode 0)
9305455Sdg	 *  Emphasis          = 0     (None)
9311541Srgrimes	 *  CP                = 1     (Copyright unasserted)
93234202Sdyson	 *  AN                = 0     (Audio data)
9335455Sdg	 *  P                 = 0     (Consumer)
9341541Srgrimes	 */
9351541Srgrimes	snd_emu10k1x_ptr_write(chip, SPCS0, 0,
9361541Srgrimes			       chip->spdif_bits[0] =
937120722Salc			       SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
938120722Salc			       SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
939120722Salc			       SPCS_GENERATIONSTATUS | 0x00001200 |
940120722Salc			       0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
941120722Salc	snd_emu10k1x_ptr_write(chip, SPCS1, 0,
942120722Salc			       chip->spdif_bits[1] =
943120722Salc			       SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
944120722Salc			       SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
945120722Salc			       SPCS_GENERATIONSTATUS | 0x00001200 |
946120722Salc			       0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
947120722Salc	snd_emu10k1x_ptr_write(chip, SPCS2, 0,
948120722Salc			       chip->spdif_bits[2] =
949120722Salc			       SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
950120722Salc			       SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
951120722Salc			       SPCS_GENERATIONSTATUS | 0x00001200 |
952120722Salc			       0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
953120722Salc
954120722Salc	snd_emu10k1x_ptr_write(chip, SPDIF_SELECT, 0, 0x700); // disable SPDIF
955120722Salc	snd_emu10k1x_ptr_write(chip, ROUTING, 0, 0x1003F); // routing
956120722Salc	snd_emu10k1x_gpio_write(chip, 0x1080); // analog mode
957120722Salc
958120722Salc	outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG);
959120722Salc
960120722Salc	return 0;
961120722Salc}
962120722Salc
963120722Salcstatic void snd_emu10k1x_proc_reg_read(struct snd_info_entry *entry,
964120722Salc				       struct snd_info_buffer *buffer)
965120722Salc{
966120722Salc	struct emu10k1x *emu = entry->private_data;
967120722Salc	unsigned long value,value1,value2;
968120722Salc	unsigned long flags;
969120722Salc	int i;
970120722Salc
971120722Salc	snd_iprintf(buffer, "Registers:\n\n");
972120722Salc	for(i = 0; i < 0x20; i+=4) {
973120722Salc		spin_lock_irqsave(&emu->emu_lock, flags);
974120722Salc		value = inl(emu->port + i);
975120722Salc		spin_unlock_irqrestore(&emu->emu_lock, flags);
976120722Salc		snd_iprintf(buffer, "Register %02X: %08lX\n", i, value);
977120722Salc	}
978120722Salc	snd_iprintf(buffer, "\nRegisters\n\n");
979120722Salc	for(i = 0; i <= 0x48; i++) {
980120722Salc		value = snd_emu10k1x_ptr_read(emu, i, 0);
981120722Salc		if(i < 0x10 || (i >= 0x20 && i < 0x40)) {
982120722Salc			value1 = snd_emu10k1x_ptr_read(emu, i, 1);
983120722Salc			value2 = snd_emu10k1x_ptr_read(emu, i, 2);
984120722Salc			snd_iprintf(buffer, "%02X: %08lX %08lX %08lX\n", i, value, value1, value2);
985120722Salc		} else {
986120722Salc			snd_iprintf(buffer, "%02X: %08lX\n", i, value);
987120722Salc		}
988120722Salc	}
989120722Salc}
990120722Salc
991120722Salcstatic void snd_emu10k1x_proc_reg_write(struct snd_info_entry *entry,
992120722Salc					struct snd_info_buffer *buffer)
993120764Salc{
994120764Salc	struct emu10k1x *emu = entry->private_data;
995120722Salc	char line[64];
996120764Salc	unsigned int reg, channel_id , val;
997120722Salc
998120722Salc	while (!snd_info_get_line(buffer, line, sizeof(line))) {
999120722Salc		if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
1000120722Salc			continue;
1001120722Salc
1002120722Salc		if (reg < 0x49 && channel_id <= 2)
1003120722Salc			snd_emu10k1x_ptr_write(emu, reg, channel_id, val);
1004120722Salc	}
1005120722Salc}
1006120722Salc
1007120764Salcstatic int snd_emu10k1x_proc_init(struct emu10k1x *emu)
1008120722Salc{
1009120764Salc	snd_card_rw_proc_new(emu->card, "emu10k1x_regs", emu,
1010120722Salc			     snd_emu10k1x_proc_reg_read,
1011120722Salc			     snd_emu10k1x_proc_reg_write);
1012120722Salc	return 0;
1013120722Salc}
1014120764Salc
1015120722Salc#define snd_emu10k1x_shared_spdif_info	snd_ctl_boolean_mono_info
1016120722Salc
1017120722Salcstatic int snd_emu10k1x_shared_spdif_get(struct snd_kcontrol *kcontrol,
1018120722Salc					 struct snd_ctl_elem_value *ucontrol)
1019109342Sdillon{
1020109342Sdillon	struct emu10k1x *emu = snd_kcontrol_chip(kcontrol);
1021109342Sdillon
1022109342Sdillon	ucontrol->value.integer.value[0] = (snd_emu10k1x_ptr_read(emu, SPDIF_SELECT, 0) == 0x700) ? 0 : 1;
1023109342Sdillon
1024109342Sdillon	return 0;
1025109342Sdillon}
1026109342Sdillon
1027109342Sdillonstatic int snd_emu10k1x_shared_spdif_put(struct snd_kcontrol *kcontrol,
1028109342Sdillon					 struct snd_ctl_elem_value *ucontrol)
1029109342Sdillon{
1030109342Sdillon	struct emu10k1x *emu = snd_kcontrol_chip(kcontrol);
1031109342Sdillon	unsigned int val;
1032109342Sdillon
1033109342Sdillon	val = ucontrol->value.integer.value[0] ;
1034109342Sdillon
1035109342Sdillon	if (val) {
1036109342Sdillon		// enable spdif output
10371541Srgrimes		snd_emu10k1x_ptr_write(emu, SPDIF_SELECT, 0, 0x000);
10381541Srgrimes		snd_emu10k1x_ptr_write(emu, ROUTING, 0, 0x700);
10391541Srgrimes		snd_emu10k1x_gpio_write(emu, 0x1000);
10401541Srgrimes	} else {
10411541Srgrimes		// disable spdif output
1042100630Salc		snd_emu10k1x_ptr_write(emu, SPDIF_SELECT, 0, 0x700);
10435455Sdg		snd_emu10k1x_ptr_write(emu, ROUTING, 0, 0x1003F);
10445455Sdg		snd_emu10k1x_gpio_write(emu, 0x1080);
1045100630Salc	}
10461541Srgrimes	return 0;
104779242Sdillon}
10481549Srgrimes
10491541Srgrimesstatic const struct snd_kcontrol_new snd_emu10k1x_shared_spdif =
10501541Srgrimes{
10515455Sdg	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
1052100630Salc	.name =		"Analog/Digital Output Jack",
1053100630Salc	.info =		snd_emu10k1x_shared_spdif_info,
10541541Srgrimes	.get =		snd_emu10k1x_shared_spdif_get,
10551541Srgrimes	.put =		snd_emu10k1x_shared_spdif_put
1056100630Salc};
1057100630Salc
1058100630Salcstatic int snd_emu10k1x_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
10591541Srgrimes{
10601541Srgrimes	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
10611541Srgrimes	uinfo->count = 1;
10625455Sdg	return 0;
10631541Srgrimes}
10641541Srgrimes
10655455Sdgstatic int snd_emu10k1x_spdif_get(struct snd_kcontrol *kcontrol,
10661541Srgrimes				  struct snd_ctl_elem_value *ucontrol)
10671541Srgrimes{
106820449Sdyson	struct emu10k1x *emu = snd_kcontrol_chip(kcontrol);
10691541Srgrimes	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
10701541Srgrimes
10711541Srgrimes	ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff;
10721541Srgrimes	ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff;
10731549Srgrimes	ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff;
10741549Srgrimes	ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff;
10755455Sdg	return 0;
10765455Sdg}
10771541Srgrimes
1078112569Sjakestatic int snd_emu10k1x_spdif_get_mask(struct snd_kcontrol *kcontrol,
1079112569Sjake				       struct snd_ctl_elem_value *ucontrol)
108079242Sdillon{
10811541Srgrimes	ucontrol->value.iec958.status[0] = 0xff;
10821541Srgrimes	ucontrol->value.iec958.status[1] = 0xff;
10831541Srgrimes	ucontrol->value.iec958.status[2] = 0xff;
1084126793Salc	ucontrol->value.iec958.status[3] = 0xff;
1085126793Salc	return 0;
10861541Srgrimes}
10875455Sdg
10885455Sdgstatic int snd_emu10k1x_spdif_put(struct snd_kcontrol *kcontrol,
10891541Srgrimes				  struct snd_ctl_elem_value *ucontrol)
10901541Srgrimes{
10911541Srgrimes	struct emu10k1x *emu = snd_kcontrol_chip(kcontrol);
1092112569Sjake	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
109315809Sdyson	int change;
109499920Salc	unsigned int val;
109540700Sdg
109699920Salc	val = (ucontrol->value.iec958.status[0] << 0) |
10971541Srgrimes		(ucontrol->value.iec958.status[1] << 8) |
10981541Srgrimes		(ucontrol->value.iec958.status[2] << 16) |
1099126793Salc		(ucontrol->value.iec958.status[3] << 24);
1100126793Salc	change = val != emu->spdif_bits[idx];
11011541Srgrimes	if (change) {
11021541Srgrimes		snd_emu10k1x_ptr_write(emu, SPCS0 + idx, 0, val);
11031541Srgrimes		emu->spdif_bits[idx] = val;
11041541Srgrimes	}
11051541Srgrimes	return change;
11061541Srgrimes}
11071541Srgrimes
11081541Srgrimesstatic const struct snd_kcontrol_new snd_emu10k1x_spdif_mask_control =
11091541Srgrimes{
11101541Srgrimes	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
11111541Srgrimes	.iface =        SNDRV_CTL_ELEM_IFACE_PCM,
11121541Srgrimes	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
11131541Srgrimes	.count =	3,
11141549Srgrimes	.info =         snd_emu10k1x_spdif_info,
11151549Srgrimes	.get =          snd_emu10k1x_spdif_get_mask
11165455Sdg};
11175455Sdg
11185455Sdgstatic const struct snd_kcontrol_new snd_emu10k1x_spdif_control =
11195455Sdg{
11201541Srgrimes	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
1121121108Salc	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
11225455Sdg	.count =	3,
112312767Sdyson	.info =         snd_emu10k1x_spdif_info,
112412767Sdyson	.get =          snd_emu10k1x_spdif_get,
1125121108Salc	.put =          snd_emu10k1x_spdif_put
11265455Sdg};
11275455Sdg
11285455Sdgstatic int snd_emu10k1x_mixer(struct emu10k1x *emu)
11295455Sdg{
11301541Srgrimes	int err;
11311541Srgrimes	struct snd_kcontrol *kctl;
11321541Srgrimes	struct snd_card *card = emu->card;
11335455Sdg
11341541Srgrimes	kctl = snd_ctl_new1(&snd_emu10k1x_spdif_mask_control, emu);
11351541Srgrimes	if (!kctl)
11361541Srgrimes		return -ENOMEM;
11371541Srgrimes	err = snd_ctl_add(card, kctl);
11381541Srgrimes	if (err)
11395455Sdg		return err;
11405455Sdg	kctl = snd_ctl_new1(&snd_emu10k1x_shared_spdif, emu);
11411541Srgrimes	if (!kctl)
11429507Sdg		return -ENOMEM;
114312767Sdyson	err = snd_ctl_add(card, kctl);
11441541Srgrimes	if (err)
1145120905Salc		return err;
11461541Srgrimes	kctl = snd_ctl_new1(&snd_emu10k1x_spdif_control, emu);
11471541Srgrimes	if (!kctl)
11481541Srgrimes		return -ENOMEM;
11495455Sdg	err = snd_ctl_add(card, kctl);
11501541Srgrimes	if (err)
11511541Srgrimes		return err;
11525455Sdg
11535455Sdg	return 0;
11545455Sdg}
11551541Srgrimes
11561541Srgrimes#define EMU10K1X_MIDI_MODE_INPUT	(1<<0)
11575455Sdg#define EMU10K1X_MIDI_MODE_OUTPUT	(1<<1)
11585455Sdg
11591541Srgrimesstatic inline unsigned char mpu401_read(struct emu10k1x *emu, struct emu10k1x_midi *mpu, int idx)
11601541Srgrimes{
11615455Sdg	return (unsigned char)snd_emu10k1x_ptr_read(emu, mpu->port + idx, 0);
11621541Srgrimes}
11631541Srgrimes
116412767Sdysonstatic inline void mpu401_write(struct emu10k1x *emu, struct emu10k1x_midi *mpu, int data, int idx)
116512767Sdyson{
11661541Srgrimes	snd_emu10k1x_ptr_write(emu, mpu->port + idx, 0, data);
1167120905Salc}
11681541Srgrimes
1169120905Salc#define mpu401_write_data(emu, mpu, data)	mpu401_write(emu, mpu, data, 0)
11701541Srgrimes#define mpu401_write_cmd(emu, mpu, data)	mpu401_write(emu, mpu, data, 1)
11711541Srgrimes#define mpu401_read_data(emu, mpu)		mpu401_read(emu, mpu, 0)
11721541Srgrimes#define mpu401_read_stat(emu, mpu)		mpu401_read(emu, mpu, 1)
11731541Srgrimes
11745455Sdg#define mpu401_input_avail(emu,mpu)	(!(mpu401_read_stat(emu,mpu) & 0x80))
11755455Sdg#define mpu401_output_ready(emu,mpu)	(!(mpu401_read_stat(emu,mpu) & 0x40))
11765455Sdg
11771541Srgrimes#define MPU401_RESET		0xff
1178116695Salc#define MPU401_ENTER_UART	0x3f
1179121108Salc#define MPU401_ACK		0xfe
1180121108Salc
1181121108Salcstatic void mpu401_clear_rx(struct emu10k1x *emu, struct emu10k1x_midi *mpu)
1182121108Salc{
1183121108Salc	int timeout = 100000;
1184121108Salc	for (; timeout > 0 && mpu401_input_avail(emu, mpu); timeout--)
1185121108Salc		mpu401_read_data(emu, mpu);
1186121108Salc#ifdef CONFIG_SND_DEBUG
1187121108Salc	if (timeout <= 0)
1188121108Salc		dev_err(emu->card->dev,
1189121108Salc			"cmd: clear rx timeout (status = 0x%x)\n",
1190121108Salc			mpu401_read_stat(emu, mpu));
1191121108Salc#endif
1192121108Salc}
11931541Srgrimes
11941541Srgrimes/*
1195120903Salc
1196121108Salc */
1197120903Salc
1198120905Salcstatic void do_emu10k1x_midi_interrupt(struct emu10k1x *emu,
11991541Srgrimes				       struct emu10k1x_midi *midi, unsigned int status)
12001541Srgrimes{
12015455Sdg	unsigned char byte;
12021541Srgrimes
120360755Speter	if (midi->rmidi == NULL) {
1204120905Salc		snd_emu10k1x_intr_disable(emu, midi->tx_enable | midi->rx_enable);
1205100742Salc		return;
1206121108Salc	}
1207121108Salc
12081541Srgrimes	spin_lock(&midi->input_lock);
12091541Srgrimes	if ((status & midi->ipr_rx) && mpu401_input_avail(emu, midi)) {
12105455Sdg		if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
12111541Srgrimes			mpu401_clear_rx(emu, midi);
12121541Srgrimes		} else {
121338799Sdfr			byte = mpu401_read_data(emu, midi);
1214100742Salc			if (midi->substream_input)
12151541Srgrimes				snd_rawmidi_receive(midi->substream_input, &byte, 1);
1216120905Salc		}
12171549Srgrimes	}
12181541Srgrimes	spin_unlock(&midi->input_lock);
12191549Srgrimes
12201549Srgrimes	spin_lock(&midi->output_lock);
12211549Srgrimes	if ((status & midi->ipr_tx) && mpu401_output_ready(emu, midi)) {
122210988Sdyson		if (midi->substream_output &&
122310988Sdyson		    snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
12241549Srgrimes			mpu401_write_data(emu, midi, byte);
12251549Srgrimes		} else {
122610988Sdyson			snd_emu10k1x_intr_disable(emu, midi->tx_enable);
12271549Srgrimes		}
12281549Srgrimes	}
12291549Srgrimes	spin_unlock(&midi->output_lock);
12301549Srgrimes}
12311549Srgrimes
12321549Srgrimesstatic void snd_emu10k1x_midi_interrupt(struct emu10k1x *emu, unsigned int status)
123376827Salfred{
123476827Salfred	do_emu10k1x_midi_interrupt(emu, &emu->midi, status);
12351549Srgrimes}
123633181Seivind
123710988Sdysonstatic int snd_emu10k1x_midi_cmd(struct emu10k1x * emu,
12381549Srgrimes				  struct emu10k1x_midi *midi, unsigned char cmd, int ack)
12391549Srgrimes{
124010988Sdyson	unsigned long flags;
12411549Srgrimes	int timeout, ok;
12421549Srgrimes
12431549Srgrimes	spin_lock_irqsave(&midi->input_lock, flags);
124432702Sdyson	mpu401_write_data(emu, midi, 0x00);
12451549Srgrimes	/* mpu401_clear_rx(emu, midi); */
124612767Sdyson
12471549Srgrimes	mpu401_write_cmd(emu, midi, cmd);
124810556Sdyson	if (ack) {
12491549Srgrimes		ok = 0;
1250116695Salc		timeout = 10000;
125176827Salfred		while (!ok && timeout-- > 0) {
12521549Srgrimes			if (mpu401_input_avail(emu, midi)) {
125312767Sdyson				if (mpu401_read_data(emu, midi) == MPU401_ACK)
12541549Srgrimes					ok = 1;
12551549Srgrimes			}
125616026Sdyson		}
125716026Sdyson		if (!ok && mpu401_read_data(emu, midi) == MPU401_ACK)
125816026Sdyson			ok = 1;
125916026Sdyson	} else {
126016026Sdyson		ok = 1;
126116026Sdyson	}
126216026Sdyson	spin_unlock_irqrestore(&midi->input_lock, flags);
126316026Sdyson	if (!ok) {
126416026Sdyson		dev_err(emu->card->dev,
12651549Srgrimes			"midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n",
12661549Srgrimes			   cmd, emu->port,
126742957Sdillon			   mpu401_read_stat(emu, midi),
12681549Srgrimes			   mpu401_read_data(emu, midi));
126932702Sdyson		return 1;
12701549Srgrimes	}
127110988Sdyson	return 0;
127210988Sdyson}
127310988Sdyson
127410988Sdysonstatic int snd_emu10k1x_midi_input_open(struct snd_rawmidi_substream *substream)
127510556Sdyson{
127610556Sdyson	struct emu10k1x *emu;
127710988Sdyson	struct emu10k1x_midi *midi = substream->rmidi->private_data;
127810988Sdyson	unsigned long flags;
127910988Sdyson
128010988Sdyson	emu = midi->emu;
128110988Sdyson	if (snd_BUG_ON(!emu))
128210988Sdyson		return -ENXIO;
128310988Sdyson	spin_lock_irqsave(&midi->open_lock, flags);
128410988Sdyson	midi->midi_mode |= EMU10K1X_MIDI_MODE_INPUT;
12851549Srgrimes	midi->substream_input = substream;
12861549Srgrimes	if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)) {
12871549Srgrimes		spin_unlock_irqrestore(&midi->open_lock, flags);
128810668Sdyson		if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1))
128910988Sdyson			goto error_out;
129010988Sdyson		if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
129132702Sdyson			goto error_out;
12921549Srgrimes	} else {
12931549Srgrimes		spin_unlock_irqrestore(&midi->open_lock, flags);
12941549Srgrimes	}
129510988Sdyson	return 0;
12961549Srgrimes
129732702Sdysonerror_out:
12981549Srgrimes	return -EIO;
129932702Sdyson}
130032702Sdyson
130112767Sdysonstatic int snd_emu10k1x_midi_output_open(struct snd_rawmidi_substream *substream)
130232702Sdyson{
130332702Sdyson	struct emu10k1x *emu;
130432702Sdyson	struct emu10k1x_midi *midi = substream->rmidi->private_data;
130532702Sdyson	unsigned long flags;
130632702Sdyson
130792029Seivind	emu = midi->emu;
130892029Seivind	if (snd_BUG_ON(!emu))
130912767Sdyson		return -ENXIO;
13104446Sdg	spin_lock_irqsave(&midi->open_lock, flags);
13114446Sdg	midi->midi_mode |= EMU10K1X_MIDI_MODE_OUTPUT;
131212767Sdyson	midi->substream_output = substream;
13134446Sdg	if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
13141549Srgrimes		spin_unlock_irqrestore(&midi->open_lock, flags);
131532702Sdyson		if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1))
131692029Seivind			goto error_out;
131732702Sdyson		if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
131832702Sdyson			goto error_out;
131932702Sdyson	} else {
1320100456Salc		spin_unlock_irqrestore(&midi->open_lock, flags);
132132702Sdyson	}
132234202Sdyson	return 0;
132332702Sdyson
1324100456Salcerror_out:
132532702Sdyson	return -EIO;
132632702Sdyson}
132732702Sdyson
132832702Sdysonstatic int snd_emu10k1x_midi_input_close(struct snd_rawmidi_substream *substream)
132932702Sdyson{
133032702Sdyson	struct emu10k1x *emu;
133132702Sdyson	struct emu10k1x_midi *midi = substream->rmidi->private_data;
13324446Sdg	unsigned long flags;
133332702Sdyson	int err = 0;
133432702Sdyson
13351549Srgrimes	emu = midi->emu;
13361549Srgrimes	if (snd_BUG_ON(!emu))
133732702Sdyson		return -ENXIO;
133832702Sdyson	spin_lock_irqsave(&midi->open_lock, flags);
133932702Sdyson	snd_emu10k1x_intr_disable(emu, midi->rx_enable);
134032702Sdyson	midi->midi_mode &= ~EMU10K1X_MIDI_MODE_INPUT;
134132702Sdyson	midi->substream_input = NULL;
134232702Sdyson	if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)) {
134332702Sdyson		spin_unlock_irqrestore(&midi->open_lock, flags);
13441549Srgrimes		err = snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 0);
134532702Sdyson	} else {
13461549Srgrimes		spin_unlock_irqrestore(&midi->open_lock, flags);
134732702Sdyson	}
134812767Sdyson	return err;
134912767Sdyson}
13501549Srgrimes
135192029Seivindstatic int snd_emu10k1x_midi_output_close(struct snd_rawmidi_substream *substream)
13521549Srgrimes{
135332702Sdyson	struct emu10k1x *emu;
135432702Sdyson	struct emu10k1x_midi *midi = substream->rmidi->private_data;
135532702Sdyson	unsigned long flags;
13565455Sdg	int err = 0;
135732702Sdyson
135832702Sdyson	emu = midi->emu;
135932702Sdyson	if (snd_BUG_ON(!emu))
13601549Srgrimes		return -ENXIO;
13611549Srgrimes	spin_lock_irqsave(&midi->open_lock, flags);
136232702Sdyson	snd_emu10k1x_intr_disable(emu, midi->tx_enable);
13631549Srgrimes	midi->midi_mode &= ~EMU10K1X_MIDI_MODE_OUTPUT;
136432702Sdyson	midi->substream_output = NULL;
136532702Sdyson	if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
136632702Sdyson		spin_unlock_irqrestore(&midi->open_lock, flags);
13671549Srgrimes		err = snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 0);
1368	} else {
1369		spin_unlock_irqrestore(&midi->open_lock, flags);
1370	}
1371	return err;
1372}
1373
1374static void snd_emu10k1x_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
1375{
1376	struct emu10k1x *emu;
1377	struct emu10k1x_midi *midi = substream->rmidi->private_data;
1378	emu = midi->emu;
1379	if (snd_BUG_ON(!emu))
1380		return;
1381
1382	if (up)
1383		snd_emu10k1x_intr_enable(emu, midi->rx_enable);
1384	else
1385		snd_emu10k1x_intr_disable(emu, midi->rx_enable);
1386}
1387
1388static void snd_emu10k1x_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
1389{
1390	struct emu10k1x *emu;
1391	struct emu10k1x_midi *midi = substream->rmidi->private_data;
1392	unsigned long flags;
1393
1394	emu = midi->emu;
1395	if (snd_BUG_ON(!emu))
1396		return;
1397
1398	if (up) {
1399		int max = 4;
1400		unsigned char byte;
1401
1402		/* try to send some amount of bytes here before interrupts */
1403		spin_lock_irqsave(&midi->output_lock, flags);
1404		while (max > 0) {
1405			if (mpu401_output_ready(emu, midi)) {
1406				if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT) ||
1407				    snd_rawmidi_transmit(substream, &byte, 1) != 1) {
1408					/* no more data */
1409					spin_unlock_irqrestore(&midi->output_lock, flags);
1410					return;
1411				}
1412				mpu401_write_data(emu, midi, byte);
1413				max--;
1414			} else {
1415				break;
1416			}
1417		}
1418		spin_unlock_irqrestore(&midi->output_lock, flags);
1419		snd_emu10k1x_intr_enable(emu, midi->tx_enable);
1420	} else {
1421		snd_emu10k1x_intr_disable(emu, midi->tx_enable);
1422	}
1423}
1424
1425/*
1426
1427 */
1428
1429static const struct snd_rawmidi_ops snd_emu10k1x_midi_output =
1430{
1431	.open =		snd_emu10k1x_midi_output_open,
1432	.close =	snd_emu10k1x_midi_output_close,
1433	.trigger =	snd_emu10k1x_midi_output_trigger,
1434};
1435
1436static const struct snd_rawmidi_ops snd_emu10k1x_midi_input =
1437{
1438	.open =		snd_emu10k1x_midi_input_open,
1439	.close =	snd_emu10k1x_midi_input_close,
1440	.trigger =	snd_emu10k1x_midi_input_trigger,
1441};
1442
1443static void snd_emu10k1x_midi_free(struct snd_rawmidi *rmidi)
1444{
1445	struct emu10k1x_midi *midi = rmidi->private_data;
1446	midi->interrupt = NULL;
1447	midi->rmidi = NULL;
1448}
1449
1450static int emu10k1x_midi_init(struct emu10k1x *emu,
1451			      struct emu10k1x_midi *midi, int device,
1452			      char *name)
1453{
1454	struct snd_rawmidi *rmidi;
1455	int err;
1456
1457	err = snd_rawmidi_new(emu->card, name, device, 1, 1, &rmidi);
1458	if (err < 0)
1459		return err;
1460	midi->emu = emu;
1461	spin_lock_init(&midi->open_lock);
1462	spin_lock_init(&midi->input_lock);
1463	spin_lock_init(&midi->output_lock);
1464	strcpy(rmidi->name, name);
1465	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_emu10k1x_midi_output);
1466	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_emu10k1x_midi_input);
1467	rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
1468	                     SNDRV_RAWMIDI_INFO_INPUT |
1469	                     SNDRV_RAWMIDI_INFO_DUPLEX;
1470	rmidi->private_data = midi;
1471	rmidi->private_free = snd_emu10k1x_midi_free;
1472	midi->rmidi = rmidi;
1473	return 0;
1474}
1475
1476static int snd_emu10k1x_midi(struct emu10k1x *emu)
1477{
1478	struct emu10k1x_midi *midi = &emu->midi;
1479	int err;
1480
1481	err = emu10k1x_midi_init(emu, midi, 0, "EMU10K1X MPU-401 (UART)");
1482	if (err < 0)
1483		return err;
1484
1485	midi->tx_enable = INTE_MIDITXENABLE;
1486	midi->rx_enable = INTE_MIDIRXENABLE;
1487	midi->port = MUDATA;
1488	midi->ipr_tx = IPR_MIDITRANSBUFEMPTY;
1489	midi->ipr_rx = IPR_MIDIRECVBUFEMPTY;
1490	midi->interrupt = snd_emu10k1x_midi_interrupt;
1491	return 0;
1492}
1493
1494static int __snd_emu10k1x_probe(struct pci_dev *pci,
1495				const struct pci_device_id *pci_id)
1496{
1497	static int dev;
1498	struct snd_card *card;
1499	struct emu10k1x *chip;
1500	int err;
1501
1502	if (dev >= SNDRV_CARDS)
1503		return -ENODEV;
1504	if (!enable[dev]) {
1505		dev++;
1506		return -ENOENT;
1507	}
1508
1509	err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
1510				sizeof(*chip), &card);
1511	if (err < 0)
1512		return err;
1513	chip = card->private_data;
1514
1515	err = snd_emu10k1x_create(card, pci);
1516	if (err < 0)
1517		return err;
1518
1519	err = snd_emu10k1x_pcm(chip, 0);
1520	if (err < 0)
1521		return err;
1522	err = snd_emu10k1x_pcm(chip, 1);
1523	if (err < 0)
1524		return err;
1525	err = snd_emu10k1x_pcm(chip, 2);
1526	if (err < 0)
1527		return err;
1528
1529	err = snd_emu10k1x_ac97(chip);
1530	if (err < 0)
1531		return err;
1532
1533	err = snd_emu10k1x_mixer(chip);
1534	if (err < 0)
1535		return err;
1536
1537	err = snd_emu10k1x_midi(chip);
1538	if (err < 0)
1539		return err;
1540
1541	snd_emu10k1x_proc_init(chip);
1542
1543	strcpy(card->driver, "EMU10K1X");
1544	strcpy(card->shortname, "Dell Sound Blaster Live!");
1545	sprintf(card->longname, "%s at 0x%lx irq %i",
1546		card->shortname, chip->port, chip->irq);
1547
1548	err = snd_card_register(card);
1549	if (err < 0)
1550		return err;
1551
1552	pci_set_drvdata(pci, card);
1553	dev++;
1554	return 0;
1555}
1556
1557static int snd_emu10k1x_probe(struct pci_dev *pci,
1558			      const struct pci_device_id *pci_id)
1559{
1560	return snd_card_free_on_error(&pci->dev, __snd_emu10k1x_probe(pci, pci_id));
1561}
1562
1563// PCI IDs
1564static const struct pci_device_id snd_emu10k1x_ids[] = {
1565	{ PCI_VDEVICE(CREATIVE, 0x0006), 0 },	/* Dell OEM version (EMU10K1) */
1566	{ 0, }
1567};
1568MODULE_DEVICE_TABLE(pci, snd_emu10k1x_ids);
1569
1570// pci_driver definition
1571static struct pci_driver emu10k1x_driver = {
1572	.name = KBUILD_MODNAME,
1573	.id_table = snd_emu10k1x_ids,
1574	.probe = snd_emu10k1x_probe,
1575};
1576
1577module_pci_driver(emu10k1x_driver);
1578