Blame view

sound/pci/ens1370.c 78.5 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
  /*
   *  Driver for Ensoniq ES1370/ES1371 AudioPCI soundcard
c1017a4cd   Jaroslav Kysela   [ALSA] Changed Ja...
3
   *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
   *		     Thomas Sailer <sailer@ife.ee.ethz.ch>
   *
   *   This program is free software; you can redistribute it and/or modify
   *   it under the terms of the GNU General Public License as published by
   *   the Free Software Foundation; either version 2 of the License, or
   *   (at your option) any later version.
   *
   *   This program is distributed in the hope that it will be useful,
   *   but WITHOUT ANY WARRANTY; without even the implied warranty of
   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *   GNU General Public License for more details.
   *
   *   You should have received a copy of the GNU General Public License
   *   along with this program; if not, write to the Free Software
   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   *
   */
f31a31b90   Kurt J. Bosch   [ALSA] Fix missin...
21
22
23
  /* Power-Management-Code ( CONFIG_PM )
   * for ens1371 only ( FIXME )
   * derived from cs4281.c, atiixp.c and via82xx.c
631dd1a88   Justin P. Mattock   Update broken web...
24
   * using http://www.alsa-project.org/~tiwai/writing-an-alsa-driver/ 
f31a31b90   Kurt J. Bosch   [ALSA] Fix missin...
25
26
   * by Kurt J. Bosch
   */
6cbbfe1c8   Takashi Iwai   ALSA: Include lin...
27
  #include <linux/io.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28
29
30
31
32
33
  #include <linux/delay.h>
  #include <linux/interrupt.h>
  #include <linux/init.h>
  #include <linux/pci.h>
  #include <linux/slab.h>
  #include <linux/gameport.h>
65a772172   Paul Gortmaker   sound: fix driver...
34
  #include <linux/module.h>
62932df8f   Ingo Molnar   [ALSA] semaphore ...
35
  #include <linux/mutex.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
  #include <sound/core.h>
  #include <sound/control.h>
  #include <sound/pcm.h>
  #include <sound/rawmidi.h>
  #ifdef CHIP1371
  #include <sound/ac97_codec.h>
  #else
  #include <sound/ak4531_codec.h>
  #endif
  #include <sound/initval.h>
  #include <sound/asoundef.h>
  
  #ifndef CHIP1371
  #undef CHIP1370
  #define CHIP1370
  #endif
  
  #ifdef CHIP1370
  #define DRIVER_NAME "ENS1370"
1fe4d42e0   Takashi Iwai   ALSA: ens1370: Re...
55
  #define CHIP_NAME "ES1370" /* it can be ENS but just to keep compatibility... */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
57
  #else
  #define DRIVER_NAME "ENS1371"
1fe4d42e0   Takashi Iwai   ALSA: ens1370: Re...
58
  #define CHIP_NAME "ES1371"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
  #endif
c1017a4cd   Jaroslav Kysela   [ALSA] Changed Ja...
60
  MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Thomas Sailer <sailer@ife.ee.ethz.ch>");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
  MODULE_LICENSE("GPL");
  #ifdef CHIP1370
  MODULE_DESCRIPTION("Ensoniq AudioPCI ES1370");
  MODULE_SUPPORTED_DEVICE("{{Ensoniq,AudioPCI-97 ES1370},"
  	        "{Creative Labs,SB PCI64/128 (ES1370)}}");
  #endif
  #ifdef CHIP1371
  MODULE_DESCRIPTION("Ensoniq/Creative AudioPCI ES1371+");
  MODULE_SUPPORTED_DEVICE("{{Ensoniq,AudioPCI ES1371/73},"
  		"{Ensoniq,AudioPCI ES1373},"
  		"{Creative Labs,Ectiva EV1938},"
  		"{Creative Labs,SB PCI64/128 (ES1371/73)},"
  		"{Creative Labs,Vibra PCI128},"
  		"{Ectiva,EV1938}}");
  #endif
b2fac0730   Fabian Frederick   ALSA: pci: don't ...
76
  #if IS_REACHABLE(CONFIG_GAMEPORT)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
78
79
80
81
  #define SUPPORT_JOYSTICK
  #endif
  
  static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
  static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
a67ff6a54   Rusty Russell   ALSA: module_para...
82
  static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable switches */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
83
84
85
86
  #ifdef SUPPORT_JOYSTICK
  #ifdef CHIP1371
  static int joystick_port[SNDRV_CARDS];
  #else
a67ff6a54   Rusty Russell   ALSA: module_para...
87
  static bool joystick[SNDRV_CARDS];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
89
  #endif
  #endif
156b2aa3b   Clemens Ladisch   [ALSA] ens1371: f...
90
91
92
93
  #ifdef CHIP1371
  static int spdif[SNDRV_CARDS];
  static int lineio[SNDRV_CARDS];
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
95
96
97
98
99
100
101
102
  
  module_param_array(index, int, NULL, 0444);
  MODULE_PARM_DESC(index, "Index value for Ensoniq AudioPCI soundcard.");
  module_param_array(id, charp, NULL, 0444);
  MODULE_PARM_DESC(id, "ID string for Ensoniq AudioPCI soundcard.");
  module_param_array(enable, bool, NULL, 0444);
  MODULE_PARM_DESC(enable, "Enable Ensoniq AudioPCI soundcard.");
  #ifdef SUPPORT_JOYSTICK
  #ifdef CHIP1371
6192c41fc   David Howells   Annotate hardware...
103
  module_param_hw_array(joystick_port, int, ioport, NULL, 0444);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
104
105
106
107
108
109
  MODULE_PARM_DESC(joystick_port, "Joystick port address.");
  #else
  module_param_array(joystick, bool, NULL, 0444);
  MODULE_PARM_DESC(joystick, "Enable joystick.");
  #endif
  #endif /* SUPPORT_JOYSTICK */
156b2aa3b   Clemens Ladisch   [ALSA] ens1371: f...
110
111
112
113
114
115
  #ifdef CHIP1371
  module_param_array(spdif, int, NULL, 0444);
  MODULE_PARM_DESC(spdif, "S/PDIF output (-1 = none, 0 = auto, 1 = force).");
  module_param_array(lineio, int, NULL, 0444);
  MODULE_PARM_DESC(lineio, "Line In to Rear Out (0 = auto, 1 = force).");
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
  /* ES1371 chip ID */
  /* This is a little confusing because all ES1371 compatible chips have the
     same DEVICE_ID, the only thing differentiating them is the REV_ID field.
     This is only significant if you want to enable features on the later parts.
     Yes, I know it's stupid and why didn't we use the sub IDs?
  */
  #define ES1371REV_ES1373_A  0x04
  #define ES1371REV_ES1373_B  0x06
  #define ES1371REV_CT5880_A  0x07
  #define CT5880REV_CT5880_C  0x02
  #define CT5880REV_CT5880_D  0x03	/* ??? -jk */
  #define CT5880REV_CT5880_E  0x04	/* mw */
  #define ES1371REV_ES1371_B  0x09
  #define EV1938REV_EV1938_A  0x00
  #define ES1371REV_ES1373_8  0x08
  
  /*
   * Direct registers
   */
  
  #define ES_REG(ensoniq, x) ((ensoniq)->port + ES_REG_##x)
  
  #define ES_REG_CONTROL	0x00	/* R/W: Interrupt/Chip select control register */
  #define   ES_1370_ADC_STOP	(1<<31)		/* disable capture buffer transfers */
  #define   ES_1370_XCTL1 	(1<<30)		/* general purpose output bit */
  #define   ES_1373_BYPASS_P1	(1<<31)		/* bypass SRC for PB1 */
  #define   ES_1373_BYPASS_P2	(1<<30)		/* bypass SRC for PB2 */
  #define   ES_1373_BYPASS_R	(1<<29)		/* bypass SRC for REC */
  #define   ES_1373_TEST_BIT	(1<<28)		/* should be set to 0 for normal operation */
  #define   ES_1373_RECEN_B	(1<<27)		/* mix record with playback for I2S/SPDIF out */
  #define   ES_1373_SPDIF_THRU	(1<<26)		/* 0 = SPDIF thru mode, 1 = SPDIF == dig out */
  #define   ES_1371_JOY_ASEL(o)	(((o)&0x03)<<24)/* joystick port mapping */
  #define   ES_1371_JOY_ASELM	(0x03<<24)	/* mask for above */
  #define   ES_1371_JOY_ASELI(i)  (((i)>>24)&0x03)
  #define   ES_1371_GPIO_IN(i)	(((i)>>20)&0x0f)/* GPIO in [3:0] pins - R/O */
  #define   ES_1370_PCLKDIVO(o)	(((o)&0x1fff)<<16)/* clock divide ratio for DAC2 */
  #define   ES_1370_PCLKDIVM	((0x1fff)<<16)	/* mask for above */
  #define   ES_1370_PCLKDIVI(i)	(((i)>>16)&0x1fff)/* clock divide ratio for DAC2 */
  #define   ES_1371_GPIO_OUT(o)	(((o)&0x0f)<<16)/* GPIO out [3:0] pins - W/R */
  #define   ES_1371_GPIO_OUTM     (0x0f<<16)	/* mask for above */
  #define   ES_MSFMTSEL		(1<<15)		/* MPEG serial data format; 0 = SONY, 1 = I2S */
  #define   ES_1370_M_SBB		(1<<14)		/* clock source for DAC - 0 = clock generator; 1 = MPEG clocks */
  #define   ES_1371_SYNC_RES	(1<<14)		/* Warm AC97 reset */
  #define   ES_1370_WTSRSEL(o)	(((o)&0x03)<<12)/* fixed frequency clock for DAC1 */
  #define   ES_1370_WTSRSELM	(0x03<<12)	/* mask for above */
  #define   ES_1371_ADC_STOP	(1<<13)		/* disable CCB transfer capture information */
  #define   ES_1371_PWR_INTRM	(1<<12)		/* power level change interrupts enable */
  #define   ES_1370_DAC_SYNC	(1<<11)		/* DAC's are synchronous */
  #define   ES_1371_M_CB		(1<<11)		/* capture clock source; 0 = AC'97 ADC; 1 = I2S */
  #define   ES_CCB_INTRM		(1<<10)		/* CCB voice interrupts enable */
  #define   ES_1370_M_CB		(1<<9)		/* capture clock source; 0 = ADC; 1 = MPEG */
  #define   ES_1370_XCTL0		(1<<8)		/* generap purpose output bit */
  #define   ES_1371_PDLEV(o)	(((o)&0x03)<<8)	/* current power down level */
  #define   ES_1371_PDLEVM	(0x03<<8)	/* mask for above */
  #define   ES_BREQ		(1<<7)		/* memory bus request enable */
  #define   ES_DAC1_EN		(1<<6)		/* DAC1 playback channel enable */
  #define   ES_DAC2_EN		(1<<5)		/* DAC2 playback channel enable */
  #define   ES_ADC_EN		(1<<4)		/* ADC capture channel enable */
  #define   ES_UART_EN		(1<<3)		/* UART enable */
  #define   ES_JYSTK_EN		(1<<2)		/* Joystick module enable */
  #define   ES_1370_CDC_EN	(1<<1)		/* Codec interface enable */
  #define   ES_1371_XTALCKDIS	(1<<1)		/* Xtal clock disable */
  #define   ES_1370_SERR_DISABLE	(1<<0)		/* PCI serr signal disable */
  #define   ES_1371_PCICLKDIS     (1<<0)		/* PCI clock disable */
  #define ES_REG_STATUS	0x04	/* R/O: Interrupt/Chip select status register */
  #define   ES_INTR               (1<<31)		/* Interrupt is pending */
  #define   ES_1371_ST_AC97_RST	(1<<29)		/* CT5880 AC'97 Reset bit */
  #define   ES_1373_REAR_BIT27	(1<<27)		/* rear bits: 000 - front, 010 - mirror, 101 - separate */
  #define   ES_1373_REAR_BIT26	(1<<26)
  #define   ES_1373_REAR_BIT24	(1<<24)
  #define   ES_1373_GPIO_INT_EN(o)(((o)&0x0f)<<20)/* GPIO [3:0] pins - interrupt enable */
  #define   ES_1373_SPDIF_EN	(1<<18)		/* SPDIF enable */
  #define   ES_1373_SPDIF_TEST	(1<<17)		/* SPDIF test */
  #define   ES_1371_TEST          (1<<16)		/* test ASIC */
  #define   ES_1373_GPIO_INT(i)	(((i)&0x0f)>>12)/* GPIO [3:0] pins - interrupt pending */
  #define   ES_1370_CSTAT		(1<<10)		/* CODEC is busy or register write in progress */
  #define   ES_1370_CBUSY         (1<<9)		/* CODEC is busy */
  #define   ES_1370_CWRIP		(1<<8)		/* CODEC register write in progress */
  #define   ES_1371_SYNC_ERR	(1<<8)		/* CODEC synchronization error occurred */
  #define   ES_1371_VC(i)         (((i)>>6)&0x03)	/* voice code from CCB module */
  #define   ES_1370_VC(i)		(((i)>>5)&0x03)	/* voice code from CCB module */
  #define   ES_1371_MPWR          (1<<5)		/* power level interrupt pending */
  #define   ES_MCCB		(1<<4)		/* CCB interrupt pending */
  #define   ES_UART		(1<<3)		/* UART interrupt pending */
  #define   ES_DAC1		(1<<2)		/* DAC1 channel interrupt pending */
  #define   ES_DAC2		(1<<1)		/* DAC2 channel interrupt pending */
  #define   ES_ADC		(1<<0)		/* ADC channel interrupt pending */
  #define ES_REG_UART_DATA 0x08	/* R/W: UART data register */
  #define ES_REG_UART_STATUS 0x09	/* R/O: UART status register */
  #define   ES_RXINT		(1<<7)		/* RX interrupt occurred */
  #define   ES_TXINT		(1<<2)		/* TX interrupt occurred */
  #define   ES_TXRDY		(1<<1)		/* transmitter ready */
  #define   ES_RXRDY		(1<<0)		/* receiver ready */
  #define ES_REG_UART_CONTROL 0x09	/* W/O: UART control register */
  #define   ES_RXINTEN		(1<<7)		/* RX interrupt enable */
  #define   ES_TXINTENO(o)	(((o)&0x03)<<5)	/* TX interrupt enable */
  #define   ES_TXINTENM		(0x03<<5)	/* mask for above */
  #define   ES_TXINTENI(i)	(((i)>>5)&0x03)
  #define   ES_CNTRL(o)		(((o)&0x03)<<0)	/* control */
  #define   ES_CNTRLM		(0x03<<0)	/* mask for above */
  #define ES_REG_UART_RES	0x0a	/* R/W: UART reserver register */
  #define   ES_TEST_MODE		(1<<0)		/* test mode enabled */
  #define ES_REG_MEM_PAGE	0x0c	/* R/W: Memory page register */
  #define   ES_MEM_PAGEO(o)	(((o)&0x0f)<<0)	/* memory page select - out */
  #define   ES_MEM_PAGEM		(0x0f<<0)	/* mask for above */
  #define   ES_MEM_PAGEI(i)	(((i)>>0)&0x0f) /* memory page select - in */
  #define ES_REG_1370_CODEC 0x10	/* W/O: Codec write register address */
  #define   ES_1370_CODEC_WRITE(a,d) ((((a)&0xff)<<8)|(((d)&0xff)<<0))
  #define ES_REG_1371_CODEC 0x14	/* W/R: Codec Read/Write register address */
  #define   ES_1371_CODEC_RDY	   (1<<31)	/* codec ready */
  #define   ES_1371_CODEC_WIP	   (1<<30)	/* codec register access in progress */
