xref: /OK3568_Linux_fs/kernel/sound/pci/es1968.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  *  Driver for ESS Maestro 1/2/2E Sound Card (started 21.8.99)
4*4882a593Smuzhiyun  *  Copyright (c) by Matze Braun <MatzeBraun@gmx.de>.
5*4882a593Smuzhiyun  *                   Takashi Iwai <tiwai@suse.de>
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  *  Most of the driver code comes from Zach Brown(zab@redhat.com)
8*4882a593Smuzhiyun  *	Alan Cox OSS Driver
9*4882a593Smuzhiyun  *  Rewritted from card-es1938.c source.
10*4882a593Smuzhiyun  *
11*4882a593Smuzhiyun  *  TODO:
12*4882a593Smuzhiyun  *   Perhaps Synth
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  *  Notes from Zach Brown about the driver code
15*4882a593Smuzhiyun  *
16*4882a593Smuzhiyun  *  Hardware Description
17*4882a593Smuzhiyun  *
18*4882a593Smuzhiyun  *	A working Maestro setup contains the Maestro chip wired to a
19*4882a593Smuzhiyun  *	codec or 2.  In the Maestro we have the APUs, the ASSP, and the
20*4882a593Smuzhiyun  *	Wavecache.  The APUs can be though of as virtual audio routing
21*4882a593Smuzhiyun  *	channels.  They can take data from a number of sources and perform
22*4882a593Smuzhiyun  *	basic encodings of the data.  The wavecache is a storehouse for
23*4882a593Smuzhiyun  *	PCM data.  Typically it deals with PCI and interracts with the
24*4882a593Smuzhiyun  *	APUs.  The ASSP is a wacky DSP like device that ESS is loth
25*4882a593Smuzhiyun  *	to release docs on.  Thankfully it isn't required on the Maestro
26*4882a593Smuzhiyun  *	until you start doing insane things like FM emulation and surround
27*4882a593Smuzhiyun  *	encoding.  The codecs are almost always AC-97 compliant codecs,
28*4882a593Smuzhiyun  *	but it appears that early Maestros may have had PT101 (an ESS
29*4882a593Smuzhiyun  *	part?) wired to them.  The only real difference in the Maestro
30*4882a593Smuzhiyun  *	families is external goop like docking capability, memory for
31*4882a593Smuzhiyun  *	the ASSP, and initialization differences.
32*4882a593Smuzhiyun  *
33*4882a593Smuzhiyun  *  Driver Operation
34*4882a593Smuzhiyun  *
35*4882a593Smuzhiyun  *	We only drive the APU/Wavecache as typical DACs and drive the
36*4882a593Smuzhiyun  *	mixers in the codecs.  There are 64 APUs.  We assign 6 to each
37*4882a593Smuzhiyun  *	/dev/dsp? device.  2 channels for output, and 4 channels for
38*4882a593Smuzhiyun  *	input.
39*4882a593Smuzhiyun  *
40*4882a593Smuzhiyun  *	Each APU can do a number of things, but we only really use
41*4882a593Smuzhiyun  *	3 basic functions.  For playback we use them to convert PCM
42*4882a593Smuzhiyun  *	data fetched over PCI by the wavecahche into analog data that
43*4882a593Smuzhiyun  *	is handed to the codec.  One APU for mono, and a pair for stereo.
44*4882a593Smuzhiyun  *	When in stereo, the combination of smarts in the APU and Wavecache
45*4882a593Smuzhiyun  *	decide which wavecache gets the left or right channel.
46*4882a593Smuzhiyun  *
47*4882a593Smuzhiyun  *	For record we still use the old overly mono system.  For each in
48*4882a593Smuzhiyun  *	coming channel the data comes in from the codec, through a 'input'
49*4882a593Smuzhiyun  *	APU, through another rate converter APU, and then into memory via
50*4882a593Smuzhiyun  *	the wavecache and PCI.  If its stereo, we mash it back into LRLR in
51*4882a593Smuzhiyun  *	software.  The pass between the 2 APUs is supposedly what requires us
52*4882a593Smuzhiyun  *	to have a 512 byte buffer sitting around in wavecache/memory.
53*4882a593Smuzhiyun  *
54*4882a593Smuzhiyun  *	The wavecache makes our life even more fun.  First off, it can
55*4882a593Smuzhiyun  *	only address the first 28 bits of PCI address space, making it
56*4882a593Smuzhiyun  *	useless on quite a few architectures.  Secondly, its insane.
57*4882a593Smuzhiyun  *	It claims to fetch from 4 regions of PCI space, each 4 meg in length.
58*4882a593Smuzhiyun  *	But that doesn't really work.  You can only use 1 region.  So all our
59*4882a593Smuzhiyun  *	allocations have to be in 4meg of each other.  Booo.  Hiss.
60*4882a593Smuzhiyun  *	So we have a module parameter, dsps_order, that is the order of
61*4882a593Smuzhiyun  *	the number of dsps to provide.  All their buffer space is allocated
62*4882a593Smuzhiyun  *	on open time.  The sonicvibes OSS routines we inherited really want
63*4882a593Smuzhiyun  *	power of 2 buffers, so we have all those next to each other, then
64*4882a593Smuzhiyun  *	512 byte regions for the recording wavecaches.  This ends up
65*4882a593Smuzhiyun  *	wasting quite a bit of memory.  The only fixes I can see would be
66*4882a593Smuzhiyun  *	getting a kernel allocator that could work in zones, or figuring out
67*4882a593Smuzhiyun  *	just how to coerce the WP into doing what we want.
68*4882a593Smuzhiyun  *
69*4882a593Smuzhiyun  *	The indirection of the various registers means we have to spinlock
70*4882a593Smuzhiyun  *	nearly all register accesses.  We have the main register indirection
71*4882a593Smuzhiyun  *	like the wave cache, maestro registers, etc.  Then we have beasts
72*4882a593Smuzhiyun  *	like the APU interface that is indirect registers gotten at through
73*4882a593Smuzhiyun  *	the main maestro indirection.  Ouch.  We spinlock around the actual
74*4882a593Smuzhiyun  *	ports on a per card basis.  This means spinlock activity at each IO
75*4882a593Smuzhiyun  *	operation, but the only IO operation clusters are in non critical
76*4882a593Smuzhiyun  *	paths and it makes the code far easier to follow.  Interrupts are
77*4882a593Smuzhiyun  *	blocked while holding the locks because the int handler has to
78*4882a593Smuzhiyun  *	get at some of them :(.  The mixer interface doesn't, however.
79*4882a593Smuzhiyun  *	We also have an OSS state lock that is thrown around in a few
80*4882a593Smuzhiyun  *	places.
81*4882a593Smuzhiyun  */
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun #include <linux/io.h>
84*4882a593Smuzhiyun #include <linux/delay.h>
85*4882a593Smuzhiyun #include <linux/interrupt.h>
86*4882a593Smuzhiyun #include <linux/init.h>
87*4882a593Smuzhiyun #include <linux/pci.h>
88*4882a593Smuzhiyun #include <linux/dma-mapping.h>
89*4882a593Smuzhiyun #include <linux/slab.h>
90*4882a593Smuzhiyun #include <linux/gameport.h>
91*4882a593Smuzhiyun #include <linux/module.h>
92*4882a593Smuzhiyun #include <linux/mutex.h>
93*4882a593Smuzhiyun #include <linux/input.h>
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun #include <sound/core.h>
96*4882a593Smuzhiyun #include <sound/pcm.h>
97*4882a593Smuzhiyun #include <sound/mpu401.h>
98*4882a593Smuzhiyun #include <sound/ac97_codec.h>
99*4882a593Smuzhiyun #include <sound/initval.h>
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun #ifdef CONFIG_SND_ES1968_RADIO
102*4882a593Smuzhiyun #include <media/drv-intf/tea575x.h>
103*4882a593Smuzhiyun #endif
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun #define CARD_NAME "ESS Maestro1/2"
106*4882a593Smuzhiyun #define DRIVER_NAME "ES1968"
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun MODULE_DESCRIPTION("ESS Maestro");
109*4882a593Smuzhiyun MODULE_LICENSE("GPL");
110*4882a593Smuzhiyun MODULE_SUPPORTED_DEVICE("{{ESS,Maestro 2e},"
111*4882a593Smuzhiyun 		"{ESS,Maestro 2},"
112*4882a593Smuzhiyun 		"{ESS,Maestro 1},"
113*4882a593Smuzhiyun 		"{TerraTec,DMX}}");
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun #if IS_REACHABLE(CONFIG_GAMEPORT)
116*4882a593Smuzhiyun #define SUPPORT_JOYSTICK 1
117*4882a593Smuzhiyun #endif
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 1-MAX */
120*4882a593Smuzhiyun static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
121*4882a593Smuzhiyun static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
122*4882a593Smuzhiyun static int total_bufsize[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1024 };
123*4882a593Smuzhiyun static int pcm_substreams_p[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4 };
124*4882a593Smuzhiyun static int pcm_substreams_c[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1 };
125*4882a593Smuzhiyun static int clock[SNDRV_CARDS];
126*4882a593Smuzhiyun static int use_pm[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
127*4882a593Smuzhiyun static int enable_mpu[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
128*4882a593Smuzhiyun #ifdef SUPPORT_JOYSTICK
129*4882a593Smuzhiyun static bool joystick[SNDRV_CARDS];
130*4882a593Smuzhiyun #endif
131*4882a593Smuzhiyun static int radio_nr[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun module_param_array(index, int, NULL, 0444);
134*4882a593Smuzhiyun MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
135*4882a593Smuzhiyun module_param_array(id, charp, NULL, 0444);
136*4882a593Smuzhiyun MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
137*4882a593Smuzhiyun module_param_array(enable, bool, NULL, 0444);
138*4882a593Smuzhiyun MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
139*4882a593Smuzhiyun module_param_array(total_bufsize, int, NULL, 0444);
140*4882a593Smuzhiyun MODULE_PARM_DESC(total_bufsize, "Total buffer size in kB.");
141*4882a593Smuzhiyun module_param_array(pcm_substreams_p, int, NULL, 0444);
142*4882a593Smuzhiyun MODULE_PARM_DESC(pcm_substreams_p, "PCM Playback substreams for " CARD_NAME " soundcard.");
143*4882a593Smuzhiyun module_param_array(pcm_substreams_c, int, NULL, 0444);
144*4882a593Smuzhiyun MODULE_PARM_DESC(pcm_substreams_c, "PCM Capture substreams for " CARD_NAME " soundcard.");
145*4882a593Smuzhiyun module_param_array(clock, int, NULL, 0444);
146*4882a593Smuzhiyun MODULE_PARM_DESC(clock, "Clock on " CARD_NAME " soundcard.  (0 = auto-detect)");
147*4882a593Smuzhiyun module_param_array(use_pm, int, NULL, 0444);
148*4882a593Smuzhiyun MODULE_PARM_DESC(use_pm, "Toggle power-management.  (0 = off, 1 = on, 2 = auto)");
149*4882a593Smuzhiyun module_param_array(enable_mpu, int, NULL, 0444);
150*4882a593Smuzhiyun MODULE_PARM_DESC(enable_mpu, "Enable MPU401.  (0 = off, 1 = on, 2 = auto)");
151*4882a593Smuzhiyun #ifdef SUPPORT_JOYSTICK
152*4882a593Smuzhiyun module_param_array(joystick, bool, NULL, 0444);
153*4882a593Smuzhiyun MODULE_PARM_DESC(joystick, "Enable joystick.");
154*4882a593Smuzhiyun #endif
155*4882a593Smuzhiyun module_param_array(radio_nr, int, NULL, 0444);
156*4882a593Smuzhiyun MODULE_PARM_DESC(radio_nr, "Radio device numbers");
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun #define NR_APUS			64
161*4882a593Smuzhiyun #define NR_APU_REGS		16
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun /* NEC Versas ? */
164*4882a593Smuzhiyun #define NEC_VERSA_SUBID1	0x80581033
165*4882a593Smuzhiyun #define NEC_VERSA_SUBID2	0x803c1033
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun /* Mode Flags */
168*4882a593Smuzhiyun #define ESS_FMT_STEREO     	0x01
169*4882a593Smuzhiyun #define ESS_FMT_16BIT      	0x02
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun #define DAC_RUNNING		1
172*4882a593Smuzhiyun #define ADC_RUNNING		2
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun /* Values for the ESM_LEGACY_AUDIO_CONTROL */
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun #define ESS_DISABLE_AUDIO	0x8000
177*4882a593Smuzhiyun #define ESS_ENABLE_SERIAL_IRQ	0x4000
178*4882a593Smuzhiyun #define IO_ADRESS_ALIAS		0x0020
179*4882a593Smuzhiyun #define MPU401_IRQ_ENABLE	0x0010
180*4882a593Smuzhiyun #define MPU401_IO_ENABLE	0x0008
181*4882a593Smuzhiyun #define GAME_IO_ENABLE		0x0004
182*4882a593Smuzhiyun #define FM_IO_ENABLE		0x0002
183*4882a593Smuzhiyun #define SB_IO_ENABLE		0x0001
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun /* Values for the ESM_CONFIG_A */
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun #define PIC_SNOOP1		0x4000
188*4882a593Smuzhiyun #define PIC_SNOOP2		0x2000
189*4882a593Smuzhiyun #define SAFEGUARD		0x0800
190*4882a593Smuzhiyun #define DMA_CLEAR		0x0700
191*4882a593Smuzhiyun #define DMA_DDMA		0x0000
192*4882a593Smuzhiyun #define DMA_TDMA		0x0100
193*4882a593Smuzhiyun #define DMA_PCPCI		0x0200
194*4882a593Smuzhiyun #define POST_WRITE		0x0080
195*4882a593Smuzhiyun #define PCI_TIMING		0x0040
196*4882a593Smuzhiyun #define SWAP_LR			0x0020
197*4882a593Smuzhiyun #define SUBTR_DECODE		0x0002
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun /* Values for the ESM_CONFIG_B */
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun #define SPDIF_CONFB		0x0100
202*4882a593Smuzhiyun #define HWV_CONFB		0x0080
203*4882a593Smuzhiyun #define DEBOUNCE		0x0040
204*4882a593Smuzhiyun #define GPIO_CONFB		0x0020
205*4882a593Smuzhiyun #define CHI_CONFB		0x0010
206*4882a593Smuzhiyun #define IDMA_CONFB		0x0008	/*undoc */
207*4882a593Smuzhiyun #define MIDI_FIX		0x0004	/*undoc */
208*4882a593Smuzhiyun #define IRQ_TO_ISA		0x0001	/*undoc */
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun /* Values for Ring Bus Control B */
211*4882a593Smuzhiyun #define	RINGB_2CODEC_ID_MASK	0x0003
212*4882a593Smuzhiyun #define RINGB_DIS_VALIDATION	0x0008
213*4882a593Smuzhiyun #define RINGB_EN_SPDIF		0x0010
214*4882a593Smuzhiyun #define	RINGB_EN_2CODEC		0x0020
215*4882a593Smuzhiyun #define RINGB_SING_BIT_DUAL	0x0040
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun /* ****Port Addresses**** */
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun /*   Write & Read */
220*4882a593Smuzhiyun #define ESM_INDEX		0x02
221*4882a593Smuzhiyun #define ESM_DATA		0x00
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun /*   AC97 + RingBus */
224*4882a593Smuzhiyun #define ESM_AC97_INDEX		0x30
225*4882a593Smuzhiyun #define	ESM_AC97_DATA		0x32
226*4882a593Smuzhiyun #define ESM_RING_BUS_DEST	0x34
227*4882a593Smuzhiyun #define ESM_RING_BUS_CONTR_A	0x36
228*4882a593Smuzhiyun #define ESM_RING_BUS_CONTR_B	0x38
229*4882a593Smuzhiyun #define ESM_RING_BUS_SDO	0x3A
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun /*   WaveCache*/
232*4882a593Smuzhiyun #define WC_INDEX		0x10
233*4882a593Smuzhiyun #define WC_DATA			0x12
234*4882a593Smuzhiyun #define WC_CONTROL		0x14
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun /*   ASSP*/
237*4882a593Smuzhiyun #define ASSP_INDEX		0x80
238*4882a593Smuzhiyun #define ASSP_MEMORY		0x82
239*4882a593Smuzhiyun #define ASSP_DATA		0x84
240*4882a593Smuzhiyun #define ASSP_CONTROL_A		0xA2
241*4882a593Smuzhiyun #define ASSP_CONTROL_B		0xA4
242*4882a593Smuzhiyun #define ASSP_CONTROL_C		0xA6
243*4882a593Smuzhiyun #define ASSP_HOSTW_INDEX	0xA8
244*4882a593Smuzhiyun #define ASSP_HOSTW_DATA		0xAA
245*4882a593Smuzhiyun #define ASSP_HOSTW_IRQ		0xAC
246*4882a593Smuzhiyun /* Midi */
247*4882a593Smuzhiyun #define ESM_MPU401_PORT		0x98
248*4882a593Smuzhiyun /* Others */
249*4882a593Smuzhiyun #define ESM_PORT_HOST_IRQ	0x18
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun #define IDR0_DATA_PORT		0x00
252*4882a593Smuzhiyun #define IDR1_CRAM_POINTER	0x01
253*4882a593Smuzhiyun #define IDR2_CRAM_DATA		0x02
254*4882a593Smuzhiyun #define IDR3_WAVE_DATA		0x03
255*4882a593Smuzhiyun #define IDR4_WAVE_PTR_LOW	0x04
256*4882a593Smuzhiyun #define IDR5_WAVE_PTR_HI	0x05
257*4882a593Smuzhiyun #define IDR6_TIMER_CTRL		0x06
258*4882a593Smuzhiyun #define IDR7_WAVE_ROMRAM	0x07
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun #define WRITEABLE_MAP		0xEFFFFF
261*4882a593Smuzhiyun #define READABLE_MAP		0x64003F
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun /* PCI Register */
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun #define ESM_LEGACY_AUDIO_CONTROL 0x40
266*4882a593Smuzhiyun #define ESM_ACPI_COMMAND	0x54
267*4882a593Smuzhiyun #define ESM_CONFIG_A		0x50
268*4882a593Smuzhiyun #define ESM_CONFIG_B		0x52
269*4882a593Smuzhiyun #define ESM_DDMA		0x60
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun /* Bob Bits */
272*4882a593Smuzhiyun #define ESM_BOB_ENABLE		0x0001
273*4882a593Smuzhiyun #define ESM_BOB_START		0x0001
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun /* Host IRQ Control Bits */
276*4882a593Smuzhiyun #define ESM_RESET_MAESTRO	0x8000
277*4882a593Smuzhiyun #define ESM_RESET_DIRECTSOUND   0x4000
278*4882a593Smuzhiyun #define ESM_HIRQ_ClkRun		0x0100
279*4882a593Smuzhiyun #define ESM_HIRQ_HW_VOLUME	0x0040
280*4882a593Smuzhiyun #define ESM_HIRQ_HARPO		0x0030	/* What's that? */
281*4882a593Smuzhiyun #define ESM_HIRQ_ASSP		0x0010
282*4882a593Smuzhiyun #define	ESM_HIRQ_DSIE		0x0004
283*4882a593Smuzhiyun #define ESM_HIRQ_MPU401		0x0002
284*4882a593Smuzhiyun #define ESM_HIRQ_SB		0x0001
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun /* Host IRQ Status Bits */
287*4882a593Smuzhiyun #define ESM_MPU401_IRQ		0x02
288*4882a593Smuzhiyun #define ESM_SB_IRQ		0x01
289*4882a593Smuzhiyun #define ESM_SOUND_IRQ		0x04
290*4882a593Smuzhiyun #define	ESM_ASSP_IRQ		0x10
291*4882a593Smuzhiyun #define ESM_HWVOL_IRQ		0x40
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun #define ESS_SYSCLK		50000000
294*4882a593Smuzhiyun #define ESM_BOB_FREQ 		200
295*4882a593Smuzhiyun #define ESM_BOB_FREQ_MAX	800
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun #define ESM_FREQ_ESM1  		(49152000L / 1024L)	/* default rate 48000 */
298*4882a593Smuzhiyun #define ESM_FREQ_ESM2  		(50000000L / 1024L)
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun /* APU Modes: reg 0x00, bit 4-7 */
301*4882a593Smuzhiyun #define ESM_APU_MODE_SHIFT	4
302*4882a593Smuzhiyun #define ESM_APU_MODE_MASK	(0xf << 4)
303*4882a593Smuzhiyun #define	ESM_APU_OFF		0x00
304*4882a593Smuzhiyun #define	ESM_APU_16BITLINEAR	0x01	/* 16-Bit Linear Sample Player */
305*4882a593Smuzhiyun #define	ESM_APU_16BITSTEREO	0x02	/* 16-Bit Stereo Sample Player */
306*4882a593Smuzhiyun #define	ESM_APU_8BITLINEAR	0x03	/* 8-Bit Linear Sample Player */
307*4882a593Smuzhiyun #define	ESM_APU_8BITSTEREO	0x04	/* 8-Bit Stereo Sample Player */
308*4882a593Smuzhiyun #define	ESM_APU_8BITDIFF	0x05	/* 8-Bit Differential Sample Playrer */
309*4882a593Smuzhiyun #define	ESM_APU_DIGITALDELAY	0x06	/* Digital Delay Line */
310*4882a593Smuzhiyun #define	ESM_APU_DUALTAP		0x07	/* Dual Tap Reader */
311*4882a593Smuzhiyun #define	ESM_APU_CORRELATOR	0x08	/* Correlator */
312*4882a593Smuzhiyun #define	ESM_APU_INPUTMIXER	0x09	/* Input Mixer */
313*4882a593Smuzhiyun #define	ESM_APU_WAVETABLE	0x0A	/* Wave Table Mode */
314*4882a593Smuzhiyun #define	ESM_APU_SRCONVERTOR	0x0B	/* Sample Rate Convertor */
315*4882a593Smuzhiyun #define	ESM_APU_16BITPINGPONG	0x0C	/* 16-Bit Ping-Pong Sample Player */
316*4882a593Smuzhiyun #define	ESM_APU_RESERVED1	0x0D	/* Reserved 1 */
317*4882a593Smuzhiyun #define	ESM_APU_RESERVED2	0x0E	/* Reserved 2 */
318*4882a593Smuzhiyun #define	ESM_APU_RESERVED3	0x0F	/* Reserved 3 */
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun /* reg 0x00 */
321*4882a593Smuzhiyun #define ESM_APU_FILTER_Q_SHIFT		0
322*4882a593Smuzhiyun #define ESM_APU_FILTER_Q_MASK		(3 << 0)
323*4882a593Smuzhiyun /* APU Filtey Q Control */
324*4882a593Smuzhiyun #define ESM_APU_FILTER_LESSQ	0x00
325*4882a593Smuzhiyun #define ESM_APU_FILTER_MOREQ	0x03
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun #define ESM_APU_FILTER_TYPE_SHIFT	2
328*4882a593Smuzhiyun #define ESM_APU_FILTER_TYPE_MASK	(3 << 2)
329*4882a593Smuzhiyun #define ESM_APU_ENV_TYPE_SHIFT		8
330*4882a593Smuzhiyun #define ESM_APU_ENV_TYPE_MASK		(3 << 8)
331*4882a593Smuzhiyun #define ESM_APU_ENV_STATE_SHIFT		10
332*4882a593Smuzhiyun #define ESM_APU_ENV_STATE_MASK		(3 << 10)
333*4882a593Smuzhiyun #define ESM_APU_END_CURVE		(1 << 12)
334*4882a593Smuzhiyun #define ESM_APU_INT_ON_LOOP		(1 << 13)
335*4882a593Smuzhiyun #define ESM_APU_DMA_ENABLE		(1 << 14)
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun /* reg 0x02 */
338*4882a593Smuzhiyun #define ESM_APU_SUBMIX_GROUP_SHIRT	0
339*4882a593Smuzhiyun #define ESM_APU_SUBMIX_GROUP_MASK	(7 << 0)
340*4882a593Smuzhiyun #define ESM_APU_SUBMIX_MODE		(1 << 3)
341*4882a593Smuzhiyun #define ESM_APU_6dB			(1 << 4)
342*4882a593Smuzhiyun #define ESM_APU_DUAL_EFFECT		(1 << 5)
343*4882a593Smuzhiyun #define ESM_APU_EFFECT_CHANNELS_SHIFT	6
344*4882a593Smuzhiyun #define ESM_APU_EFFECT_CHANNELS_MASK	(3 << 6)
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun /* reg 0x03 */
347*4882a593Smuzhiyun #define ESM_APU_STEP_SIZE_MASK		0x0fff
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun /* reg 0x04 */
350*4882a593Smuzhiyun #define ESM_APU_PHASE_SHIFT		0
351*4882a593Smuzhiyun #define ESM_APU_PHASE_MASK		(0xff << 0)
352*4882a593Smuzhiyun #define ESM_APU_WAVE64K_PAGE_SHIFT	8	/* most 8bit of wave start offset */
353*4882a593Smuzhiyun #define ESM_APU_WAVE64K_PAGE_MASK	(0xff << 8)
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun /* reg 0x05 - wave start offset */
356*4882a593Smuzhiyun /* reg 0x06 - wave end offset */
357*4882a593Smuzhiyun /* reg 0x07 - wave loop length */
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun /* reg 0x08 */
360*4882a593Smuzhiyun #define ESM_APU_EFFECT_GAIN_SHIFT	0
361*4882a593Smuzhiyun #define ESM_APU_EFFECT_GAIN_MASK	(0xff << 0)
362*4882a593Smuzhiyun #define ESM_APU_TREMOLO_DEPTH_SHIFT	8
363*4882a593Smuzhiyun #define ESM_APU_TREMOLO_DEPTH_MASK	(0xf << 8)
364*4882a593Smuzhiyun #define ESM_APU_TREMOLO_RATE_SHIFT	12
365*4882a593Smuzhiyun #define ESM_APU_TREMOLO_RATE_MASK	(0xf << 12)
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun /* reg 0x09 */
368*4882a593Smuzhiyun /* bit 0-7 amplitude dest? */
369*4882a593Smuzhiyun #define ESM_APU_AMPLITUDE_NOW_SHIFT	8
370*4882a593Smuzhiyun #define ESM_APU_AMPLITUDE_NOW_MASK	(0xff << 8)
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun /* reg 0x0a */
373*4882a593Smuzhiyun #define ESM_APU_POLAR_PAN_SHIFT		0
374*4882a593Smuzhiyun #define ESM_APU_POLAR_PAN_MASK		(0x3f << 0)
375*4882a593Smuzhiyun /* Polar Pan Control */
376*4882a593Smuzhiyun #define	ESM_APU_PAN_CENTER_CIRCLE		0x00
377*4882a593Smuzhiyun #define	ESM_APU_PAN_MIDDLE_RADIUS		0x01
378*4882a593Smuzhiyun #define	ESM_APU_PAN_OUTSIDE_RADIUS		0x02
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun #define ESM_APU_FILTER_TUNING_SHIFT	8
381*4882a593Smuzhiyun #define ESM_APU_FILTER_TUNING_MASK	(0xff << 8)
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun /* reg 0x0b */
384*4882a593Smuzhiyun #define ESM_APU_DATA_SRC_A_SHIFT	0
385*4882a593Smuzhiyun #define ESM_APU_DATA_SRC_A_MASK		(0x7f << 0)
386*4882a593Smuzhiyun #define ESM_APU_INV_POL_A		(1 << 7)
387*4882a593Smuzhiyun #define ESM_APU_DATA_SRC_B_SHIFT	8
388*4882a593Smuzhiyun #define ESM_APU_DATA_SRC_B_MASK		(0x7f << 8)
389*4882a593Smuzhiyun #define ESM_APU_INV_POL_B		(1 << 15)
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun #define ESM_APU_VIBRATO_RATE_SHIFT	0
392*4882a593Smuzhiyun #define ESM_APU_VIBRATO_RATE_MASK	(0xf << 0)
393*4882a593Smuzhiyun #define ESM_APU_VIBRATO_DEPTH_SHIFT	4
394*4882a593Smuzhiyun #define ESM_APU_VIBRATO_DEPTH_MASK	(0xf << 4)
395*4882a593Smuzhiyun #define ESM_APU_VIBRATO_PHASE_SHIFT	8
396*4882a593Smuzhiyun #define ESM_APU_VIBRATO_PHASE_MASK	(0xff << 8)
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun /* reg 0x0c */
399*4882a593Smuzhiyun #define ESM_APU_RADIUS_SELECT		(1 << 6)
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun /* APU Filter Control */
402*4882a593Smuzhiyun #define	ESM_APU_FILTER_2POLE_LOPASS	0x00
403*4882a593Smuzhiyun #define	ESM_APU_FILTER_2POLE_BANDPASS	0x01
404*4882a593Smuzhiyun #define	ESM_APU_FILTER_2POLE_HIPASS	0x02
405*4882a593Smuzhiyun #define	ESM_APU_FILTER_1POLE_LOPASS	0x03
406*4882a593Smuzhiyun #define	ESM_APU_FILTER_1POLE_HIPASS	0x04
407*4882a593Smuzhiyun #define	ESM_APU_FILTER_OFF		0x05
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun /* APU ATFP Type */
410*4882a593Smuzhiyun #define	ESM_APU_ATFP_AMPLITUDE			0x00
411*4882a593Smuzhiyun #define	ESM_APU_ATFP_TREMELO			0x01
412*4882a593Smuzhiyun #define	ESM_APU_ATFP_FILTER			0x02
413*4882a593Smuzhiyun #define	ESM_APU_ATFP_PAN			0x03
414*4882a593Smuzhiyun 
415*4882a593Smuzhiyun /* APU ATFP Flags */
416*4882a593Smuzhiyun #define	ESM_APU_ATFP_FLG_OFF			0x00
417*4882a593Smuzhiyun #define	ESM_APU_ATFP_FLG_WAIT			0x01
418*4882a593Smuzhiyun #define	ESM_APU_ATFP_FLG_DONE			0x02
419*4882a593Smuzhiyun #define	ESM_APU_ATFP_FLG_INPROCESS		0x03
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun /* capture mixing buffer size */
423*4882a593Smuzhiyun #define ESM_MEM_ALIGN		0x1000
424*4882a593Smuzhiyun #define ESM_MIXBUF_SIZE		0x400
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun #define ESM_MODE_PLAY		0
427*4882a593Smuzhiyun #define ESM_MODE_CAPTURE	1
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun /* APU use in the driver */
431*4882a593Smuzhiyun enum snd_enum_apu_type {
432*4882a593Smuzhiyun 	ESM_APU_PCM_PLAY,
433*4882a593Smuzhiyun 	ESM_APU_PCM_CAPTURE,
434*4882a593Smuzhiyun 	ESM_APU_PCM_RATECONV,
435*4882a593Smuzhiyun 	ESM_APU_FREE
436*4882a593Smuzhiyun };
437*4882a593Smuzhiyun 
438*4882a593Smuzhiyun /* chip type */
439*4882a593Smuzhiyun enum {
440*4882a593Smuzhiyun 	TYPE_MAESTRO, TYPE_MAESTRO2, TYPE_MAESTRO2E
441*4882a593Smuzhiyun };
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun /* DMA Hack! */
444*4882a593Smuzhiyun struct esm_memory {
445*4882a593Smuzhiyun 	struct snd_dma_buffer buf;
446*4882a593Smuzhiyun 	int empty;	/* status */
447*4882a593Smuzhiyun 	struct list_head list;
448*4882a593Smuzhiyun };
449*4882a593Smuzhiyun 
450*4882a593Smuzhiyun /* Playback Channel */
451*4882a593Smuzhiyun struct esschan {
452*4882a593Smuzhiyun 	int running;
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun 	u8 apu[4];
455*4882a593Smuzhiyun 	u8 apu_mode[4];
456*4882a593Smuzhiyun 
457*4882a593Smuzhiyun 	/* playback/capture pcm buffer */
458*4882a593Smuzhiyun 	struct esm_memory *memory;
459*4882a593Smuzhiyun 	/* capture mixer buffer */
460*4882a593Smuzhiyun 	struct esm_memory *mixbuf;
461*4882a593Smuzhiyun 
462*4882a593Smuzhiyun 	unsigned int hwptr;	/* current hw pointer in bytes */
463*4882a593Smuzhiyun 	unsigned int count;	/* sample counter in bytes */
464*4882a593Smuzhiyun 	unsigned int dma_size;	/* total buffer size in bytes */
465*4882a593Smuzhiyun 	unsigned int frag_size;	/* period size in bytes */
466*4882a593Smuzhiyun 	unsigned int wav_shift;
467*4882a593Smuzhiyun 	u16 base[4];		/* offset for ptr */
468*4882a593Smuzhiyun 
469*4882a593Smuzhiyun 	/* stereo/16bit flag */
470*4882a593Smuzhiyun 	unsigned char fmt;
471*4882a593Smuzhiyun 	int mode;	/* playback / capture */
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun 	int bob_freq;	/* required timer frequency */
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun 	struct snd_pcm_substream *substream;
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun 	/* linked list */
478*4882a593Smuzhiyun 	struct list_head list;
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
481*4882a593Smuzhiyun 	u16 wc_map[4];
482*4882a593Smuzhiyun #endif
483*4882a593Smuzhiyun };
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun struct es1968 {
486*4882a593Smuzhiyun 	/* Module Config */
487*4882a593Smuzhiyun 	int total_bufsize;			/* in bytes */
488*4882a593Smuzhiyun 
489*4882a593Smuzhiyun 	int playback_streams, capture_streams;
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun 	unsigned int clock;		/* clock */
492*4882a593Smuzhiyun 	/* for clock measurement */
493*4882a593Smuzhiyun 	unsigned int in_measurement: 1;
494*4882a593Smuzhiyun 	unsigned int measure_apu;
495*4882a593Smuzhiyun 	unsigned int measure_lastpos;
496*4882a593Smuzhiyun 	unsigned int measure_count;
497*4882a593Smuzhiyun 
498*4882a593Smuzhiyun 	/* buffer */
499*4882a593Smuzhiyun 	struct snd_dma_buffer dma;
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun 	/* Resources... */
502*4882a593Smuzhiyun 	int irq;
503*4882a593Smuzhiyun 	unsigned long io_port;
504*4882a593Smuzhiyun 	int type;
505*4882a593Smuzhiyun 	struct pci_dev *pci;
506*4882a593Smuzhiyun 	struct snd_card *card;
507*4882a593Smuzhiyun 	struct snd_pcm *pcm;
508*4882a593Smuzhiyun 	int do_pm;		/* power-management enabled */
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun 	/* DMA memory block */
511*4882a593Smuzhiyun 	struct list_head buf_list;
512*4882a593Smuzhiyun 
513*4882a593Smuzhiyun 	/* ALSA Stuff */
514*4882a593Smuzhiyun 	struct snd_ac97 *ac97;
515*4882a593Smuzhiyun 	struct snd_rawmidi *rmidi;
516*4882a593Smuzhiyun 
517*4882a593Smuzhiyun 	spinlock_t reg_lock;
518*4882a593Smuzhiyun 	unsigned int in_suspend;
519*4882a593Smuzhiyun 
520*4882a593Smuzhiyun 	/* Maestro Stuff */
521*4882a593Smuzhiyun 	u16 maestro_map[32];
522*4882a593Smuzhiyun 	int bobclient;		/* active timer instancs */
523*4882a593Smuzhiyun 	int bob_freq;		/* timer frequency */
524*4882a593Smuzhiyun 	struct mutex memory_mutex;	/* memory lock */
525*4882a593Smuzhiyun 
526*4882a593Smuzhiyun 	/* APU states */
527*4882a593Smuzhiyun 	unsigned char apu[NR_APUS];
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun 	/* active substreams */
530*4882a593Smuzhiyun 	struct list_head substream_list;
531*4882a593Smuzhiyun 	spinlock_t substream_lock;
532*4882a593Smuzhiyun 
533*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
534*4882a593Smuzhiyun 	u16 apu_map[NR_APUS][NR_APU_REGS];
535*4882a593Smuzhiyun #endif
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun #ifdef SUPPORT_JOYSTICK
538*4882a593Smuzhiyun 	struct gameport *gameport;
539*4882a593Smuzhiyun #endif
540*4882a593Smuzhiyun 
541*4882a593Smuzhiyun #ifdef CONFIG_SND_ES1968_INPUT
542*4882a593Smuzhiyun 	struct input_dev *input_dev;
543*4882a593Smuzhiyun 	char phys[64];			/* physical device path */
544*4882a593Smuzhiyun #else
545*4882a593Smuzhiyun 	struct snd_kcontrol *master_switch; /* for h/w volume control */
546*4882a593Smuzhiyun 	struct snd_kcontrol *master_volume;
547*4882a593Smuzhiyun #endif
548*4882a593Smuzhiyun 	struct work_struct hwvol_work;
549*4882a593Smuzhiyun 
550*4882a593Smuzhiyun #ifdef CONFIG_SND_ES1968_RADIO
551*4882a593Smuzhiyun 	struct v4l2_device v4l2_dev;
552*4882a593Smuzhiyun 	struct snd_tea575x tea;
553*4882a593Smuzhiyun 	unsigned int tea575x_tuner;
554*4882a593Smuzhiyun #endif
555*4882a593Smuzhiyun };
556*4882a593Smuzhiyun 
557*4882a593Smuzhiyun static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id);
558*4882a593Smuzhiyun 
559*4882a593Smuzhiyun static const struct pci_device_id snd_es1968_ids[] = {
560*4882a593Smuzhiyun 	/* Maestro 1 */
561*4882a593Smuzhiyun         { 0x1285, 0x0100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, TYPE_MAESTRO },
562*4882a593Smuzhiyun 	/* Maestro 2 */
563*4882a593Smuzhiyun 	{ 0x125d, 0x1968, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, TYPE_MAESTRO2 },
564*4882a593Smuzhiyun 	/* Maestro 2E */
565*4882a593Smuzhiyun         { 0x125d, 0x1978, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, TYPE_MAESTRO2E },
566*4882a593Smuzhiyun 	{ 0, }
567*4882a593Smuzhiyun };
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun MODULE_DEVICE_TABLE(pci, snd_es1968_ids);
570*4882a593Smuzhiyun 
571*4882a593Smuzhiyun /* *********************
572*4882a593Smuzhiyun    * Low Level Funcs!  *
573*4882a593Smuzhiyun    *********************/
574*4882a593Smuzhiyun 
575*4882a593Smuzhiyun /* no spinlock */
__maestro_write(struct es1968 * chip,u16 reg,u16 data)576*4882a593Smuzhiyun static void __maestro_write(struct es1968 *chip, u16 reg, u16 data)
577*4882a593Smuzhiyun {
578*4882a593Smuzhiyun 	outw(reg, chip->io_port + ESM_INDEX);
579*4882a593Smuzhiyun 	outw(data, chip->io_port + ESM_DATA);
580*4882a593Smuzhiyun 	chip->maestro_map[reg] = data;
581*4882a593Smuzhiyun }
582*4882a593Smuzhiyun 
maestro_write(struct es1968 * chip,u16 reg,u16 data)583*4882a593Smuzhiyun static inline void maestro_write(struct es1968 *chip, u16 reg, u16 data)
584*4882a593Smuzhiyun {
585*4882a593Smuzhiyun 	unsigned long flags;
586*4882a593Smuzhiyun 	spin_lock_irqsave(&chip->reg_lock, flags);
587*4882a593Smuzhiyun 	__maestro_write(chip, reg, data);
588*4882a593Smuzhiyun 	spin_unlock_irqrestore(&chip->reg_lock, flags);
589*4882a593Smuzhiyun }
590*4882a593Smuzhiyun 
591*4882a593Smuzhiyun /* no spinlock */
__maestro_read(struct es1968 * chip,u16 reg)592*4882a593Smuzhiyun static u16 __maestro_read(struct es1968 *chip, u16 reg)
593*4882a593Smuzhiyun {
594*4882a593Smuzhiyun 	if (READABLE_MAP & (1 << reg)) {
595*4882a593Smuzhiyun 		outw(reg, chip->io_port + ESM_INDEX);
596*4882a593Smuzhiyun 		chip->maestro_map[reg] = inw(chip->io_port + ESM_DATA);
597*4882a593Smuzhiyun 	}
598*4882a593Smuzhiyun 	return chip->maestro_map[reg];
599*4882a593Smuzhiyun }
600*4882a593Smuzhiyun 
maestro_read(struct es1968 * chip,u16 reg)601*4882a593Smuzhiyun static inline u16 maestro_read(struct es1968 *chip, u16 reg)
602*4882a593Smuzhiyun {
603*4882a593Smuzhiyun 	unsigned long flags;
604*4882a593Smuzhiyun 	u16 result;
605*4882a593Smuzhiyun 	spin_lock_irqsave(&chip->reg_lock, flags);
606*4882a593Smuzhiyun 	result = __maestro_read(chip, reg);
607*4882a593Smuzhiyun 	spin_unlock_irqrestore(&chip->reg_lock, flags);
608*4882a593Smuzhiyun 	return result;
609*4882a593Smuzhiyun }
610*4882a593Smuzhiyun 
611*4882a593Smuzhiyun /* Wait for the codec bus to be free */
snd_es1968_ac97_wait(struct es1968 * chip)612*4882a593Smuzhiyun static int snd_es1968_ac97_wait(struct es1968 *chip)
613*4882a593Smuzhiyun {
614*4882a593Smuzhiyun 	int timeout = 100000;
615*4882a593Smuzhiyun 
616*4882a593Smuzhiyun 	while (timeout-- > 0) {
617*4882a593Smuzhiyun 		if (!(inb(chip->io_port + ESM_AC97_INDEX) & 1))
618*4882a593Smuzhiyun 			return 0;
619*4882a593Smuzhiyun 		cond_resched();
620*4882a593Smuzhiyun 	}
621*4882a593Smuzhiyun 	dev_dbg(chip->card->dev, "ac97 timeout\n");
622*4882a593Smuzhiyun 	return 1; /* timeout */
623*4882a593Smuzhiyun }
624*4882a593Smuzhiyun 
snd_es1968_ac97_wait_poll(struct es1968 * chip)625*4882a593Smuzhiyun static int snd_es1968_ac97_wait_poll(struct es1968 *chip)
626*4882a593Smuzhiyun {
627*4882a593Smuzhiyun 	int timeout = 100000;
628*4882a593Smuzhiyun 
629*4882a593Smuzhiyun 	while (timeout-- > 0) {
630*4882a593Smuzhiyun 		if (!(inb(chip->io_port + ESM_AC97_INDEX) & 1))
631*4882a593Smuzhiyun 			return 0;
632*4882a593Smuzhiyun 	}
633*4882a593Smuzhiyun 	dev_dbg(chip->card->dev, "ac97 timeout\n");
634*4882a593Smuzhiyun 	return 1; /* timeout */
635*4882a593Smuzhiyun }
636*4882a593Smuzhiyun 
snd_es1968_ac97_write(struct snd_ac97 * ac97,unsigned short reg,unsigned short val)637*4882a593Smuzhiyun static void snd_es1968_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
638*4882a593Smuzhiyun {
639*4882a593Smuzhiyun 	struct es1968 *chip = ac97->private_data;
640*4882a593Smuzhiyun 
641*4882a593Smuzhiyun 	snd_es1968_ac97_wait(chip);
642*4882a593Smuzhiyun 
643*4882a593Smuzhiyun 	/* Write the bus */
644*4882a593Smuzhiyun 	outw(val, chip->io_port + ESM_AC97_DATA);
645*4882a593Smuzhiyun 	/*msleep(1);*/
646*4882a593Smuzhiyun 	outb(reg, chip->io_port + ESM_AC97_INDEX);
647*4882a593Smuzhiyun 	/*msleep(1);*/
648*4882a593Smuzhiyun }
649*4882a593Smuzhiyun 
snd_es1968_ac97_read(struct snd_ac97 * ac97,unsigned short reg)650*4882a593Smuzhiyun static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
651*4882a593Smuzhiyun {
652*4882a593Smuzhiyun 	u16 data = 0;
653*4882a593Smuzhiyun 	struct es1968 *chip = ac97->private_data;
654*4882a593Smuzhiyun 
655*4882a593Smuzhiyun 	snd_es1968_ac97_wait(chip);
656*4882a593Smuzhiyun 
657*4882a593Smuzhiyun 	outb(reg | 0x80, chip->io_port + ESM_AC97_INDEX);
658*4882a593Smuzhiyun 	/*msleep(1);*/
659*4882a593Smuzhiyun 
660*4882a593Smuzhiyun 	if (!snd_es1968_ac97_wait_poll(chip)) {
661*4882a593Smuzhiyun 		data = inw(chip->io_port + ESM_AC97_DATA);
662*4882a593Smuzhiyun 		/*msleep(1);*/
663*4882a593Smuzhiyun 	}
664*4882a593Smuzhiyun 
665*4882a593Smuzhiyun 	return data;
666*4882a593Smuzhiyun }
667*4882a593Smuzhiyun 
668*4882a593Smuzhiyun /* no spinlock */
apu_index_set(struct es1968 * chip,u16 index)669*4882a593Smuzhiyun static void apu_index_set(struct es1968 *chip, u16 index)
670*4882a593Smuzhiyun {
671*4882a593Smuzhiyun 	int i;
672*4882a593Smuzhiyun 	__maestro_write(chip, IDR1_CRAM_POINTER, index);
673*4882a593Smuzhiyun 	for (i = 0; i < 1000; i++)
674*4882a593Smuzhiyun 		if (__maestro_read(chip, IDR1_CRAM_POINTER) == index)
675*4882a593Smuzhiyun 			return;
676*4882a593Smuzhiyun 	dev_dbg(chip->card->dev, "APU register select failed. (Timeout)\n");
677*4882a593Smuzhiyun }
678*4882a593Smuzhiyun 
679*4882a593Smuzhiyun /* no spinlock */
apu_data_set(struct es1968 * chip,u16 data)680*4882a593Smuzhiyun static void apu_data_set(struct es1968 *chip, u16 data)
681*4882a593Smuzhiyun {
682*4882a593Smuzhiyun 	int i;
683*4882a593Smuzhiyun 	for (i = 0; i < 1000; i++) {
684*4882a593Smuzhiyun 		if (__maestro_read(chip, IDR0_DATA_PORT) == data)
685*4882a593Smuzhiyun 			return;
686*4882a593Smuzhiyun 		__maestro_write(chip, IDR0_DATA_PORT, data);
687*4882a593Smuzhiyun 	}
688*4882a593Smuzhiyun 	dev_dbg(chip->card->dev, "APU register set probably failed (Timeout)!\n");
689*4882a593Smuzhiyun }
690*4882a593Smuzhiyun 
691*4882a593Smuzhiyun /* no spinlock */
__apu_set_register(struct es1968 * chip,u16 channel,u8 reg,u16 data)692*4882a593Smuzhiyun static void __apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 data)
693*4882a593Smuzhiyun {
694*4882a593Smuzhiyun 	if (snd_BUG_ON(channel >= NR_APUS))
695*4882a593Smuzhiyun 		return;
696*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
697*4882a593Smuzhiyun 	chip->apu_map[channel][reg] = data;
698*4882a593Smuzhiyun #endif
699*4882a593Smuzhiyun 	reg |= (channel << 4);
700*4882a593Smuzhiyun 	apu_index_set(chip, reg);
701*4882a593Smuzhiyun 	apu_data_set(chip, data);
702*4882a593Smuzhiyun }
703*4882a593Smuzhiyun 
apu_set_register(struct es1968 * chip,u16 channel,u8 reg,u16 data)704*4882a593Smuzhiyun static void apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 data)
705*4882a593Smuzhiyun {
706*4882a593Smuzhiyun 	unsigned long flags;
707*4882a593Smuzhiyun 	spin_lock_irqsave(&chip->reg_lock, flags);
708*4882a593Smuzhiyun 	__apu_set_register(chip, channel, reg, data);
709*4882a593Smuzhiyun 	spin_unlock_irqrestore(&chip->reg_lock, flags);
710*4882a593Smuzhiyun }
711*4882a593Smuzhiyun 
__apu_get_register(struct es1968 * chip,u16 channel,u8 reg)712*4882a593Smuzhiyun static u16 __apu_get_register(struct es1968 *chip, u16 channel, u8 reg)
713*4882a593Smuzhiyun {
714*4882a593Smuzhiyun 	if (snd_BUG_ON(channel >= NR_APUS))
715*4882a593Smuzhiyun 		return 0;
716*4882a593Smuzhiyun 	reg |= (channel << 4);
717*4882a593Smuzhiyun 	apu_index_set(chip, reg);
718*4882a593Smuzhiyun 	return __maestro_read(chip, IDR0_DATA_PORT);
719*4882a593Smuzhiyun }
720*4882a593Smuzhiyun 
apu_get_register(struct es1968 * chip,u16 channel,u8 reg)721*4882a593Smuzhiyun static u16 apu_get_register(struct es1968 *chip, u16 channel, u8 reg)
722*4882a593Smuzhiyun {
723*4882a593Smuzhiyun 	unsigned long flags;
724*4882a593Smuzhiyun 	u16 v;
725*4882a593Smuzhiyun 	spin_lock_irqsave(&chip->reg_lock, flags);
726*4882a593Smuzhiyun 	v = __apu_get_register(chip, channel, reg);
727*4882a593Smuzhiyun 	spin_unlock_irqrestore(&chip->reg_lock, flags);
728*4882a593Smuzhiyun 	return v;
729*4882a593Smuzhiyun }
730*4882a593Smuzhiyun 
731*4882a593Smuzhiyun #if 0 /* ASSP is not supported */
732*4882a593Smuzhiyun 
733*4882a593Smuzhiyun static void assp_set_register(struct es1968 *chip, u32 reg, u32 value)
734*4882a593Smuzhiyun {
735*4882a593Smuzhiyun 	unsigned long flags;
736*4882a593Smuzhiyun 
737*4882a593Smuzhiyun 	spin_lock_irqsave(&chip->reg_lock, flags);
738*4882a593Smuzhiyun 	outl(reg, chip->io_port + ASSP_INDEX);
739*4882a593Smuzhiyun 	outl(value, chip->io_port + ASSP_DATA);
740*4882a593Smuzhiyun 	spin_unlock_irqrestore(&chip->reg_lock, flags);
741*4882a593Smuzhiyun }
742*4882a593Smuzhiyun 
743*4882a593Smuzhiyun static u32 assp_get_register(struct es1968 *chip, u32 reg)
744*4882a593Smuzhiyun {
745*4882a593Smuzhiyun 	unsigned long flags;
746*4882a593Smuzhiyun 	u32 value;
747*4882a593Smuzhiyun 
748*4882a593Smuzhiyun 	spin_lock_irqsave(&chip->reg_lock, flags);
749*4882a593Smuzhiyun 	outl(reg, chip->io_port + ASSP_INDEX);
750*4882a593Smuzhiyun 	value = inl(chip->io_port + ASSP_DATA);
751*4882a593Smuzhiyun 	spin_unlock_irqrestore(&chip->reg_lock, flags);
752*4882a593Smuzhiyun 
753*4882a593Smuzhiyun 	return value;
754*4882a593Smuzhiyun }
755*4882a593Smuzhiyun 
756*4882a593Smuzhiyun #endif
757*4882a593Smuzhiyun 
wave_set_register(struct es1968 * chip,u16 reg,u16 value)758*4882a593Smuzhiyun static void wave_set_register(struct es1968 *chip, u16 reg, u16 value)
759*4882a593Smuzhiyun {
760*4882a593Smuzhiyun 	unsigned long flags;
761*4882a593Smuzhiyun 
762*4882a593Smuzhiyun 	spin_lock_irqsave(&chip->reg_lock, flags);
763*4882a593Smuzhiyun 	outw(reg, chip->io_port + WC_INDEX);
764*4882a593Smuzhiyun 	outw(value, chip->io_port + WC_DATA);
765*4882a593Smuzhiyun 	spin_unlock_irqrestore(&chip->reg_lock, flags);
766*4882a593Smuzhiyun }
767*4882a593Smuzhiyun 
wave_get_register(struct es1968 * chip,u16 reg)768*4882a593Smuzhiyun static u16 wave_get_register(struct es1968 *chip, u16 reg)
769*4882a593Smuzhiyun {
770*4882a593Smuzhiyun 	unsigned long flags;
771*4882a593Smuzhiyun 	u16 value;
772*4882a593Smuzhiyun 
773*4882a593Smuzhiyun 	spin_lock_irqsave(&chip->reg_lock, flags);
774*4882a593Smuzhiyun 	outw(reg, chip->io_port + WC_INDEX);
775*4882a593Smuzhiyun 	value = inw(chip->io_port + WC_DATA);
776*4882a593Smuzhiyun 	spin_unlock_irqrestore(&chip->reg_lock, flags);
777*4882a593Smuzhiyun 
778*4882a593Smuzhiyun 	return value;
779*4882a593Smuzhiyun }
780*4882a593Smuzhiyun 
781*4882a593Smuzhiyun /* *******************
782*4882a593Smuzhiyun    * Bob the Timer!  *
783*4882a593Smuzhiyun    *******************/
784*4882a593Smuzhiyun 
snd_es1968_bob_stop(struct es1968 * chip)785*4882a593Smuzhiyun static void snd_es1968_bob_stop(struct es1968 *chip)
786*4882a593Smuzhiyun {
787*4882a593Smuzhiyun 	u16 reg;
788*4882a593Smuzhiyun 
789*4882a593Smuzhiyun 	reg = __maestro_read(chip, 0x11);
790*4882a593Smuzhiyun 	reg &= ~ESM_BOB_ENABLE;
791*4882a593Smuzhiyun 	__maestro_write(chip, 0x11, reg);
792*4882a593Smuzhiyun 	reg = __maestro_read(chip, 0x17);
793*4882a593Smuzhiyun 	reg &= ~ESM_BOB_START;
794*4882a593Smuzhiyun 	__maestro_write(chip, 0x17, reg);
795*4882a593Smuzhiyun }
796*4882a593Smuzhiyun 
snd_es1968_bob_start(struct es1968 * chip)797*4882a593Smuzhiyun static void snd_es1968_bob_start(struct es1968 *chip)
798*4882a593Smuzhiyun {
799*4882a593Smuzhiyun 	int prescale;
800*4882a593Smuzhiyun 	int divide;
801*4882a593Smuzhiyun 
802*4882a593Smuzhiyun 	/* compute ideal interrupt frequency for buffer size & play rate */
803*4882a593Smuzhiyun 	/* first, find best prescaler value to match freq */
804*4882a593Smuzhiyun 	for (prescale = 5; prescale < 12; prescale++)
805*4882a593Smuzhiyun 		if (chip->bob_freq > (ESS_SYSCLK >> (prescale + 9)))
806*4882a593Smuzhiyun 			break;
807*4882a593Smuzhiyun 
808*4882a593Smuzhiyun 	/* next, back off prescaler whilst getting divider into optimum range */
809*4882a593Smuzhiyun 	divide = 1;
810*4882a593Smuzhiyun 	while ((prescale > 5) && (divide < 32)) {
811*4882a593Smuzhiyun 		prescale--;
812*4882a593Smuzhiyun 		divide <<= 1;
813*4882a593Smuzhiyun 	}
814*4882a593Smuzhiyun 	divide >>= 1;
815*4882a593Smuzhiyun 
816*4882a593Smuzhiyun 	/* now fine-tune the divider for best match */
817*4882a593Smuzhiyun 	for (; divide < 31; divide++)
818*4882a593Smuzhiyun 		if (chip->bob_freq >
819*4882a593Smuzhiyun 		    ((ESS_SYSCLK >> (prescale + 9)) / (divide + 1))) break;
820*4882a593Smuzhiyun 
821*4882a593Smuzhiyun 	/* divide = 0 is illegal, but don't let prescale = 4! */
822*4882a593Smuzhiyun 	if (divide == 0) {
823*4882a593Smuzhiyun 		divide++;
824*4882a593Smuzhiyun 		if (prescale > 5)
825*4882a593Smuzhiyun 			prescale--;
826*4882a593Smuzhiyun 	} else if (divide > 1)
827*4882a593Smuzhiyun 		divide--;
828*4882a593Smuzhiyun 
829*4882a593Smuzhiyun 	__maestro_write(chip, 6, 0x9000 | (prescale << 5) | divide);	/* set reg */
830*4882a593Smuzhiyun 
831*4882a593Smuzhiyun 	/* Now set IDR 11/17 */
832*4882a593Smuzhiyun 	__maestro_write(chip, 0x11, __maestro_read(chip, 0x11) | 1);
833*4882a593Smuzhiyun 	__maestro_write(chip, 0x17, __maestro_read(chip, 0x17) | 1);
834*4882a593Smuzhiyun }
835*4882a593Smuzhiyun 
836*4882a593Smuzhiyun /* call with substream spinlock */
snd_es1968_bob_inc(struct es1968 * chip,int freq)837*4882a593Smuzhiyun static void snd_es1968_bob_inc(struct es1968 *chip, int freq)
838*4882a593Smuzhiyun {
839*4882a593Smuzhiyun 	chip->bobclient++;
840*4882a593Smuzhiyun 	if (chip->bobclient == 1) {
841*4882a593Smuzhiyun 		chip->bob_freq = freq;
842*4882a593Smuzhiyun 		snd_es1968_bob_start(chip);
843*4882a593Smuzhiyun 	} else if (chip->bob_freq < freq) {
844*4882a593Smuzhiyun 		snd_es1968_bob_stop(chip);
845*4882a593Smuzhiyun 		chip->bob_freq = freq;
846*4882a593Smuzhiyun 		snd_es1968_bob_start(chip);
847*4882a593Smuzhiyun 	}
848*4882a593Smuzhiyun }
849*4882a593Smuzhiyun 
850*4882a593Smuzhiyun /* call with substream spinlock */
snd_es1968_bob_dec(struct es1968 * chip)851*4882a593Smuzhiyun static void snd_es1968_bob_dec(struct es1968 *chip)
852*4882a593Smuzhiyun {
853*4882a593Smuzhiyun 	chip->bobclient--;
854*4882a593Smuzhiyun 	if (chip->bobclient <= 0)
855*4882a593Smuzhiyun 		snd_es1968_bob_stop(chip);
856*4882a593Smuzhiyun 	else if (chip->bob_freq > ESM_BOB_FREQ) {
857*4882a593Smuzhiyun 		/* check reduction of timer frequency */
858*4882a593Smuzhiyun 		int max_freq = ESM_BOB_FREQ;
859*4882a593Smuzhiyun 		struct esschan *es;
860*4882a593Smuzhiyun 		list_for_each_entry(es, &chip->substream_list, list) {
861*4882a593Smuzhiyun 			if (max_freq < es->bob_freq)
862*4882a593Smuzhiyun 				max_freq = es->bob_freq;
863*4882a593Smuzhiyun 		}
864*4882a593Smuzhiyun 		if (max_freq != chip->bob_freq) {
865*4882a593Smuzhiyun 			snd_es1968_bob_stop(chip);
866*4882a593Smuzhiyun 			chip->bob_freq = max_freq;
867*4882a593Smuzhiyun 			snd_es1968_bob_start(chip);
868*4882a593Smuzhiyun 		}
869*4882a593Smuzhiyun 	}
870*4882a593Smuzhiyun }
871*4882a593Smuzhiyun 
872*4882a593Smuzhiyun static int
snd_es1968_calc_bob_rate(struct es1968 * chip,struct esschan * es,struct snd_pcm_runtime * runtime)873*4882a593Smuzhiyun snd_es1968_calc_bob_rate(struct es1968 *chip, struct esschan *es,
874*4882a593Smuzhiyun 			 struct snd_pcm_runtime *runtime)
875*4882a593Smuzhiyun {
876*4882a593Smuzhiyun 	/* we acquire 4 interrupts per period for precise control.. */
877*4882a593Smuzhiyun 	int freq = runtime->rate * 4;
878*4882a593Smuzhiyun 	if (es->fmt & ESS_FMT_STEREO)
879*4882a593Smuzhiyun 		freq <<= 1;
880*4882a593Smuzhiyun 	if (es->fmt & ESS_FMT_16BIT)
881*4882a593Smuzhiyun 		freq <<= 1;
882*4882a593Smuzhiyun 	freq /= es->frag_size;
883*4882a593Smuzhiyun 	if (freq < ESM_BOB_FREQ)
884*4882a593Smuzhiyun 		freq = ESM_BOB_FREQ;
885*4882a593Smuzhiyun 	else if (freq > ESM_BOB_FREQ_MAX)
886*4882a593Smuzhiyun 		freq = ESM_BOB_FREQ_MAX;
887*4882a593Smuzhiyun 	return freq;
888*4882a593Smuzhiyun }
889*4882a593Smuzhiyun 
890*4882a593Smuzhiyun 
891*4882a593Smuzhiyun /*************
892*4882a593Smuzhiyun  *  PCM Part *
893*4882a593Smuzhiyun  *************/
894*4882a593Smuzhiyun 
snd_es1968_compute_rate(struct es1968 * chip,u32 freq)895*4882a593Smuzhiyun static u32 snd_es1968_compute_rate(struct es1968 *chip, u32 freq)
896*4882a593Smuzhiyun {
897*4882a593Smuzhiyun 	u32 rate = (freq << 16) / chip->clock;
898*4882a593Smuzhiyun #if 0 /* XXX: do we need this? */
899*4882a593Smuzhiyun 	if (rate > 0x10000)
900*4882a593Smuzhiyun 		rate = 0x10000;
901*4882a593Smuzhiyun #endif
902*4882a593Smuzhiyun 	return rate;
903*4882a593Smuzhiyun }
904*4882a593Smuzhiyun 
905*4882a593Smuzhiyun /* get current pointer */
906*4882a593Smuzhiyun static inline unsigned int
snd_es1968_get_dma_ptr(struct es1968 * chip,struct esschan * es)907*4882a593Smuzhiyun snd_es1968_get_dma_ptr(struct es1968 *chip, struct esschan *es)
908*4882a593Smuzhiyun {
909*4882a593Smuzhiyun 	unsigned int offset;
910*4882a593Smuzhiyun 
911*4882a593Smuzhiyun 	offset = apu_get_register(chip, es->apu[0], 5);
912*4882a593Smuzhiyun 
913*4882a593Smuzhiyun 	offset -= es->base[0];
914*4882a593Smuzhiyun 
915*4882a593Smuzhiyun 	return (offset & 0xFFFE);	/* hardware is in words */
916*4882a593Smuzhiyun }
917*4882a593Smuzhiyun 
snd_es1968_apu_set_freq(struct es1968 * chip,int apu,int freq)918*4882a593Smuzhiyun static void snd_es1968_apu_set_freq(struct es1968 *chip, int apu, int freq)
919*4882a593Smuzhiyun {
920*4882a593Smuzhiyun 	apu_set_register(chip, apu, 2,
921*4882a593Smuzhiyun 			   (apu_get_register(chip, apu, 2) & 0x00FF) |
922*4882a593Smuzhiyun 			   ((freq & 0xff) << 8) | 0x10);
923*4882a593Smuzhiyun 	apu_set_register(chip, apu, 3, freq >> 8);
924*4882a593Smuzhiyun }
925*4882a593Smuzhiyun 
926*4882a593Smuzhiyun /* spin lock held */
snd_es1968_trigger_apu(struct es1968 * esm,int apu,int mode)927*4882a593Smuzhiyun static inline void snd_es1968_trigger_apu(struct es1968 *esm, int apu, int mode)
928*4882a593Smuzhiyun {
929*4882a593Smuzhiyun 	/* set the APU mode */
930*4882a593Smuzhiyun 	__apu_set_register(esm, apu, 0,
931*4882a593Smuzhiyun 			   (__apu_get_register(esm, apu, 0) & 0xff0f) |
932*4882a593Smuzhiyun 			   (mode << 4));
933*4882a593Smuzhiyun }
934*4882a593Smuzhiyun 
snd_es1968_pcm_start(struct es1968 * chip,struct esschan * es)935*4882a593Smuzhiyun static void snd_es1968_pcm_start(struct es1968 *chip, struct esschan *es)
936*4882a593Smuzhiyun {
937*4882a593Smuzhiyun 	spin_lock(&chip->reg_lock);
938*4882a593Smuzhiyun 	__apu_set_register(chip, es->apu[0], 5, es->base[0]);
939*4882a593Smuzhiyun 	snd_es1968_trigger_apu(chip, es->apu[0], es->apu_mode[0]);
940*4882a593Smuzhiyun 	if (es->mode == ESM_MODE_CAPTURE) {
941*4882a593Smuzhiyun 		__apu_set_register(chip, es->apu[2], 5, es->base[2]);
942*4882a593Smuzhiyun 		snd_es1968_trigger_apu(chip, es->apu[2], es->apu_mode[2]);
943*4882a593Smuzhiyun 	}
944*4882a593Smuzhiyun 	if (es->fmt & ESS_FMT_STEREO) {
945*4882a593Smuzhiyun 		__apu_set_register(chip, es->apu[1], 5, es->base[1]);
946*4882a593Smuzhiyun 		snd_es1968_trigger_apu(chip, es->apu[1], es->apu_mode[1]);
947*4882a593Smuzhiyun 		if (es->mode == ESM_MODE_CAPTURE) {
948*4882a593Smuzhiyun 			__apu_set_register(chip, es->apu[3], 5, es->base[3]);
949*4882a593Smuzhiyun 			snd_es1968_trigger_apu(chip, es->apu[3], es->apu_mode[3]);
950*4882a593Smuzhiyun 		}
951*4882a593Smuzhiyun 	}
952*4882a593Smuzhiyun 	spin_unlock(&chip->reg_lock);
953*4882a593Smuzhiyun }
954*4882a593Smuzhiyun 
snd_es1968_pcm_stop(struct es1968 * chip,struct esschan * es)955*4882a593Smuzhiyun static void snd_es1968_pcm_stop(struct es1968 *chip, struct esschan *es)
956*4882a593Smuzhiyun {
957*4882a593Smuzhiyun 	spin_lock(&chip->reg_lock);
958*4882a593Smuzhiyun 	snd_es1968_trigger_apu(chip, es->apu[0], 0);
959*4882a593Smuzhiyun 	snd_es1968_trigger_apu(chip, es->apu[1], 0);
960*4882a593Smuzhiyun 	if (es->mode == ESM_MODE_CAPTURE) {
961*4882a593Smuzhiyun 		snd_es1968_trigger_apu(chip, es->apu[2], 0);
962*4882a593Smuzhiyun 		snd_es1968_trigger_apu(chip, es->apu[3], 0);
963*4882a593Smuzhiyun 	}
964*4882a593Smuzhiyun 	spin_unlock(&chip->reg_lock);
965*4882a593Smuzhiyun }
966*4882a593Smuzhiyun 
967*4882a593Smuzhiyun /* set the wavecache control reg */
snd_es1968_program_wavecache(struct es1968 * chip,struct esschan * es,int channel,u32 addr,int capture)968*4882a593Smuzhiyun static void snd_es1968_program_wavecache(struct es1968 *chip, struct esschan *es,
969*4882a593Smuzhiyun 					 int channel, u32 addr, int capture)
970*4882a593Smuzhiyun {
971*4882a593Smuzhiyun 	u32 tmpval = (addr - 0x10) & 0xFFF8;
972*4882a593Smuzhiyun 
973*4882a593Smuzhiyun 	if (! capture) {
974*4882a593Smuzhiyun 		if (!(es->fmt & ESS_FMT_16BIT))
975*4882a593Smuzhiyun 			tmpval |= 4;	/* 8bit */
976*4882a593Smuzhiyun 		if (es->fmt & ESS_FMT_STEREO)
977*4882a593Smuzhiyun 			tmpval |= 2;	/* stereo */
978*4882a593Smuzhiyun 	}
979*4882a593Smuzhiyun 
980*4882a593Smuzhiyun 	/* set the wavecache control reg */
981*4882a593Smuzhiyun 	wave_set_register(chip, es->apu[channel] << 3, tmpval);
982*4882a593Smuzhiyun 
983*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
984*4882a593Smuzhiyun 	es->wc_map[channel] = tmpval;
985*4882a593Smuzhiyun #endif
986*4882a593Smuzhiyun }
987*4882a593Smuzhiyun 
988*4882a593Smuzhiyun 
snd_es1968_playback_setup(struct es1968 * chip,struct esschan * es,struct snd_pcm_runtime * runtime)989*4882a593Smuzhiyun static void snd_es1968_playback_setup(struct es1968 *chip, struct esschan *es,
990*4882a593Smuzhiyun 				      struct snd_pcm_runtime *runtime)
991*4882a593Smuzhiyun {
992*4882a593Smuzhiyun 	u32 pa;
993*4882a593Smuzhiyun 	int high_apu = 0;
994*4882a593Smuzhiyun 	int channel, apu;
995*4882a593Smuzhiyun 	int i, size;
996*4882a593Smuzhiyun 	unsigned long flags;
997*4882a593Smuzhiyun 	u32 freq;
998*4882a593Smuzhiyun 
999*4882a593Smuzhiyun 	size = es->dma_size >> es->wav_shift;
1000*4882a593Smuzhiyun 
1001*4882a593Smuzhiyun 	if (es->fmt & ESS_FMT_STEREO)
1002*4882a593Smuzhiyun 		high_apu++;
1003*4882a593Smuzhiyun 
1004*4882a593Smuzhiyun 	for (channel = 0; channel <= high_apu; channel++) {
1005*4882a593Smuzhiyun 		apu = es->apu[channel];
1006*4882a593Smuzhiyun 
1007*4882a593Smuzhiyun 		snd_es1968_program_wavecache(chip, es, channel, es->memory->buf.addr, 0);
1008*4882a593Smuzhiyun 
1009*4882a593Smuzhiyun 		/* Offset to PCMBAR */
1010*4882a593Smuzhiyun 		pa = es->memory->buf.addr;
1011*4882a593Smuzhiyun 		pa -= chip->dma.addr;
1012*4882a593Smuzhiyun 		pa >>= 1;	/* words */
1013*4882a593Smuzhiyun 
1014*4882a593Smuzhiyun 		pa |= 0x00400000;	/* System RAM (Bit 22) */
1015*4882a593Smuzhiyun 
1016*4882a593Smuzhiyun 		if (es->fmt & ESS_FMT_STEREO) {
1017*4882a593Smuzhiyun 			/* Enable stereo */
1018*4882a593Smuzhiyun 			if (channel)
1019*4882a593Smuzhiyun 				pa |= 0x00800000;	/* (Bit 23) */
1020*4882a593Smuzhiyun 			if (es->fmt & ESS_FMT_16BIT)
1021*4882a593Smuzhiyun 				pa >>= 1;
1022*4882a593Smuzhiyun 		}
1023*4882a593Smuzhiyun 
1024*4882a593Smuzhiyun 		/* base offset of dma calcs when reading the pointer
1025*4882a593Smuzhiyun 		   on this left one */
1026*4882a593Smuzhiyun 		es->base[channel] = pa & 0xFFFF;
1027*4882a593Smuzhiyun 
1028*4882a593Smuzhiyun 		for (i = 0; i < 16; i++)
1029*4882a593Smuzhiyun 			apu_set_register(chip, apu, i, 0x0000);
1030*4882a593Smuzhiyun 
1031*4882a593Smuzhiyun 		/* Load the buffer into the wave engine */
1032*4882a593Smuzhiyun 		apu_set_register(chip, apu, 4, ((pa >> 16) & 0xFF) << 8);
1033*4882a593Smuzhiyun 		apu_set_register(chip, apu, 5, pa & 0xFFFF);
1034*4882a593Smuzhiyun 		apu_set_register(chip, apu, 6, (pa + size) & 0xFFFF);
1035*4882a593Smuzhiyun 		/* setting loop == sample len */
1036*4882a593Smuzhiyun 		apu_set_register(chip, apu, 7, size);
1037*4882a593Smuzhiyun 
1038*4882a593Smuzhiyun 		/* clear effects/env.. */
1039*4882a593Smuzhiyun 		apu_set_register(chip, apu, 8, 0x0000);
1040*4882a593Smuzhiyun 		/* set amp now to 0xd0 (?), low byte is 'amplitude dest'? */
1041*4882a593Smuzhiyun 		apu_set_register(chip, apu, 9, 0xD000);
1042*4882a593Smuzhiyun 
1043*4882a593Smuzhiyun 		/* clear routing stuff */
1044*4882a593Smuzhiyun 		apu_set_register(chip, apu, 11, 0x0000);
1045*4882a593Smuzhiyun 		/* dma on, no envelopes, filter to all 1s) */
1046*4882a593Smuzhiyun 		apu_set_register(chip, apu, 0, 0x400F);
1047*4882a593Smuzhiyun 
1048*4882a593Smuzhiyun 		if (es->fmt & ESS_FMT_16BIT)
1049*4882a593Smuzhiyun 			es->apu_mode[channel] = ESM_APU_16BITLINEAR;
1050*4882a593Smuzhiyun 		else
1051*4882a593Smuzhiyun 			es->apu_mode[channel] = ESM_APU_8BITLINEAR;
1052*4882a593Smuzhiyun 
1053*4882a593Smuzhiyun 		if (es->fmt & ESS_FMT_STEREO) {
1054*4882a593Smuzhiyun 			/* set panning: left or right */
1055*4882a593Smuzhiyun 			/* Check: different panning. On my Canyon 3D Chipset the
1056*4882a593Smuzhiyun 			   Channels are swapped. I don't know, about the output
1057*4882a593Smuzhiyun 			   to the SPDif Link. Perhaps you have to change this
1058*4882a593Smuzhiyun 			   and not the APU Regs 4-5. */
1059*4882a593Smuzhiyun 			apu_set_register(chip, apu, 10,
1060*4882a593Smuzhiyun 					 0x8F00 | (channel ? 0 : 0x10));
1061*4882a593Smuzhiyun 			es->apu_mode[channel] += 1;	/* stereo */
1062*4882a593Smuzhiyun 		} else
1063*4882a593Smuzhiyun 			apu_set_register(chip, apu, 10, 0x8F08);
1064*4882a593Smuzhiyun 	}
1065*4882a593Smuzhiyun 
1066*4882a593Smuzhiyun 	spin_lock_irqsave(&chip->reg_lock, flags);
1067*4882a593Smuzhiyun 	/* clear WP interrupts */
1068*4882a593Smuzhiyun 	outw(1, chip->io_port + 0x04);
1069*4882a593Smuzhiyun 	/* enable WP ints */
1070*4882a593Smuzhiyun 	outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ);
1071*4882a593Smuzhiyun 	spin_unlock_irqrestore(&chip->reg_lock, flags);
1072*4882a593Smuzhiyun 
1073*4882a593Smuzhiyun 	freq = runtime->rate;
1074*4882a593Smuzhiyun 	/* set frequency */
1075*4882a593Smuzhiyun 	if (freq > 48000)
1076*4882a593Smuzhiyun 		freq = 48000;
1077*4882a593Smuzhiyun 	if (freq < 4000)
1078*4882a593Smuzhiyun 		freq = 4000;
1079*4882a593Smuzhiyun 
1080*4882a593Smuzhiyun 	/* hmmm.. */
1081*4882a593Smuzhiyun 	if (!(es->fmt & ESS_FMT_16BIT) && !(es->fmt & ESS_FMT_STEREO))
1082*4882a593Smuzhiyun 		freq >>= 1;
1083*4882a593Smuzhiyun 
1084*4882a593Smuzhiyun 	freq = snd_es1968_compute_rate(chip, freq);
1085*4882a593Smuzhiyun 
1086*4882a593Smuzhiyun 	/* Load the frequency, turn on 6dB */
1087*4882a593Smuzhiyun 	snd_es1968_apu_set_freq(chip, es->apu[0], freq);
1088*4882a593Smuzhiyun 	snd_es1968_apu_set_freq(chip, es->apu[1], freq);
1089*4882a593Smuzhiyun }
1090*4882a593Smuzhiyun 
1091*4882a593Smuzhiyun 
init_capture_apu(struct es1968 * chip,struct esschan * es,int channel,unsigned int pa,unsigned int bsize,int mode,int route)1092*4882a593Smuzhiyun static void init_capture_apu(struct es1968 *chip, struct esschan *es, int channel,
1093*4882a593Smuzhiyun 			     unsigned int pa, unsigned int bsize,
1094*4882a593Smuzhiyun 			     int mode, int route)
1095*4882a593Smuzhiyun {
1096*4882a593Smuzhiyun 	int i, apu = es->apu[channel];
1097*4882a593Smuzhiyun 
1098*4882a593Smuzhiyun 	es->apu_mode[channel] = mode;
1099*4882a593Smuzhiyun 
1100*4882a593Smuzhiyun 	/* set the wavecache control reg */
1101*4882a593Smuzhiyun 	snd_es1968_program_wavecache(chip, es, channel, pa, 1);
1102*4882a593Smuzhiyun 
1103*4882a593Smuzhiyun 	/* Offset to PCMBAR */
1104*4882a593Smuzhiyun 	pa -= chip->dma.addr;
1105*4882a593Smuzhiyun 	pa >>= 1;	/* words */
1106*4882a593Smuzhiyun 
1107*4882a593Smuzhiyun 	/* base offset of dma calcs when reading the pointer
1108*4882a593Smuzhiyun 	   on this left one */
1109*4882a593Smuzhiyun 	es->base[channel] = pa & 0xFFFF;
1110*4882a593Smuzhiyun 	pa |= 0x00400000;	/* bit 22 -> System RAM */
1111*4882a593Smuzhiyun 
1112*4882a593Smuzhiyun 	/* Begin loading the APU */
1113*4882a593Smuzhiyun 	for (i = 0; i < 16; i++)
1114*4882a593Smuzhiyun 		apu_set_register(chip, apu, i, 0x0000);
1115*4882a593Smuzhiyun 
1116*4882a593Smuzhiyun 	/* need to enable subgroups.. and we should probably
1117*4882a593Smuzhiyun 	   have different groups for different /dev/dsps..  */
1118*4882a593Smuzhiyun 	apu_set_register(chip, apu, 2, 0x8);
1119*4882a593Smuzhiyun 
1120*4882a593Smuzhiyun 	/* Load the buffer into the wave engine */
1121*4882a593Smuzhiyun 	apu_set_register(chip, apu, 4, ((pa >> 16) & 0xFF) << 8);
1122*4882a593Smuzhiyun 	apu_set_register(chip, apu, 5, pa & 0xFFFF);
1123*4882a593Smuzhiyun 	apu_set_register(chip, apu, 6, (pa + bsize) & 0xFFFF);
1124*4882a593Smuzhiyun 	apu_set_register(chip, apu, 7, bsize);
1125*4882a593Smuzhiyun 	/* clear effects/env.. */
1126*4882a593Smuzhiyun 	apu_set_register(chip, apu, 8, 0x00F0);
1127*4882a593Smuzhiyun 	/* amplitude now?  sure.  why not.  */
1128*4882a593Smuzhiyun 	apu_set_register(chip, apu, 9, 0x0000);
1129*4882a593Smuzhiyun 	/* set filter tune, radius, polar pan */
1130*4882a593Smuzhiyun 	apu_set_register(chip, apu, 10, 0x8F08);
1131*4882a593Smuzhiyun 	/* route input */
1132*4882a593Smuzhiyun 	apu_set_register(chip, apu, 11, route);
1133*4882a593Smuzhiyun 	/* dma on, no envelopes, filter to all 1s) */
1134*4882a593Smuzhiyun 	apu_set_register(chip, apu, 0, 0x400F);
1135*4882a593Smuzhiyun }
1136*4882a593Smuzhiyun 
snd_es1968_capture_setup(struct es1968 * chip,struct esschan * es,struct snd_pcm_runtime * runtime)1137*4882a593Smuzhiyun static void snd_es1968_capture_setup(struct es1968 *chip, struct esschan *es,
1138*4882a593Smuzhiyun 				     struct snd_pcm_runtime *runtime)
1139*4882a593Smuzhiyun {
1140*4882a593Smuzhiyun 	int size;
1141*4882a593Smuzhiyun 	u32 freq;
1142*4882a593Smuzhiyun 	unsigned long flags;
1143*4882a593Smuzhiyun 
1144*4882a593Smuzhiyun 	size = es->dma_size >> es->wav_shift;
1145*4882a593Smuzhiyun 
1146*4882a593Smuzhiyun 	/* APU assignments:
1147*4882a593Smuzhiyun 	   0 = mono/left SRC
1148*4882a593Smuzhiyun 	   1 = right SRC
1149*4882a593Smuzhiyun 	   2 = mono/left Input Mixer
1150*4882a593Smuzhiyun 	   3 = right Input Mixer
1151*4882a593Smuzhiyun 	*/
1152*4882a593Smuzhiyun 	/* data seems to flow from the codec, through an apu into
1153*4882a593Smuzhiyun 	   the 'mixbuf' bit of page, then through the SRC apu
1154*4882a593Smuzhiyun 	   and out to the real 'buffer'.  ok.  sure.  */
1155*4882a593Smuzhiyun 
1156*4882a593Smuzhiyun 	/* input mixer (left/mono) */
1157*4882a593Smuzhiyun 	/* parallel in crap, see maestro reg 0xC [8-11] */
1158*4882a593Smuzhiyun 	init_capture_apu(chip, es, 2,
1159*4882a593Smuzhiyun 			 es->mixbuf->buf.addr, ESM_MIXBUF_SIZE/4, /* in words */
1160*4882a593Smuzhiyun 			 ESM_APU_INPUTMIXER, 0x14);
1161*4882a593Smuzhiyun 	/* SRC (left/mono); get input from inputing apu */
1162*4882a593Smuzhiyun 	init_capture_apu(chip, es, 0, es->memory->buf.addr, size,
1163*4882a593Smuzhiyun 			 ESM_APU_SRCONVERTOR, es->apu[2]);
1164*4882a593Smuzhiyun 	if (es->fmt & ESS_FMT_STEREO) {
1165*4882a593Smuzhiyun 		/* input mixer (right) */
1166*4882a593Smuzhiyun 		init_capture_apu(chip, es, 3,
1167*4882a593Smuzhiyun 				 es->mixbuf->buf.addr + ESM_MIXBUF_SIZE/2,
1168*4882a593Smuzhiyun 				 ESM_MIXBUF_SIZE/4, /* in words */
1169*4882a593Smuzhiyun 				 ESM_APU_INPUTMIXER, 0x15);
1170*4882a593Smuzhiyun 		/* SRC (right) */
1171*4882a593Smuzhiyun 		init_capture_apu(chip, es, 1,
1172*4882a593Smuzhiyun 				 es->memory->buf.addr + size*2, size,
1173*4882a593Smuzhiyun 				 ESM_APU_SRCONVERTOR, es->apu[3]);
1174*4882a593Smuzhiyun 	}
1175*4882a593Smuzhiyun 
1176*4882a593Smuzhiyun 	freq = runtime->rate;
1177*4882a593Smuzhiyun 	/* Sample Rate conversion APUs don't like 0x10000 for their rate */
1178*4882a593Smuzhiyun 	if (freq > 47999)
1179*4882a593Smuzhiyun 		freq = 47999;
1180*4882a593Smuzhiyun 	if (freq < 4000)
1181*4882a593Smuzhiyun 		freq = 4000;
1182*4882a593Smuzhiyun 
1183*4882a593Smuzhiyun 	freq = snd_es1968_compute_rate(chip, freq);
1184*4882a593Smuzhiyun 
1185*4882a593Smuzhiyun 	/* Load the frequency, turn on 6dB */
1186*4882a593Smuzhiyun 	snd_es1968_apu_set_freq(chip, es->apu[0], freq);
1187*4882a593Smuzhiyun 	snd_es1968_apu_set_freq(chip, es->apu[1], freq);
1188*4882a593Smuzhiyun 
1189*4882a593Smuzhiyun 	/* fix mixer rate at 48khz.  and its _must_ be 0x10000. */
1190*4882a593Smuzhiyun 	freq = 0x10000;
1191*4882a593Smuzhiyun 	snd_es1968_apu_set_freq(chip, es->apu[2], freq);
1192*4882a593Smuzhiyun 	snd_es1968_apu_set_freq(chip, es->apu[3], freq);
1193*4882a593Smuzhiyun 
1194*4882a593Smuzhiyun 	spin_lock_irqsave(&chip->reg_lock, flags);
1195*4882a593Smuzhiyun 	/* clear WP interrupts */
1196*4882a593Smuzhiyun 	outw(1, chip->io_port + 0x04);
1197*4882a593Smuzhiyun 	/* enable WP ints */
1198*4882a593Smuzhiyun 	outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ);
1199*4882a593Smuzhiyun 	spin_unlock_irqrestore(&chip->reg_lock, flags);
1200*4882a593Smuzhiyun }
1201*4882a593Smuzhiyun 
1202*4882a593Smuzhiyun /*******************
1203*4882a593Smuzhiyun  *  ALSA Interface *
1204*4882a593Smuzhiyun  *******************/
1205*4882a593Smuzhiyun 
snd_es1968_pcm_prepare(struct snd_pcm_substream * substream)1206*4882a593Smuzhiyun static int snd_es1968_pcm_prepare(struct snd_pcm_substream *substream)
1207*4882a593Smuzhiyun {
1208*4882a593Smuzhiyun 	struct es1968 *chip = snd_pcm_substream_chip(substream);
1209*4882a593Smuzhiyun 	struct snd_pcm_runtime *runtime = substream->runtime;
1210*4882a593Smuzhiyun 	struct esschan *es = runtime->private_data;
1211*4882a593Smuzhiyun 
1212*4882a593Smuzhiyun 	es->dma_size = snd_pcm_lib_buffer_bytes(substream);
1213*4882a593Smuzhiyun 	es->frag_size = snd_pcm_lib_period_bytes(substream);
1214*4882a593Smuzhiyun 
1215*4882a593Smuzhiyun 	es->wav_shift = 1; /* maestro handles always 16bit */
1216*4882a593Smuzhiyun 	es->fmt = 0;
1217*4882a593Smuzhiyun 	if (snd_pcm_format_width(runtime->format) == 16)
1218*4882a593Smuzhiyun 		es->fmt |= ESS_FMT_16BIT;
1219*4882a593Smuzhiyun 	if (runtime->channels > 1) {
1220*4882a593Smuzhiyun 		es->fmt |= ESS_FMT_STEREO;
1221*4882a593Smuzhiyun 		if (es->fmt & ESS_FMT_16BIT) /* 8bit is already word shifted */
1222*4882a593Smuzhiyun 			es->wav_shift++;
1223*4882a593Smuzhiyun 	}
1224*4882a593Smuzhiyun 	es->bob_freq = snd_es1968_calc_bob_rate(chip, es, runtime);
1225*4882a593Smuzhiyun 
1226*4882a593Smuzhiyun 	switch (es->mode) {
1227*4882a593Smuzhiyun 	case ESM_MODE_PLAY:
1228*4882a593Smuzhiyun 		snd_es1968_playback_setup(chip, es, runtime);
1229*4882a593Smuzhiyun 		break;
1230*4882a593Smuzhiyun 	case ESM_MODE_CAPTURE:
1231*4882a593Smuzhiyun 		snd_es1968_capture_setup(chip, es, runtime);
1232*4882a593Smuzhiyun 		break;
1233*4882a593Smuzhiyun 	}
1234*4882a593Smuzhiyun 
1235*4882a593Smuzhiyun 	return 0;
1236*4882a593Smuzhiyun }
1237*4882a593Smuzhiyun 
snd_es1968_pcm_trigger(struct snd_pcm_substream * substream,int cmd)1238*4882a593Smuzhiyun static int snd_es1968_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1239*4882a593Smuzhiyun {
1240*4882a593Smuzhiyun 	struct es1968 *chip = snd_pcm_substream_chip(substream);
1241*4882a593Smuzhiyun 	struct esschan *es = substream->runtime->private_data;
1242*4882a593Smuzhiyun 
1243*4882a593Smuzhiyun 	spin_lock(&chip->substream_lock);
1244*4882a593Smuzhiyun 	switch (cmd) {
1245*4882a593Smuzhiyun 	case SNDRV_PCM_TRIGGER_START:
1246*4882a593Smuzhiyun 	case SNDRV_PCM_TRIGGER_RESUME:
1247*4882a593Smuzhiyun 		if (es->running)
1248*4882a593Smuzhiyun 			break;
1249*4882a593Smuzhiyun 		snd_es1968_bob_inc(chip, es->bob_freq);
1250*4882a593Smuzhiyun 		es->count = 0;
1251*4882a593Smuzhiyun 		es->hwptr = 0;
1252*4882a593Smuzhiyun 		snd_es1968_pcm_start(chip, es);
1253*4882a593Smuzhiyun 		es->running = 1;
1254*4882a593Smuzhiyun 		break;
1255*4882a593Smuzhiyun 	case SNDRV_PCM_TRIGGER_STOP:
1256*4882a593Smuzhiyun 	case SNDRV_PCM_TRIGGER_SUSPEND:
1257*4882a593Smuzhiyun 		if (! es->running)
1258*4882a593Smuzhiyun 			break;
1259*4882a593Smuzhiyun 		snd_es1968_pcm_stop(chip, es);
1260*4882a593Smuzhiyun 		es->running = 0;
1261*4882a593Smuzhiyun 		snd_es1968_bob_dec(chip);
1262*4882a593Smuzhiyun 		break;
1263*4882a593Smuzhiyun 	}
1264*4882a593Smuzhiyun 	spin_unlock(&chip->substream_lock);
1265*4882a593Smuzhiyun 	return 0;
1266*4882a593Smuzhiyun }
1267*4882a593Smuzhiyun 
snd_es1968_pcm_pointer(struct snd_pcm_substream * substream)1268*4882a593Smuzhiyun static snd_pcm_uframes_t snd_es1968_pcm_pointer(struct snd_pcm_substream *substream)
1269*4882a593Smuzhiyun {
1270*4882a593Smuzhiyun 	struct es1968 *chip = snd_pcm_substream_chip(substream);
1271*4882a593Smuzhiyun 	struct esschan *es = substream->runtime->private_data;
1272*4882a593Smuzhiyun 	unsigned int ptr;
1273*4882a593Smuzhiyun 
1274*4882a593Smuzhiyun 	ptr = snd_es1968_get_dma_ptr(chip, es) << es->wav_shift;
1275*4882a593Smuzhiyun 
1276*4882a593Smuzhiyun 	return bytes_to_frames(substream->runtime, ptr % es->dma_size);
1277*4882a593Smuzhiyun }
1278*4882a593Smuzhiyun 
1279*4882a593Smuzhiyun static const struct snd_pcm_hardware snd_es1968_playback = {
1280*4882a593Smuzhiyun 	.info =			(SNDRV_PCM_INFO_MMAP |
1281*4882a593Smuzhiyun                		         SNDRV_PCM_INFO_MMAP_VALID |
1282*4882a593Smuzhiyun 				 SNDRV_PCM_INFO_INTERLEAVED |
1283*4882a593Smuzhiyun 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1284*4882a593Smuzhiyun 				 /*SNDRV_PCM_INFO_PAUSE |*/
1285*4882a593Smuzhiyun 				 SNDRV_PCM_INFO_RESUME),
1286*4882a593Smuzhiyun 	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
1287*4882a593Smuzhiyun 	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1288*4882a593Smuzhiyun 	.rate_min =		4000,
1289*4882a593Smuzhiyun 	.rate_max =		48000,
1290*4882a593Smuzhiyun 	.channels_min =		1,
1291*4882a593Smuzhiyun 	.channels_max =		2,
1292*4882a593Smuzhiyun 	.buffer_bytes_max =	65536,
1293*4882a593Smuzhiyun 	.period_bytes_min =	256,
1294*4882a593Smuzhiyun 	.period_bytes_max =	65536,
1295*4882a593Smuzhiyun 	.periods_min =		1,
1296*4882a593Smuzhiyun 	.periods_max =		1024,
1297*4882a593Smuzhiyun 	.fifo_size =		0,
1298*4882a593Smuzhiyun };
1299*4882a593Smuzhiyun 
1300*4882a593Smuzhiyun static const struct snd_pcm_hardware snd_es1968_capture = {
1301*4882a593Smuzhiyun 	.info =			(SNDRV_PCM_INFO_NONINTERLEAVED |
1302*4882a593Smuzhiyun 				 SNDRV_PCM_INFO_MMAP |
1303*4882a593Smuzhiyun 				 SNDRV_PCM_INFO_MMAP_VALID |
1304*4882a593Smuzhiyun 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1305*4882a593Smuzhiyun 				 /*SNDRV_PCM_INFO_PAUSE |*/
1306*4882a593Smuzhiyun 				 SNDRV_PCM_INFO_RESUME),
1307*4882a593Smuzhiyun 	.formats =		/*SNDRV_PCM_FMTBIT_U8 |*/ SNDRV_PCM_FMTBIT_S16_LE,
1308*4882a593Smuzhiyun 	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1309*4882a593Smuzhiyun 	.rate_min =		4000,
1310*4882a593Smuzhiyun 	.rate_max =		48000,
1311*4882a593Smuzhiyun 	.channels_min =		1,
1312*4882a593Smuzhiyun 	.channels_max =		2,
1313*4882a593Smuzhiyun 	.buffer_bytes_max =	65536,
1314*4882a593Smuzhiyun 	.period_bytes_min =	256,
1315*4882a593Smuzhiyun 	.period_bytes_max =	65536,
1316*4882a593Smuzhiyun 	.periods_min =		1,
1317*4882a593Smuzhiyun 	.periods_max =		1024,
1318*4882a593Smuzhiyun 	.fifo_size =		0,
1319*4882a593Smuzhiyun };
1320*4882a593Smuzhiyun 
1321*4882a593Smuzhiyun /* *************************
1322*4882a593Smuzhiyun    * DMA memory management *
1323*4882a593Smuzhiyun    *************************/
1324*4882a593Smuzhiyun 
1325*4882a593Smuzhiyun /* Because the Maestro can only take addresses relative to the PCM base address
1326*4882a593Smuzhiyun    register :( */
1327*4882a593Smuzhiyun 
calc_available_memory_size(struct es1968 * chip)1328*4882a593Smuzhiyun static int calc_available_memory_size(struct es1968 *chip)
1329*4882a593Smuzhiyun {
1330*4882a593Smuzhiyun 	int max_size = 0;
1331*4882a593Smuzhiyun 	struct esm_memory *buf;
1332*4882a593Smuzhiyun 
1333*4882a593Smuzhiyun 	mutex_lock(&chip->memory_mutex);
1334*4882a593Smuzhiyun 	list_for_each_entry(buf, &chip->buf_list, list) {
1335*4882a593Smuzhiyun 		if (buf->empty && buf->buf.bytes > max_size)
1336*4882a593Smuzhiyun 			max_size = buf->buf.bytes;
1337*4882a593Smuzhiyun 	}
1338*4882a593Smuzhiyun 	mutex_unlock(&chip->memory_mutex);
1339*4882a593Smuzhiyun 	if (max_size >= 128*1024)
1340*4882a593Smuzhiyun 		max_size = 127*1024;
1341*4882a593Smuzhiyun 	return max_size;
1342*4882a593Smuzhiyun }
1343*4882a593Smuzhiyun 
1344*4882a593Smuzhiyun /* allocate a new memory chunk with the specified size */
snd_es1968_new_memory(struct es1968 * chip,int size)1345*4882a593Smuzhiyun static struct esm_memory *snd_es1968_new_memory(struct es1968 *chip, int size)
1346*4882a593Smuzhiyun {
1347*4882a593Smuzhiyun 	struct esm_memory *buf;
1348*4882a593Smuzhiyun 
1349*4882a593Smuzhiyun 	size = ALIGN(size, ESM_MEM_ALIGN);
1350*4882a593Smuzhiyun 	mutex_lock(&chip->memory_mutex);
1351*4882a593Smuzhiyun 	list_for_each_entry(buf, &chip->buf_list, list) {
1352*4882a593Smuzhiyun 		if (buf->empty && buf->buf.bytes >= size)
1353*4882a593Smuzhiyun 			goto __found;
1354*4882a593Smuzhiyun 	}
1355*4882a593Smuzhiyun 	mutex_unlock(&chip->memory_mutex);
1356*4882a593Smuzhiyun 	return NULL;
1357*4882a593Smuzhiyun 
1358*4882a593Smuzhiyun __found:
1359*4882a593Smuzhiyun 	if (buf->buf.bytes > size) {
1360*4882a593Smuzhiyun 		struct esm_memory *chunk = kmalloc(sizeof(*chunk), GFP_KERNEL);
1361*4882a593Smuzhiyun 		if (chunk == NULL) {
1362*4882a593Smuzhiyun 			mutex_unlock(&chip->memory_mutex);
1363*4882a593Smuzhiyun 			return NULL;
1364*4882a593Smuzhiyun 		}
1365*4882a593Smuzhiyun 		chunk->buf = buf->buf;
1366*4882a593Smuzhiyun 		chunk->buf.bytes -= size;
1367*4882a593Smuzhiyun 		chunk->buf.area += size;
1368*4882a593Smuzhiyun 		chunk->buf.addr += size;
1369*4882a593Smuzhiyun 		chunk->empty = 1;
1370*4882a593Smuzhiyun 		buf->buf.bytes = size;
1371*4882a593Smuzhiyun 		list_add(&chunk->list, &buf->list);
1372*4882a593Smuzhiyun 	}
1373*4882a593Smuzhiyun 	buf->empty = 0;
1374*4882a593Smuzhiyun 	mutex_unlock(&chip->memory_mutex);
1375*4882a593Smuzhiyun 	return buf;
1376*4882a593Smuzhiyun }
1377*4882a593Smuzhiyun 
1378*4882a593Smuzhiyun /* free a memory chunk */
snd_es1968_free_memory(struct es1968 * chip,struct esm_memory * buf)1379*4882a593Smuzhiyun static void snd_es1968_free_memory(struct es1968 *chip, struct esm_memory *buf)
1380*4882a593Smuzhiyun {
1381*4882a593Smuzhiyun 	struct esm_memory *chunk;
1382*4882a593Smuzhiyun 
1383*4882a593Smuzhiyun 	mutex_lock(&chip->memory_mutex);
1384*4882a593Smuzhiyun 	buf->empty = 1;
1385*4882a593Smuzhiyun 	if (buf->list.prev != &chip->buf_list) {
1386*4882a593Smuzhiyun 		chunk = list_entry(buf->list.prev, struct esm_memory, list);
1387*4882a593Smuzhiyun 		if (chunk->empty) {
1388*4882a593Smuzhiyun 			chunk->buf.bytes += buf->buf.bytes;
1389*4882a593Smuzhiyun 			list_del(&buf->list);
1390*4882a593Smuzhiyun 			kfree(buf);
1391*4882a593Smuzhiyun 			buf = chunk;
1392*4882a593Smuzhiyun 		}
1393*4882a593Smuzhiyun 	}
1394*4882a593Smuzhiyun 	if (buf->list.next != &chip->buf_list) {
1395*4882a593Smuzhiyun 		chunk = list_entry(buf->list.next, struct esm_memory, list);
1396*4882a593Smuzhiyun 		if (chunk->empty) {
1397*4882a593Smuzhiyun 			buf->buf.bytes += chunk->buf.bytes;
1398*4882a593Smuzhiyun 			list_del(&chunk->list);
1399*4882a593Smuzhiyun 			kfree(chunk);
1400*4882a593Smuzhiyun 		}
1401*4882a593Smuzhiyun 	}
1402*4882a593Smuzhiyun 	mutex_unlock(&chip->memory_mutex);
1403*4882a593Smuzhiyun }
1404*4882a593Smuzhiyun 
snd_es1968_free_dmabuf(struct es1968 * chip)1405*4882a593Smuzhiyun static void snd_es1968_free_dmabuf(struct es1968 *chip)
1406*4882a593Smuzhiyun {
1407*4882a593Smuzhiyun 	struct list_head *p;
1408*4882a593Smuzhiyun 
1409*4882a593Smuzhiyun 	if (! chip->dma.area)
1410*4882a593Smuzhiyun 		return;
1411*4882a593Smuzhiyun 	snd_dma_free_pages(&chip->dma);
1412*4882a593Smuzhiyun 	while ((p = chip->buf_list.next) != &chip->buf_list) {
1413*4882a593Smuzhiyun 		struct esm_memory *chunk = list_entry(p, struct esm_memory, list);
1414*4882a593Smuzhiyun 		list_del(p);
1415*4882a593Smuzhiyun 		kfree(chunk);
1416*4882a593Smuzhiyun 	}
1417*4882a593Smuzhiyun }
1418*4882a593Smuzhiyun 
1419*4882a593Smuzhiyun static int
snd_es1968_init_dmabuf(struct es1968 * chip)1420*4882a593Smuzhiyun snd_es1968_init_dmabuf(struct es1968 *chip)
1421*4882a593Smuzhiyun {
1422*4882a593Smuzhiyun 	int err;
1423*4882a593Smuzhiyun 	struct esm_memory *chunk;
1424*4882a593Smuzhiyun 
1425*4882a593Smuzhiyun 	err = snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV,
1426*4882a593Smuzhiyun 					   &chip->pci->dev,
1427*4882a593Smuzhiyun 					   chip->total_bufsize, &chip->dma);
1428*4882a593Smuzhiyun 	if (err < 0 || ! chip->dma.area) {
1429*4882a593Smuzhiyun 		dev_err(chip->card->dev,
1430*4882a593Smuzhiyun 			"can't allocate dma pages for size %d\n",
1431*4882a593Smuzhiyun 			   chip->total_bufsize);
1432*4882a593Smuzhiyun 		return -ENOMEM;
1433*4882a593Smuzhiyun 	}
1434*4882a593Smuzhiyun 	if ((chip->dma.addr + chip->dma.bytes - 1) & ~((1 << 28) - 1)) {
1435*4882a593Smuzhiyun 		snd_dma_free_pages(&chip->dma);
1436*4882a593Smuzhiyun 		dev_err(chip->card->dev, "DMA buffer beyond 256MB.\n");
1437*4882a593Smuzhiyun 		return -ENOMEM;
1438*4882a593Smuzhiyun 	}
1439*4882a593Smuzhiyun 
1440*4882a593Smuzhiyun 	INIT_LIST_HEAD(&chip->buf_list);
1441*4882a593Smuzhiyun 	/* allocate an empty chunk */
1442*4882a593Smuzhiyun 	chunk = kmalloc(sizeof(*chunk), GFP_KERNEL);
1443*4882a593Smuzhiyun 	if (chunk == NULL) {
1444*4882a593Smuzhiyun 		snd_es1968_free_dmabuf(chip);
1445*4882a593Smuzhiyun 		return -ENOMEM;
1446*4882a593Smuzhiyun 	}
1447*4882a593Smuzhiyun 	memset(chip->dma.area, 0, ESM_MEM_ALIGN);
1448*4882a593Smuzhiyun 	chunk->buf = chip->dma;
1449*4882a593Smuzhiyun 	chunk->buf.area += ESM_MEM_ALIGN;
1450*4882a593Smuzhiyun 	chunk->buf.addr += ESM_MEM_ALIGN;
1451*4882a593Smuzhiyun 	chunk->buf.bytes -= ESM_MEM_ALIGN;
1452*4882a593Smuzhiyun 	chunk->empty = 1;
1453*4882a593Smuzhiyun 	list_add(&chunk->list, &chip->buf_list);
1454*4882a593Smuzhiyun 
1455*4882a593Smuzhiyun 	return 0;
1456*4882a593Smuzhiyun }
1457*4882a593Smuzhiyun 
1458*4882a593Smuzhiyun /* setup the dma_areas */
1459*4882a593Smuzhiyun /* buffer is extracted from the pre-allocated memory chunk */
snd_es1968_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * hw_params)1460*4882a593Smuzhiyun static int snd_es1968_hw_params(struct snd_pcm_substream *substream,
1461*4882a593Smuzhiyun 				struct snd_pcm_hw_params *hw_params)
1462*4882a593Smuzhiyun {
1463*4882a593Smuzhiyun 	struct es1968 *chip = snd_pcm_substream_chip(substream);
1464*4882a593Smuzhiyun 	struct snd_pcm_runtime *runtime = substream->runtime;
1465*4882a593Smuzhiyun 	struct esschan *chan = runtime->private_data;
1466*4882a593Smuzhiyun 	int size = params_buffer_bytes(hw_params);
1467*4882a593Smuzhiyun 
1468*4882a593Smuzhiyun 	if (chan->memory) {
1469*4882a593Smuzhiyun 		if (chan->memory->buf.bytes >= size) {
1470*4882a593Smuzhiyun 			runtime->dma_bytes = size;
1471*4882a593Smuzhiyun 			return 0;
1472*4882a593Smuzhiyun 		}
1473*4882a593Smuzhiyun 		snd_es1968_free_memory(chip, chan->memory);
1474*4882a593Smuzhiyun 	}
1475*4882a593Smuzhiyun 	chan->memory = snd_es1968_new_memory(chip, size);
1476*4882a593Smuzhiyun 	if (chan->memory == NULL) {
1477*4882a593Smuzhiyun 		dev_dbg(chip->card->dev,
1478*4882a593Smuzhiyun 			"cannot allocate dma buffer: size = %d\n", size);
1479*4882a593Smuzhiyun 		return -ENOMEM;
1480*4882a593Smuzhiyun 	}
1481*4882a593Smuzhiyun 	snd_pcm_set_runtime_buffer(substream, &chan->memory->buf);
1482*4882a593Smuzhiyun 	return 1; /* area was changed */
1483*4882a593Smuzhiyun }
1484*4882a593Smuzhiyun 
1485*4882a593Smuzhiyun /* remove dma areas if allocated */
snd_es1968_hw_free(struct snd_pcm_substream * substream)1486*4882a593Smuzhiyun static int snd_es1968_hw_free(struct snd_pcm_substream *substream)
1487*4882a593Smuzhiyun {
1488*4882a593Smuzhiyun 	struct es1968 *chip = snd_pcm_substream_chip(substream);
1489*4882a593Smuzhiyun 	struct snd_pcm_runtime *runtime = substream->runtime;
1490*4882a593Smuzhiyun 	struct esschan *chan;
1491*4882a593Smuzhiyun 
1492*4882a593Smuzhiyun 	if (runtime->private_data == NULL)
1493*4882a593Smuzhiyun 		return 0;
1494*4882a593Smuzhiyun 	chan = runtime->private_data;
1495*4882a593Smuzhiyun 	if (chan->memory) {
1496*4882a593Smuzhiyun 		snd_es1968_free_memory(chip, chan->memory);
1497*4882a593Smuzhiyun 		chan->memory = NULL;
1498*4882a593Smuzhiyun 	}
1499*4882a593Smuzhiyun 	return 0;
1500*4882a593Smuzhiyun }
1501*4882a593Smuzhiyun 
1502*4882a593Smuzhiyun 
1503*4882a593Smuzhiyun /*
1504*4882a593Smuzhiyun  * allocate APU pair
1505*4882a593Smuzhiyun  */
snd_es1968_alloc_apu_pair(struct es1968 * chip,int type)1506*4882a593Smuzhiyun static int snd_es1968_alloc_apu_pair(struct es1968 *chip, int type)
1507*4882a593Smuzhiyun {
1508*4882a593Smuzhiyun 	int apu;
1509*4882a593Smuzhiyun 
1510*4882a593Smuzhiyun 	for (apu = 0; apu < NR_APUS; apu += 2) {
1511*4882a593Smuzhiyun 		if (chip->apu[apu] == ESM_APU_FREE &&
1512*4882a593Smuzhiyun 		    chip->apu[apu + 1] == ESM_APU_FREE) {
1513*4882a593Smuzhiyun 			chip->apu[apu] = chip->apu[apu + 1] = type;
1514*4882a593Smuzhiyun 			return apu;
1515*4882a593Smuzhiyun 		}
1516*4882a593Smuzhiyun 	}
1517*4882a593Smuzhiyun 	return -EBUSY;
1518*4882a593Smuzhiyun }
1519*4882a593Smuzhiyun 
1520*4882a593Smuzhiyun /*
1521*4882a593Smuzhiyun  * release APU pair
1522*4882a593Smuzhiyun  */
snd_es1968_free_apu_pair(struct es1968 * chip,int apu)1523*4882a593Smuzhiyun static void snd_es1968_free_apu_pair(struct es1968 *chip, int apu)
1524*4882a593Smuzhiyun {
1525*4882a593Smuzhiyun 	chip->apu[apu] = chip->apu[apu + 1] = ESM_APU_FREE;
1526*4882a593Smuzhiyun }
1527*4882a593Smuzhiyun 
1528*4882a593Smuzhiyun 
1529*4882a593Smuzhiyun /******************
1530*4882a593Smuzhiyun  * PCM open/close *
1531*4882a593Smuzhiyun  ******************/
1532*4882a593Smuzhiyun 
snd_es1968_playback_open(struct snd_pcm_substream * substream)1533*4882a593Smuzhiyun static int snd_es1968_playback_open(struct snd_pcm_substream *substream)
1534*4882a593Smuzhiyun {
1535*4882a593Smuzhiyun 	struct es1968 *chip = snd_pcm_substream_chip(substream);
1536*4882a593Smuzhiyun 	struct snd_pcm_runtime *runtime = substream->runtime;
1537*4882a593Smuzhiyun 	struct esschan *es;
1538*4882a593Smuzhiyun 	int apu1;
1539*4882a593Smuzhiyun 
1540*4882a593Smuzhiyun 	/* search 2 APUs */
1541*4882a593Smuzhiyun 	apu1 = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_PLAY);
1542*4882a593Smuzhiyun 	if (apu1 < 0)
1543*4882a593Smuzhiyun 		return apu1;
1544*4882a593Smuzhiyun 
1545*4882a593Smuzhiyun 	es = kzalloc(sizeof(*es), GFP_KERNEL);
1546*4882a593Smuzhiyun 	if (!es) {
1547*4882a593Smuzhiyun 		snd_es1968_free_apu_pair(chip, apu1);
1548*4882a593Smuzhiyun 		return -ENOMEM;
1549*4882a593Smuzhiyun 	}
1550*4882a593Smuzhiyun 
1551*4882a593Smuzhiyun 	es->apu[0] = apu1;
1552*4882a593Smuzhiyun 	es->apu[1] = apu1 + 1;
1553*4882a593Smuzhiyun 	es->apu_mode[0] = 0;
1554*4882a593Smuzhiyun 	es->apu_mode[1] = 0;
1555*4882a593Smuzhiyun 	es->running = 0;
1556*4882a593Smuzhiyun 	es->substream = substream;
1557*4882a593Smuzhiyun 	es->mode = ESM_MODE_PLAY;
1558*4882a593Smuzhiyun 
1559*4882a593Smuzhiyun 	runtime->private_data = es;
1560*4882a593Smuzhiyun 	runtime->hw = snd_es1968_playback;
1561*4882a593Smuzhiyun 	runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max =
1562*4882a593Smuzhiyun 		calc_available_memory_size(chip);
1563*4882a593Smuzhiyun 
1564*4882a593Smuzhiyun 	spin_lock_irq(&chip->substream_lock);
1565*4882a593Smuzhiyun 	list_add(&es->list, &chip->substream_list);
1566*4882a593Smuzhiyun 	spin_unlock_irq(&chip->substream_lock);
1567*4882a593Smuzhiyun 
1568*4882a593Smuzhiyun 	return 0;
1569*4882a593Smuzhiyun }
1570*4882a593Smuzhiyun 
snd_es1968_capture_open(struct snd_pcm_substream * substream)1571*4882a593Smuzhiyun static int snd_es1968_capture_open(struct snd_pcm_substream *substream)
1572*4882a593Smuzhiyun {
1573*4882a593Smuzhiyun 	struct snd_pcm_runtime *runtime = substream->runtime;
1574*4882a593Smuzhiyun 	struct es1968 *chip = snd_pcm_substream_chip(substream);
1575*4882a593Smuzhiyun 	struct esschan *es;
1576*4882a593Smuzhiyun 	int apu1, apu2;
1577*4882a593Smuzhiyun 
1578*4882a593Smuzhiyun 	apu1 = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_CAPTURE);
1579*4882a593Smuzhiyun 	if (apu1 < 0)
1580*4882a593Smuzhiyun 		return apu1;
1581*4882a593Smuzhiyun 	apu2 = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_RATECONV);
1582*4882a593Smuzhiyun 	if (apu2 < 0) {
1583*4882a593Smuzhiyun 		snd_es1968_free_apu_pair(chip, apu1);
1584*4882a593Smuzhiyun 		return apu2;
1585*4882a593Smuzhiyun 	}
1586*4882a593Smuzhiyun 
1587*4882a593Smuzhiyun 	es = kzalloc(sizeof(*es), GFP_KERNEL);
1588*4882a593Smuzhiyun 	if (!es) {
1589*4882a593Smuzhiyun 		snd_es1968_free_apu_pair(chip, apu1);
1590*4882a593Smuzhiyun 		snd_es1968_free_apu_pair(chip, apu2);
1591*4882a593Smuzhiyun 		return -ENOMEM;
1592*4882a593Smuzhiyun 	}
1593*4882a593Smuzhiyun 
1594*4882a593Smuzhiyun 	es->apu[0] = apu1;
1595*4882a593Smuzhiyun 	es->apu[1] = apu1 + 1;
1596*4882a593Smuzhiyun 	es->apu[2] = apu2;
1597*4882a593Smuzhiyun 	es->apu[3] = apu2 + 1;
1598*4882a593Smuzhiyun 	es->apu_mode[0] = 0;
1599*4882a593Smuzhiyun 	es->apu_mode[1] = 0;
1600*4882a593Smuzhiyun 	es->apu_mode[2] = 0;
1601*4882a593Smuzhiyun 	es->apu_mode[3] = 0;
1602*4882a593Smuzhiyun 	es->running = 0;
1603*4882a593Smuzhiyun 	es->substream = substream;
1604*4882a593Smuzhiyun 	es->mode = ESM_MODE_CAPTURE;
1605*4882a593Smuzhiyun 
1606*4882a593Smuzhiyun 	/* get mixbuffer */
1607*4882a593Smuzhiyun 	if ((es->mixbuf = snd_es1968_new_memory(chip, ESM_MIXBUF_SIZE)) == NULL) {
1608*4882a593Smuzhiyun 		snd_es1968_free_apu_pair(chip, apu1);
1609*4882a593Smuzhiyun 		snd_es1968_free_apu_pair(chip, apu2);
1610*4882a593Smuzhiyun 		kfree(es);
1611*4882a593Smuzhiyun                 return -ENOMEM;
1612*4882a593Smuzhiyun         }
1613*4882a593Smuzhiyun 	memset(es->mixbuf->buf.area, 0, ESM_MIXBUF_SIZE);
1614*4882a593Smuzhiyun 
1615*4882a593Smuzhiyun 	runtime->private_data = es;
1616*4882a593Smuzhiyun 	runtime->hw = snd_es1968_capture;
1617*4882a593Smuzhiyun 	runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max =
1618*4882a593Smuzhiyun 		calc_available_memory_size(chip) - 1024; /* keep MIXBUF size */
1619*4882a593Smuzhiyun 	snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
1620*4882a593Smuzhiyun 
1621*4882a593Smuzhiyun 	spin_lock_irq(&chip->substream_lock);
1622*4882a593Smuzhiyun 	list_add(&es->list, &chip->substream_list);
1623*4882a593Smuzhiyun 	spin_unlock_irq(&chip->substream_lock);
1624*4882a593Smuzhiyun 
1625*4882a593Smuzhiyun 	return 0;
1626*4882a593Smuzhiyun }
1627*4882a593Smuzhiyun 
snd_es1968_playback_close(struct snd_pcm_substream * substream)1628*4882a593Smuzhiyun static int snd_es1968_playback_close(struct snd_pcm_substream *substream)
1629*4882a593Smuzhiyun {
1630*4882a593Smuzhiyun 	struct es1968 *chip = snd_pcm_substream_chip(substream);
1631*4882a593Smuzhiyun 	struct esschan *es;
1632*4882a593Smuzhiyun 
1633*4882a593Smuzhiyun 	if (substream->runtime->private_data == NULL)
1634*4882a593Smuzhiyun 		return 0;
1635*4882a593Smuzhiyun 	es = substream->runtime->private_data;
1636*4882a593Smuzhiyun 	spin_lock_irq(&chip->substream_lock);
1637*4882a593Smuzhiyun 	list_del(&es->list);
1638*4882a593Smuzhiyun 	spin_unlock_irq(&chip->substream_lock);
1639*4882a593Smuzhiyun 	snd_es1968_free_apu_pair(chip, es->apu[0]);
1640*4882a593Smuzhiyun 	kfree(es);
1641*4882a593Smuzhiyun 
1642*4882a593Smuzhiyun 	return 0;
1643*4882a593Smuzhiyun }
1644*4882a593Smuzhiyun 
snd_es1968_capture_close(struct snd_pcm_substream * substream)1645*4882a593Smuzhiyun static int snd_es1968_capture_close(struct snd_pcm_substream *substream)
1646*4882a593Smuzhiyun {
1647*4882a593Smuzhiyun 	struct es1968 *chip = snd_pcm_substream_chip(substream);
1648*4882a593Smuzhiyun 	struct esschan *es;
1649*4882a593Smuzhiyun 
1650*4882a593Smuzhiyun 	if (substream->runtime->private_data == NULL)
1651*4882a593Smuzhiyun 		return 0;
1652*4882a593Smuzhiyun 	es = substream->runtime->private_data;
1653*4882a593Smuzhiyun 	spin_lock_irq(&chip->substream_lock);
1654*4882a593Smuzhiyun 	list_del(&es->list);
1655*4882a593Smuzhiyun 	spin_unlock_irq(&chip->substream_lock);
1656*4882a593Smuzhiyun 	snd_es1968_free_memory(chip, es->mixbuf);
1657*4882a593Smuzhiyun 	snd_es1968_free_apu_pair(chip, es->apu[0]);
1658*4882a593Smuzhiyun 	snd_es1968_free_apu_pair(chip, es->apu[2]);
1659*4882a593Smuzhiyun 	kfree(es);
1660*4882a593Smuzhiyun 
1661*4882a593Smuzhiyun 	return 0;
1662*4882a593Smuzhiyun }
1663*4882a593Smuzhiyun 
1664*4882a593Smuzhiyun static const struct snd_pcm_ops snd_es1968_playback_ops = {
1665*4882a593Smuzhiyun 	.open =		snd_es1968_playback_open,
1666*4882a593Smuzhiyun 	.close =	snd_es1968_playback_close,
1667*4882a593Smuzhiyun 	.hw_params =	snd_es1968_hw_params,
1668*4882a593Smuzhiyun 	.hw_free =	snd_es1968_hw_free,
1669*4882a593Smuzhiyun 	.prepare =	snd_es1968_pcm_prepare,
1670*4882a593Smuzhiyun 	.trigger =	snd_es1968_pcm_trigger,
1671*4882a593Smuzhiyun 	.pointer =	snd_es1968_pcm_pointer,
1672*4882a593Smuzhiyun };
1673*4882a593Smuzhiyun 
1674*4882a593Smuzhiyun static const struct snd_pcm_ops snd_es1968_capture_ops = {
1675*4882a593Smuzhiyun 	.open =		snd_es1968_capture_open,
1676*4882a593Smuzhiyun 	.close =	snd_es1968_capture_close,
1677*4882a593Smuzhiyun 	.hw_params =	snd_es1968_hw_params,
1678*4882a593Smuzhiyun 	.hw_free =	snd_es1968_hw_free,
1679*4882a593Smuzhiyun 	.prepare =	snd_es1968_pcm_prepare,
1680*4882a593Smuzhiyun 	.trigger =	snd_es1968_pcm_trigger,
1681*4882a593Smuzhiyun 	.pointer =	snd_es1968_pcm_pointer,
1682*4882a593Smuzhiyun };
1683*4882a593Smuzhiyun 
1684*4882a593Smuzhiyun 
1685*4882a593Smuzhiyun /*
1686*4882a593Smuzhiyun  * measure clock
1687*4882a593Smuzhiyun  */
1688*4882a593Smuzhiyun #define CLOCK_MEASURE_BUFSIZE	16768	/* enough large for a single shot */
1689*4882a593Smuzhiyun 
es1968_measure_clock(struct es1968 * chip)1690*4882a593Smuzhiyun static void es1968_measure_clock(struct es1968 *chip)
1691*4882a593Smuzhiyun {
1692*4882a593Smuzhiyun 	int i, apu;
1693*4882a593Smuzhiyun 	unsigned int pa, offset, t;
1694*4882a593Smuzhiyun 	struct esm_memory *memory;
1695*4882a593Smuzhiyun 	ktime_t start_time, stop_time;
1696*4882a593Smuzhiyun 	ktime_t diff;
1697*4882a593Smuzhiyun 
1698*4882a593Smuzhiyun 	if (chip->clock == 0)
1699*4882a593Smuzhiyun 		chip->clock = 48000; /* default clock value */
1700*4882a593Smuzhiyun 
1701*4882a593Smuzhiyun 	/* search 2 APUs (although one apu is enough) */
1702*4882a593Smuzhiyun 	if ((apu = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_PLAY)) < 0) {
1703*4882a593Smuzhiyun 		dev_err(chip->card->dev, "Hmm, cannot find empty APU pair!?\n");
1704*4882a593Smuzhiyun 		return;
1705*4882a593Smuzhiyun 	}
1706*4882a593Smuzhiyun 	if ((memory = snd_es1968_new_memory(chip, CLOCK_MEASURE_BUFSIZE)) == NULL) {
1707*4882a593Smuzhiyun 		dev_warn(chip->card->dev,
1708*4882a593Smuzhiyun 			 "cannot allocate dma buffer - using default clock %d\n",
1709*4882a593Smuzhiyun 			 chip->clock);
1710*4882a593Smuzhiyun 		snd_es1968_free_apu_pair(chip, apu);
1711*4882a593Smuzhiyun 		return;
1712*4882a593Smuzhiyun 	}
1713*4882a593Smuzhiyun 
1714*4882a593Smuzhiyun 	memset(memory->buf.area, 0, CLOCK_MEASURE_BUFSIZE);
1715*4882a593Smuzhiyun 
1716*4882a593Smuzhiyun 	wave_set_register(chip, apu << 3, (memory->buf.addr - 0x10) & 0xfff8);
1717*4882a593Smuzhiyun 
1718*4882a593Smuzhiyun 	pa = (unsigned int)((memory->buf.addr - chip->dma.addr) >> 1);
1719*4882a593Smuzhiyun 	pa |= 0x00400000;	/* System RAM (Bit 22) */
1720*4882a593Smuzhiyun 
1721*4882a593Smuzhiyun 	/* initialize apu */
1722*4882a593Smuzhiyun 	for (i = 0; i < 16; i++)
1723*4882a593Smuzhiyun 		apu_set_register(chip, apu, i, 0x0000);
1724*4882a593Smuzhiyun 
1725*4882a593Smuzhiyun 	apu_set_register(chip, apu, 0, 0x400f);
1726*4882a593Smuzhiyun 	apu_set_register(chip, apu, 4, ((pa >> 16) & 0xff) << 8);
1727*4882a593Smuzhiyun 	apu_set_register(chip, apu, 5, pa & 0xffff);
1728*4882a593Smuzhiyun 	apu_set_register(chip, apu, 6, (pa + CLOCK_MEASURE_BUFSIZE/2) & 0xffff);
1729*4882a593Smuzhiyun 	apu_set_register(chip, apu, 7, CLOCK_MEASURE_BUFSIZE/2);
1730*4882a593Smuzhiyun 	apu_set_register(chip, apu, 8, 0x0000);
1731*4882a593Smuzhiyun 	apu_set_register(chip, apu, 9, 0xD000);
1732*4882a593Smuzhiyun 	apu_set_register(chip, apu, 10, 0x8F08);
1733*4882a593Smuzhiyun 	apu_set_register(chip, apu, 11, 0x0000);
1734*4882a593Smuzhiyun 	spin_lock_irq(&chip->reg_lock);
1735*4882a593Smuzhiyun 	outw(1, chip->io_port + 0x04); /* clear WP interrupts */
1736*4882a593Smuzhiyun 	outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ); /* enable WP ints */
1737*4882a593Smuzhiyun 	spin_unlock_irq(&chip->reg_lock);
1738*4882a593Smuzhiyun 
1739*4882a593Smuzhiyun 	snd_es1968_apu_set_freq(chip, apu, ((unsigned int)48000 << 16) / chip->clock); /* 48000 Hz */
1740*4882a593Smuzhiyun 
1741*4882a593Smuzhiyun 	chip->in_measurement = 1;
1742*4882a593Smuzhiyun 	chip->measure_apu = apu;
1743*4882a593Smuzhiyun 	spin_lock_irq(&chip->reg_lock);
1744*4882a593Smuzhiyun 	snd_es1968_bob_inc(chip, ESM_BOB_FREQ);
1745*4882a593Smuzhiyun 	__apu_set_register(chip, apu, 5, pa & 0xffff);
1746*4882a593Smuzhiyun 	snd_es1968_trigger_apu(chip, apu, ESM_APU_16BITLINEAR);
1747*4882a593Smuzhiyun 	start_time = ktime_get();
1748*4882a593Smuzhiyun 	spin_unlock_irq(&chip->reg_lock);
1749*4882a593Smuzhiyun 	msleep(50);
1750*4882a593Smuzhiyun 	spin_lock_irq(&chip->reg_lock);
1751*4882a593Smuzhiyun 	offset = __apu_get_register(chip, apu, 5);
1752*4882a593Smuzhiyun 	stop_time = ktime_get();
1753*4882a593Smuzhiyun 	snd_es1968_trigger_apu(chip, apu, 0); /* stop */
1754*4882a593Smuzhiyun 	snd_es1968_bob_dec(chip);
1755*4882a593Smuzhiyun 	chip->in_measurement = 0;
1756*4882a593Smuzhiyun 	spin_unlock_irq(&chip->reg_lock);
1757*4882a593Smuzhiyun 
1758*4882a593Smuzhiyun 	/* check the current position */
1759*4882a593Smuzhiyun 	offset -= (pa & 0xffff);
1760*4882a593Smuzhiyun 	offset &= 0xfffe;
1761*4882a593Smuzhiyun 	offset += chip->measure_count * (CLOCK_MEASURE_BUFSIZE/2);
1762*4882a593Smuzhiyun 
1763*4882a593Smuzhiyun 	diff = ktime_sub(stop_time, start_time);
1764*4882a593Smuzhiyun 	t = ktime_to_us(diff);
1765*4882a593Smuzhiyun 	if (t == 0) {
1766*4882a593Smuzhiyun 		dev_err(chip->card->dev, "?? calculation error..\n");
1767*4882a593Smuzhiyun 	} else {
1768*4882a593Smuzhiyun 		offset *= 1000;
1769*4882a593Smuzhiyun 		offset = (offset / t) * 1000 + ((offset % t) * 1000) / t;
1770*4882a593Smuzhiyun 		if (offset < 47500 || offset > 48500) {
1771*4882a593Smuzhiyun 			if (offset >= 40000 && offset <= 50000)
1772*4882a593Smuzhiyun 				chip->clock = (chip->clock * offset) / 48000;
1773*4882a593Smuzhiyun 		}
1774*4882a593Smuzhiyun 		dev_info(chip->card->dev, "clocking to %d\n", chip->clock);
1775*4882a593Smuzhiyun 	}
1776*4882a593Smuzhiyun 	snd_es1968_free_memory(chip, memory);
1777*4882a593Smuzhiyun 	snd_es1968_free_apu_pair(chip, apu);
1778*4882a593Smuzhiyun }
1779*4882a593Smuzhiyun 
1780*4882a593Smuzhiyun 
1781*4882a593Smuzhiyun /*
1782*4882a593Smuzhiyun  */
1783*4882a593Smuzhiyun 
snd_es1968_pcm_free(struct snd_pcm * pcm)1784*4882a593Smuzhiyun static void snd_es1968_pcm_free(struct snd_pcm *pcm)
1785*4882a593Smuzhiyun {
1786*4882a593Smuzhiyun 	struct es1968 *esm = pcm->private_data;
1787*4882a593Smuzhiyun 	snd_es1968_free_dmabuf(esm);
1788*4882a593Smuzhiyun 	esm->pcm = NULL;
1789*4882a593Smuzhiyun }
1790*4882a593Smuzhiyun 
1791*4882a593Smuzhiyun static int
snd_es1968_pcm(struct es1968 * chip,int device)1792*4882a593Smuzhiyun snd_es1968_pcm(struct es1968 *chip, int device)
1793*4882a593Smuzhiyun {
1794*4882a593Smuzhiyun 	struct snd_pcm *pcm;
1795*4882a593Smuzhiyun 	int err;
1796*4882a593Smuzhiyun 
1797*4882a593Smuzhiyun 	/* get DMA buffer */
1798*4882a593Smuzhiyun 	if ((err = snd_es1968_init_dmabuf(chip)) < 0)
1799*4882a593Smuzhiyun 		return err;
1800*4882a593Smuzhiyun 
1801*4882a593Smuzhiyun 	/* set PCMBAR */
1802*4882a593Smuzhiyun 	wave_set_register(chip, 0x01FC, chip->dma.addr >> 12);
1803*4882a593Smuzhiyun 	wave_set_register(chip, 0x01FD, chip->dma.addr >> 12);
1804*4882a593Smuzhiyun 	wave_set_register(chip, 0x01FE, chip->dma.addr >> 12);
1805*4882a593Smuzhiyun 	wave_set_register(chip, 0x01FF, chip->dma.addr >> 12);
1806*4882a593Smuzhiyun 
1807*4882a593Smuzhiyun 	if ((err = snd_pcm_new(chip->card, "ESS Maestro", device,
1808*4882a593Smuzhiyun 			       chip->playback_streams,
1809*4882a593Smuzhiyun 			       chip->capture_streams, &pcm)) < 0)
1810*4882a593Smuzhiyun 		return err;
1811*4882a593Smuzhiyun 
1812*4882a593Smuzhiyun 	pcm->private_data = chip;
1813*4882a593Smuzhiyun 	pcm->private_free = snd_es1968_pcm_free;
1814*4882a593Smuzhiyun 
1815*4882a593Smuzhiyun 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_es1968_playback_ops);
1816*4882a593Smuzhiyun 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_es1968_capture_ops);
1817*4882a593Smuzhiyun 
1818*4882a593Smuzhiyun 	pcm->info_flags = 0;
1819*4882a593Smuzhiyun 
1820*4882a593Smuzhiyun 	strcpy(pcm->name, "ESS Maestro");
1821*4882a593Smuzhiyun 
1822*4882a593Smuzhiyun 	chip->pcm = pcm;
1823*4882a593Smuzhiyun 
1824*4882a593Smuzhiyun 	return 0;
1825*4882a593Smuzhiyun }
1826*4882a593Smuzhiyun /*
1827*4882a593Smuzhiyun  * suppress jitter on some maestros when playing stereo
1828*4882a593Smuzhiyun  */
snd_es1968_suppress_jitter(struct es1968 * chip,struct esschan * es)1829*4882a593Smuzhiyun static void snd_es1968_suppress_jitter(struct es1968 *chip, struct esschan *es)
1830*4882a593Smuzhiyun {
1831*4882a593Smuzhiyun 	unsigned int cp1;
1832*4882a593Smuzhiyun 	unsigned int cp2;
1833*4882a593Smuzhiyun 	unsigned int diff;
1834*4882a593Smuzhiyun 
1835*4882a593Smuzhiyun 	cp1 = __apu_get_register(chip, 0, 5);
1836*4882a593Smuzhiyun 	cp2 = __apu_get_register(chip, 1, 5);
1837*4882a593Smuzhiyun 	diff = (cp1 > cp2 ? cp1 - cp2 : cp2 - cp1);
1838*4882a593Smuzhiyun 
1839*4882a593Smuzhiyun 	if (diff > 1)
1840*4882a593Smuzhiyun 		__maestro_write(chip, IDR0_DATA_PORT, cp1);
1841*4882a593Smuzhiyun }
1842*4882a593Smuzhiyun 
1843*4882a593Smuzhiyun /*
1844*4882a593Smuzhiyun  * update pointer
1845*4882a593Smuzhiyun  */
snd_es1968_update_pcm(struct es1968 * chip,struct esschan * es)1846*4882a593Smuzhiyun static void snd_es1968_update_pcm(struct es1968 *chip, struct esschan *es)
1847*4882a593Smuzhiyun {
1848*4882a593Smuzhiyun 	unsigned int hwptr;
1849*4882a593Smuzhiyun 	unsigned int diff;
1850*4882a593Smuzhiyun 	struct snd_pcm_substream *subs = es->substream;
1851*4882a593Smuzhiyun 
1852*4882a593Smuzhiyun 	if (subs == NULL || !es->running)
1853*4882a593Smuzhiyun 		return;
1854*4882a593Smuzhiyun 
1855*4882a593Smuzhiyun 	hwptr = snd_es1968_get_dma_ptr(chip, es) << es->wav_shift;
1856*4882a593Smuzhiyun 	hwptr %= es->dma_size;
1857*4882a593Smuzhiyun 
1858*4882a593Smuzhiyun 	diff = (es->dma_size + hwptr - es->hwptr) % es->dma_size;
1859*4882a593Smuzhiyun 
1860*4882a593Smuzhiyun 	es->hwptr = hwptr;
1861*4882a593Smuzhiyun 	es->count += diff;
1862*4882a593Smuzhiyun 
1863*4882a593Smuzhiyun 	if (es->count > es->frag_size) {
1864*4882a593Smuzhiyun 		spin_unlock(&chip->substream_lock);
1865*4882a593Smuzhiyun 		snd_pcm_period_elapsed(subs);
1866*4882a593Smuzhiyun 		spin_lock(&chip->substream_lock);
1867*4882a593Smuzhiyun 		es->count %= es->frag_size;
1868*4882a593Smuzhiyun 	}
1869*4882a593Smuzhiyun }
1870*4882a593Smuzhiyun 
1871*4882a593Smuzhiyun /* The hardware volume works by incrementing / decrementing 2 counters
1872*4882a593Smuzhiyun    (without wrap around) in response to volume button presses and then
1873*4882a593Smuzhiyun    generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7
1874*4882a593Smuzhiyun    of a byte wide register. The meaning of bits 0 and 4 is unknown. */
es1968_update_hw_volume(struct work_struct * work)1875*4882a593Smuzhiyun static void es1968_update_hw_volume(struct work_struct *work)
1876*4882a593Smuzhiyun {
1877*4882a593Smuzhiyun 	struct es1968 *chip = container_of(work, struct es1968, hwvol_work);
1878*4882a593Smuzhiyun 	int x, val;
1879*4882a593Smuzhiyun 
1880*4882a593Smuzhiyun 	/* Figure out which volume control button was pushed,
1881*4882a593Smuzhiyun 	   based on differences from the default register
1882*4882a593Smuzhiyun 	   values. */
1883*4882a593Smuzhiyun 	x = inb(chip->io_port + 0x1c) & 0xee;
1884*4882a593Smuzhiyun 	/* Reset the volume control registers. */
1885*4882a593Smuzhiyun 	outb(0x88, chip->io_port + 0x1c);
1886*4882a593Smuzhiyun 	outb(0x88, chip->io_port + 0x1d);
1887*4882a593Smuzhiyun 	outb(0x88, chip->io_port + 0x1e);
1888*4882a593Smuzhiyun 	outb(0x88, chip->io_port + 0x1f);
1889*4882a593Smuzhiyun 
1890*4882a593Smuzhiyun 	if (chip->in_suspend)
1891*4882a593Smuzhiyun 		return;
1892*4882a593Smuzhiyun 
1893*4882a593Smuzhiyun #ifndef CONFIG_SND_ES1968_INPUT
1894*4882a593Smuzhiyun 	if (! chip->master_switch || ! chip->master_volume)
1895*4882a593Smuzhiyun 		return;
1896*4882a593Smuzhiyun 
1897*4882a593Smuzhiyun 	val = snd_ac97_read(chip->ac97, AC97_MASTER);
1898*4882a593Smuzhiyun 	switch (x) {
1899*4882a593Smuzhiyun 	case 0x88:
1900*4882a593Smuzhiyun 		/* mute */
1901*4882a593Smuzhiyun 		val ^= 0x8000;
1902*4882a593Smuzhiyun 		break;
1903*4882a593Smuzhiyun 	case 0xaa:
1904*4882a593Smuzhiyun 		/* volume up */
1905*4882a593Smuzhiyun 		if ((val & 0x7f) > 0)
1906*4882a593Smuzhiyun 			val--;
1907*4882a593Smuzhiyun 		if ((val & 0x7f00) > 0)
1908*4882a593Smuzhiyun 			val -= 0x0100;
1909*4882a593Smuzhiyun 		break;
1910*4882a593Smuzhiyun 	case 0x66:
1911*4882a593Smuzhiyun 		/* volume down */
1912*4882a593Smuzhiyun 		if ((val & 0x7f) < 0x1f)
1913*4882a593Smuzhiyun 			val++;
1914*4882a593Smuzhiyun 		if ((val & 0x7f00) < 0x1f00)
1915*4882a593Smuzhiyun 			val += 0x0100;
1916*4882a593Smuzhiyun 		break;
1917*4882a593Smuzhiyun 	}
1918*4882a593Smuzhiyun 	if (snd_ac97_update(chip->ac97, AC97_MASTER, val))
1919*4882a593Smuzhiyun 		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
1920*4882a593Smuzhiyun 			       &chip->master_volume->id);
1921*4882a593Smuzhiyun #else
1922*4882a593Smuzhiyun 	if (!chip->input_dev)
1923*4882a593Smuzhiyun 		return;
1924*4882a593Smuzhiyun 
1925*4882a593Smuzhiyun 	val = 0;
1926*4882a593Smuzhiyun 	switch (x) {
1927*4882a593Smuzhiyun 	case 0x88:
1928*4882a593Smuzhiyun 		/* The counters have not changed, yet we've received a HV
1929*4882a593Smuzhiyun 		   interrupt. According to tests run by various people this
1930*4882a593Smuzhiyun 		   happens when pressing the mute button. */
1931*4882a593Smuzhiyun 		val = KEY_MUTE;
1932*4882a593Smuzhiyun 		break;
1933*4882a593Smuzhiyun 	case 0xaa:
1934*4882a593Smuzhiyun 		/* counters increased by 1 -> volume up */
1935*4882a593Smuzhiyun 		val = KEY_VOLUMEUP;
1936*4882a593Smuzhiyun 		break;
1937*4882a593Smuzhiyun 	case 0x66:
1938*4882a593Smuzhiyun 		/* counters decreased by 1 -> volume down */
1939*4882a593Smuzhiyun 		val = KEY_VOLUMEDOWN;
1940*4882a593Smuzhiyun 		break;
1941*4882a593Smuzhiyun 	}
1942*4882a593Smuzhiyun 
1943*4882a593Smuzhiyun 	if (val) {
1944*4882a593Smuzhiyun 		input_report_key(chip->input_dev, val, 1);
1945*4882a593Smuzhiyun 		input_sync(chip->input_dev);
1946*4882a593Smuzhiyun 		input_report_key(chip->input_dev, val, 0);
1947*4882a593Smuzhiyun 		input_sync(chip->input_dev);
1948*4882a593Smuzhiyun 	}
1949*4882a593Smuzhiyun #endif
1950*4882a593Smuzhiyun }
1951*4882a593Smuzhiyun 
1952*4882a593Smuzhiyun /*
1953*4882a593Smuzhiyun  * interrupt handler
1954*4882a593Smuzhiyun  */
snd_es1968_interrupt(int irq,void * dev_id)1955*4882a593Smuzhiyun static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id)
1956*4882a593Smuzhiyun {
1957*4882a593Smuzhiyun 	struct es1968 *chip = dev_id;
1958*4882a593Smuzhiyun 	u32 event;
1959*4882a593Smuzhiyun 
1960*4882a593Smuzhiyun 	if (!(event = inb(chip->io_port + 0x1A)))
1961*4882a593Smuzhiyun 		return IRQ_NONE;
1962*4882a593Smuzhiyun 
1963*4882a593Smuzhiyun 	outw(inw(chip->io_port + 4) & 1, chip->io_port + 4);
1964*4882a593Smuzhiyun 
1965*4882a593Smuzhiyun 	if (event & ESM_HWVOL_IRQ)
1966*4882a593Smuzhiyun 		schedule_work(&chip->hwvol_work);
1967*4882a593Smuzhiyun 
1968*4882a593Smuzhiyun 	/* else ack 'em all, i imagine */
1969*4882a593Smuzhiyun 	outb(0xFF, chip->io_port + 0x1A);
1970*4882a593Smuzhiyun 
1971*4882a593Smuzhiyun 	if ((event & ESM_MPU401_IRQ) && chip->rmidi) {
1972*4882a593Smuzhiyun 		snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
1973*4882a593Smuzhiyun 	}
1974*4882a593Smuzhiyun 
1975*4882a593Smuzhiyun 	if (event & ESM_SOUND_IRQ) {
1976*4882a593Smuzhiyun 		struct esschan *es;
1977*4882a593Smuzhiyun 		spin_lock(&chip->substream_lock);
1978*4882a593Smuzhiyun 		list_for_each_entry(es, &chip->substream_list, list) {
1979*4882a593Smuzhiyun 			if (es->running) {
1980*4882a593Smuzhiyun 				snd_es1968_update_pcm(chip, es);
1981*4882a593Smuzhiyun 				if (es->fmt & ESS_FMT_STEREO)
1982*4882a593Smuzhiyun 					snd_es1968_suppress_jitter(chip, es);
1983*4882a593Smuzhiyun 			}
1984*4882a593Smuzhiyun 		}
1985*4882a593Smuzhiyun 		spin_unlock(&chip->substream_lock);
1986*4882a593Smuzhiyun 		if (chip->in_measurement) {
1987*4882a593Smuzhiyun 			unsigned int curp = __apu_get_register(chip, chip->measure_apu, 5);
1988*4882a593Smuzhiyun 			if (curp < chip->measure_lastpos)
1989*4882a593Smuzhiyun 				chip->measure_count++;
1990*4882a593Smuzhiyun 			chip->measure_lastpos = curp;
1991*4882a593Smuzhiyun 		}
1992*4882a593Smuzhiyun 	}
1993*4882a593Smuzhiyun 
1994*4882a593Smuzhiyun 	return IRQ_HANDLED;
1995*4882a593Smuzhiyun }
1996*4882a593Smuzhiyun 
1997*4882a593Smuzhiyun /*
1998*4882a593Smuzhiyun  *  Mixer stuff
1999*4882a593Smuzhiyun  */
2000*4882a593Smuzhiyun 
2001*4882a593Smuzhiyun static int
snd_es1968_mixer(struct es1968 * chip)2002*4882a593Smuzhiyun snd_es1968_mixer(struct es1968 *chip)
2003*4882a593Smuzhiyun {
2004*4882a593Smuzhiyun 	struct snd_ac97_bus *pbus;
2005*4882a593Smuzhiyun 	struct snd_ac97_template ac97;
2006*4882a593Smuzhiyun #ifndef CONFIG_SND_ES1968_INPUT
2007*4882a593Smuzhiyun 	struct snd_ctl_elem_id elem_id;
2008*4882a593Smuzhiyun #endif
2009*4882a593Smuzhiyun 	int err;
2010*4882a593Smuzhiyun 	static const struct snd_ac97_bus_ops ops = {
2011*4882a593Smuzhiyun 		.write = snd_es1968_ac97_write,
2012*4882a593Smuzhiyun 		.read = snd_es1968_ac97_read,
2013*4882a593Smuzhiyun 	};
2014*4882a593Smuzhiyun 
2015*4882a593Smuzhiyun 	if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0)
2016*4882a593Smuzhiyun 		return err;
2017*4882a593Smuzhiyun 	pbus->no_vra = 1; /* ES1968 doesn't need VRA */
2018*4882a593Smuzhiyun 
2019*4882a593Smuzhiyun 	memset(&ac97, 0, sizeof(ac97));
2020*4882a593Smuzhiyun 	ac97.private_data = chip;
2021*4882a593Smuzhiyun 	if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97)) < 0)
2022*4882a593Smuzhiyun 		return err;
2023*4882a593Smuzhiyun 
2024*4882a593Smuzhiyun #ifndef CONFIG_SND_ES1968_INPUT
2025*4882a593Smuzhiyun 	/* attach master switch / volumes for h/w volume control */
2026*4882a593Smuzhiyun 	memset(&elem_id, 0, sizeof(elem_id));
2027*4882a593Smuzhiyun 	elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2028*4882a593Smuzhiyun 	strcpy(elem_id.name, "Master Playback Switch");
2029*4882a593Smuzhiyun 	chip->master_switch = snd_ctl_find_id(chip->card, &elem_id);
2030*4882a593Smuzhiyun 	memset(&elem_id, 0, sizeof(elem_id));
2031*4882a593Smuzhiyun 	elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2032*4882a593Smuzhiyun 	strcpy(elem_id.name, "Master Playback Volume");
2033*4882a593Smuzhiyun 	chip->master_volume = snd_ctl_find_id(chip->card, &elem_id);
2034*4882a593Smuzhiyun #endif
2035*4882a593Smuzhiyun 
2036*4882a593Smuzhiyun 	return 0;
2037*4882a593Smuzhiyun }
2038*4882a593Smuzhiyun 
2039*4882a593Smuzhiyun /*
2040*4882a593Smuzhiyun  * reset ac97 codec
2041*4882a593Smuzhiyun  */
2042*4882a593Smuzhiyun 
snd_es1968_ac97_reset(struct es1968 * chip)2043*4882a593Smuzhiyun static void snd_es1968_ac97_reset(struct es1968 *chip)
2044*4882a593Smuzhiyun {
2045*4882a593Smuzhiyun 	unsigned long ioaddr = chip->io_port;
2046*4882a593Smuzhiyun 
2047*4882a593Smuzhiyun 	unsigned short save_ringbus_a;
2048*4882a593Smuzhiyun 	unsigned short save_68;
2049*4882a593Smuzhiyun 	unsigned short w;
2050*4882a593Smuzhiyun 	unsigned int vend;
2051*4882a593Smuzhiyun 
2052*4882a593Smuzhiyun 	/* save configuration */
2053*4882a593Smuzhiyun 	save_ringbus_a = inw(ioaddr + 0x36);
2054*4882a593Smuzhiyun 
2055*4882a593Smuzhiyun 	//outw(inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38); /* clear second codec id? */
2056*4882a593Smuzhiyun 	/* set command/status address i/o to 1st codec */
2057*4882a593Smuzhiyun 	outw(inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a);
2058*4882a593Smuzhiyun 	outw(inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c);
2059*4882a593Smuzhiyun 
2060*4882a593Smuzhiyun 	/* disable ac link */
2061*4882a593Smuzhiyun 	outw(0x0000, ioaddr + 0x36);
2062*4882a593Smuzhiyun 	save_68 = inw(ioaddr + 0x68);
2063*4882a593Smuzhiyun 	pci_read_config_word(chip->pci, 0x58, &w);	/* something magical with gpio and bus arb. */
2064*4882a593Smuzhiyun 	pci_read_config_dword(chip->pci, PCI_SUBSYSTEM_VENDOR_ID, &vend);
2065*4882a593Smuzhiyun 	if (w & 1)
2066*4882a593Smuzhiyun 		save_68 |= 0x10;
2067*4882a593Smuzhiyun 	outw(0xfffe, ioaddr + 0x64);	/* unmask gpio 0 */
2068*4882a593Smuzhiyun 	outw(0x0001, ioaddr + 0x68);	/* gpio write */
2069*4882a593Smuzhiyun 	outw(0x0000, ioaddr + 0x60);	/* write 0 to gpio 0 */
2070*4882a593Smuzhiyun 	udelay(20);
2071*4882a593Smuzhiyun 	outw(0x0001, ioaddr + 0x60);	/* write 1 to gpio 1 */
2072*4882a593Smuzhiyun 	msleep(20);
2073*4882a593Smuzhiyun 
2074*4882a593Smuzhiyun 	outw(save_68 | 0x1, ioaddr + 0x68);	/* now restore .. */
2075*4882a593Smuzhiyun 	outw((inw(ioaddr + 0x38) & 0xfffc) | 0x1, ioaddr + 0x38);
2076*4882a593Smuzhiyun 	outw((inw(ioaddr + 0x3a) & 0xfffc) | 0x1, ioaddr + 0x3a);
2077*4882a593Smuzhiyun 	outw((inw(ioaddr + 0x3c) & 0xfffc) | 0x1, ioaddr + 0x3c);
2078*4882a593Smuzhiyun 
2079*4882a593Smuzhiyun 	/* now the second codec */
2080*4882a593Smuzhiyun 	/* disable ac link */
2081*4882a593Smuzhiyun 	outw(0x0000, ioaddr + 0x36);
2082*4882a593Smuzhiyun 	outw(0xfff7, ioaddr + 0x64);	/* unmask gpio 3 */
2083*4882a593Smuzhiyun 	save_68 = inw(ioaddr + 0x68);
2084*4882a593Smuzhiyun 	outw(0x0009, ioaddr + 0x68);	/* gpio write 0 & 3 ?? */
2085*4882a593Smuzhiyun 	outw(0x0001, ioaddr + 0x60);	/* write 1 to gpio */
2086*4882a593Smuzhiyun 	udelay(20);
2087*4882a593Smuzhiyun 	outw(0x0009, ioaddr + 0x60);	/* write 9 to gpio */
2088*4882a593Smuzhiyun 	msleep(500);
2089*4882a593Smuzhiyun 	//outw(inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38);
2090*4882a593Smuzhiyun 	outw(inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a);
2091*4882a593Smuzhiyun 	outw(inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c);
2092*4882a593Smuzhiyun 
2093*4882a593Smuzhiyun #if 0				/* the loop here needs to be much better if we want it.. */
2094*4882a593Smuzhiyun 	dev_info(chip->card->dev, "trying software reset\n");
2095*4882a593Smuzhiyun 	/* try and do a software reset */
2096*4882a593Smuzhiyun 	outb(0x80 | 0x7c, ioaddr + 0x30);
2097*4882a593Smuzhiyun 	for (w = 0;; w++) {
2098*4882a593Smuzhiyun 		if ((inw(ioaddr + 0x30) & 1) == 0) {
2099*4882a593Smuzhiyun 			if (inb(ioaddr + 0x32) != 0)
2100*4882a593Smuzhiyun 				break;
2101*4882a593Smuzhiyun 
2102*4882a593Smuzhiyun 			outb(0x80 | 0x7d, ioaddr + 0x30);
2103*4882a593Smuzhiyun 			if (((inw(ioaddr + 0x30) & 1) == 0)
2104*4882a593Smuzhiyun 			    && (inb(ioaddr + 0x32) != 0))
2105*4882a593Smuzhiyun 				break;
2106*4882a593Smuzhiyun 			outb(0x80 | 0x7f, ioaddr + 0x30);
2107*4882a593Smuzhiyun 			if (((inw(ioaddr + 0x30) & 1) == 0)
2108*4882a593Smuzhiyun 			    && (inb(ioaddr + 0x32) != 0))
2109*4882a593Smuzhiyun 				break;
2110*4882a593Smuzhiyun 		}
2111*4882a593Smuzhiyun 
2112*4882a593Smuzhiyun 		if (w > 10000) {
2113*4882a593Smuzhiyun 			outb(inb(ioaddr + 0x37) | 0x08, ioaddr + 0x37);	/* do a software reset */
2114*4882a593Smuzhiyun 			msleep(500);	/* oh my.. */
2115*4882a593Smuzhiyun 			outb(inb(ioaddr + 0x37) & ~0x08,
2116*4882a593Smuzhiyun 				ioaddr + 0x37);
2117*4882a593Smuzhiyun 			udelay(1);
2118*4882a593Smuzhiyun 			outw(0x80, ioaddr + 0x30);
2119*4882a593Smuzhiyun 			for (w = 0; w < 10000; w++) {
2120*4882a593Smuzhiyun 				if ((inw(ioaddr + 0x30) & 1) == 0)
2121*4882a593Smuzhiyun 					break;
2122*4882a593Smuzhiyun 			}
2123*4882a593Smuzhiyun 		}
2124*4882a593Smuzhiyun 	}
2125*4882a593Smuzhiyun #endif
2126*4882a593Smuzhiyun 	if (vend == NEC_VERSA_SUBID1 || vend == NEC_VERSA_SUBID2) {
2127*4882a593Smuzhiyun 		/* turn on external amp? */
2128*4882a593Smuzhiyun 		outw(0xf9ff, ioaddr + 0x64);
2129*4882a593Smuzhiyun 		outw(inw(ioaddr + 0x68) | 0x600, ioaddr + 0x68);
2130*4882a593Smuzhiyun 		outw(0x0209, ioaddr + 0x60);
2131*4882a593Smuzhiyun 	}
2132*4882a593Smuzhiyun 
2133*4882a593Smuzhiyun 	/* restore.. */
2134*4882a593Smuzhiyun 	outw(save_ringbus_a, ioaddr + 0x36);
2135*4882a593Smuzhiyun 
2136*4882a593Smuzhiyun 	/* Turn on the 978 docking chip.
2137*4882a593Smuzhiyun 	   First frob the "master output enable" bit,
2138*4882a593Smuzhiyun 	   then set most of the playback volume control registers to max. */
2139*4882a593Smuzhiyun 	outb(inb(ioaddr+0xc0)|(1<<5), ioaddr+0xc0);
2140*4882a593Smuzhiyun 	outb(0xff, ioaddr+0xc3);
2141*4882a593Smuzhiyun 	outb(0xff, ioaddr+0xc4);
2142*4882a593Smuzhiyun 	outb(0xff, ioaddr+0xc6);
2143*4882a593Smuzhiyun 	outb(0xff, ioaddr+0xc8);
2144*4882a593Smuzhiyun 	outb(0x3f, ioaddr+0xcf);
2145*4882a593Smuzhiyun 	outb(0x3f, ioaddr+0xd0);
2146*4882a593Smuzhiyun }
2147*4882a593Smuzhiyun 
snd_es1968_reset(struct es1968 * chip)2148*4882a593Smuzhiyun static void snd_es1968_reset(struct es1968 *chip)
2149*4882a593Smuzhiyun {
2150*4882a593Smuzhiyun 	/* Reset */
2151*4882a593Smuzhiyun 	outw(ESM_RESET_MAESTRO | ESM_RESET_DIRECTSOUND,
2152*4882a593Smuzhiyun 	     chip->io_port + ESM_PORT_HOST_IRQ);
2153*4882a593Smuzhiyun 	udelay(10);
2154*4882a593Smuzhiyun 	outw(0x0000, chip->io_port + ESM_PORT_HOST_IRQ);
2155*4882a593Smuzhiyun 	udelay(10);
2156*4882a593Smuzhiyun }
2157*4882a593Smuzhiyun 
2158*4882a593Smuzhiyun /*
2159*4882a593Smuzhiyun  * initialize maestro chip
2160*4882a593Smuzhiyun  */
snd_es1968_chip_init(struct es1968 * chip)2161*4882a593Smuzhiyun static void snd_es1968_chip_init(struct es1968 *chip)
2162*4882a593Smuzhiyun {
2163*4882a593Smuzhiyun 	struct pci_dev *pci = chip->pci;
2164*4882a593Smuzhiyun 	int i;
2165*4882a593Smuzhiyun 	unsigned long iobase  = chip->io_port;
2166*4882a593Smuzhiyun 	u16 w;
2167*4882a593Smuzhiyun 	u32 n;
2168*4882a593Smuzhiyun 
2169*4882a593Smuzhiyun 	/* We used to muck around with pci config space that
2170*4882a593Smuzhiyun 	 * we had no business messing with.  We don't know enough
2171*4882a593Smuzhiyun 	 * about the machine to know which DMA mode is appropriate,
2172*4882a593Smuzhiyun 	 * etc.  We were guessing wrong on some machines and making
2173*4882a593Smuzhiyun 	 * them unhappy.  We now trust in the BIOS to do things right,
2174*4882a593Smuzhiyun 	 * which almost certainly means a new host of problems will
2175*4882a593Smuzhiyun 	 * arise with broken BIOS implementations.  screw 'em.
2176*4882a593Smuzhiyun 	 * We're already intolerant of machines that don't assign
2177*4882a593Smuzhiyun 	 * IRQs.
2178*4882a593Smuzhiyun 	 */
2179*4882a593Smuzhiyun 
2180*4882a593Smuzhiyun 	/* Config Reg A */
2181*4882a593Smuzhiyun 	pci_read_config_word(pci, ESM_CONFIG_A, &w);
2182*4882a593Smuzhiyun 
2183*4882a593Smuzhiyun 	w &= ~DMA_CLEAR;	/* Clear DMA bits */
2184*4882a593Smuzhiyun 	w &= ~(PIC_SNOOP1 | PIC_SNOOP2);	/* Clear Pic Snoop Mode Bits */
2185*4882a593Smuzhiyun 	w &= ~SAFEGUARD;	/* Safeguard off */
2186*4882a593Smuzhiyun 	w |= POST_WRITE;	/* Posted write */
2187*4882a593Smuzhiyun 	w |= PCI_TIMING;	/* PCI timing on */
2188*4882a593Smuzhiyun 	/* XXX huh?  claims to be reserved.. */
2189*4882a593Smuzhiyun 	w &= ~SWAP_LR;		/* swap left/right
2190*4882a593Smuzhiyun 				   seems to only have effect on SB
2191*4882a593Smuzhiyun 				   Emulation */
2192*4882a593Smuzhiyun 	w &= ~SUBTR_DECODE;	/* Subtractive decode off */
2193*4882a593Smuzhiyun 
2194*4882a593Smuzhiyun 	pci_write_config_word(pci, ESM_CONFIG_A, w);
2195*4882a593Smuzhiyun 
2196*4882a593Smuzhiyun 	/* Config Reg B */
2197*4882a593Smuzhiyun 
2198*4882a593Smuzhiyun 	pci_read_config_word(pci, ESM_CONFIG_B, &w);
2199*4882a593Smuzhiyun 
2200*4882a593Smuzhiyun 	w &= ~(1 << 15);	/* Turn off internal clock multiplier */
2201*4882a593Smuzhiyun 	/* XXX how do we know which to use? */
2202*4882a593Smuzhiyun 	w &= ~(1 << 14);	/* External clock */
2203*4882a593Smuzhiyun 
2204*4882a593Smuzhiyun 	w &= ~SPDIF_CONFB;	/* disable S/PDIF output */
2205*4882a593Smuzhiyun 	w |= HWV_CONFB;		/* HWV on */
2206*4882a593Smuzhiyun 	w |= DEBOUNCE;		/* Debounce off: easier to push the HW buttons */
2207*4882a593Smuzhiyun 	w &= ~GPIO_CONFB;	/* GPIO 4:5 */
2208*4882a593Smuzhiyun 	w |= CHI_CONFB;		/* Disconnect from the CHI.  Enabling this made a dell 7500 work. */
2209*4882a593Smuzhiyun 	w &= ~IDMA_CONFB;	/* IDMA off (undocumented) */
2210*4882a593Smuzhiyun 	w &= ~MIDI_FIX;		/* MIDI fix off (undoc) */
2211*4882a593Smuzhiyun 	w &= ~(1 << 1);		/* reserved, always write 0 */
2212*4882a593Smuzhiyun 	w &= ~IRQ_TO_ISA;	/* IRQ to ISA off (undoc) */
2213*4882a593Smuzhiyun 
2214*4882a593Smuzhiyun 	pci_write_config_word(pci, ESM_CONFIG_B, w);
2215*4882a593Smuzhiyun 
2216*4882a593Smuzhiyun 	/* DDMA off */
2217*4882a593Smuzhiyun 
2218*4882a593Smuzhiyun 	pci_read_config_word(pci, ESM_DDMA, &w);
2219*4882a593Smuzhiyun 	w &= ~(1 << 0);
2220*4882a593Smuzhiyun 	pci_write_config_word(pci, ESM_DDMA, w);
2221*4882a593Smuzhiyun 
2222*4882a593Smuzhiyun 	/*
2223*4882a593Smuzhiyun 	 *	Legacy mode
2224*4882a593Smuzhiyun 	 */
2225*4882a593Smuzhiyun 
2226*4882a593Smuzhiyun 	pci_read_config_word(pci, ESM_LEGACY_AUDIO_CONTROL, &w);
2227*4882a593Smuzhiyun 
2228*4882a593Smuzhiyun 	w |= ESS_DISABLE_AUDIO;	/* Disable Legacy Audio */
2229*4882a593Smuzhiyun 	w &= ~ESS_ENABLE_SERIAL_IRQ;	/* Disable SIRQ */
2230*4882a593Smuzhiyun 	w &= ~(0x1f);		/* disable mpu irq/io, game port, fm, SB */
2231*4882a593Smuzhiyun 
2232*4882a593Smuzhiyun 	pci_write_config_word(pci, ESM_LEGACY_AUDIO_CONTROL, w);
2233*4882a593Smuzhiyun 
2234*4882a593Smuzhiyun 	/* Set up 978 docking control chip. */
2235*4882a593Smuzhiyun 	pci_read_config_word(pci, 0x58, &w);
2236*4882a593Smuzhiyun 	w|=1<<2;	/* Enable 978. */
2237*4882a593Smuzhiyun 	w|=1<<3;	/* Turn on 978 hardware volume control. */
2238*4882a593Smuzhiyun 	w&=~(1<<11);	/* Turn on 978 mixer volume control. */
2239*4882a593Smuzhiyun 	pci_write_config_word(pci, 0x58, w);
2240*4882a593Smuzhiyun 
2241*4882a593Smuzhiyun 	/* Sound Reset */
2242*4882a593Smuzhiyun 
2243*4882a593Smuzhiyun 	snd_es1968_reset(chip);
2244*4882a593Smuzhiyun 
2245*4882a593Smuzhiyun 	/*
2246*4882a593Smuzhiyun 	 *	Ring Bus Setup
2247*4882a593Smuzhiyun 	 */
2248*4882a593Smuzhiyun 
2249*4882a593Smuzhiyun 	/* setup usual 0x34 stuff.. 0x36 may be chip specific */
2250*4882a593Smuzhiyun 	outw(0xC090, iobase + ESM_RING_BUS_DEST); /* direct sound, stereo */
2251*4882a593Smuzhiyun 	udelay(20);
2252*4882a593Smuzhiyun 	outw(0x3000, iobase + ESM_RING_BUS_CONTR_A); /* enable ringbus/serial */
2253*4882a593Smuzhiyun 	udelay(20);
2254*4882a593Smuzhiyun 
2255*4882a593Smuzhiyun 	/*
2256*4882a593Smuzhiyun 	 *	Reset the CODEC
2257*4882a593Smuzhiyun 	 */
2258*4882a593Smuzhiyun 
2259*4882a593Smuzhiyun 	snd_es1968_ac97_reset(chip);
2260*4882a593Smuzhiyun 
2261*4882a593Smuzhiyun 	/* Ring Bus Control B */
2262*4882a593Smuzhiyun 
2263*4882a593Smuzhiyun 	n = inl(iobase + ESM_RING_BUS_CONTR_B);
2264*4882a593Smuzhiyun 	n &= ~RINGB_EN_SPDIF;	/* SPDIF off */
2265*4882a593Smuzhiyun 	//w |= RINGB_EN_2CODEC;	/* enable 2nd codec */
2266*4882a593Smuzhiyun 	outl(n, iobase + ESM_RING_BUS_CONTR_B);
2267*4882a593Smuzhiyun 
2268*4882a593Smuzhiyun 	/* Set hardware volume control registers to midpoints.
2269*4882a593Smuzhiyun 	   We can tell which button was pushed based on how they change. */
2270*4882a593Smuzhiyun 	outb(0x88, iobase+0x1c);
2271*4882a593Smuzhiyun 	outb(0x88, iobase+0x1d);
2272*4882a593Smuzhiyun 	outb(0x88, iobase+0x1e);
2273*4882a593Smuzhiyun 	outb(0x88, iobase+0x1f);
2274*4882a593Smuzhiyun 
2275*4882a593Smuzhiyun 	/* it appears some maestros (dell 7500) only work if these are set,
2276*4882a593Smuzhiyun 	   regardless of whether we use the assp or not. */
2277*4882a593Smuzhiyun 
2278*4882a593Smuzhiyun 	outb(0, iobase + ASSP_CONTROL_B);
2279*4882a593Smuzhiyun 	outb(3, iobase + ASSP_CONTROL_A);	/* M: Reserved bits... */
2280*4882a593Smuzhiyun 	outb(0, iobase + ASSP_CONTROL_C);	/* M: Disable ASSP, ASSP IRQ's and FM Port */
2281*4882a593Smuzhiyun 
2282*4882a593Smuzhiyun 	/*
2283*4882a593Smuzhiyun 	 * set up wavecache
2284*4882a593Smuzhiyun 	 */
2285*4882a593Smuzhiyun 	for (i = 0; i < 16; i++) {
2286*4882a593Smuzhiyun 		/* Write 0 into the buffer area 0x1E0->1EF */
2287*4882a593Smuzhiyun 		outw(0x01E0 + i, iobase + WC_INDEX);
2288*4882a593Smuzhiyun 		outw(0x0000, iobase + WC_DATA);
2289*4882a593Smuzhiyun 
2290*4882a593Smuzhiyun 		/* The 1.10 test program seem to write 0 into the buffer area
2291*4882a593Smuzhiyun 		 * 0x1D0-0x1DF too.*/
2292*4882a593Smuzhiyun 		outw(0x01D0 + i, iobase + WC_INDEX);
2293*4882a593Smuzhiyun 		outw(0x0000, iobase + WC_DATA);
2294*4882a593Smuzhiyun 	}
2295*4882a593Smuzhiyun 	wave_set_register(chip, IDR7_WAVE_ROMRAM,
2296*4882a593Smuzhiyun 			  (wave_get_register(chip, IDR7_WAVE_ROMRAM) & 0xFF00));
2297*4882a593Smuzhiyun 	wave_set_register(chip, IDR7_WAVE_ROMRAM,
2298*4882a593Smuzhiyun 			  wave_get_register(chip, IDR7_WAVE_ROMRAM) | 0x100);
2299*4882a593Smuzhiyun 	wave_set_register(chip, IDR7_WAVE_ROMRAM,
2300*4882a593Smuzhiyun 			  wave_get_register(chip, IDR7_WAVE_ROMRAM) & ~0x200);
2301*4882a593Smuzhiyun 	wave_set_register(chip, IDR7_WAVE_ROMRAM,
2302*4882a593Smuzhiyun 			  wave_get_register(chip, IDR7_WAVE_ROMRAM) | ~0x400);
2303*4882a593Smuzhiyun 
2304*4882a593Smuzhiyun 
2305*4882a593Smuzhiyun 	maestro_write(chip, IDR2_CRAM_DATA, 0x0000);
2306*4882a593Smuzhiyun 	/* Now back to the DirectSound stuff */
2307*4882a593Smuzhiyun 	/* audio serial configuration.. ? */
2308*4882a593Smuzhiyun 	maestro_write(chip, 0x08, 0xB004);
2309*4882a593Smuzhiyun 	maestro_write(chip, 0x09, 0x001B);
2310*4882a593Smuzhiyun 	maestro_write(chip, 0x0A, 0x8000);
2311*4882a593Smuzhiyun 	maestro_write(chip, 0x0B, 0x3F37);
2312*4882a593Smuzhiyun 	maestro_write(chip, 0x0C, 0x0098);
2313*4882a593Smuzhiyun 
2314*4882a593Smuzhiyun 	/* parallel in, has something to do with recording :) */
2315*4882a593Smuzhiyun 	maestro_write(chip, 0x0C,
2316*4882a593Smuzhiyun 		      (maestro_read(chip, 0x0C) & ~0xF000) | 0x8000);
2317*4882a593Smuzhiyun 	/* parallel out */
2318*4882a593Smuzhiyun 	maestro_write(chip, 0x0C,
2319*4882a593Smuzhiyun 		      (maestro_read(chip, 0x0C) & ~0x0F00) | 0x0500);
2320*4882a593Smuzhiyun 
2321*4882a593Smuzhiyun 	maestro_write(chip, 0x0D, 0x7632);
2322*4882a593Smuzhiyun 
2323*4882a593Smuzhiyun 	/* Wave cache control on - test off, sg off,
2324*4882a593Smuzhiyun 	   enable, enable extra chans 1Mb */
2325*4882a593Smuzhiyun 
2326*4882a593Smuzhiyun 	w = inw(iobase + WC_CONTROL);
2327*4882a593Smuzhiyun 
2328*4882a593Smuzhiyun 	w &= ~0xFA00;		/* Seems to be reserved? I don't know */
2329*4882a593Smuzhiyun 	w |= 0xA000;		/* reserved... I don't know */
2330*4882a593Smuzhiyun 	w &= ~0x0200;		/* Channels 56,57,58,59 as Extra Play,Rec Channel enable
2331*4882a593Smuzhiyun 				   Seems to crash the Computer if enabled... */
2332*4882a593Smuzhiyun 	w |= 0x0100;		/* Wave Cache Operation Enabled */
2333*4882a593Smuzhiyun 	w |= 0x0080;		/* Channels 60/61 as Placback/Record enabled */
2334*4882a593Smuzhiyun 	w &= ~0x0060;		/* Clear Wavtable Size */
2335*4882a593Smuzhiyun 	w |= 0x0020;		/* Wavetable Size : 1MB */
2336*4882a593Smuzhiyun 	/* Bit 4 is reserved */
2337*4882a593Smuzhiyun 	w &= ~0x000C;		/* DMA Stuff? I don't understand what the datasheet means */
2338*4882a593Smuzhiyun 	/* Bit 1 is reserved */
2339*4882a593Smuzhiyun 	w &= ~0x0001;		/* Test Mode off */
2340*4882a593Smuzhiyun 
2341*4882a593Smuzhiyun 	outw(w, iobase + WC_CONTROL);
2342*4882a593Smuzhiyun 
2343*4882a593Smuzhiyun 	/* Now clear the APU control ram */
2344*4882a593Smuzhiyun 	for (i = 0; i < NR_APUS; i++) {
2345*4882a593Smuzhiyun 		for (w = 0; w < NR_APU_REGS; w++)
2346*4882a593Smuzhiyun 			apu_set_register(chip, i, w, 0);
2347*4882a593Smuzhiyun 
2348*4882a593Smuzhiyun 	}
2349*4882a593Smuzhiyun }
2350*4882a593Smuzhiyun 
2351*4882a593Smuzhiyun /* Enable IRQ's */
snd_es1968_start_irq(struct es1968 * chip)2352*4882a593Smuzhiyun static void snd_es1968_start_irq(struct es1968 *chip)
2353*4882a593Smuzhiyun {
2354*4882a593Smuzhiyun 	unsigned short w;
2355*4882a593Smuzhiyun 	w = ESM_HIRQ_DSIE | ESM_HIRQ_HW_VOLUME;
2356*4882a593Smuzhiyun 	if (chip->rmidi)
2357*4882a593Smuzhiyun 		w |= ESM_HIRQ_MPU401;
2358*4882a593Smuzhiyun 	outb(w, chip->io_port + 0x1A);
2359*4882a593Smuzhiyun 	outw(w, chip->io_port + ESM_PORT_HOST_IRQ);
2360*4882a593Smuzhiyun }
2361*4882a593Smuzhiyun 
2362*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
2363*4882a593Smuzhiyun /*
2364*4882a593Smuzhiyun  * PM support
2365*4882a593Smuzhiyun  */
es1968_suspend(struct device * dev)2366*4882a593Smuzhiyun static int es1968_suspend(struct device *dev)
2367*4882a593Smuzhiyun {
2368*4882a593Smuzhiyun 	struct snd_card *card = dev_get_drvdata(dev);
2369*4882a593Smuzhiyun 	struct es1968 *chip = card->private_data;
2370*4882a593Smuzhiyun 
2371*4882a593Smuzhiyun 	if (! chip->do_pm)
2372*4882a593Smuzhiyun 		return 0;
2373*4882a593Smuzhiyun 
2374*4882a593Smuzhiyun 	chip->in_suspend = 1;
2375*4882a593Smuzhiyun 	cancel_work_sync(&chip->hwvol_work);
2376*4882a593Smuzhiyun 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2377*4882a593Smuzhiyun 	snd_ac97_suspend(chip->ac97);
2378*4882a593Smuzhiyun 	snd_es1968_bob_stop(chip);
2379*4882a593Smuzhiyun 	return 0;
2380*4882a593Smuzhiyun }
2381*4882a593Smuzhiyun 
es1968_resume(struct device * dev)2382*4882a593Smuzhiyun static int es1968_resume(struct device *dev)
2383*4882a593Smuzhiyun {
2384*4882a593Smuzhiyun 	struct snd_card *card = dev_get_drvdata(dev);
2385*4882a593Smuzhiyun 	struct es1968 *chip = card->private_data;
2386*4882a593Smuzhiyun 	struct esschan *es;
2387*4882a593Smuzhiyun 
2388*4882a593Smuzhiyun 	if (! chip->do_pm)
2389*4882a593Smuzhiyun 		return 0;
2390*4882a593Smuzhiyun 
2391*4882a593Smuzhiyun 	snd_es1968_chip_init(chip);
2392*4882a593Smuzhiyun 
2393*4882a593Smuzhiyun 	/* need to restore the base pointers.. */
2394*4882a593Smuzhiyun 	if (chip->dma.addr) {
2395*4882a593Smuzhiyun 		/* set PCMBAR */
2396*4882a593Smuzhiyun 		wave_set_register(chip, 0x01FC, chip->dma.addr >> 12);
2397*4882a593Smuzhiyun 	}
2398*4882a593Smuzhiyun 
2399*4882a593Smuzhiyun 	snd_es1968_start_irq(chip);
2400*4882a593Smuzhiyun 
2401*4882a593Smuzhiyun 	/* restore ac97 state */
2402*4882a593Smuzhiyun 	snd_ac97_resume(chip->ac97);
2403*4882a593Smuzhiyun 
2404*4882a593Smuzhiyun 	list_for_each_entry(es, &chip->substream_list, list) {
2405*4882a593Smuzhiyun 		switch (es->mode) {
2406*4882a593Smuzhiyun 		case ESM_MODE_PLAY:
2407*4882a593Smuzhiyun 			snd_es1968_playback_setup(chip, es, es->substream->runtime);
2408*4882a593Smuzhiyun 			break;
2409*4882a593Smuzhiyun 		case ESM_MODE_CAPTURE:
2410*4882a593Smuzhiyun 			snd_es1968_capture_setup(chip, es, es->substream->runtime);
2411*4882a593Smuzhiyun 			break;
2412*4882a593Smuzhiyun 		}
2413*4882a593Smuzhiyun 	}
2414*4882a593Smuzhiyun 
2415*4882a593Smuzhiyun 	/* start timer again */
2416*4882a593Smuzhiyun 	if (chip->bobclient)
2417*4882a593Smuzhiyun 		snd_es1968_bob_start(chip);
2418*4882a593Smuzhiyun 
2419*4882a593Smuzhiyun 	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2420*4882a593Smuzhiyun 	chip->in_suspend = 0;
2421*4882a593Smuzhiyun 	return 0;
2422*4882a593Smuzhiyun }
2423*4882a593Smuzhiyun 
2424*4882a593Smuzhiyun static SIMPLE_DEV_PM_OPS(es1968_pm, es1968_suspend, es1968_resume);
2425*4882a593Smuzhiyun #define ES1968_PM_OPS	&es1968_pm
2426*4882a593Smuzhiyun #else
2427*4882a593Smuzhiyun #define ES1968_PM_OPS	NULL
2428*4882a593Smuzhiyun #endif /* CONFIG_PM_SLEEP */
2429*4882a593Smuzhiyun 
2430*4882a593Smuzhiyun #ifdef SUPPORT_JOYSTICK
2431*4882a593Smuzhiyun #define JOYSTICK_ADDR	0x200
snd_es1968_create_gameport(struct es1968 * chip,int dev)2432*4882a593Smuzhiyun static int snd_es1968_create_gameport(struct es1968 *chip, int dev)
2433*4882a593Smuzhiyun {
2434*4882a593Smuzhiyun 	struct gameport *gp;
2435*4882a593Smuzhiyun 	struct resource *r;
2436*4882a593Smuzhiyun 	u16 val;
2437*4882a593Smuzhiyun 
2438*4882a593Smuzhiyun 	if (!joystick[dev])
2439*4882a593Smuzhiyun 		return -ENODEV;
2440*4882a593Smuzhiyun 
2441*4882a593Smuzhiyun 	r = request_region(JOYSTICK_ADDR, 8, "ES1968 gameport");
2442*4882a593Smuzhiyun 	if (!r)
2443*4882a593Smuzhiyun 		return -EBUSY;
2444*4882a593Smuzhiyun 
2445*4882a593Smuzhiyun 	chip->gameport = gp = gameport_allocate_port();
2446*4882a593Smuzhiyun 	if (!gp) {
2447*4882a593Smuzhiyun 		dev_err(chip->card->dev,
2448*4882a593Smuzhiyun 			"cannot allocate memory for gameport\n");
2449*4882a593Smuzhiyun 		release_and_free_resource(r);
2450*4882a593Smuzhiyun 		return -ENOMEM;
2451*4882a593Smuzhiyun 	}
2452*4882a593Smuzhiyun 
2453*4882a593Smuzhiyun 	pci_read_config_word(chip->pci, ESM_LEGACY_AUDIO_CONTROL, &val);
2454*4882a593Smuzhiyun 	pci_write_config_word(chip->pci, ESM_LEGACY_AUDIO_CONTROL, val | 0x04);
2455*4882a593Smuzhiyun 
2456*4882a593Smuzhiyun 	gameport_set_name(gp, "ES1968 Gameport");
2457*4882a593Smuzhiyun 	gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
2458*4882a593Smuzhiyun 	gameport_set_dev_parent(gp, &chip->pci->dev);
2459*4882a593Smuzhiyun 	gp->io = JOYSTICK_ADDR;
2460*4882a593Smuzhiyun 	gameport_set_port_data(gp, r);
2461*4882a593Smuzhiyun 
2462*4882a593Smuzhiyun 	gameport_register_port(gp);
2463*4882a593Smuzhiyun 
2464*4882a593Smuzhiyun 	return 0;
2465*4882a593Smuzhiyun }
2466*4882a593Smuzhiyun 
snd_es1968_free_gameport(struct es1968 * chip)2467*4882a593Smuzhiyun static void snd_es1968_free_gameport(struct es1968 *chip)
2468*4882a593Smuzhiyun {
2469*4882a593Smuzhiyun 	if (chip->gameport) {
2470*4882a593Smuzhiyun 		struct resource *r = gameport_get_port_data(chip->gameport);
2471*4882a593Smuzhiyun 
2472*4882a593Smuzhiyun 		gameport_unregister_port(chip->gameport);
2473*4882a593Smuzhiyun 		chip->gameport = NULL;
2474*4882a593Smuzhiyun 
2475*4882a593Smuzhiyun 		release_and_free_resource(r);
2476*4882a593Smuzhiyun 	}
2477*4882a593Smuzhiyun }
2478*4882a593Smuzhiyun #else
snd_es1968_create_gameport(struct es1968 * chip,int dev)2479*4882a593Smuzhiyun static inline int snd_es1968_create_gameport(struct es1968 *chip, int dev) { return -ENOSYS; }
snd_es1968_free_gameport(struct es1968 * chip)2480*4882a593Smuzhiyun static inline void snd_es1968_free_gameport(struct es1968 *chip) { }
2481*4882a593Smuzhiyun #endif
2482*4882a593Smuzhiyun 
2483*4882a593Smuzhiyun #ifdef CONFIG_SND_ES1968_INPUT
snd_es1968_input_register(struct es1968 * chip)2484*4882a593Smuzhiyun static int snd_es1968_input_register(struct es1968 *chip)
2485*4882a593Smuzhiyun {
2486*4882a593Smuzhiyun 	struct input_dev *input_dev;
2487*4882a593Smuzhiyun 	int err;
2488*4882a593Smuzhiyun 
2489*4882a593Smuzhiyun 	input_dev = input_allocate_device();
2490*4882a593Smuzhiyun 	if (!input_dev)
2491*4882a593Smuzhiyun 		return -ENOMEM;
2492*4882a593Smuzhiyun 
2493*4882a593Smuzhiyun 	snprintf(chip->phys, sizeof(chip->phys), "pci-%s/input0",
2494*4882a593Smuzhiyun 		 pci_name(chip->pci));
2495*4882a593Smuzhiyun 
2496*4882a593Smuzhiyun 	input_dev->name = chip->card->driver;
2497*4882a593Smuzhiyun 	input_dev->phys = chip->phys;
2498*4882a593Smuzhiyun 	input_dev->id.bustype = BUS_PCI;
2499*4882a593Smuzhiyun 	input_dev->id.vendor  = chip->pci->vendor;
2500*4882a593Smuzhiyun 	input_dev->id.product = chip->pci->device;
2501*4882a593Smuzhiyun 	input_dev->dev.parent = &chip->pci->dev;
2502*4882a593Smuzhiyun 
2503*4882a593Smuzhiyun 	__set_bit(EV_KEY, input_dev->evbit);
2504*4882a593Smuzhiyun 	__set_bit(KEY_MUTE, input_dev->keybit);
2505*4882a593Smuzhiyun 	__set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
2506*4882a593Smuzhiyun 	__set_bit(KEY_VOLUMEUP, input_dev->keybit);
2507*4882a593Smuzhiyun 
2508*4882a593Smuzhiyun 	err = input_register_device(input_dev);
2509*4882a593Smuzhiyun 	if (err) {
2510*4882a593Smuzhiyun 		input_free_device(input_dev);
2511*4882a593Smuzhiyun 		return err;
2512*4882a593Smuzhiyun 	}
2513*4882a593Smuzhiyun 
2514*4882a593Smuzhiyun 	chip->input_dev = input_dev;
2515*4882a593Smuzhiyun 	return 0;
2516*4882a593Smuzhiyun }
2517*4882a593Smuzhiyun #endif /* CONFIG_SND_ES1968_INPUT */
2518*4882a593Smuzhiyun 
2519*4882a593Smuzhiyun #ifdef CONFIG_SND_ES1968_RADIO
2520*4882a593Smuzhiyun #define GPIO_DATA	0x60
2521*4882a593Smuzhiyun #define IO_MASK		4      /* mask      register offset from GPIO_DATA
2522*4882a593Smuzhiyun 				bits 1=unmask write to given bit */
2523*4882a593Smuzhiyun #define IO_DIR		8      /* direction register offset from GPIO_DATA
2524*4882a593Smuzhiyun 				bits 0/1=read/write direction */
2525*4882a593Smuzhiyun 
2526*4882a593Smuzhiyun /* GPIO to TEA575x maps */
2527*4882a593Smuzhiyun struct snd_es1968_tea575x_gpio {
2528*4882a593Smuzhiyun 	u8 data, clk, wren, most;
2529*4882a593Smuzhiyun 	char *name;
2530*4882a593Smuzhiyun };
2531*4882a593Smuzhiyun 
2532*4882a593Smuzhiyun static const struct snd_es1968_tea575x_gpio snd_es1968_tea575x_gpios[] = {
2533*4882a593Smuzhiyun 	{ .data = 6, .clk = 7, .wren = 8, .most = 9, .name = "SF64-PCE2" },
2534*4882a593Smuzhiyun 	{ .data = 7, .clk = 8, .wren = 6, .most = 10, .name = "M56VAP" },
2535*4882a593Smuzhiyun };
2536*4882a593Smuzhiyun 
2537*4882a593Smuzhiyun #define get_tea575x_gpio(chip) \
2538*4882a593Smuzhiyun 	(&snd_es1968_tea575x_gpios[(chip)->tea575x_tuner])
2539*4882a593Smuzhiyun 
2540*4882a593Smuzhiyun 
snd_es1968_tea575x_set_pins(struct snd_tea575x * tea,u8 pins)2541*4882a593Smuzhiyun static void snd_es1968_tea575x_set_pins(struct snd_tea575x *tea, u8 pins)
2542*4882a593Smuzhiyun {
2543*4882a593Smuzhiyun 	struct es1968 *chip = tea->private_data;
2544*4882a593Smuzhiyun 	struct snd_es1968_tea575x_gpio gpio = *get_tea575x_gpio(chip);
2545*4882a593Smuzhiyun 	u16 val = 0;
2546*4882a593Smuzhiyun 
2547*4882a593Smuzhiyun 	val |= (pins & TEA575X_DATA) ? (1 << gpio.data) : 0;
2548*4882a593Smuzhiyun 	val |= (pins & TEA575X_CLK)  ? (1 << gpio.clk)  : 0;
2549*4882a593Smuzhiyun 	val |= (pins & TEA575X_WREN) ? (1 << gpio.wren) : 0;
2550*4882a593Smuzhiyun 
2551*4882a593Smuzhiyun 	outw(val, chip->io_port + GPIO_DATA);
2552*4882a593Smuzhiyun }
2553*4882a593Smuzhiyun 
snd_es1968_tea575x_get_pins(struct snd_tea575x * tea)2554*4882a593Smuzhiyun static u8 snd_es1968_tea575x_get_pins(struct snd_tea575x *tea)
2555*4882a593Smuzhiyun {
2556*4882a593Smuzhiyun 	struct es1968 *chip = tea->private_data;
2557*4882a593Smuzhiyun 	struct snd_es1968_tea575x_gpio gpio = *get_tea575x_gpio(chip);
2558*4882a593Smuzhiyun 	u16 val = inw(chip->io_port + GPIO_DATA);
2559*4882a593Smuzhiyun 	u8 ret = 0;
2560*4882a593Smuzhiyun 
2561*4882a593Smuzhiyun 	if (val & (1 << gpio.data))
2562*4882a593Smuzhiyun 		ret |= TEA575X_DATA;
2563*4882a593Smuzhiyun 	if (val & (1 << gpio.most))
2564*4882a593Smuzhiyun 		ret |= TEA575X_MOST;
2565*4882a593Smuzhiyun 
2566*4882a593Smuzhiyun 	return ret;
2567*4882a593Smuzhiyun }
2568*4882a593Smuzhiyun 
snd_es1968_tea575x_set_direction(struct snd_tea575x * tea,bool output)2569*4882a593Smuzhiyun static void snd_es1968_tea575x_set_direction(struct snd_tea575x *tea, bool output)
2570*4882a593Smuzhiyun {
2571*4882a593Smuzhiyun 	struct es1968 *chip = tea->private_data;
2572*4882a593Smuzhiyun 	unsigned long io = chip->io_port + GPIO_DATA;
2573*4882a593Smuzhiyun 	u16 odir = inw(io + IO_DIR);
2574*4882a593Smuzhiyun 	struct snd_es1968_tea575x_gpio gpio = *get_tea575x_gpio(chip);
2575*4882a593Smuzhiyun 
2576*4882a593Smuzhiyun 	if (output) {
2577*4882a593Smuzhiyun 		outw(~((1 << gpio.data) | (1 << gpio.clk) | (1 << gpio.wren)),
2578*4882a593Smuzhiyun 			io + IO_MASK);
2579*4882a593Smuzhiyun 		outw(odir | (1 << gpio.data) | (1 << gpio.clk) | (1 << gpio.wren),
2580*4882a593Smuzhiyun 			io + IO_DIR);
2581*4882a593Smuzhiyun 	} else {
2582*4882a593Smuzhiyun 		outw(~((1 << gpio.clk) | (1 << gpio.wren) | (1 << gpio.data) | (1 << gpio.most)),
2583*4882a593Smuzhiyun 			io + IO_MASK);
2584*4882a593Smuzhiyun 		outw((odir & ~((1 << gpio.data) | (1 << gpio.most)))
2585*4882a593Smuzhiyun 			| (1 << gpio.clk) | (1 << gpio.wren), io + IO_DIR);
2586*4882a593Smuzhiyun 	}
2587*4882a593Smuzhiyun }
2588*4882a593Smuzhiyun 
2589*4882a593Smuzhiyun static const struct snd_tea575x_ops snd_es1968_tea_ops = {
2590*4882a593Smuzhiyun 	.set_pins = snd_es1968_tea575x_set_pins,
2591*4882a593Smuzhiyun 	.get_pins = snd_es1968_tea575x_get_pins,
2592*4882a593Smuzhiyun 	.set_direction = snd_es1968_tea575x_set_direction,
2593*4882a593Smuzhiyun };
2594*4882a593Smuzhiyun #endif
2595*4882a593Smuzhiyun 
snd_es1968_free(struct es1968 * chip)2596*4882a593Smuzhiyun static int snd_es1968_free(struct es1968 *chip)
2597*4882a593Smuzhiyun {
2598*4882a593Smuzhiyun 	cancel_work_sync(&chip->hwvol_work);
2599*4882a593Smuzhiyun #ifdef CONFIG_SND_ES1968_INPUT
2600*4882a593Smuzhiyun 	if (chip->input_dev)
2601*4882a593Smuzhiyun 		input_unregister_device(chip->input_dev);
2602*4882a593Smuzhiyun #endif
2603*4882a593Smuzhiyun 
2604*4882a593Smuzhiyun 	if (chip->io_port) {
2605*4882a593Smuzhiyun 		outw(1, chip->io_port + 0x04); /* clear WP interrupts */
2606*4882a593Smuzhiyun 		outw(0, chip->io_port + ESM_PORT_HOST_IRQ); /* disable IRQ */
2607*4882a593Smuzhiyun 	}
2608*4882a593Smuzhiyun 
2609*4882a593Smuzhiyun #ifdef CONFIG_SND_ES1968_RADIO
2610*4882a593Smuzhiyun 	snd_tea575x_exit(&chip->tea);
2611*4882a593Smuzhiyun 	v4l2_device_unregister(&chip->v4l2_dev);
2612*4882a593Smuzhiyun #endif
2613*4882a593Smuzhiyun 
2614*4882a593Smuzhiyun 	if (chip->irq >= 0)
2615*4882a593Smuzhiyun 		free_irq(chip->irq, chip);
2616*4882a593Smuzhiyun 	snd_es1968_free_gameport(chip);
2617*4882a593Smuzhiyun 	pci_release_regions(chip->pci);
2618*4882a593Smuzhiyun 	pci_disable_device(chip->pci);
2619*4882a593Smuzhiyun 	kfree(chip);
2620*4882a593Smuzhiyun 	return 0;
2621*4882a593Smuzhiyun }
2622*4882a593Smuzhiyun 
snd_es1968_dev_free(struct snd_device * device)2623*4882a593Smuzhiyun static int snd_es1968_dev_free(struct snd_device *device)
2624*4882a593Smuzhiyun {
2625*4882a593Smuzhiyun 	struct es1968 *chip = device->device_data;
2626*4882a593Smuzhiyun 	return snd_es1968_free(chip);
2627*4882a593Smuzhiyun }
2628*4882a593Smuzhiyun 
2629*4882a593Smuzhiyun struct ess_device_list {
2630*4882a593Smuzhiyun 	unsigned short type;	/* chip type */
2631*4882a593Smuzhiyun 	unsigned short vendor;	/* subsystem vendor id */
2632*4882a593Smuzhiyun };
2633*4882a593Smuzhiyun 
2634*4882a593Smuzhiyun static const struct ess_device_list pm_allowlist[] = {
2635*4882a593Smuzhiyun 	{ TYPE_MAESTRO2E, 0x0e11 },	/* Compaq Armada */
2636*4882a593Smuzhiyun 	{ TYPE_MAESTRO2E, 0x1028 },
2637*4882a593Smuzhiyun 	{ TYPE_MAESTRO2E, 0x103c },
2638*4882a593Smuzhiyun 	{ TYPE_MAESTRO2E, 0x1179 },
2639*4882a593Smuzhiyun 	{ TYPE_MAESTRO2E, 0x14c0 },	/* HP omnibook 4150 */
2640*4882a593Smuzhiyun 	{ TYPE_MAESTRO2E, 0x1558 },
2641*4882a593Smuzhiyun 	{ TYPE_MAESTRO2E, 0x125d },	/* a PCI card, e.g. Terratec DMX */
2642*4882a593Smuzhiyun 	{ TYPE_MAESTRO2, 0x125d },	/* a PCI card, e.g. SF64-PCE2 */
2643*4882a593Smuzhiyun };
2644*4882a593Smuzhiyun 
2645*4882a593Smuzhiyun static const struct ess_device_list mpu_denylist[] = {
2646*4882a593Smuzhiyun 	{ TYPE_MAESTRO2, 0x125d },
2647*4882a593Smuzhiyun };
2648*4882a593Smuzhiyun 
snd_es1968_create(struct snd_card * card,struct pci_dev * pci,int total_bufsize,int play_streams,int capt_streams,int chip_type,int do_pm,int radio_nr,struct es1968 ** chip_ret)2649*4882a593Smuzhiyun static int snd_es1968_create(struct snd_card *card,
2650*4882a593Smuzhiyun 			     struct pci_dev *pci,
2651*4882a593Smuzhiyun 			     int total_bufsize,
2652*4882a593Smuzhiyun 			     int play_streams,
2653*4882a593Smuzhiyun 			     int capt_streams,
2654*4882a593Smuzhiyun 			     int chip_type,
2655*4882a593Smuzhiyun 			     int do_pm,
2656*4882a593Smuzhiyun 			     int radio_nr,
2657*4882a593Smuzhiyun 			     struct es1968 **chip_ret)
2658*4882a593Smuzhiyun {
2659*4882a593Smuzhiyun 	static const struct snd_device_ops ops = {
2660*4882a593Smuzhiyun 		.dev_free =	snd_es1968_dev_free,
2661*4882a593Smuzhiyun 	};
2662*4882a593Smuzhiyun 	struct es1968 *chip;
2663*4882a593Smuzhiyun 	int i, err;
2664*4882a593Smuzhiyun 
2665*4882a593Smuzhiyun 	*chip_ret = NULL;
2666*4882a593Smuzhiyun 
2667*4882a593Smuzhiyun 	/* enable PCI device */
2668*4882a593Smuzhiyun 	if ((err = pci_enable_device(pci)) < 0)
2669*4882a593Smuzhiyun 		return err;
2670*4882a593Smuzhiyun 	/* check, if we can restrict PCI DMA transfers to 28 bits */
2671*4882a593Smuzhiyun 	if (dma_set_mask(&pci->dev, DMA_BIT_MASK(28)) < 0 ||
2672*4882a593Smuzhiyun 	    dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(28)) < 0) {
2673*4882a593Smuzhiyun 		dev_err(card->dev,
2674*4882a593Smuzhiyun 			"architecture does not support 28bit PCI busmaster DMA\n");
2675*4882a593Smuzhiyun 		pci_disable_device(pci);
2676*4882a593Smuzhiyun 		return -ENXIO;
2677*4882a593Smuzhiyun 	}
2678*4882a593Smuzhiyun 
2679*4882a593Smuzhiyun 	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
2680*4882a593Smuzhiyun 	if (! chip) {
2681*4882a593Smuzhiyun 		pci_disable_device(pci);
2682*4882a593Smuzhiyun 		return -ENOMEM;
2683*4882a593Smuzhiyun 	}
2684*4882a593Smuzhiyun 
2685*4882a593Smuzhiyun 	/* Set Vars */
2686*4882a593Smuzhiyun 	chip->type = chip_type;
2687*4882a593Smuzhiyun 	spin_lock_init(&chip->reg_lock);
2688*4882a593Smuzhiyun 	spin_lock_init(&chip->substream_lock);
2689*4882a593Smuzhiyun 	INIT_LIST_HEAD(&chip->buf_list);
2690*4882a593Smuzhiyun 	INIT_LIST_HEAD(&chip->substream_list);
2691*4882a593Smuzhiyun 	mutex_init(&chip->memory_mutex);
2692*4882a593Smuzhiyun 	INIT_WORK(&chip->hwvol_work, es1968_update_hw_volume);
2693*4882a593Smuzhiyun 	chip->card = card;
2694*4882a593Smuzhiyun 	chip->pci = pci;
2695*4882a593Smuzhiyun 	chip->irq = -1;
2696*4882a593Smuzhiyun 	chip->total_bufsize = total_bufsize;	/* in bytes */
2697*4882a593Smuzhiyun 	chip->playback_streams = play_streams;
2698*4882a593Smuzhiyun 	chip->capture_streams = capt_streams;
2699*4882a593Smuzhiyun 
2700*4882a593Smuzhiyun 	if ((err = pci_request_regions(pci, "ESS Maestro")) < 0) {
2701*4882a593Smuzhiyun 		kfree(chip);
2702*4882a593Smuzhiyun 		pci_disable_device(pci);
2703*4882a593Smuzhiyun 		return err;
2704*4882a593Smuzhiyun 	}
2705*4882a593Smuzhiyun 	chip->io_port = pci_resource_start(pci, 0);
2706*4882a593Smuzhiyun 	if (request_irq(pci->irq, snd_es1968_interrupt, IRQF_SHARED,
2707*4882a593Smuzhiyun 			KBUILD_MODNAME, chip)) {
2708*4882a593Smuzhiyun 		dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
2709*4882a593Smuzhiyun 		snd_es1968_free(chip);
2710*4882a593Smuzhiyun 		return -EBUSY;
2711*4882a593Smuzhiyun 	}
2712*4882a593Smuzhiyun 	chip->irq = pci->irq;
2713*4882a593Smuzhiyun 	card->sync_irq = chip->irq;
2714*4882a593Smuzhiyun 
2715*4882a593Smuzhiyun 	/* Clear Maestro_map */
2716*4882a593Smuzhiyun 	for (i = 0; i < 32; i++)
2717*4882a593Smuzhiyun 		chip->maestro_map[i] = 0;
2718*4882a593Smuzhiyun 
2719*4882a593Smuzhiyun 	/* Clear Apu Map */
2720*4882a593Smuzhiyun 	for (i = 0; i < NR_APUS; i++)
2721*4882a593Smuzhiyun 		chip->apu[i] = ESM_APU_FREE;
2722*4882a593Smuzhiyun 
2723*4882a593Smuzhiyun 	/* just to be sure */
2724*4882a593Smuzhiyun 	pci_set_master(pci);
2725*4882a593Smuzhiyun 
2726*4882a593Smuzhiyun 	if (do_pm > 1) {
2727*4882a593Smuzhiyun 		/* disable power-management if not on the allowlist */
2728*4882a593Smuzhiyun 		unsigned short vend;
2729*4882a593Smuzhiyun 		pci_read_config_word(chip->pci, PCI_SUBSYSTEM_VENDOR_ID, &vend);
2730*4882a593Smuzhiyun 		for (i = 0; i < (int)ARRAY_SIZE(pm_allowlist); i++) {
2731*4882a593Smuzhiyun 			if (chip->type == pm_allowlist[i].type &&
2732*4882a593Smuzhiyun 			    vend == pm_allowlist[i].vendor) {
2733*4882a593Smuzhiyun 				do_pm = 1;
2734*4882a593Smuzhiyun 				break;
2735*4882a593Smuzhiyun 			}
2736*4882a593Smuzhiyun 		}
2737*4882a593Smuzhiyun 		if (do_pm > 1) {
2738*4882a593Smuzhiyun 			/* not matched; disabling pm */
2739*4882a593Smuzhiyun 			dev_info(card->dev, "not attempting power management.\n");
2740*4882a593Smuzhiyun 			do_pm = 0;
2741*4882a593Smuzhiyun 		}
2742*4882a593Smuzhiyun 	}
2743*4882a593Smuzhiyun 	chip->do_pm = do_pm;
2744*4882a593Smuzhiyun 
2745*4882a593Smuzhiyun 	snd_es1968_chip_init(chip);
2746*4882a593Smuzhiyun 
2747*4882a593Smuzhiyun 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
2748*4882a593Smuzhiyun 		snd_es1968_free(chip);
2749*4882a593Smuzhiyun 		return err;
2750*4882a593Smuzhiyun 	}
2751*4882a593Smuzhiyun 
2752*4882a593Smuzhiyun #ifdef CONFIG_SND_ES1968_RADIO
2753*4882a593Smuzhiyun 	/* don't play with GPIOs on laptops */
2754*4882a593Smuzhiyun 	if (chip->pci->subsystem_vendor != 0x125d)
2755*4882a593Smuzhiyun 		goto no_radio;
2756*4882a593Smuzhiyun 	err = v4l2_device_register(&pci->dev, &chip->v4l2_dev);
2757*4882a593Smuzhiyun 	if (err < 0) {
2758*4882a593Smuzhiyun 		snd_es1968_free(chip);
2759*4882a593Smuzhiyun 		return err;
2760*4882a593Smuzhiyun 	}
2761*4882a593Smuzhiyun 	chip->tea.v4l2_dev = &chip->v4l2_dev;
2762*4882a593Smuzhiyun 	chip->tea.private_data = chip;
2763*4882a593Smuzhiyun 	chip->tea.radio_nr = radio_nr;
2764*4882a593Smuzhiyun 	chip->tea.ops = &snd_es1968_tea_ops;
2765*4882a593Smuzhiyun 	sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci));
2766*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(snd_es1968_tea575x_gpios); i++) {
2767*4882a593Smuzhiyun 		chip->tea575x_tuner = i;
2768*4882a593Smuzhiyun 		if (!snd_tea575x_init(&chip->tea, THIS_MODULE)) {
2769*4882a593Smuzhiyun 			dev_info(card->dev, "detected TEA575x radio type %s\n",
2770*4882a593Smuzhiyun 				   get_tea575x_gpio(chip)->name);
2771*4882a593Smuzhiyun 			strlcpy(chip->tea.card, get_tea575x_gpio(chip)->name,
2772*4882a593Smuzhiyun 				sizeof(chip->tea.card));
2773*4882a593Smuzhiyun 			break;
2774*4882a593Smuzhiyun 		}
2775*4882a593Smuzhiyun 	}
2776*4882a593Smuzhiyun no_radio:
2777*4882a593Smuzhiyun #endif
2778*4882a593Smuzhiyun 
2779*4882a593Smuzhiyun 	*chip_ret = chip;
2780*4882a593Smuzhiyun 
2781*4882a593Smuzhiyun 	return 0;
2782*4882a593Smuzhiyun }
2783*4882a593Smuzhiyun 
2784*4882a593Smuzhiyun 
2785*4882a593Smuzhiyun /*
2786*4882a593Smuzhiyun  */
snd_es1968_probe(struct pci_dev * pci,const struct pci_device_id * pci_id)2787*4882a593Smuzhiyun static int snd_es1968_probe(struct pci_dev *pci,
2788*4882a593Smuzhiyun 			    const struct pci_device_id *pci_id)
2789*4882a593Smuzhiyun {
2790*4882a593Smuzhiyun 	static int dev;
2791*4882a593Smuzhiyun 	struct snd_card *card;
2792*4882a593Smuzhiyun 	struct es1968 *chip;
2793*4882a593Smuzhiyun 	unsigned int i;
2794*4882a593Smuzhiyun 	int err;
2795*4882a593Smuzhiyun 
2796*4882a593Smuzhiyun 	if (dev >= SNDRV_CARDS)
2797*4882a593Smuzhiyun 		return -ENODEV;
2798*4882a593Smuzhiyun 	if (!enable[dev]) {
2799*4882a593Smuzhiyun 		dev++;
2800*4882a593Smuzhiyun 		return -ENOENT;
2801*4882a593Smuzhiyun 	}
2802*4882a593Smuzhiyun 
2803*4882a593Smuzhiyun 	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
2804*4882a593Smuzhiyun 			   0, &card);
2805*4882a593Smuzhiyun 	if (err < 0)
2806*4882a593Smuzhiyun 		return err;
2807*4882a593Smuzhiyun 
2808*4882a593Smuzhiyun 	if (total_bufsize[dev] < 128)
2809*4882a593Smuzhiyun 		total_bufsize[dev] = 128;
2810*4882a593Smuzhiyun 	if (total_bufsize[dev] > 4096)
2811*4882a593Smuzhiyun 		total_bufsize[dev] = 4096;
2812*4882a593Smuzhiyun 	if ((err = snd_es1968_create(card, pci,
2813*4882a593Smuzhiyun 				     total_bufsize[dev] * 1024, /* in bytes */
2814*4882a593Smuzhiyun 				     pcm_substreams_p[dev],
2815*4882a593Smuzhiyun 				     pcm_substreams_c[dev],
2816*4882a593Smuzhiyun 				     pci_id->driver_data,
2817*4882a593Smuzhiyun 				     use_pm[dev],
2818*4882a593Smuzhiyun 				     radio_nr[dev],
2819*4882a593Smuzhiyun 				     &chip)) < 0) {
2820*4882a593Smuzhiyun 		snd_card_free(card);
2821*4882a593Smuzhiyun 		return err;
2822*4882a593Smuzhiyun 	}
2823*4882a593Smuzhiyun 	card->private_data = chip;
2824*4882a593Smuzhiyun 
2825*4882a593Smuzhiyun 	switch (chip->type) {
2826*4882a593Smuzhiyun 	case TYPE_MAESTRO2E:
2827*4882a593Smuzhiyun 		strcpy(card->driver, "ES1978");
2828*4882a593Smuzhiyun 		strcpy(card->shortname, "ESS ES1978 (Maestro 2E)");
2829*4882a593Smuzhiyun 		break;
2830*4882a593Smuzhiyun 	case TYPE_MAESTRO2:
2831*4882a593Smuzhiyun 		strcpy(card->driver, "ES1968");
2832*4882a593Smuzhiyun 		strcpy(card->shortname, "ESS ES1968 (Maestro 2)");
2833*4882a593Smuzhiyun 		break;
2834*4882a593Smuzhiyun 	case TYPE_MAESTRO:
2835*4882a593Smuzhiyun 		strcpy(card->driver, "ESM1");
2836*4882a593Smuzhiyun 		strcpy(card->shortname, "ESS Maestro 1");
2837*4882a593Smuzhiyun 		break;
2838*4882a593Smuzhiyun 	}
2839*4882a593Smuzhiyun 
2840*4882a593Smuzhiyun 	if ((err = snd_es1968_pcm(chip, 0)) < 0) {
2841*4882a593Smuzhiyun 		snd_card_free(card);
2842*4882a593Smuzhiyun 		return err;
2843*4882a593Smuzhiyun 	}
2844*4882a593Smuzhiyun 
2845*4882a593Smuzhiyun 	if ((err = snd_es1968_mixer(chip)) < 0) {
2846*4882a593Smuzhiyun 		snd_card_free(card);
2847*4882a593Smuzhiyun 		return err;
2848*4882a593Smuzhiyun 	}
2849*4882a593Smuzhiyun 
2850*4882a593Smuzhiyun 	if (enable_mpu[dev] == 2) {
2851*4882a593Smuzhiyun 		/* check the deny list */
2852*4882a593Smuzhiyun 		unsigned short vend;
2853*4882a593Smuzhiyun 		pci_read_config_word(chip->pci, PCI_SUBSYSTEM_VENDOR_ID, &vend);
2854*4882a593Smuzhiyun 		for (i = 0; i < ARRAY_SIZE(mpu_denylist); i++) {
2855*4882a593Smuzhiyun 			if (chip->type == mpu_denylist[i].type &&
2856*4882a593Smuzhiyun 			    vend == mpu_denylist[i].vendor) {
2857*4882a593Smuzhiyun 				enable_mpu[dev] = 0;
2858*4882a593Smuzhiyun 				break;
2859*4882a593Smuzhiyun 			}
2860*4882a593Smuzhiyun 		}
2861*4882a593Smuzhiyun 	}
2862*4882a593Smuzhiyun 	if (enable_mpu[dev]) {
2863*4882a593Smuzhiyun 		if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
2864*4882a593Smuzhiyun 					       chip->io_port + ESM_MPU401_PORT,
2865*4882a593Smuzhiyun 					       MPU401_INFO_INTEGRATED |
2866*4882a593Smuzhiyun 					       MPU401_INFO_IRQ_HOOK,
2867*4882a593Smuzhiyun 					       -1, &chip->rmidi)) < 0) {
2868*4882a593Smuzhiyun 			dev_warn(card->dev, "skipping MPU-401 MIDI support..\n");
2869*4882a593Smuzhiyun 		}
2870*4882a593Smuzhiyun 	}
2871*4882a593Smuzhiyun 
2872*4882a593Smuzhiyun 	snd_es1968_create_gameport(chip, dev);
2873*4882a593Smuzhiyun 
2874*4882a593Smuzhiyun #ifdef CONFIG_SND_ES1968_INPUT
2875*4882a593Smuzhiyun 	err = snd_es1968_input_register(chip);
2876*4882a593Smuzhiyun 	if (err)
2877*4882a593Smuzhiyun 		dev_warn(card->dev,
2878*4882a593Smuzhiyun 			 "Input device registration failed with error %i", err);
2879*4882a593Smuzhiyun #endif
2880*4882a593Smuzhiyun 
2881*4882a593Smuzhiyun 	snd_es1968_start_irq(chip);
2882*4882a593Smuzhiyun 
2883*4882a593Smuzhiyun 	chip->clock = clock[dev];
2884*4882a593Smuzhiyun 	if (! chip->clock)
2885*4882a593Smuzhiyun 		es1968_measure_clock(chip);
2886*4882a593Smuzhiyun 
2887*4882a593Smuzhiyun 	sprintf(card->longname, "%s at 0x%lx, irq %i",
2888*4882a593Smuzhiyun 		card->shortname, chip->io_port, chip->irq);
2889*4882a593Smuzhiyun 
2890*4882a593Smuzhiyun 	if ((err = snd_card_register(card)) < 0) {
2891*4882a593Smuzhiyun 		snd_card_free(card);
2892*4882a593Smuzhiyun 		return err;
2893*4882a593Smuzhiyun 	}
2894*4882a593Smuzhiyun 	pci_set_drvdata(pci, card);
2895*4882a593Smuzhiyun 	dev++;
2896*4882a593Smuzhiyun 	return 0;
2897*4882a593Smuzhiyun }
2898*4882a593Smuzhiyun 
snd_es1968_remove(struct pci_dev * pci)2899*4882a593Smuzhiyun static void snd_es1968_remove(struct pci_dev *pci)
2900*4882a593Smuzhiyun {
2901*4882a593Smuzhiyun 	snd_card_free(pci_get_drvdata(pci));
2902*4882a593Smuzhiyun }
2903*4882a593Smuzhiyun 
2904*4882a593Smuzhiyun static struct pci_driver es1968_driver = {
2905*4882a593Smuzhiyun 	.name = KBUILD_MODNAME,
2906*4882a593Smuzhiyun 	.id_table = snd_es1968_ids,
2907*4882a593Smuzhiyun 	.probe = snd_es1968_probe,
2908*4882a593Smuzhiyun 	.remove = snd_es1968_remove,
2909*4882a593Smuzhiyun 	.driver = {
2910*4882a593Smuzhiyun 		.pm = ES1968_PM_OPS,
2911*4882a593Smuzhiyun 	},
2912*4882a593Smuzhiyun };
2913*4882a593Smuzhiyun 
2914*4882a593Smuzhiyun module_pci_driver(es1968_driver);
2915