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