6ebb8a4a4   Clemens Ladisch   ALSA: ens1371: fi...
228
  #define   EV_1938_CODEC_MAGIC	   (1<<26)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
  #define   ES_1371_CODEC_PIRD	   (1<<23)	/* codec read/write select register */
  #define   ES_1371_CODEC_WRITE(a,d) ((((a)&0x7f)<<16)|(((d)&0xffff)<<0))
  #define   ES_1371_CODEC_READS(a)   ((((a)&0x7f)<<16)|ES_1371_CODEC_PIRD)
  #define   ES_1371_CODEC_READ(i)    (((i)>>0)&0xffff)
  
  #define ES_REG_1371_SMPRATE 0x10	/* W/R: Codec rate converter interface register */
  #define   ES_1371_SRC_RAM_ADDRO(o) (((o)&0x7f)<<25)/* address of the sample rate converter */
  #define   ES_1371_SRC_RAM_ADDRM	   (0x7f<<25)	/* mask for above */
  #define   ES_1371_SRC_RAM_ADDRI(i) (((i)>>25)&0x7f)/* address of the sample rate converter */
  #define   ES_1371_SRC_RAM_WE	   (1<<24)	/* R/W: read/write control for sample rate converter */
  #define   ES_1371_SRC_RAM_BUSY     (1<<23)	/* R/O: sample rate memory is busy */
  #define   ES_1371_SRC_DISABLE      (1<<22)	/* sample rate converter disable */
  #define   ES_1371_DIS_P1	   (1<<21)	/* playback channel 1 accumulator update disable */
  #define   ES_1371_DIS_P2	   (1<<20)	/* playback channel 1 accumulator update disable */
  #define   ES_1371_DIS_R1	   (1<<19)	/* capture channel accumulator update disable */
  #define   ES_1371_SRC_RAM_DATAO(o) (((o)&0xffff)<<0)/* current value of the sample rate converter */
  #define   ES_1371_SRC_RAM_DATAM	   (0xffff<<0)	/* mask for above */
  #define   ES_1371_SRC_RAM_DATAI(i) (((i)>>0)&0xffff)/* current value of the sample rate converter */
  
  #define ES_REG_1371_LEGACY 0x18	/* W/R: Legacy control/status register */
  #define   ES_1371_JFAST		(1<<31)		/* fast joystick timing */
  #define   ES_1371_HIB		(1<<30)		/* host interrupt blocking enable */
  #define   ES_1371_VSB		(1<<29)		/* SB; 0 = addr 0x220xH, 1 = 0x22FxH */
  #define   ES_1371_VMPUO(o)	(((o)&0x03)<<27)/* base register address; 0 = 0x320xH; 1 = 0x330xH; 2 = 0x340xH; 3 = 0x350xH */
  #define   ES_1371_VMPUM		(0x03<<27)	/* mask for above */
  #define   ES_1371_VMPUI(i)	(((i)>>27)&0x03)/* base register address */
  #define   ES_1371_VCDCO(o)	(((o)&0x03)<<25)/* CODEC; 0 = 0x530xH; 1 = undefined; 2 = 0xe80xH; 3 = 0xF40xH */
  #define   ES_1371_VCDCM		(0x03<<25)	/* mask for above */
  #define   ES_1371_VCDCI(i)	(((i)>>25)&0x03)/* CODEC address */
  #define   ES_1371_FIRQ		(1<<24)		/* force an interrupt */
  #define   ES_1371_SDMACAP	(1<<23)		/* enable event capture for slave DMA controller */
  #define   ES_1371_SPICAP	(1<<22)		/* enable event capture for slave IRQ controller */
  #define   ES_1371_MDMACAP	(1<<21)		/* enable event capture for master DMA controller */
  #define   ES_1371_MPICAP	(1<<20)		/* enable event capture for master IRQ controller */
  #define   ES_1371_ADCAP		(1<<19)		/* enable event capture for ADLIB register; 0x388xH */
  #define   ES_1371_SVCAP		(1<<18)		/* enable event capture for SB registers */
  #define   ES_1371_CDCCAP	(1<<17)		/* enable event capture for CODEC registers */
  #define   ES_1371_BACAP		(1<<16)		/* enable event capture for SoundScape base address */
  #define   ES_1371_EXI(i)	(((i)>>8)&0x07)	/* event number */
  #define   ES_1371_AI(i)		(((i)>>3)&0x1f)	/* event significant I/O address */
  #define   ES_1371_WR		(1<<2)	/* event capture; 0 = read; 1 = write */
  #define   ES_1371_LEGINT	(1<<0)	/* interrupt for legacy events; 0 = interrupt did occur */
  
  #define ES_REG_CHANNEL_STATUS 0x1c /* R/W: first 32-bits from S/PDIF channel status block, es1373 */
  
  #define ES_REG_SERIAL	0x20	/* R/W: Serial interface control register */
  #define   ES_1371_DAC_TEST	(1<<22)		/* DAC test mode enable */
  #define   ES_P2_END_INCO(o)	(((o)&0x07)<<19)/* binary offset value to increment / loop end */
  #define   ES_P2_END_INCM	(0x07<<19)	/* mask for above */
  #define   ES_P2_END_INCI(i)	(((i)>>16)&0x07)/* binary offset value to increment / loop end */
  #define   ES_P2_ST_INCO(o)	(((o)&0x07)<<16)/* binary offset value to increment / start */
  #define   ES_P2_ST_INCM		(0x07<<16)	/* mask for above */
  #define   ES_P2_ST_INCI(i)	(((i)<<16)&0x07)/* binary offset value to increment / start */
  #define   ES_R1_LOOP_SEL	(1<<15)		/* ADC; 0 - loop mode; 1 = stop mode */
  #define   ES_P2_LOOP_SEL	(1<<14)		/* DAC2; 0 - loop mode; 1 = stop mode */
  #define   ES_P1_LOOP_SEL	(1<<13)		/* DAC1; 0 - loop mode; 1 = stop mode */
  #define   ES_P2_PAUSE		(1<<12)		/* DAC2; 0 - play mode; 1 = pause mode */
  #define   ES_P1_PAUSE		(1<<11)		/* DAC1; 0 - play mode; 1 = pause mode */
  #define   ES_R1_INT_EN		(1<<10)		/* ADC interrupt enable */
  #define   ES_P2_INT_EN		(1<<9)		/* DAC2 interrupt enable */
  #define   ES_P1_INT_EN		(1<<8)		/* DAC1 interrupt enable */
  #define   ES_P1_SCT_RLD		(1<<7)		/* force sample counter reload for DAC1 */
  #define   ES_P2_DAC_SEN		(1<<6)		/* when stop mode: 0 - DAC2 play back zeros; 1 = DAC2 play back last sample */
  #define   ES_R1_MODEO(o)	(((o)&0x03)<<4)	/* ADC mode; 0 = 8-bit mono; 1 = 8-bit stereo; 2 = 16-bit mono; 3 = 16-bit stereo */
  #define   ES_R1_MODEM		(0x03<<4)	/* mask for above */
  #define   ES_R1_MODEI(i)	(((i)>>4)&0x03)
  #define   ES_P2_MODEO(o)	(((o)&0x03)<<2)	/* DAC2 mode; -- '' -- */
  #define   ES_P2_MODEM		(0x03<<2)	/* mask for above */
  #define   ES_P2_MODEI(i)	(((i)>>2)&0x03)
  #define   ES_P1_MODEO(o)	(((o)&0x03)<<0)	/* DAC1 mode; -- '' -- */
  #define   ES_P1_MODEM		(0x03<<0)	/* mask for above */
  #define   ES_P1_MODEI(i)	(((i)>>0)&0x03)
  
  #define ES_REG_DAC1_COUNT 0x24	/* R/W: DAC1 sample count register */
  #define ES_REG_DAC2_COUNT 0x28	/* R/W: DAC2 sample count register */
  #define ES_REG_ADC_COUNT  0x2c	/* R/W: ADC sample count register */
  #define   ES_REG_CURR_COUNT(i)  (((i)>>16)&0xffff)
  #define   ES_REG_COUNTO(o)	(((o)&0xffff)<<0)
  #define   ES_REG_COUNTM		(0xffff<<0)
  #define   ES_REG_COUNTI(i)	(((i)>>0)&0xffff)
  
  #define ES_REG_DAC1_FRAME 0x30	/* R/W: PAGE 0x0c; DAC1 frame address */
  #define ES_REG_DAC1_SIZE  0x34	/* R/W: PAGE 0x0c; DAC1 frame size */
  #define ES_REG_DAC2_FRAME 0x38	/* R/W: PAGE 0x0c; DAC2 frame address */
  #define ES_REG_DAC2_SIZE  0x3c	/* R/W: PAGE 0x0c; DAC2 frame size */
  #define ES_REG_ADC_FRAME  0x30	/* R/W: PAGE 0x0d; ADC frame address */
  #define ES_REG_ADC_SIZE	  0x34	/* R/W: PAGE 0x0d; ADC frame size */
  #define   ES_REG_FCURR_COUNTO(o) (((o)&0xffff)<<16)
  #define   ES_REG_FCURR_COUNTM    (0xffff<<16)
  #define   ES_REG_FCURR_COUNTI(i) (((i)>>14)&0x3fffc)
  #define   ES_REG_FSIZEO(o)	 (((o)&0xffff)<<0)
  #define   ES_REG_FSIZEM		 (0xffff<<0)
  #define   ES_REG_FSIZEI(i)	 (((i)>>0)&0xffff)
  #define ES_REG_PHANTOM_FRAME 0x38 /* R/W: PAGE 0x0d: phantom frame address */
  #define ES_REG_PHANTOM_COUNT 0x3c /* R/W: PAGE 0x0d: phantom frame count */
  
  #define ES_REG_UART_FIFO  0x30	/* R/W: PAGE 0x0e; UART FIFO register */
  #define   ES_REG_UF_VALID	 (1<<8)
  #define   ES_REG_UF_BYTEO(o)	 (((o)&0xff)<<0)
  #define   ES_REG_UF_BYTEM	 (0xff<<0)
  #define   ES_REG_UF_BYTEI(i)	 (((i)>>0)&0xff)
  
  
  /*
   *  Pages
   */
  
  #define ES_PAGE_DAC	0x0c
  #define ES_PAGE_ADC	0x0d
  #define ES_PAGE_UART	0x0e
  #define ES_PAGE_UART1	0x0f
  
  /*
   *  Sample rate converter addresses
   */
  
  #define ES_SMPREG_DAC1		0x70
  #define ES_SMPREG_DAC2		0x74
  #define ES_SMPREG_ADC		0x78
  #define ES_SMPREG_VOL_ADC	0x6c
  #define ES_SMPREG_VOL_DAC1	0x7c
  #define ES_SMPREG_VOL_DAC2	0x7e
  #define ES_SMPREG_TRUNC_N	0x00
  #define ES_SMPREG_INT_REGS	0x01
  #define ES_SMPREG_ACCUM_FRAC	0x02
  #define ES_SMPREG_VFREQ_FRAC	0x03
  
  /*
   *  Some contants
   */
  
  #define ES_1370_SRCLOCK	   1411200
  #define ES_1370_SRTODIV(x) (ES_1370_SRCLOCK/(x)-2)
  
  /*
   *  Open modes
   */
  
  #define ES_MODE_PLAY1	0x0001
  #define ES_MODE_PLAY2	0x0002
  #define ES_MODE_CAPTURE	0x0004
  
  #define ES_MODE_OUTPUT	0x0001	/* for MIDI */
  #define ES_MODE_INPUT	0x0002	/* for MIDI */
  
  /*
  
   */
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
377
  struct ensoniq {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
378
  	spinlock_t reg_lock;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
379
  	struct mutex src_mutex;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
  
  	int irq;
  
  	unsigned long playback1size;
  	unsigned long playback2size;
  	unsigned long capture3size;
  
  	unsigned long port;
  	unsigned int mode;
  	unsigned int uartm;	/* UART mode */
  
  	unsigned int ctrl;	/* control register */
  	unsigned int sctrl;	/* serial control register */
  	unsigned int cssr;	/* control status register */
  	unsigned int uartc;	/* uart control register */
  	unsigned int rev;	/* chip revision */
  
  	union {
  #ifdef CHIP1371
  		struct {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
400
  			struct snd_ac97 *ac97;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
402
403
404
  		} es1371;
  #else
  		struct {
  			int pclkdiv_lock;
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
405
  			struct snd_ak4531 *ak4531;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
406
407
408
409
410
  		} es1370;
  #endif
  	} u;
  
  	struct pci_dev *pci;
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
411
412
413
414
415
416
  	struct snd_card *card;
  	struct snd_pcm *pcm1;	/* DAC1/ADC PCM */
  	struct snd_pcm *pcm2;	/* DAC2 PCM */
  	struct snd_pcm_substream *playback1_substream;
  	struct snd_pcm_substream *playback2_substream;
  	struct snd_pcm_substream *capture_substream;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
417
418
419
420
421
422
  	unsigned int p1_dma_size;
  	unsigned int p2_dma_size;
  	unsigned int c_dma_size;
  	unsigned int p1_period_size;
  	unsigned int p2_period_size;
  	unsigned int c_period_size;
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
423
424
425
  	struct snd_rawmidi *rmidi;
  	struct snd_rawmidi_substream *midi_input;
  	struct snd_rawmidi_substream *midi_output;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
426
427
428
429
430
431
432
433
434
435
436
437
438
  
  	unsigned int spdif;
  	unsigned int spdif_default;
  	unsigned int spdif_stream;
  
  #ifdef CHIP1370
  	struct snd_dma_buffer dma_bug;
  #endif
  
  #ifdef SUPPORT_JOYSTICK
  	struct gameport *gameport;
  #endif
  };
7d12e780e   David Howells   IRQ: Maintain reg...
439
  static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
440

9baa3c34a   Benoit Taine   PCI: Remove DEFIN...
441
  static const struct pci_device_id snd_audiopci_ids[] = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
442
  #ifdef CHIP1370
28d27aae9   Joe Perches   sound: Use PCI_VD...
443
  	{ PCI_VDEVICE(ENSONIQ, 0x5000), 0, },	/* ES1370 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
444
445
  #endif
  #ifdef CHIP1371
28d27aae9   Joe Perches   sound: Use PCI_VD...
446
447
  	{ PCI_VDEVICE(ENSONIQ, 0x1371), 0, },	/* ES1371 */
  	{ PCI_VDEVICE(ENSONIQ, 0x5880), 0, },	/* ES1373 - CT5880 */
0d7392e54   Joe Perches   sound: Use PCI_VD...
448
  	{ PCI_VDEVICE(ECTIVA, 0x8938), 0, },	/* Ectiva EV1938 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
449
450
451
452
453
454
455
456
457
458
459
460
461
  #endif
  	{ 0, }
  };
  
  MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
  
  /*
   *  constants
   */
  
  #define POLL_COUNT	0xa000
  
  #ifdef CHIP1370
8130829a9   Takashi Iwai   ALSA: ens137x: Co...
462
  static const unsigned int snd_es1370_fixed_rates[] =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
463
  	{5512, 11025, 22050, 44100};
8130829a9   Takashi Iwai   ALSA: ens137x: Co...
464
  static const struct snd_pcm_hw_constraint_list snd_es1370_hw_constraints_rates = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
465
466
467
468
  	.count = 4, 
  	.list = snd_es1370_fixed_rates,
  	.mask = 0,
  };
8130829a9   Takashi Iwai   ALSA: ens137x: Co...
469
  static const struct snd_ratnum es1370_clock = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
470
471
472
473
474
  	.num = ES_1370_SRCLOCK,
  	.den_min = 29, 
  	.den_max = 353,
  	.den_step = 1,
  };
8130829a9   Takashi Iwai   ALSA: ens137x: Co...
475
  static const struct snd_pcm_hw_constraint_ratnums snd_es1370_hw_constraints_clock = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
476
477
478
479
  	.nrats = 1,
  	.rats = &es1370_clock,
  };
  #else
8130829a9   Takashi Iwai   ALSA: ens137x: Co...
480
  static const struct snd_ratden es1371_dac_clock = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
481
482
483
484
485
  	.num_min = 3000 * (1 << 15),
  	.num_max = 48000 * (1 << 15),
  	.num_step = 3000,
  	.den = 1 << 15,
  };
8130829a9   Takashi Iwai   ALSA: ens137x: Co...
486
  static const struct snd_pcm_hw_constraint_ratdens snd_es1371_hw_constraints_dac_clock = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
487
488
489
  	.nrats = 1,
  	.rats = &es1371_dac_clock,
  };
8130829a9   Takashi Iwai   ALSA: ens137x: Co...
490
  static const struct snd_ratnum es1371_adc_clock = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
491
492
493
494
495
  	.num = 48000 << 15,
  	.den_min = 32768, 
  	.den_max = 393216,
  	.den_step = 1,
  };
8130829a9   Takashi Iwai   ALSA: ens137x: Co...
496
  static const struct snd_pcm_hw_constraint_ratnums snd_es1371_hw_constraints_adc_clock = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
497
498
499
500
501
502
503
504
505
506
507
508
  	.nrats = 1,
  	.rats = &es1371_adc_clock,
  };
  #endif
  static const unsigned int snd_ensoniq_sample_shift[] =
  	{0, 1, 1, 2};
  
  /*
   *  common I/O routines
   */
  
  #ifdef CHIP1371
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
509
  static unsigned int snd_es1371_wait_src_ready(struct ensoniq * ensoniq)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
510
511
512
513
514
515
516
517
518
  {
  	unsigned int t, r = 0;
  
  	for (t = 0; t < POLL_COUNT; t++) {
  		r = inl(ES_REG(ensoniq, 1371_SMPRATE));
  		if ((r & ES_1371_SRC_RAM_BUSY) == 0)
  			return r;
  		cond_resched();
  	}
7ddbd1819   Takashi Iwai   ALSA: ens137x: Us...
519
520
  	dev_err(ensoniq->card->dev, "wait src ready timeout 0x%lx [0x%x]
  ",
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
521
  		   ES_REG(ensoniq, 1371_SMPRATE), r);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
522
523
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
524
  static unsigned int snd_es1371_src_read(struct ensoniq * ensoniq, unsigned short reg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
  {
  	unsigned int temp, i, orig, r;
  
  	/* wait for ready */
  	temp = orig = snd_es1371_wait_src_ready(ensoniq);
  
  	/* expose the SRC state bits */
  	r = temp & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |
  		    ES_1371_DIS_P2 | ES_1371_DIS_R1);
  	r |= ES_1371_SRC_RAM_ADDRO(reg) | 0x10000;
  	outl(r, ES_REG(ensoniq, 1371_SMPRATE));
  
  	/* now, wait for busy and the correct time to read */
  	temp = snd_es1371_wait_src_ready(ensoniq);
  	
  	if ((temp & 0x00870000) != 0x00010000) {
  		/* wait for the right state */
  		for (i = 0; i < POLL_COUNT; i++) {
  			temp = inl(ES_REG(ensoniq, 1371_SMPRATE));
  			if ((temp & 0x00870000) == 0x00010000)
  				break;
  		}
  	}
  
  	/* hide the state bits */	
  	r = orig & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |
  		   ES_1371_DIS_P2 | ES_1371_DIS_R1);
  	r |= ES_1371_SRC_RAM_ADDRO(reg);
  	outl(r, ES_REG(ensoniq, 1371_SMPRATE));
  	
  	return temp;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
557
  static void snd_es1371_src_write(struct ensoniq * ensoniq,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
558
559
560
561
562
563
564
565
566
567
568
569
570
571
  				 unsigned short reg, unsigned short data)
  {
  	unsigned int r;
  
  	r = snd_es1371_wait_src_ready(ensoniq) &
  	    (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |
  	     ES_1371_DIS_P2 | ES_1371_DIS_R1);
  	r |= ES_1371_SRC_RAM_ADDRO(reg) | ES_1371_SRC_RAM_DATAO(data);
  	outl(r | ES_1371_SRC_RAM_WE, ES_REG(ensoniq, 1371_SMPRATE));
  }
  
  #endif /* CHIP1371 */
  
  #ifdef CHIP1370
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
572
  static void snd_es1370_codec_write(struct snd_ak4531 *ak4531,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
573
574
  				   unsigned short reg, unsigned short val)
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
575
  	struct ensoniq *ensoniq = ak4531->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
576
577
578
  	unsigned long end_time = jiffies + HZ / 10;
  
  #if 0
7ddbd1819   Takashi Iwai   ALSA: ens137x: Us...
579
  	dev_dbg(ensoniq->card->dev,
ee419653a   Takashi Iwai   ALSA: Fix missing...
580
581
  	       "CODEC WRITE: reg = 0x%x, val = 0x%x (0x%x), creg = 0x%x
  ",
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
582
  	       reg, val, ES_1370_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1370_CODEC));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
583
584
585
586
587
588
  #endif
  	do {
  		if (!(inl(ES_REG(ensoniq, STATUS)) & ES_1370_CSTAT)) {
  			outw(ES_1370_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1370_CODEC));
  			return;
  		}
8433a509c   Nishanth Aravamudan   [ALSA] Fix schedu...
589
  		schedule_timeout_uninterruptible(1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
590
  	} while (time_after(end_time, jiffies));
7ddbd1819   Takashi Iwai   ALSA: ens137x: Us...
591
592
  	dev_err(ensoniq->card->dev, "codec write timeout, status = 0x%x
  ",
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
593
  		   inl(ES_REG(ensoniq, STATUS)));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
594
595
596
597
598
  }
  
  #endif /* CHIP1370 */
  
  #ifdef CHIP1371
6ebb8a4a4   Clemens Ladisch   ALSA: ens1371: fi...
599
600
601
602
  static inline bool is_ev1938(struct ensoniq *ensoniq)
  {
  	return ensoniq->pci->device == 0x8938;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
603
  static void snd_es1371_codec_write(struct snd_ac97 *ac97,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
604
605
  				   unsigned short reg, unsigned short val)
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
606
  	struct ensoniq *ensoniq = ac97->private_data;
6ebb8a4a4   Clemens Ladisch   ALSA: ens1371: fi...
607
  	unsigned int t, x, flag;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
608

6ebb8a4a4   Clemens Ladisch   ALSA: ens1371: fi...
609
  	flag = is_ev1938(ensoniq) ? EV_1938_CODEC_MAGIC : 0;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
610
  	mutex_lock(&ensoniq->src_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
611
612
613
614
615
616
617
618
619
620
  	for (t = 0; t < POLL_COUNT; t++) {
  		if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) {
  			/* save the current state for latter */
  			x = snd_es1371_wait_src_ready(ensoniq);
  			outl((x & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |
  			           ES_1371_DIS_P2 | ES_1371_DIS_R1)) | 0x00010000,
  			     ES_REG(ensoniq, 1371_SMPRATE));
  			/* wait for not busy (state 0) first to avoid
  			   transition states */
  			for (t = 0; t < POLL_COUNT; t++) {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
621
622
  				if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==
  				    0x00000000)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
623
624
625
626
  					break;
  			}
  			/* wait for a SAFE time to write addr/data and then do it, dammit */
  			for (t = 0; t < POLL_COUNT; t++) {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
627
628
  				if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==
  				    0x00010000)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
629
630
  					break;
  			}
6ebb8a4a4   Clemens Ladisch   ALSA: ens1371: fi...
631
632
  			outl(ES_1371_CODEC_WRITE(reg, val) | flag,
  			     ES_REG(ensoniq, 1371_CODEC));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
633
634
635
  			/* restore SRC reg */
  			snd_es1371_wait_src_ready(ensoniq);
  			outl(x, ES_REG(ensoniq, 1371_SMPRATE));
62932df8f   Ingo Molnar   [ALSA] semaphore ...
636
  			mutex_unlock(&ensoniq->src_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
637
638
639
  			return;
  		}
  	}
62932df8f   Ingo Molnar   [ALSA] semaphore ...
640
  	mutex_unlock(&ensoniq->src_mutex);
7ddbd1819   Takashi Iwai   ALSA: ens137x: Us...
641
642
  	dev_err(ensoniq->card->dev, "codec write timeout at 0x%lx [0x%x]
  ",
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
643
  		   ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
644
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
645
  static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
646
647
  					    unsigned short reg)
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
648
  	struct ensoniq *ensoniq = ac97->private_data;
6ebb8a4a4   Clemens Ladisch   ALSA: ens1371: fi...
649
  	unsigned int t, x, flag, fail = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
650

6ebb8a4a4   Clemens Ladisch   ALSA: ens1371: fi...
651
  	flag = is_ev1938(ensoniq) ? EV_1938_CODEC_MAGIC : 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
652
        __again:
62932df8f   Ingo Molnar   [ALSA] semaphore ...
653
  	mutex_lock(&ensoniq->src_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
654
655
656
657
658
659
660
661
662
663
  	for (t = 0; t < POLL_COUNT; t++) {
  		if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) {
  			/* save the current state for latter */
  			x = snd_es1371_wait_src_ready(ensoniq);
  			outl((x & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |
  			           ES_1371_DIS_P2 | ES_1371_DIS_R1)) | 0x00010000,
  			     ES_REG(ensoniq, 1371_SMPRATE));
  			/* wait for not busy (state 0) first to avoid
  			   transition states */
  			for (t = 0; t < POLL_COUNT; t++) {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
664
665
  				if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==
  				    0x00000000)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
666
667
668
669
  					break;
  			}
  			/* wait for a SAFE time to write addr/data and then do it, dammit */
  			for (t = 0; t < POLL_COUNT; t++) {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
670
671
  				if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==
  				    0x00010000)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
672
673
  					break;
  			}
6ebb8a4a4   Clemens Ladisch   ALSA: ens1371: fi...
674
675
  			outl(ES_1371_CODEC_READS(reg) | flag,
  			     ES_REG(ensoniq, 1371_CODEC));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
676
677
678
679
680
681
682
683
684
685
686
  			/* restore SRC reg */
  			snd_es1371_wait_src_ready(ensoniq);
  			outl(x, ES_REG(ensoniq, 1371_SMPRATE));
  			/* wait for WIP again */
  			for (t = 0; t < POLL_COUNT; t++) {
  				if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP))
  					break;		
  			}
  			/* now wait for the stinkin' data (RDY) */
  			for (t = 0; t < POLL_COUNT; t++) {
  				if ((x = inl(ES_REG(ensoniq, 1371_CODEC))) & ES_1371_CODEC_RDY) {
6ebb8a4a4   Clemens Ladisch   ALSA: ens1371: fi...
687
688
689
690
691
  					if (is_ev1938(ensoniq)) {
  						for (t = 0; t < 100; t++)
  							inl(ES_REG(ensoniq, CONTROL));
  						x = inl(ES_REG(ensoniq, 1371_CODEC));
  					}
62932df8f   Ingo Molnar   [ALSA] semaphore ...
692
  					mutex_unlock(&ensoniq->src_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
693
694
695
  					return ES_1371_CODEC_READ(x);
  				}
  			}
62932df8f   Ingo Molnar   [ALSA] semaphore ...
696
  			mutex_unlock(&ensoniq->src_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
697
  			if (++fail > 10) {
7ddbd1819   Takashi Iwai   ALSA: ens137x: Us...
698
699
700
  				dev_err(ensoniq->card->dev,
  					"codec read timeout (final) at 0x%lx, reg = 0x%x [0x%x]
  ",
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
701
702
  					   ES_REG(ensoniq, 1371_CODEC), reg,
  					   inl(ES_REG(ensoniq, 1371_CODEC)));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
703
704
705
706
707
  				return 0;
  			}
  			goto __again;
  		}
  	}
62932df8f   Ingo Molnar   [ALSA] semaphore ...
708
  	mutex_unlock(&ensoniq->src_mutex);
7ddbd1819   Takashi Iwai   ALSA: ens137x: Us...
709
710
  	dev_err(ensoniq->card->dev, "codec read timeout at 0x%lx [0x%x]
  ",
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
711
  		   ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
712
713
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
714
  static void snd_es1371_codec_wait(struct snd_ac97 *ac97)
072c01194   Jaroslav Kysela   [ALSA] ens1371 - ...
715
716
717
718
719
720
721
  {
  	msleep(750);
  	snd_es1371_codec_read(ac97, AC97_RESET);
  	snd_es1371_codec_read(ac97, AC97_VENDOR_ID1);
  	snd_es1371_codec_read(ac97, AC97_VENDOR_ID2);
  	msleep(50);
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
722
  static void snd_es1371_adc_rate(struct ensoniq * ensoniq, unsigned int rate)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
723
724
  {
  	unsigned int n, truncm, freq, result;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
725
  	mutex_lock(&ensoniq->src_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
  	n = rate / 3000;
  	if ((1 << n) & ((1 << 15) | (1 << 13) | (1 << 11) | (1 << 9)))
  		n--;
  	truncm = (21 * n - 1) | 1;
  	freq = ((48000UL << 15) / rate) * n;
  	result = (48000UL << 15) / (freq / n);
  	if (rate >= 24000) {
  		if (truncm > 239)
  			truncm = 239;
  		snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N,
  				(((239 - truncm) >> 1) << 9) | (n << 4));
  	} else {
  		if (truncm > 119)
  			truncm = 119;
  		snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N,
  				0x8000 | (((119 - truncm) >> 1) << 9) | (n << 4));
  	}
  	snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_INT_REGS,
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
744
745
746
  			     (snd_es1371_src_read(ensoniq, ES_SMPREG_ADC +
  						  ES_SMPREG_INT_REGS) & 0x00ff) |
  			     ((freq >> 5) & 0xfc00));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
747
748
749
  	snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
  	snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, n << 8);
  	snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, n << 8);
62932df8f   Ingo Molnar   [ALSA] semaphore ...
750
  	mutex_unlock(&ensoniq->src_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
751
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
752
  static void snd_es1371_dac1_rate(struct ensoniq * ensoniq, unsigned int rate)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
753
754
  {
  	unsigned int freq, r;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
755
  	mutex_lock(&ensoniq->src_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
756
  	freq = ((rate << 15) + 1500) / 3000;
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
757
758
759
  	r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |
  						   ES_1371_DIS_P2 | ES_1371_DIS_R1)) |
  		ES_1371_DIS_P1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
760
761
  	outl(r, ES_REG(ensoniq, 1371_SMPRATE));
  	snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS,
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
762
763
  			     (snd_es1371_src_read(ensoniq, ES_SMPREG_DAC1 +
  						  ES_SMPREG_INT_REGS) & 0x00ff) |
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
764
765
  			     ((freq >> 5) & 0xfc00));
  	snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
766
767
  	r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |
  						   ES_1371_DIS_P2 | ES_1371_DIS_R1));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
768
  	outl(r, ES_REG(ensoniq, 1371_SMPRATE));
62932df8f   Ingo Molnar   [ALSA] semaphore ...
769
  	mutex_unlock(&ensoniq->src_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
770
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
771
  static void snd_es1371_dac2_rate(struct ensoniq * ensoniq, unsigned int rate)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
772
773
  {
  	unsigned int freq, r;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
774
  	mutex_lock(&ensoniq->src_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
775
  	freq = ((rate << 15) + 1500) / 3000;
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
776
777
778
  	r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |
  						   ES_1371_DIS_P1 | ES_1371_DIS_R1)) |
  		ES_1371_DIS_P2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
779
780
  	outl(r, ES_REG(ensoniq, 1371_SMPRATE));
  	snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS,
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
781
782
  			     (snd_es1371_src_read(ensoniq, ES_SMPREG_DAC2 +
  						  ES_SMPREG_INT_REGS) & 0x00ff) |
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
783
  			     ((freq >> 5) & 0xfc00));
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
784
785
786
787
  	snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_VFREQ_FRAC,
  			     freq & 0x7fff);
  	r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |
  						   ES_1371_DIS_P1 | ES_1371_DIS_R1));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
788
  	outl(r, ES_REG(ensoniq, 1371_SMPRATE));
62932df8f   Ingo Molnar   [ALSA] semaphore ...
789
  	mutex_unlock(&ensoniq->src_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
790
791
792
  }
  
  #endif /* CHIP1371 */
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
793
  static int snd_ensoniq_trigger(struct snd_pcm_substream *substream, int cmd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
794
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
795
  	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
796
797
798
799
800
  	switch (cmd) {
  	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  	{
  		unsigned int what = 0;
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
801
  		struct snd_pcm_substream *s;
ef991b95a   Takashi Iwai   [ALSA] Add snd_pc...
802
  		snd_pcm_group_for_each_entry(s, substream) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
  			if (s == ensoniq->playback1_substream) {
  				what |= ES_P1_PAUSE;
  				snd_pcm_trigger_done(s, substream);
  			} else if (s == ensoniq->playback2_substream) {
  				what |= ES_P2_PAUSE;
  				snd_pcm_trigger_done(s, substream);
  			} else if (s == ensoniq->capture_substream)
  				return -EINVAL;
  		}
  		spin_lock(&ensoniq->reg_lock);
  		if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
  			ensoniq->sctrl |= what;
  		else
  			ensoniq->sctrl &= ~what;
  		outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
  		spin_unlock(&ensoniq->reg_lock);
  		break;
  	}
  	case SNDRV_PCM_TRIGGER_START:
  	case SNDRV_PCM_TRIGGER_STOP:
  	{
  		unsigned int what = 0;
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
825
  		struct snd_pcm_substream *s;
ef991b95a   Takashi Iwai   [ALSA] Add snd_pc...
826
  		snd_pcm_group_for_each_entry(s, substream) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
  			if (s == ensoniq->playback1_substream) {
  				what |= ES_DAC1_EN;
  				snd_pcm_trigger_done(s, substream);
  			} else if (s == ensoniq->playback2_substream) {
  				what |= ES_DAC2_EN;
  				snd_pcm_trigger_done(s, substream);
  			} else if (s == ensoniq->capture_substream) {
  				what |= ES_ADC_EN;
  				snd_pcm_trigger_done(s, substream);
  			}
  		}
  		spin_lock(&ensoniq->reg_lock);
  		if (cmd == SNDRV_PCM_TRIGGER_START)
  			ensoniq->ctrl |= what;
  		else
  			ensoniq->ctrl &= ~what;
  		outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
  		spin_unlock(&ensoniq->reg_lock);
  		break;
  	}
  	default:
  		return -EINVAL;
  	}
  	return 0;
  }
  
  /*
   *  PCM part
   */
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
856
857
  static int snd_ensoniq_hw_params(struct snd_pcm_substream *substream,
  				 struct snd_pcm_hw_params *hw_params)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
858
859
860
  {
  	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
861
  static int snd_ensoniq_hw_free(struct snd_pcm_substream *substream)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
862
863
864
  {
  	return snd_pcm_lib_free_pages(substream);
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
865
  static int snd_ensoniq_playback1_prepare(struct snd_pcm_substream *substream)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
866
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
867
868
  	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
  	struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
  	unsigned int mode = 0;
  
  	ensoniq->p1_dma_size = snd_pcm_lib_buffer_bytes(substream);
  	ensoniq->p1_period_size = snd_pcm_lib_period_bytes(substream);
  	if (snd_pcm_format_width(runtime->format) == 16)
  		mode |= 0x02;
  	if (runtime->channels > 1)
  		mode |= 0x01;
  	spin_lock_irq(&ensoniq->reg_lock);
  	ensoniq->ctrl &= ~ES_DAC1_EN;
  #ifdef CHIP1371
  	/* 48k doesn't need SRC (it breaks AC3-passthru) */
  	if (runtime->rate == 48000)
  		ensoniq->ctrl |= ES_1373_BYPASS_P1;
  	else
  		ensoniq->ctrl &= ~ES_1373_BYPASS_P1;
  #endif
  	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
  	outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));
  	outl(runtime->dma_addr, ES_REG(ensoniq, DAC1_FRAME));
  	outl((ensoniq->p1_dma_size >> 2) - 1, ES_REG(ensoniq, DAC1_SIZE));
  	ensoniq->sctrl &= ~(ES_P1_LOOP_SEL | ES_P1_PAUSE | ES_P1_SCT_RLD | ES_P1_MODEM);
  	ensoniq->sctrl |= ES_P1_INT_EN | ES_P1_MODEO(mode);
  	outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
893
894
  	outl((ensoniq->p1_period_size >> snd_ensoniq_sample_shift[mode]) - 1,
  	     ES_REG(ensoniq, DAC1_COUNT));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
  #ifdef CHIP1370
  	ensoniq->ctrl &= ~ES_1370_WTSRSELM;
  	switch (runtime->rate) {
  	case 5512: ensoniq->ctrl |= ES_1370_WTSRSEL(0); break;
  	case 11025: ensoniq->ctrl |= ES_1370_WTSRSEL(1); break;
  	case 22050: ensoniq->ctrl |= ES_1370_WTSRSEL(2); break;
  	case 44100: ensoniq->ctrl |= ES_1370_WTSRSEL(3); break;
  	default: snd_BUG();
  	}
  #endif
  	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
  	spin_unlock_irq(&ensoniq->reg_lock);
  #ifndef CHIP1370
  	snd_es1371_dac1_rate(ensoniq, runtime->rate);
  #endif
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
912
  static int snd_ensoniq_playback2_prepare(struct snd_pcm_substream *substream)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
913
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
914
915
  	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
  	struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
  	unsigned int mode = 0;
  
  	ensoniq->p2_dma_size = snd_pcm_lib_buffer_bytes(substream);
  	ensoniq->p2_period_size = snd_pcm_lib_period_bytes(substream);
  	if (snd_pcm_format_width(runtime->format) == 16)
  		mode |= 0x02;
  	if (runtime->channels > 1)
  		mode |= 0x01;
  	spin_lock_irq(&ensoniq->reg_lock);
  	ensoniq->ctrl &= ~ES_DAC2_EN;
  	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
  	outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));
  	outl(runtime->dma_addr, ES_REG(ensoniq, DAC2_FRAME));
  	outl((ensoniq->p2_dma_size >> 2) - 1, ES_REG(ensoniq, DAC2_SIZE));
  	ensoniq->sctrl &= ~(ES_P2_LOOP_SEL | ES_P2_PAUSE | ES_P2_DAC_SEN |
  			    ES_P2_END_INCM | ES_P2_ST_INCM | ES_P2_MODEM);
  	ensoniq->sctrl |= ES_P2_INT_EN | ES_P2_MODEO(mode) |
  			  ES_P2_END_INCO(mode & 2 ? 2 : 1) | ES_P2_ST_INCO(0);
  	outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
935
936
  	outl((ensoniq->p2_period_size >> snd_ensoniq_sample_shift[mode]) - 1,
  	     ES_REG(ensoniq, DAC2_COUNT));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
937
938
939
940
941
942
943
944
945
946
947
948
949
950
  #ifdef CHIP1370
  	if (!(ensoniq->u.es1370.pclkdiv_lock & ES_MODE_CAPTURE)) {
  		ensoniq->ctrl &= ~ES_1370_PCLKDIVM;
  		ensoniq->ctrl |= ES_1370_PCLKDIVO(ES_1370_SRTODIV(runtime->rate));
  		ensoniq->u.es1370.pclkdiv_lock |= ES_MODE_PLAY2;
  	}
  #endif
  	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
  	spin_unlock_irq(&ensoniq->reg_lock);
  #ifndef CHIP1370
  	snd_es1371_dac2_rate(ensoniq, runtime->rate);
  #endif
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
951
  static int snd_ensoniq_capture_prepare(struct snd_pcm_substream *substream)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
952
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
953
954
  	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
  	struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
  	unsigned int mode = 0;
  
  	ensoniq->c_dma_size = snd_pcm_lib_buffer_bytes(substream);
  	ensoniq->c_period_size = snd_pcm_lib_period_bytes(substream);
  	if (snd_pcm_format_width(runtime->format) == 16)
  		mode |= 0x02;
  	if (runtime->channels > 1)
  		mode |= 0x01;
  	spin_lock_irq(&ensoniq->reg_lock);
  	ensoniq->ctrl &= ~ES_ADC_EN;
  	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
  	outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE));
  	outl(runtime->dma_addr, ES_REG(ensoniq, ADC_FRAME));
  	outl((ensoniq->c_dma_size >> 2) - 1, ES_REG(ensoniq, ADC_SIZE));
  	ensoniq->sctrl &= ~(ES_R1_LOOP_SEL | ES_R1_MODEM);
  	ensoniq->sctrl |= ES_R1_INT_EN | ES_R1_MODEO(mode);
  	outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
972
973
  	outl((ensoniq->c_period_size >> snd_ensoniq_sample_shift[mode]) - 1,
  	     ES_REG(ensoniq, ADC_COUNT));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
974
975
976
977
978
979
980
981
982
983
984
985
986
987
  #ifdef CHIP1370
  	if (!(ensoniq->u.es1370.pclkdiv_lock & ES_MODE_PLAY2)) {
  		ensoniq->ctrl &= ~ES_1370_PCLKDIVM;
  		ensoniq->ctrl |= ES_1370_PCLKDIVO(ES_1370_SRTODIV(runtime->rate));
  		ensoniq->u.es1370.pclkdiv_lock |= ES_MODE_CAPTURE;
  	}
  #endif
  	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
  	spin_unlock_irq(&ensoniq->reg_lock);
  #ifndef CHIP1370
  	snd_es1371_adc_rate(ensoniq, runtime->rate);
  #endif
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
988
  static snd_pcm_uframes_t snd_ensoniq_playback1_pointer(struct snd_pcm_substream *substream)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
989
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
990
  	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
  	size_t ptr;
  
  	spin_lock(&ensoniq->reg_lock);
  	if (inl(ES_REG(ensoniq, CONTROL)) & ES_DAC1_EN) {
  		outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));
  		ptr = ES_REG_FCURR_COUNTI(inl(ES_REG(ensoniq, DAC1_SIZE)));
  		ptr = bytes_to_frames(substream->runtime, ptr);
  	} else {
  		ptr = 0;
  	}
  	spin_unlock(&ensoniq->reg_lock);
  	return ptr;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1004
  static snd_pcm_uframes_t snd_ensoniq_playback2_pointer(struct snd_pcm_substream *substream)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1005
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1006
  	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
  	size_t ptr;
  
  	spin_lock(&ensoniq->reg_lock);
  	if (inl(ES_REG(ensoniq, CONTROL)) & ES_DAC2_EN) {
  		outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));
  		ptr = ES_REG_FCURR_COUNTI(inl(ES_REG(ensoniq, DAC2_SIZE)));
  		ptr = bytes_to_frames(substream->runtime, ptr);
  	} else {
  		ptr = 0;
  	}
  	spin_unlock(&ensoniq->reg_lock);
  	return ptr;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1020
  static snd_pcm_uframes_t snd_ensoniq_capture_pointer(struct snd_pcm_substream *substream)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1021
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1022
  	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
  	size_t ptr;
  
  	spin_lock(&ensoniq->reg_lock);
  	if (inl(ES_REG(ensoniq, CONTROL)) & ES_ADC_EN) {
  		outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE));
  		ptr = ES_REG_FCURR_COUNTI(inl(ES_REG(ensoniq, ADC_SIZE)));
  		ptr = bytes_to_frames(substream->runtime, ptr);
  	} else {
  		ptr = 0;
  	}
  	spin_unlock(&ensoniq->reg_lock);
  	return ptr;
  }
dee49895b   Bhumika Goyal   ALSA: pci: make s...
1036
  static const struct snd_pcm_hardware snd_ensoniq_playback1 =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
  {
  	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
  				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
  				 SNDRV_PCM_INFO_MMAP_VALID |
  				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
  	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
  	.rates =
  #ifndef CHIP1370
  				SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
  #else
  				(SNDRV_PCM_RATE_KNOT | 	/* 5512Hz rate */
  				 SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_22050 | 
  				 SNDRV_PCM_RATE_44100),
  #endif
  	.rate_min =		4000,
  	.rate_max =		48000,
  	.channels_min =		1,
  	.channels_max =		2,
  	.buffer_bytes_max =	(128*1024),
  	.period_bytes_min =	64,
  	.period_bytes_max =	(128*1024),
  	.periods_min =		1,
  	.periods_max =		1024,
  	.fifo_size =		0,
  };
dee49895b   Bhumika Goyal   ALSA: pci: make s...
1062
  static const struct snd_pcm_hardware snd_ensoniq_playback2 =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
  {
  	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
  				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
  				 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | 
  				 SNDRV_PCM_INFO_SYNC_START),
  	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
  	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
  	.rate_min =		4000,
  	.rate_max =		48000,
  	.channels_min =		1,
  	.channels_max =		2,
  	.buffer_bytes_max =	(128*1024),
  	.period_bytes_min =	64,
  	.period_bytes_max =	(128*1024),
  	.periods_min =		1,
  	.periods_max =		1024,
  	.fifo_size =		0,
  };
dee49895b   Bhumika Goyal   ALSA: pci: make s...
1081
  static const struct snd_pcm_hardware snd_ensoniq_capture =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
  {
  	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
  				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
  				 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START),
  	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
  	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
  	.rate_min =		4000,
  	.rate_max =		48000,
  	.channels_min =		1,
  	.channels_max =		2,
  	.buffer_bytes_max =	(128*1024),
  	.period_bytes_min =	64,
  	.period_bytes_max =	(128*1024),
  	.periods_min =		1,
  	.periods_max =		1024,
  	.fifo_size =		0,
  };
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1099
  static int snd_ensoniq_playback1_open(struct snd_pcm_substream *substream)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1100
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1101
1102
  	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
  	struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
  
  	ensoniq->mode |= ES_MODE_PLAY1;
  	ensoniq->playback1_substream = substream;
  	runtime->hw = snd_ensoniq_playback1;
  	snd_pcm_set_sync(substream);
  	spin_lock_irq(&ensoniq->reg_lock);
  	if (ensoniq->spdif && ensoniq->playback2_substream == NULL)
  		ensoniq->spdif_stream = ensoniq->spdif_default;
  	spin_unlock_irq(&ensoniq->reg_lock);
  #ifdef CHIP1370
  	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
  				   &snd_es1370_hw_constraints_rates);
  #else
  	snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
  				      &snd_es1371_hw_constraints_dac_clock);
  #endif
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1121
  static int snd_ensoniq_playback2_open(struct snd_pcm_substream *substream)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1122
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1123
1124
  	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
  	struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
  
  	ensoniq->mode |= ES_MODE_PLAY2;
  	ensoniq->playback2_substream = substream;
  	runtime->hw = snd_ensoniq_playback2;
  	snd_pcm_set_sync(substream);
  	spin_lock_irq(&ensoniq->reg_lock);
  	if (ensoniq->spdif && ensoniq->playback1_substream == NULL)
  		ensoniq->spdif_stream = ensoniq->spdif_default;
  	spin_unlock_irq(&ensoniq->reg_lock);
  #ifdef CHIP1370
  	snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
  				      &snd_es1370_hw_constraints_clock);
  #else
  	snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
  				      &snd_es1371_hw_constraints_dac_clock);
  #endif
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1143
  static int snd_ensoniq_capture_open(struct snd_pcm_substream *substream)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1144
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1145
1146
  	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
  	struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
  
  	ensoniq->mode |= ES_MODE_CAPTURE;
  	ensoniq->capture_substream = substream;
  	runtime->hw = snd_ensoniq_capture;
  	snd_pcm_set_sync(substream);
  #ifdef CHIP1370
  	snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
  				      &snd_es1370_hw_constraints_clock);
  #else
  	snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
  				      &snd_es1371_hw_constraints_adc_clock);
  #endif
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1161
  static int snd_ensoniq_playback1_close(struct snd_pcm_substream *substream)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1162
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1163
  	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1164
1165
1166
1167
1168
  
  	ensoniq->playback1_substream = NULL;
  	ensoniq->mode &= ~ES_MODE_PLAY1;
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1169
  static int snd_ensoniq_playback2_close(struct snd_pcm_substream *substream)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1170
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1171
  	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
  
  	ensoniq->playback2_substream = NULL;
  	spin_lock_irq(&ensoniq->reg_lock);
  #ifdef CHIP1370
  	ensoniq->u.es1370.pclkdiv_lock &= ~ES_MODE_PLAY2;
  #endif
  	ensoniq->mode &= ~ES_MODE_PLAY2;
  	spin_unlock_irq(&ensoniq->reg_lock);
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1182
  static int snd_ensoniq_capture_close(struct snd_pcm_substream *substream)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1183
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1184
  	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
  
  	ensoniq->capture_substream = NULL;
  	spin_lock_irq(&ensoniq->reg_lock);
  #ifdef CHIP1370
  	ensoniq->u.es1370.pclkdiv_lock &= ~ES_MODE_CAPTURE;
  #endif
  	ensoniq->mode &= ~ES_MODE_CAPTURE;
  	spin_unlock_irq(&ensoniq->reg_lock);
  	return 0;
  }
6769e988b   Julia Lawall   ALSA: constify sn...
1195
  static const struct snd_pcm_ops snd_ensoniq_playback1_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1196
1197
1198
1199
1200
1201
1202
1203
1204
  	.open =		snd_ensoniq_playback1_open,
  	.close =	snd_ensoniq_playback1_close,
  	.ioctl =	snd_pcm_lib_ioctl,
  	.hw_params =	snd_ensoniq_hw_params,
  	.hw_free =	snd_ensoniq_hw_free,
  	.prepare =	snd_ensoniq_playback1_prepare,
  	.trigger =	snd_ensoniq_trigger,
  	.pointer =	snd_ensoniq_playback1_pointer,
  };
6769e988b   Julia Lawall   ALSA: constify sn...
1205
  static const struct snd_pcm_ops snd_ensoniq_playback2_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1206
1207
1208
1209
1210
1211
1212
1213
1214
  	.open =		snd_ensoniq_playback2_open,
  	.close =	snd_ensoniq_playback2_close,
  	.ioctl =	snd_pcm_lib_ioctl,
  	.hw_params =	snd_ensoniq_hw_params,
  	.hw_free =	snd_ensoniq_hw_free,
  	.prepare =	snd_ensoniq_playback2_prepare,
  	.trigger =	snd_ensoniq_trigger,
  	.pointer =	snd_ensoniq_playback2_pointer,
  };
6769e988b   Julia Lawall   ALSA: constify sn...
1215
  static const struct snd_pcm_ops snd_ensoniq_capture_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1216
1217
1218
1219
1220
1221
1222
1223
1224
  	.open =		snd_ensoniq_capture_open,
  	.close =	snd_ensoniq_capture_close,
  	.ioctl =	snd_pcm_lib_ioctl,
  	.hw_params =	snd_ensoniq_hw_params,
  	.hw_free =	snd_ensoniq_hw_free,
  	.prepare =	snd_ensoniq_capture_prepare,
  	.trigger =	snd_ensoniq_trigger,
  	.pointer =	snd_ensoniq_capture_pointer,
  };
7fb6861d6   Takashi Iwai   ALSA: ens1370: De...
1225
1226
  static const struct snd_pcm_chmap_elem surround_map[] = {
  	{ .channels = 1,
5efbc2610   Takashi Iwai   ALSA: Fix leftove...
1227
  	  .map = { SNDRV_CHMAP_MONO } },
7fb6861d6   Takashi Iwai   ALSA: ens1370: De...
1228
1229
1230
1231
  	{ .channels = 2,
  	  .map = { SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
  	{ }
  };
50b8d94e1   Lars-Peter Clausen   ALSA: ens1370: Re...
1232
  static int snd_ensoniq_pcm(struct ensoniq *ensoniq, int device)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1233
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1234
  	struct snd_pcm *pcm;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1235
  	int err;
1fe4d42e0   Takashi Iwai   ALSA: ens1370: Re...
1236
  	err = snd_pcm_new(ensoniq->card, CHIP_NAME "/1", device, 1, 1, &pcm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
  	if (err < 0)
  		return err;
  
  #ifdef CHIP1370
  	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback2_ops);
  #else
  	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback1_ops);
  #endif
  	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ensoniq_capture_ops);
  
  	pcm->private_data = ensoniq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1248
  	pcm->info_flags = 0;
1fe4d42e0   Takashi Iwai   ALSA: ens1370: Re...
1249
  	strcpy(pcm->name, CHIP_NAME " DAC2/ADC");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1250
1251
1252
1253
  	ensoniq->pcm1 = pcm;
  
  	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
  					      snd_dma_pci_data(ensoniq->pci), 64*1024, 128*1024);
7fb6861d6   Takashi Iwai   ALSA: ens1370: De...
1254
1255
1256
1257
1258
1259
1260
  #ifdef CHIP1370
  	err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
  				     surround_map, 2, 0, NULL);
  #else
  	err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
  				     snd_pcm_std_chmaps, 2, 0, NULL);
  #endif
50b8d94e1   Lars-Peter Clausen   ALSA: ens1370: Re...
1261
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1262
  }
50b8d94e1   Lars-Peter Clausen   ALSA: ens1370: Re...
1263
  static int snd_ensoniq_pcm2(struct ensoniq *ensoniq, int device)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1264
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1265
  	struct snd_pcm *pcm;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1266
  	int err;
1fe4d42e0   Takashi Iwai   ALSA: ens1370: Re...
1267
  	err = snd_pcm_new(ensoniq->card, CHIP_NAME "/2", device, 1, 0, &pcm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1268
1269
1270
1271
1272
1273
1274
1275
1276
  	if (err < 0)
  		return err;
  
  #ifdef CHIP1370
  	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback1_ops);
  #else
  	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback2_ops);
  #endif
  	pcm->private_data = ensoniq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1277
  	pcm->info_flags = 0;
1fe4d42e0   Takashi Iwai   ALSA: ens1370: Re...
1278
  	strcpy(pcm->name, CHIP_NAME " DAC1");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1279
1280
1281
1282
  	ensoniq->pcm2 = pcm;
  
  	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
  					      snd_dma_pci_data(ensoniq->pci), 64*1024, 128*1024);
7fb6861d6   Takashi Iwai   ALSA: ens1370: De...
1283
1284
1285
1286
1287
1288
1289
  #ifdef CHIP1370
  	err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
  				     snd_pcm_std_chmaps, 2, 0, NULL);
  #else
  	err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
  				     surround_map, 2, 0, NULL);
  #endif
50b8d94e1   Lars-Peter Clausen   ALSA: ens1370: Re...
1290
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
  }
  
  /*
   *  Mixer section
   */
  
  /*
   * ENS1371 mixer (including SPDIF interface)
   */
  #ifdef CHIP1371
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1301
1302
  static int snd_ens1373_spdif_info(struct snd_kcontrol *kcontrol,
  				  struct snd_ctl_elem_info *uinfo)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1303
1304
1305
1306
1307
  {
  	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
  	uinfo->count = 1;
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1308
1309
  static int snd_ens1373_spdif_default_get(struct snd_kcontrol *kcontrol,
                                           struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1310
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1311
  	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1312
1313
1314
1315
1316
1317
1318
1319
  	spin_lock_irq(&ensoniq->reg_lock);
  	ucontrol->value.iec958.status[0] = (ensoniq->spdif_default >> 0) & 0xff;
  	ucontrol->value.iec958.status[1] = (ensoniq->spdif_default >> 8) & 0xff;
  	ucontrol->value.iec958.status[2] = (ensoniq->spdif_default >> 16) & 0xff;
  	ucontrol->value.iec958.status[3] = (ensoniq->spdif_default >> 24) & 0xff;
  	spin_unlock_irq(&ensoniq->reg_lock);
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1320
1321
  static int snd_ens1373_spdif_default_put(struct snd_kcontrol *kcontrol,
                                           struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1322
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1323
  	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
  	unsigned int val;
  	int change;
  
  	val = ((u32)ucontrol->value.iec958.status[0] << 0) |
  	      ((u32)ucontrol->value.iec958.status[1] << 8) |
  	      ((u32)ucontrol->value.iec958.status[2] << 16) |
  	      ((u32)ucontrol->value.iec958.status[3] << 24);
  	spin_lock_irq(&ensoniq->reg_lock);
  	change = ensoniq->spdif_default != val;
  	ensoniq->spdif_default = val;
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1334
1335
  	if (change && ensoniq->playback1_substream == NULL &&
  	    ensoniq->playback2_substream == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1336
1337
1338
1339
  		outl(val, ES_REG(ensoniq, CHANNEL_STATUS));
  	spin_unlock_irq(&ensoniq->reg_lock);
  	return change;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1340
1341
  static int snd_ens1373_spdif_mask_get(struct snd_kcontrol *kcontrol,
  				      struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1342
1343
1344
1345
1346
1347
1348
  {
  	ucontrol->value.iec958.status[0] = 0xff;
  	ucontrol->value.iec958.status[1] = 0xff;
  	ucontrol->value.iec958.status[2] = 0xff;
  	ucontrol->value.iec958.status[3] = 0xff;
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1349
1350
  static int snd_ens1373_spdif_stream_get(struct snd_kcontrol *kcontrol,
  					struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1351
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1352
  	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1353
1354
1355
1356
1357
1358
1359
1360
  	spin_lock_irq(&ensoniq->reg_lock);
  	ucontrol->value.iec958.status[0] = (ensoniq->spdif_stream >> 0) & 0xff;
  	ucontrol->value.iec958.status[1] = (ensoniq->spdif_stream >> 8) & 0xff;
  	ucontrol->value.iec958.status[2] = (ensoniq->spdif_stream >> 16) & 0xff;
  	ucontrol->value.iec958.status[3] = (ensoniq->spdif_stream >> 24) & 0xff;
  	spin_unlock_irq(&ensoniq->reg_lock);
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1361
1362
  static int snd_ens1373_spdif_stream_put(struct snd_kcontrol *kcontrol,
                                          struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1363
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1364
  	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
  	unsigned int val;
  	int change;
  
  	val = ((u32)ucontrol->value.iec958.status[0] << 0) |
  	      ((u32)ucontrol->value.iec958.status[1] << 8) |
  	      ((u32)ucontrol->value.iec958.status[2] << 16) |
  	      ((u32)ucontrol->value.iec958.status[3] << 24);
  	spin_lock_irq(&ensoniq->reg_lock);
  	change = ensoniq->spdif_stream != val;
  	ensoniq->spdif_stream = val;
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1375
1376
  	if (change && (ensoniq->playback1_substream != NULL ||
  		       ensoniq->playback2_substream != NULL))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1377
1378
1379
1380
1381
1382
1383
1384
  		outl(val, ES_REG(ensoniq, CHANNEL_STATUS));
  	spin_unlock_irq(&ensoniq->reg_lock);
  	return change;
  }
  
  #define ES1371_SPDIF(xname) \
  { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_es1371_spdif_info, \
    .get = snd_es1371_spdif_get, .put = snd_es1371_spdif_put }
a5ce88909   Takashi Iwai   [ALSA] Clean up w...
1385
  #define snd_es1371_spdif_info		snd_ctl_boolean_mono_info
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1386

eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1387
1388
  static int snd_es1371_spdif_get(struct snd_kcontrol *kcontrol,
  				struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1389
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1390
  	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1391
1392
1393
1394
1395
1396
  	
  	spin_lock_irq(&ensoniq->reg_lock);
  	ucontrol->value.integer.value[0] = ensoniq->ctrl & ES_1373_SPDIF_THRU ? 1 : 0;
  	spin_unlock_irq(&ensoniq->reg_lock);
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1397
1398
  static int snd_es1371_spdif_put(struct snd_kcontrol *kcontrol,
  				struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1399
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1400
  	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
  	unsigned int nval1, nval2;
  	int change;
  	
  	nval1 = ucontrol->value.integer.value[0] ? ES_1373_SPDIF_THRU : 0;
  	nval2 = ucontrol->value.integer.value[0] ? ES_1373_SPDIF_EN : 0;
  	spin_lock_irq(&ensoniq->reg_lock);
  	change = (ensoniq->ctrl & ES_1373_SPDIF_THRU) != nval1;
  	ensoniq->ctrl &= ~ES_1373_SPDIF_THRU;
  	ensoniq->ctrl |= nval1;
  	ensoniq->cssr &= ~ES_1373_SPDIF_EN;
  	ensoniq->cssr |= nval2;
  	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
  	outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
  	spin_unlock_irq(&ensoniq->reg_lock);
  	return change;
  }
  
  
  /* spdif controls */
e23e7a143   Bill Pemberton   ALSA: pci: remove...
1420
  static struct snd_kcontrol_new snd_es1371_mixer_spdif[] = {
10e8d78a9   Clemens Ladisch   [ALSA] use SNDRV_...
1421
  	ES1371_SPDIF(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH)),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1422
  	{
5549d5499   Clemens Ladisch   [ALSA] use PCM in...
1423
  		.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1424
1425
1426
1427
1428
1429
1430
  		.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
  		.info =		snd_ens1373_spdif_info,
  		.get =		snd_ens1373_spdif_default_get,
  		.put =		snd_ens1373_spdif_default_put,
  	},
  	{
  		.access =	SNDRV_CTL_ELEM_ACCESS_READ,
5549d5499   Clemens Ladisch   [ALSA] use PCM in...
1431
  		.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1432
1433
1434
1435
1436
  		.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
  		.info =		snd_ens1373_spdif_info,
  		.get =		snd_ens1373_spdif_mask_get
  	},
  	{
5549d5499   Clemens Ladisch   [ALSA] use PCM in...
1437
  		.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1438
1439
1440
1441
1442
1443
  		.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
  		.info =		snd_ens1373_spdif_info,
  		.get =		snd_ens1373_spdif_stream_get,
  		.put =		snd_ens1373_spdif_stream_put
  	},
  };
a5ce88909   Takashi Iwai   [ALSA] Clean up w...
1444
  #define snd_es1373_rear_info		snd_ctl_boolean_mono_info
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1445

eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1446
1447
  static int snd_es1373_rear_get(struct snd_kcontrol *kcontrol,
  			       struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1448
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1449
  	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1450
1451
1452
  	int val = 0;
  	
  	spin_lock_irq(&ensoniq->reg_lock);
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1453
1454
  	if ((ensoniq->cssr & (ES_1373_REAR_BIT27|ES_1373_REAR_BIT26|
  			      ES_1373_REAR_BIT24)) == ES_1373_REAR_BIT26)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1455
1456
1457
1458
1459
  	    	val = 1;
  	ucontrol->value.integer.value[0] = val;
  	spin_unlock_irq(&ensoniq->reg_lock);
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1460
1461
  static int snd_es1373_rear_put(struct snd_kcontrol *kcontrol,
  			       struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1462
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1463
  	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1464
1465
1466
  	unsigned int nval1;
  	int change;
  	
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1467
1468
  	nval1 = ucontrol->value.integer.value[0] ?
  		ES_1373_REAR_BIT26 : (ES_1373_REAR_BIT27|ES_1373_REAR_BIT24);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1469
  	spin_lock_irq(&ensoniq->reg_lock);
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1470
1471
  	change = (ensoniq->cssr & (ES_1373_REAR_BIT27|
  				   ES_1373_REAR_BIT26|ES_1373_REAR_BIT24)) != nval1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1472
1473
1474
1475
1476
1477
  	ensoniq->cssr &= ~(ES_1373_REAR_BIT27|ES_1373_REAR_BIT26|ES_1373_REAR_BIT24);
  	ensoniq->cssr |= nval1;
  	outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
  	spin_unlock_irq(&ensoniq->reg_lock);
  	return change;
  }
f3b827e0b   Bhumika Goyal   ALSA: pci: consti...
1478
  static const struct snd_kcontrol_new snd_ens1373_rear =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1479
1480
1481
1482
1483
1484
1485
  {
  	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
  	.name =		"AC97 2ch->4ch Copy Switch",
  	.info =		snd_es1373_rear_info,
  	.get =		snd_es1373_rear_get,
  	.put =		snd_es1373_rear_put,
  };
a5ce88909   Takashi Iwai   [ALSA] Clean up w...
1486
  #define snd_es1373_line_info		snd_ctl_boolean_mono_info
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1487

eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1488
1489
  static int snd_es1373_line_get(struct snd_kcontrol *kcontrol,
  			       struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1490
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1491
  	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1492
1493
1494
  	int val = 0;
  	
  	spin_lock_irq(&ensoniq->reg_lock);
d23f05173   Takashi Iwai   ALSA: ens1371: Fi...
1495
  	if (ensoniq->ctrl & ES_1371_GPIO_OUT(4))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1496
1497
1498
1499
1500
  	    	val = 1;
  	ucontrol->value.integer.value[0] = val;
  	spin_unlock_irq(&ensoniq->reg_lock);
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1501
1502
  static int snd_es1373_line_put(struct snd_kcontrol *kcontrol,
  			       struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1503
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1504
  	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
  	int changed;
  	unsigned int ctrl;
  	
  	spin_lock_irq(&ensoniq->reg_lock);
  	ctrl = ensoniq->ctrl;
  	if (ucontrol->value.integer.value[0])
  		ensoniq->ctrl |= ES_1371_GPIO_OUT(4);	/* switch line-in -> rear out */
  	else
  		ensoniq->ctrl &= ~ES_1371_GPIO_OUT(4);
  	changed = (ctrl != ensoniq->ctrl);
  	if (changed)
  		outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
  	spin_unlock_irq(&ensoniq->reg_lock);
  	return changed;
  }
f3b827e0b   Bhumika Goyal   ALSA: pci: consti...
1520
  static const struct snd_kcontrol_new snd_ens1373_line =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1521
1522
1523
1524
1525
1526
1527
  {
  	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
  	.name =		"Line In->Rear Out Switch",
  	.info =		snd_es1373_line_info,
  	.get =		snd_es1373_line_get,
  	.put =		snd_es1373_line_put,
  };
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1528
  static void snd_ensoniq_mixer_free_ac97(struct snd_ac97 *ac97)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1529
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1530
  	struct ensoniq *ensoniq = ac97->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1531
1532
  	ensoniq->u.es1371.ac97 = NULL;
  }
5da8fa251   Takashi Iwai   [ALSA] ens1371 - ...
1533
  struct es1371_quirk {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1534
1535
1536
  	unsigned short vid;		/* vendor ID */
  	unsigned short did;		/* device ID */
  	unsigned char rev;		/* revision */
5da8fa251   Takashi Iwai   [ALSA] ens1371 - ...
1537
  };
076c0e4fd   Randy Dunlap   [ALSA] fix ensoni...
1538
1539
  static int es1371_quirk_lookup(struct ensoniq *ensoniq,
  				struct es1371_quirk *list)
5da8fa251   Takashi Iwai   [ALSA] ens1371 - ...
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
  {
  	while (list->vid != (unsigned short)PCI_ANY_ID) {
  		if (ensoniq->pci->vendor == list->vid &&
  		    ensoniq->pci->device == list->did &&
  		    ensoniq->rev == list->rev)
  			return 1;
  		list++;
  	}
  	return 0;
  }
e23e7a143   Bill Pemberton   ALSA: pci: remove...
1550
  static struct es1371_quirk es1371_spdif_present[] = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1551
1552
1553
1554
1555
1556
1557
  	{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_C },
  	{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_D },
  	{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_E },
  	{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_ES1371, .rev = ES1371REV_CT5880_A },
  	{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_ES1371, .rev = ES1371REV_ES1373_8 },
  	{ .vid = PCI_ANY_ID, .did = PCI_ANY_ID }
  };
e23e7a143   Bill Pemberton   ALSA: pci: remove...
1558
  static struct snd_pci_quirk ens1373_line_quirk[] = {
5da8fa251   Takashi Iwai   [ALSA] ens1371 - ...
1559
1560
1561
1562
  	SND_PCI_QUIRK_ID(0x1274, 0x2000), /* GA-7DXR */
  	SND_PCI_QUIRK_ID(0x1458, 0xa000), /* GA-8IEXP */
  	{ } /* end */
  };
e23e7a143   Bill Pemberton   ALSA: pci: remove...
1563
1564
  static int snd_ensoniq_1371_mixer(struct ensoniq *ensoniq,
  				  int has_spdif, int has_line)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1565
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1566
1567
1568
  	struct snd_card *card = ensoniq->card;
  	struct snd_ac97_bus *pbus;
  	struct snd_ac97_template ac97;
5da8fa251   Takashi Iwai   [ALSA] ens1371 - ...
1569
  	int err;
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1570
  	static struct snd_ac97_bus_ops ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1571
1572
  		.write = snd_es1371_codec_write,
  		.read = snd_es1371_codec_read,
072c01194   Jaroslav Kysela   [ALSA] ens1371 - ...
1573
  		.wait = snd_es1371_codec_wait,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1574
1575
1576
1577
1578
1579
1580
1581
  	};
  
  	if ((err = snd_ac97_bus(card, 0, &ops, NULL, &pbus)) < 0)
  		return err;
  
  	memset(&ac97, 0, sizeof(ac97));
  	ac97.private_data = ensoniq;
  	ac97.private_free = snd_ensoniq_mixer_free_ac97;
462dba28e   Rene Herman   ALSA: ALSA: ens13...
1582
  	ac97.pci = ensoniq->pci;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1583
1584
1585
  	ac97.scaps = AC97_SCAP_AUDIO;
  	if ((err = snd_ac97_mixer(pbus, &ac97, &ensoniq->u.es1371.ac97)) < 0)
  		return err;
5da8fa251   Takashi Iwai   [ALSA] ens1371 - ...
1586
1587
1588
  	if (has_spdif > 0 ||
  	    (!has_spdif && es1371_quirk_lookup(ensoniq, es1371_spdif_present))) {
  		struct snd_kcontrol *kctl;
405b0a377   Harvey Harrison   [ALSA] sound: ens...
1589
  		int i, is_spdif = 0;
5da8fa251   Takashi Iwai   [ALSA] ens1371 - ...
1590
1591
1592
1593
1594
1595
  
  		ensoniq->spdif_default = ensoniq->spdif_stream =
  			SNDRV_PCM_DEFAULT_CON_SPDIF;
  		outl(ensoniq->spdif_default, ES_REG(ensoniq, CHANNEL_STATUS));
  
  		if (ensoniq->u.es1371.ac97->ext_id & AC97_EI_SPDIF)
405b0a377   Harvey Harrison   [ALSA] sound: ens...
1596
  			is_spdif++;
5da8fa251   Takashi Iwai   [ALSA] ens1371 - ...
1597
1598
1599
1600
1601
  
  		for (i = 0; i < ARRAY_SIZE(snd_es1371_mixer_spdif); i++) {
  			kctl = snd_ctl_new1(&snd_es1371_mixer_spdif[i], ensoniq);
  			if (!kctl)
  				return -ENOMEM;
405b0a377   Harvey Harrison   [ALSA] sound: ens...
1602
  			kctl->id.index = is_spdif;
5da8fa251   Takashi Iwai   [ALSA] ens1371 - ...
1603
1604
1605
  			err = snd_ctl_add(card, kctl);
  			if (err < 0)
  				return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1606
  		}
5da8fa251   Takashi Iwai   [ALSA] ens1371 - ...
1607
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1608
1609
1610
1611
1612
1613
1614
1615
  	if (ensoniq->u.es1371.ac97->ext_id & AC97_EI_SDAC) {
  		/* mirror rear to front speakers */
  		ensoniq->cssr &= ~(ES_1373_REAR_BIT27|ES_1373_REAR_BIT24);
  		ensoniq->cssr |= ES_1373_REAR_BIT26;
  		err = snd_ctl_add(card, snd_ctl_new1(&snd_ens1373_rear, ensoniq));
  		if (err < 0)
  			return err;
  	}
5da8fa251   Takashi Iwai   [ALSA] ens1371 - ...
1616
1617
1618
1619
  	if (has_line > 0 ||
  	    snd_pci_quirk_lookup(ensoniq->pci, ens1373_line_quirk)) {
  		 err = snd_ctl_add(card, snd_ctl_new1(&snd_ens1373_line,
  						      ensoniq));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
  		 if (err < 0)
  			 return err;
  	}
  
  	return 0;
  }
  
  #endif /* CHIP1371 */
  
  /* generic control callbacks for ens1370 */
  #ifdef CHIP1370
  #define ENSONIQ_CONTROL(xname, mask) \
  { .iface = SNDRV_CTL_ELEM_IFACE_CARD, .name = xname, .info = snd_ensoniq_control_info, \
    .get = snd_ensoniq_control_get, .put = snd_ensoniq_control_put, \
    .private_value = mask }
a5ce88909   Takashi Iwai   [ALSA] Clean up w...
1635
  #define snd_ensoniq_control_info	snd_ctl_boolean_mono_info
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1636

eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1637
1638
  static int snd_ensoniq_control_get(struct snd_kcontrol *kcontrol,
  				   struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1639
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1640
  	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1641
1642
1643
1644
1645
1646
1647
  	int mask = kcontrol->private_value;
  	
  	spin_lock_irq(&ensoniq->reg_lock);
  	ucontrol->value.integer.value[0] = ensoniq->ctrl & mask ? 1 : 0;
  	spin_unlock_irq(&ensoniq->reg_lock);
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1648
1649
  static int snd_ensoniq_control_put(struct snd_kcontrol *kcontrol,
  				   struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1650
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1651
  	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
  	int mask = kcontrol->private_value;
  	unsigned int nval;
  	int change;
  	
  	nval = ucontrol->value.integer.value[0] ? mask : 0;
  	spin_lock_irq(&ensoniq->reg_lock);
  	change = (ensoniq->ctrl & mask) != nval;
  	ensoniq->ctrl &= ~mask;
  	ensoniq->ctrl |= nval;
  	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
  	spin_unlock_irq(&ensoniq->reg_lock);
  	return change;
  }
  
  /*
   * ENS1370 mixer
   */
e23e7a143   Bill Pemberton   ALSA: pci: remove...
1669
  static struct snd_kcontrol_new snd_es1370_controls[2] = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1670
1671
1672
1673
1674
  ENSONIQ_CONTROL("PCM 0 Output also on Line-In Jack", ES_1370_XCTL0),
  ENSONIQ_CONTROL("Mic +5V bias", ES_1370_XCTL1)
  };
  
  #define ES1370_CONTROLS ARRAY_SIZE(snd_es1370_controls)
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1675
  static void snd_ensoniq_mixer_free_ak4531(struct snd_ak4531 *ak4531)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1676
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1677
  	struct ensoniq *ensoniq = ak4531->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1678
1679
  	ensoniq->u.es1370.ak4531 = NULL;
  }
e23e7a143   Bill Pemberton   ALSA: pci: remove...
1680
  static int snd_ensoniq_1370_mixer(struct ensoniq *ensoniq)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1681
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1682
1683
  	struct snd_card *card = ensoniq->card;
  	struct snd_ak4531 ak4531;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
  	unsigned int idx;
  	int err;
  
  	/* try reset AK4531 */
  	outw(ES_1370_CODEC_WRITE(AK4531_RESET, 0x02), ES_REG(ensoniq, 1370_CODEC));
  	inw(ES_REG(ensoniq, 1370_CODEC));
  	udelay(100);
  	outw(ES_1370_CODEC_WRITE(AK4531_RESET, 0x03), ES_REG(ensoniq, 1370_CODEC));
  	inw(ES_REG(ensoniq, 1370_CODEC));
  	udelay(100);
  
  	memset(&ak4531, 0, sizeof(ak4531));
  	ak4531.write = snd_es1370_codec_write;
  	ak4531.private_data = ensoniq;
  	ak4531.private_free = snd_ensoniq_mixer_free_ak4531;
  	if ((err = snd_ak4531_mixer(card, &ak4531, &ensoniq->u.es1370.ak4531)) < 0)
  		return err;
  	for (idx = 0; idx < ES1370_CONTROLS; idx++) {
  		err = snd_ctl_add(card, snd_ctl_new1(&snd_es1370_controls[idx], ensoniq));
  		if (err < 0)
  			return err;
  	}
  	return 0;
  }
  
  #endif /* CHIP1370 */
  
  #ifdef SUPPORT_JOYSTICK
  
  #ifdef CHIP1371
7ddbd1819   Takashi Iwai   ALSA: ens137x: Us...
1714
  static int snd_ensoniq_get_joystick_port(struct ensoniq *ensoniq, int dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
  {
  	switch (joystick_port[dev]) {
  	case 0: /* disabled */
  	case 1: /* auto-detect */
  	case 0x200:
  	case 0x208:
  	case 0x210:
  	case 0x218:
  		return joystick_port[dev];
  
  	default:
7ddbd1819   Takashi Iwai   ALSA: ens137x: Us...
1726
1727
  		dev_err(ensoniq->card->dev,
  			"invalid joystick port %#x", joystick_port[dev]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1728
1729
1730
1731
  		return 0;
  	}
  }
  #else
7ddbd1819   Takashi Iwai   ALSA: ens137x: Us...
1732
  static int snd_ensoniq_get_joystick_port(struct ensoniq *ensoniq, int dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1733
1734
1735
1736
  {
  	return joystick[dev] ? 0x200 : 0;
  }
  #endif
e23e7a143   Bill Pemberton   ALSA: pci: remove...
1737
  static int snd_ensoniq_create_gameport(struct ensoniq *ensoniq, int dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1738
1739
1740
  {
  	struct gameport *gp;
  	int io_port;
7ddbd1819   Takashi Iwai   ALSA: ens137x: Us...
1741
  	io_port = snd_ensoniq_get_joystick_port(ensoniq, dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
  
  	switch (io_port) {
  	case 0:
  		return -ENOSYS;
  
  	case 1: /* auto_detect */
  		for (io_port = 0x200; io_port <= 0x218; io_port += 8)
  			if (request_region(io_port, 8, "ens137x: gameport"))
  				break;
  		if (io_port > 0x218) {
7ddbd1819   Takashi Iwai   ALSA: ens137x: Us...
1752
1753
1754
  			dev_warn(ensoniq->card->dev,
  				 "no gameport ports available
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1755
1756
1757
1758
1759
1760
  			return -EBUSY;
  		}
  		break;
  
  	default:
  		if (!request_region(io_port, 8, "ens137x: gameport")) {
7ddbd1819   Takashi Iwai   ALSA: ens137x: Us...
1761
1762
1763
  			dev_warn(ensoniq->card->dev,
  				 "gameport io port %#x in use
  ",
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1764
  			       io_port);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1765
1766
1767
1768
1769
1770
1771
  			return -EBUSY;
  		}
  		break;
  	}
  
  	ensoniq->gameport = gp = gameport_allocate_port();
  	if (!gp) {
7ddbd1819   Takashi Iwai   ALSA: ens137x: Us...
1772
1773
1774
  		dev_err(ensoniq->card->dev,
  			"cannot allocate memory for gameport
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
  		release_region(io_port, 8);
  		return -ENOMEM;
  	}
  
  	gameport_set_name(gp, "ES137x");
  	gameport_set_phys(gp, "pci%s/gameport0", pci_name(ensoniq->pci));
  	gameport_set_dev_parent(gp, &ensoniq->pci->dev);
  	gp->io = io_port;
  
  	ensoniq->ctrl |= ES_JYSTK_EN;
  #ifdef CHIP1371
  	ensoniq->ctrl &= ~ES_1371_JOY_ASELM;
  	ensoniq->ctrl |= ES_1371_JOY_ASEL((io_port - 0x200) / 8);
  #endif
  	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
  
  	gameport_register_port(ensoniq->gameport);
  
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1795
  static void snd_ensoniq_free_gameport(struct ensoniq *ensoniq)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
  {
  	if (ensoniq->gameport) {
  		int port = ensoniq->gameport->io;
  
  		gameport_unregister_port(ensoniq->gameport);
  		ensoniq->gameport = NULL;
  		ensoniq->ctrl &= ~ES_JYSTK_EN;
  		outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
  		release_region(port, 8);
  	}
  }
  #else
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1808
1809
  static inline int snd_ensoniq_create_gameport(struct ensoniq *ensoniq, long port) { return -ENOSYS; }
  static inline void snd_ensoniq_free_gameport(struct ensoniq *ensoniq) { }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1810
1811
1812
1813
1814
  #endif /* SUPPORT_JOYSTICK */
  
  /*
  
   */
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1815
1816
  static void snd_ensoniq_proc_read(struct snd_info_entry *entry, 
  				  struct snd_info_buffer *buffer)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1817
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1818
  	struct ensoniq *ensoniq = entry->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1819

1fe4d42e0   Takashi Iwai   ALSA: ens1370: Re...
1820
1821
1822
  	snd_iprintf(buffer, "Ensoniq AudioPCI " CHIP_NAME "
  
  ");
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1823
1824
1825
  	snd_iprintf(buffer, "Joystick enable  : %s
  ",
  		    ensoniq->ctrl & ES_JYSTK_EN ? "on" : "off");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1826
  #ifdef CHIP1370
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1827
1828
1829
1830
1831
1832
  	snd_iprintf(buffer, "MIC +5V bias     : %s
  ",
  		    ensoniq->ctrl & ES_1370_XCTL1 ? "on" : "off");
  	snd_iprintf(buffer, "Line In to AOUT  : %s
  ",
  		    ensoniq->ctrl & ES_1370_XCTL0 ? "on" : "off");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1833
  #else
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1834
1835
1836
  	snd_iprintf(buffer, "Joystick port    : 0x%x
  ",
  		    (ES_1371_JOY_ASELI(ensoniq->ctrl) * 8) + 0x200);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1837
1838
  #endif
  }
e23e7a143   Bill Pemberton   ALSA: pci: remove...
1839
  static void snd_ensoniq_proc_init(struct ensoniq *ensoniq)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1840
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1841
  	struct snd_info_entry *entry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1842
1843
  
  	if (! snd_card_proc_new(ensoniq->card, "audiopci", &entry))
bf850204a   Takashi Iwai   [ALSA] Remove unn...
1844
  		snd_info_set_text_ops(entry, ensoniq, snd_ensoniq_proc_read);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1845
1846
1847
1848
1849
  }
  
  /*
  
   */
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1850
  static int snd_ensoniq_free(struct ensoniq *ensoniq)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
  {
  	snd_ensoniq_free_gameport(ensoniq);
  	if (ensoniq->irq < 0)
  		goto __hw_end;
  #ifdef CHIP1370
  	outl(ES_1370_SERR_DISABLE, ES_REG(ensoniq, CONTROL));	/* switch everything off */
  	outl(0, ES_REG(ensoniq, SERIAL));	/* clear serial interface */
  #else
  	outl(0, ES_REG(ensoniq, CONTROL));	/* switch everything off */
  	outl(0, ES_REG(ensoniq, SERIAL));	/* clear serial interface */
  #endif
f000fd809   Jeff Garzik   [ALSA] Fix synchr...
1862
1863
  	if (ensoniq->irq >= 0)
  		synchronize_irq(ensoniq->irq);
db10e7fbb   Yijing Wang   ALSA: pci: trivia...
1864
  	pci_set_power_state(ensoniq->pci, PCI_D3hot);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1865
1866
1867
1868
1869
1870
        __hw_end:
  #ifdef CHIP1370
  	if (ensoniq->dma_bug.area)
  		snd_dma_free_pages(&ensoniq->dma_bug);
  #endif
  	if (ensoniq->irq >= 0)
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1871
  		free_irq(ensoniq->irq, ensoniq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1872
1873
1874
1875
1876
  	pci_release_regions(ensoniq->pci);
  	pci_disable_device(ensoniq->pci);
  	kfree(ensoniq);
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1877
  static int snd_ensoniq_dev_free(struct snd_device *device)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1878
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1879
  	struct ensoniq *ensoniq = device->device_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1880
1881
1882
1883
  	return snd_ensoniq_free(ensoniq);
  }
  
  #ifdef CHIP1371
e23e7a143   Bill Pemberton   ALSA: pci: remove...
1884
  static struct snd_pci_quirk es1371_amplifier_hack[] = {
5da8fa251   Takashi Iwai   [ALSA] ens1371 - ...
1885
1886
1887
1888
1889
  	SND_PCI_QUIRK_ID(0x107b, 0x2150),	/* Gateway Solo 2150 */
  	SND_PCI_QUIRK_ID(0x13bd, 0x100c),	/* EV1938 on Mebius PC-MJ100V */
  	SND_PCI_QUIRK_ID(0x1102, 0x5938),	/* Targa Xtender300 */
  	SND_PCI_QUIRK_ID(0x1102, 0x8938),	/* IPC Topnote G notebook */
  	{ } /* end */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1890
  };
5da8fa251   Takashi Iwai   [ALSA] ens1371 - ...
1891
1892
  
  static struct es1371_quirk es1371_ac97_reset_hack[] = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1893
1894
1895
1896
1897
1898
1899
1900
  	{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_C },
  	{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_D },
  	{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_E },
  	{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_ES1371, .rev = ES1371REV_CT5880_A },
  	{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_ES1371, .rev = ES1371REV_ES1373_8 },
  	{ .vid = PCI_ANY_ID, .did = PCI_ANY_ID }
  };
  #endif
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1901
  static void snd_ensoniq_chip_init(struct ensoniq *ensoniq)
f31a31b90   Kurt J. Bosch   [ALSA] Fix missin...
1902
1903
1904
  {
  #ifdef CHIP1371
  	int idx;
f31a31b90   Kurt J. Bosch   [ALSA] Fix missin...
1905
  #endif
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
1906
1907
1908
  	/* this code was part of snd_ensoniq_create before intruduction
  	  * of suspend/resume
  	  */
f31a31b90   Kurt J. Bosch   [ALSA] Fix missin...
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
  #ifdef CHIP1370
  	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
  	outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
  	outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE));
  	outl(ensoniq->dma_bug.addr, ES_REG(ensoniq, PHANTOM_FRAME));
  	outl(0, ES_REG(ensoniq, PHANTOM_COUNT));
  #else
  	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
  	outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
  	outl(0, ES_REG(ensoniq, 1371_LEGACY));
5da8fa251   Takashi Iwai   [ALSA] ens1371 - ...
1919
1920
1921
1922
1923
1924
  	if (es1371_quirk_lookup(ensoniq, es1371_ac97_reset_hack)) {
  	    outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
  	    /* need to delay around 20ms(bleech) to give
  	       some CODECs enough time to wakeup */
  	    msleep(20);
  	}
f31a31b90   Kurt J. Bosch   [ALSA] Fix missin...
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
  	/* AC'97 warm reset to start the bitclk */
  	outl(ensoniq->ctrl | ES_1371_SYNC_RES, ES_REG(ensoniq, CONTROL));
  	inl(ES_REG(ensoniq, CONTROL));
  	udelay(20);
  	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
  	/* Init the sample rate converter */
  	snd_es1371_wait_src_ready(ensoniq);	
  	outl(ES_1371_SRC_DISABLE, ES_REG(ensoniq, 1371_SMPRATE));
  	for (idx = 0; idx < 0x80; idx++)
  		snd_es1371_src_write(ensoniq, idx, 0);
  	snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_TRUNC_N, 16 << 4);
  	snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, 16 << 10);
  	snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_TRUNC_N, 16 << 4);
  	snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, 16 << 10);
  	snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, 1 << 12);
  	snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, 1 << 12);
  	snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1, 1 << 12);
  	snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1 + 1, 1 << 12);
  	snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2, 1 << 12);
  	snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2 + 1, 1 << 12);
  	snd_es1371_adc_rate(ensoniq, 22050);
  	snd_es1371_dac1_rate(ensoniq, 22050);
  	snd_es1371_dac2_rate(ensoniq, 22050);
  	/* WARNING:
  	 * enabling the sample rate converter without properly programming
  	 * its parameters causes the chip to lock up (the SRC busy bit will
  	 * be stuck high, and I've found no way to rectify this other than
  	 * power cycle) - Thomas Sailer
  	 */
  	snd_es1371_wait_src_ready(ensoniq);
  	outl(0, ES_REG(ensoniq, 1371_SMPRATE));
  	/* try reset codec directly */
  	outl(ES_1371_CODEC_WRITE(0, 0), ES_REG(ensoniq, 1371_CODEC));
  #endif
  	outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL));
  	outb(0x00, ES_REG(ensoniq, UART_RES));
  	outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
  	synchronize_irq(ensoniq->irq);
  }
c7561cd80   Takashi Iwai   ALSA: PCI: Replac...
1964
  #ifdef CONFIG_PM_SLEEP
68cb2b559   Takashi Iwai   ALSA: Convert to ...
1965
  static int snd_ensoniq_suspend(struct device *dev)
f31a31b90   Kurt J. Bosch   [ALSA] Fix missin...
1966
  {
68cb2b559   Takashi Iwai   ALSA: Convert to ...
1967
  	struct snd_card *card = dev_get_drvdata(dev);
fe8be1078   Takashi Iwai   [ALSA] ens137x - ...
1968
  	struct ensoniq *ensoniq = card->private_data;
f31a31b90   Kurt J. Bosch   [ALSA] Fix missin...
1969
  	
fe8be1078   Takashi Iwai   [ALSA] ens137x - ...
1970
  	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
f31a31b90   Kurt J. Bosch   [ALSA] Fix missin...
1971
1972
1973
1974
  	snd_pcm_suspend_all(ensoniq->pcm1);
  	snd_pcm_suspend_all(ensoniq->pcm2);
  	
  #ifdef CHIP1371	
fe8be1078   Takashi Iwai   [ALSA] ens137x - ...
1975
  	snd_ac97_suspend(ensoniq->u.es1371.ac97);
f31a31b90   Kurt J. Bosch   [ALSA] Fix missin...
1976
  #else
15f500a69   Takashi Iwai   [ALSA] ens1370 - ...
1977
1978
1979
1980
1981
1982
1983
  	/* try to reset AK4531 */
  	outw(ES_1370_CODEC_WRITE(AK4531_RESET, 0x02), ES_REG(ensoniq, 1370_CODEC));
  	inw(ES_REG(ensoniq, 1370_CODEC));
  	udelay(100);
  	outw(ES_1370_CODEC_WRITE(AK4531_RESET, 0x03), ES_REG(ensoniq, 1370_CODEC));
  	inw(ES_REG(ensoniq, 1370_CODEC));
  	udelay(100);
fe8be1078   Takashi Iwai   [ALSA] ens137x - ...
1984
  	snd_ak4531_suspend(ensoniq->u.es1370.ak4531);
f31a31b90   Kurt J. Bosch   [ALSA] Fix missin...
1985
  #endif	
f31a31b90   Kurt J. Bosch   [ALSA] Fix missin...
1986
1987
  	return 0;
  }
68cb2b559   Takashi Iwai   ALSA: Convert to ...
1988
  static int snd_ensoniq_resume(struct device *dev)
f31a31b90   Kurt J. Bosch   [ALSA] Fix missin...
1989
  {
68cb2b559   Takashi Iwai   ALSA: Convert to ...
1990
  	struct snd_card *card = dev_get_drvdata(dev);
fe8be1078   Takashi Iwai   [ALSA] ens137x - ...
1991
  	struct ensoniq *ensoniq = card->private_data;
f31a31b90   Kurt J. Bosch   [ALSA] Fix missin...
1992

f31a31b90   Kurt J. Bosch   [ALSA] Fix missin...
1993
1994
1995
  	snd_ensoniq_chip_init(ensoniq);
  
  #ifdef CHIP1371	
fe8be1078   Takashi Iwai   [ALSA] ens137x - ...
1996
  	snd_ac97_resume(ensoniq->u.es1371.ac97);
f31a31b90   Kurt J. Bosch   [ALSA] Fix missin...
1997
  #else
fe8be1078   Takashi Iwai   [ALSA] ens137x - ...
1998
  	snd_ak4531_resume(ensoniq->u.es1370.ak4531);
f31a31b90   Kurt J. Bosch   [ALSA] Fix missin...
1999
  #endif	
fe8be1078   Takashi Iwai   [ALSA] ens137x - ...
2000
  	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
f31a31b90   Kurt J. Bosch   [ALSA] Fix missin...
2001
2002
  	return 0;
  }
f31a31b90   Kurt J. Bosch   [ALSA] Fix missin...
2003

68cb2b559   Takashi Iwai   ALSA: Convert to ...
2004
2005
2006
2007
  static SIMPLE_DEV_PM_OPS(snd_ensoniq_pm, snd_ensoniq_suspend, snd_ensoniq_resume);
  #define SND_ENSONIQ_PM_OPS	&snd_ensoniq_pm
  #else
  #define SND_ENSONIQ_PM_OPS	NULL
c7561cd80   Takashi Iwai   ALSA: PCI: Replac...
2008
  #endif /* CONFIG_PM_SLEEP */
f31a31b90   Kurt J. Bosch   [ALSA] Fix missin...
2009

e23e7a143   Bill Pemberton   ALSA: pci: remove...
2010
2011
2012
  static int snd_ensoniq_create(struct snd_card *card,
  			      struct pci_dev *pci,
  			      struct ensoniq **rensoniq)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2013
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
2014
  	struct ensoniq *ensoniq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2015
  	int err;
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
2016
  	static struct snd_device_ops ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2017
2018
2019
2020
2021
2022
  		.dev_free =	snd_ensoniq_dev_free,
  	};
  
  	*rensoniq = NULL;
  	if ((err = pci_enable_device(pci)) < 0)
  		return err;
e560d8d83   Takashi Iwai   [ALSA] Replace wi...
2023
  	ensoniq = kzalloc(sizeof(*ensoniq), GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2024
2025
2026
2027
2028
  	if (ensoniq == NULL) {
  		pci_disable_device(pci);
  		return -ENOMEM;
  	}
  	spin_lock_init(&ensoniq->reg_lock);
62932df8f   Ingo Molnar   [ALSA] semaphore ...
2029
  	mutex_init(&ensoniq->src_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2030
2031
2032
2033
2034
2035
2036
2037
2038
  	ensoniq->card = card;
  	ensoniq->pci = pci;
  	ensoniq->irq = -1;
  	if ((err = pci_request_regions(pci, "Ensoniq AudioPCI")) < 0) {
  		kfree(ensoniq);
  		pci_disable_device(pci);
  		return err;
  	}
  	ensoniq->port = pci_resource_start(pci, 0);
437a5a460   Takashi Iwai   [ALSA] Remove IRQ...
2039
  	if (request_irq(pci->irq, snd_audiopci_interrupt, IRQF_SHARED,
934c2b6d0   Takashi Iwai   ALSA: use KBUILD_...
2040
  			KBUILD_MODNAME, ensoniq)) {
7ddbd1819   Takashi Iwai   ALSA: ens137x: Us...
2041
2042
  		dev_err(card->dev, "unable to grab IRQ %d
  ", pci->irq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2043
2044
2045
2046
2047
2048
2049
  		snd_ensoniq_free(ensoniq);
  		return -EBUSY;
  	}
  	ensoniq->irq = pci->irq;
  #ifdef CHIP1370
  	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
  				16, &ensoniq->dma_bug) < 0) {
7ddbd1819   Takashi Iwai   ALSA: ens137x: Us...
2050
2051
  		dev_err(card->dev, "unable to allocate space for phantom area - dma_bug
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2052
2053
2054
2055
2056
  		snd_ensoniq_free(ensoniq);
  		return -EBUSY;
  	}
  #endif
  	pci_set_master(pci);
44c10138f   Auke Kok   PCI: Change all d...
2057
  	ensoniq->rev = pci->revision;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2058
2059
  #ifdef CHIP1370
  #if 0
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
2060
2061
  	ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_SERR_DISABLE |
  		ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2062
2063
2064
2065
  #else	/* get microphone working */
  	ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000));
  #endif
  	ensoniq->sctrl = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2066
2067
2068
2069
  #else
  	ensoniq->ctrl = 0;
  	ensoniq->sctrl = 0;
  	ensoniq->cssr = 0;
5da8fa251   Takashi Iwai   [ALSA] ens1371 - ...
2070
2071
2072
2073
2074
  	if (snd_pci_quirk_lookup(pci, es1371_amplifier_hack))
  		ensoniq->ctrl |= ES_1371_GPIO_OUT(1);	/* turn amplifier on */
  
  	if (es1371_quirk_lookup(ensoniq, es1371_ac97_reset_hack))
  		ensoniq->cssr |= ES_1371_ST_AC97_RST;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2075
  #endif
f31a31b90   Kurt J. Bosch   [ALSA] Fix missin...
2076
2077
  
  	snd_ensoniq_chip_init(ensoniq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2078
2079
2080
2081
2082
2083
2084
  
  	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ensoniq, &ops)) < 0) {
  		snd_ensoniq_free(ensoniq);
  		return err;
  	}
  
  	snd_ensoniq_proc_init(ensoniq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2085
2086
2087
2088
2089
2090
2091
  	*rensoniq = ensoniq;
  	return 0;
  }
  
  /*
   *  MIDI section
   */
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
2092
  static void snd_ensoniq_midi_interrupt(struct ensoniq * ensoniq)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2093
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
2094
  	struct snd_rawmidi *rmidi = ensoniq->rmidi;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
  	unsigned char status, mask, byte;
  
  	if (rmidi == NULL)
  		return;
  	/* do Rx at first */
  	spin_lock(&ensoniq->reg_lock);
  	mask = ensoniq->uartm & ES_MODE_INPUT ? ES_RXRDY : 0;
  	while (mask) {
  		status = inb(ES_REG(ensoniq, UART_STATUS));
  		if ((status & mask) == 0)
  			break;
  		byte = inb(ES_REG(ensoniq, UART_DATA));
  		snd_rawmidi_receive(ensoniq->midi_input, &byte, 1);
  	}
  	spin_unlock(&ensoniq->reg_lock);
  
  	/* do Tx at second */
  	spin_lock(&ensoniq->reg_lock);
  	mask = ensoniq->uartm & ES_MODE_OUTPUT ? ES_TXRDY : 0;
  	while (mask) {
  		status = inb(ES_REG(ensoniq, UART_STATUS));
  		if ((status & mask) == 0)
  			break;
  		if (snd_rawmidi_transmit(ensoniq->midi_output, &byte, 1) != 1) {
  			ensoniq->uartc &= ~ES_TXINTENM;
  			outb(ensoniq->uartc, ES_REG(ensoniq, UART_CONTROL));
  			mask &= ~ES_TXRDY;
  		} else {
  			outb(byte, ES_REG(ensoniq, UART_DATA));
  		}
  	}
  	spin_unlock(&ensoniq->reg_lock);
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
2128
  static int snd_ensoniq_midi_input_open(struct snd_rawmidi_substream *substream)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2129
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
2130
  	struct ensoniq *ensoniq = substream->rmidi->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
  
  	spin_lock_irq(&ensoniq->reg_lock);
  	ensoniq->uartm |= ES_MODE_INPUT;
  	ensoniq->midi_input = substream;
  	if (!(ensoniq->uartm & ES_MODE_OUTPUT)) {
  		outb(ES_CNTRL(3), ES_REG(ensoniq, UART_CONTROL));
  		outb(ensoniq->uartc = 0, ES_REG(ensoniq, UART_CONTROL));
  		outl(ensoniq->ctrl |= ES_UART_EN, ES_REG(ensoniq, CONTROL));
  	}
  	spin_unlock_irq(&ensoniq->reg_lock);
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
2143
  static int snd_ensoniq_midi_input_close(struct snd_rawmidi_substream *substream)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2144
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
2145
  	struct ensoniq *ensoniq = substream->rmidi->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
  
  	spin_lock_irq(&ensoniq->reg_lock);
  	if (!(ensoniq->uartm & ES_MODE_OUTPUT)) {
  		outb(ensoniq->uartc = 0, ES_REG(ensoniq, UART_CONTROL));
  		outl(ensoniq->ctrl &= ~ES_UART_EN, ES_REG(ensoniq, CONTROL));
  	} else {
  		outb(ensoniq->uartc &= ~ES_RXINTEN, ES_REG(ensoniq, UART_CONTROL));
  	}
  	ensoniq->midi_input = NULL;
  	ensoniq->uartm &= ~ES_MODE_INPUT;
  	spin_unlock_irq(&ensoniq->reg_lock);
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
2159
  static int snd_ensoniq_midi_output_open(struct snd_rawmidi_substream *substream)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2160
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
2161
  	struct ensoniq *ensoniq = substream->rmidi->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
  
  	spin_lock_irq(&ensoniq->reg_lock);
  	ensoniq->uartm |= ES_MODE_OUTPUT;
  	ensoniq->midi_output = substream;
  	if (!(ensoniq->uartm & ES_MODE_INPUT)) {
  		outb(ES_CNTRL(3), ES_REG(ensoniq, UART_CONTROL));
  		outb(ensoniq->uartc = 0, ES_REG(ensoniq, UART_CONTROL));
  		outl(ensoniq->ctrl |= ES_UART_EN, ES_REG(ensoniq, CONTROL));
  	}
  	spin_unlock_irq(&ensoniq->reg_lock);
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
2174
  static int snd_ensoniq_midi_output_close(struct snd_rawmidi_substream *substream)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2175
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
2176
  	struct ensoniq *ensoniq = substream->rmidi->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
  
  	spin_lock_irq(&ensoniq->reg_lock);
  	if (!(ensoniq->uartm & ES_MODE_INPUT)) {
  		outb(ensoniq->uartc = 0, ES_REG(ensoniq, UART_CONTROL));
  		outl(ensoniq->ctrl &= ~ES_UART_EN, ES_REG(ensoniq, CONTROL));
  	} else {
  		outb(ensoniq->uartc &= ~ES_TXINTENM, ES_REG(ensoniq, UART_CONTROL));
  	}
  	ensoniq->midi_output = NULL;
  	ensoniq->uartm &= ~ES_MODE_OUTPUT;
  	spin_unlock_irq(&ensoniq->reg_lock);
  	return 0;
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
2190
  static void snd_ensoniq_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2191
2192
  {
  	unsigned long flags;
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
2193
  	struct ensoniq *ensoniq = substream->rmidi->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
  	int idx;
  
  	spin_lock_irqsave(&ensoniq->reg_lock, flags);
  	if (up) {
  		if ((ensoniq->uartc & ES_RXINTEN) == 0) {
  			/* empty input FIFO */
  			for (idx = 0; idx < 32; idx++)
  				inb(ES_REG(ensoniq, UART_DATA));
  			ensoniq->uartc |= ES_RXINTEN;
  			outb(ensoniq->uartc, ES_REG(ensoniq, UART_CONTROL));
  		}
  	} else {
  		if (ensoniq->uartc & ES_RXINTEN) {
  			ensoniq->uartc &= ~ES_RXINTEN;
  			outb(ensoniq->uartc, ES_REG(ensoniq, UART_CONTROL));
  		}
  	}
  	spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
  }
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
2213
  static void snd_ensoniq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2214
2215
  {
  	unsigned long flags;
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
2216
  	struct ensoniq *ensoniq = substream->rmidi->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
  	unsigned char byte;
  
  	spin_lock_irqsave(&ensoniq->reg_lock, flags);
  	if (up) {
  		if (ES_TXINTENI(ensoniq->uartc) == 0) {
  			ensoniq->uartc |= ES_TXINTENO(1);
  			/* fill UART FIFO buffer at first, and turn Tx interrupts only if necessary */
  			while (ES_TXINTENI(ensoniq->uartc) == 1 &&
  			       (inb(ES_REG(ensoniq, UART_STATUS)) & ES_TXRDY)) {
  				if (snd_rawmidi_transmit(substream, &byte, 1) != 1) {
  					ensoniq->uartc &= ~ES_TXINTENM;
  				} else {
  					outb(byte, ES_REG(ensoniq, UART_DATA));
  				}
  			}
  			outb(ensoniq->uartc, ES_REG(ensoniq, UART_CONTROL));
  		}
  	} else {
  		if (ES_TXINTENI(ensoniq->uartc) == 1) {
  			ensoniq->uartc &= ~ES_TXINTENM;
  			outb(ensoniq->uartc, ES_REG(ensoniq, UART_CONTROL));
  		}
  	}
  	spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
  }
485885b9d   Takashi Iwai   ALSA: pci: Consti...
2242
  static const struct snd_rawmidi_ops snd_ensoniq_midi_output =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2243
2244
2245
2246
2247
  {
  	.open =		snd_ensoniq_midi_output_open,
  	.close =	snd_ensoniq_midi_output_close,
  	.trigger =	snd_ensoniq_midi_output_trigger,
  };
485885b9d   Takashi Iwai   ALSA: pci: Consti...
2248
  static const struct snd_rawmidi_ops snd_ensoniq_midi_input =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2249
2250
2251
2252
2253
  {
  	.open =		snd_ensoniq_midi_input_open,
  	.close =	snd_ensoniq_midi_input_close,
  	.trigger =	snd_ensoniq_midi_input_trigger,
  };
50b8d94e1   Lars-Peter Clausen   ALSA: ens1370: Re...
2254
  static int snd_ensoniq_midi(struct ensoniq *ensoniq, int device)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2255
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
2256
  	struct snd_rawmidi *rmidi;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2257
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2258
2259
  	if ((err = snd_rawmidi_new(ensoniq->card, "ES1370/1", device, 1, 1, &rmidi)) < 0)
  		return err;
1fe4d42e0   Takashi Iwai   ALSA: ens1370: Re...
2260
  	strcpy(rmidi->name, CHIP_NAME);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2261
2262
  	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_ensoniq_midi_output);
  	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_ensoniq_midi_input);
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
2263
2264
  	rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT |
  		SNDRV_RAWMIDI_INFO_DUPLEX;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2265
2266
  	rmidi->private_data = ensoniq;
  	ensoniq->rmidi = rmidi;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2267
2268
2269
2270
2271
2272
  	return 0;
  }
  
  /*
   *  Interrupt handler
   */
7d12e780e   David Howells   IRQ: Maintain reg...
2273
  static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2274
  {
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
2275
  	struct ensoniq *ensoniq = dev_id;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
  	unsigned int status, sctrl;
  
  	if (ensoniq == NULL)
  		return IRQ_NONE;
  
  	status = inl(ES_REG(ensoniq, STATUS));
  	if (!(status & ES_INTR))
  		return IRQ_NONE;
  
  	spin_lock(&ensoniq->reg_lock);
  	sctrl = ensoniq->sctrl;
  	if (status & ES_DAC1)
  		sctrl &= ~ES_P1_INT_EN;
  	if (status & ES_DAC2)
  		sctrl &= ~ES_P2_INT_EN;
  	if (status & ES_ADC)
  		sctrl &= ~ES_R1_INT_EN;
  	outl(sctrl, ES_REG(ensoniq, SERIAL));
  	outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
  	spin_unlock(&ensoniq->reg_lock);
  
  	if (status & ES_UART)
  		snd_ensoniq_midi_interrupt(ensoniq);
  	if ((status & ES_DAC2) && ensoniq->playback2_substream)
  		snd_pcm_period_elapsed(ensoniq->playback2_substream);
  	if ((status & ES_ADC) && ensoniq->capture_substream)
  		snd_pcm_period_elapsed(ensoniq->capture_substream);
  	if ((status & ES_DAC1) && ensoniq->playback1_substream)
  		snd_pcm_period_elapsed(ensoniq->playback1_substream);
  	return IRQ_HANDLED;
  }
e23e7a143   Bill Pemberton   ALSA: pci: remove...
2307
2308
  static int snd_audiopci_probe(struct pci_dev *pci,
  			      const struct pci_device_id *pci_id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2309
2310
  {
  	static int dev;
eb3414b46   Takashi Iwai   [ALSA] Remove xxx...
2311
2312
  	struct snd_card *card;
  	struct ensoniq *ensoniq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2313
2314
2315
2316
2317
2318
2319
2320
  	int err, pcm_devs[2];
  
  	if (dev >= SNDRV_CARDS)
  		return -ENODEV;
  	if (!enable[dev]) {
  		dev++;
  		return -ENOENT;
  	}
60c5772b5   Takashi Iwai   ALSA: pci: Conver...
2321
2322
  	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
  			   0, &card);
e58de7baf   Takashi Iwai   ALSA: Convert to ...
2323
2324
  	if (err < 0)
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2325
2326
2327
2328
2329
  
  	if ((err = snd_ensoniq_create(card, pci, &ensoniq)) < 0) {
  		snd_card_free(card);
  		return err;
  	}
fe8be1078   Takashi Iwai   [ALSA] ens137x - ...
2330
  	card->private_data = ensoniq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2331
2332
2333
2334
2335
2336
2337
2338
2339
  
  	pcm_devs[0] = 0; pcm_devs[1] = 1;
  #ifdef CHIP1370
  	if ((err = snd_ensoniq_1370_mixer(ensoniq)) < 0) {
  		snd_card_free(card);
  		return err;
  	}
  #endif
  #ifdef CHIP1371
015b6a198   Jaroslav Kysela   [ALSA] ens1371: a...
2340
  	if ((err = snd_ensoniq_1371_mixer(ensoniq, spdif[dev], lineio[dev])) < 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2341
2342
2343
2344
  		snd_card_free(card);
  		return err;
  	}
  #endif
50b8d94e1   Lars-Peter Clausen   ALSA: ens1370: Re...
2345
  	if ((err = snd_ensoniq_pcm(ensoniq, 0)) < 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2346
2347
2348
  		snd_card_free(card);
  		return err;
  	}
50b8d94e1   Lars-Peter Clausen   ALSA: ens1370: Re...
2349
  	if ((err = snd_ensoniq_pcm2(ensoniq, 1)) < 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2350
2351
2352
  		snd_card_free(card);
  		return err;
  	}
50b8d94e1   Lars-Peter Clausen   ALSA: ens1370: Re...
2353
  	if ((err = snd_ensoniq_midi(ensoniq, 0)) < 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
  		snd_card_free(card);
  		return err;
  	}
  
  	snd_ensoniq_create_gameport(ensoniq, dev);
  
  	strcpy(card->driver, DRIVER_NAME);
  
  	strcpy(card->shortname, "Ensoniq AudioPCI");
  	sprintf(card->longname, "%s %s at 0x%lx, irq %i",
  		card->shortname,
  		card->driver,
  		ensoniq->port,
  		ensoniq->irq);
  
  	if ((err = snd_card_register(card)) < 0) {
  		snd_card_free(card);
  		return err;
  	}
  
  	pci_set_drvdata(pci, card);
  	dev++;
  	return 0;
  }
e23e7a143   Bill Pemberton   ALSA: pci: remove...
2378
  static void snd_audiopci_remove(struct pci_dev *pci)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2379
2380
  {
  	snd_card_free(pci_get_drvdata(pci));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2381
  }
e9f66d9b9   Takashi Iwai   ALSA: pci: clean ...
2382
  static struct pci_driver ens137x_driver = {
3733e424c   Takashi Iwai   ALSA: Use KBUILD_...
2383
  	.name = KBUILD_MODNAME,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2384
2385
  	.id_table = snd_audiopci_ids,
  	.probe = snd_audiopci_probe,
e23e7a143   Bill Pemberton   ALSA: pci: remove...
2386
  	.remove = snd_audiopci_remove,
68cb2b559   Takashi Iwai   ALSA: Convert to ...
2387
2388
2389
  	.driver = {
  		.pm = SND_ENSONIQ_PM_OPS,
  	},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2390
2391
  };
  	
e9f66d9b9   Takashi Iwai   ALSA: pci: clean ...
2392
  module_pci_driver(ens137x_driver);