source: GPL/trunk/alsa-kernel/pci/intel8x0.c@ 43

Last change on this file since 43 was 35, checked in by vladest, 20 years ago

Fixed UNIAUD API
Added PM support for Yamaha chipsets
Added PM support for Intel chipsets

File size: 104.1 KB
Line 
1/*
2 * ALSA driver for Intel ICH (i8x0) chipsets
3 *
4 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
5 *
6 *
7 * This code also contains alpha support for SiS 735 chipsets provided
8 * by Mike Pieper <mptei@users.sourceforge.net>. We have no datasheet
9 * for SiS735, so the code is not fully functional.
10 *
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
26 *
27 */
28
29#include <sound/driver.h>
30#include <asm/io.h>
31#include <linux/delay.h>
32#include <linux/interrupt.h>
33#include <linux/init.h>
34#include <linux/pci.h>
35#include <linux/slab.h>
36#include <sound/core.h>
37#include <sound/pcm.h>
38#include <sound/ac97_codec.h>
39#include <sound/info.h>
40#include <sound/mpu401.h>
41#define SNDRV_GET_ID
42#include <sound/initval.h>
43
44#define I810_DEBUG
45
46MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
47MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7012; Ali 5455");
48MODULE_LICENSE("GPL");
49MODULE_CLASSES("{sound}");
50MODULE_DEVICES("{{Intel,82801AA-ICH},"
51 "{Intel,82901AB-ICH0},"
52 "{Intel,82801BA-ICH2},"
53 "{Intel,82801CA-ICH3},"
54 "{Intel,82801DB-ICH4},"
55 "{Intel,ICH5},"
56 "{Intel,ICH6},"
57 "{Intel,ICH7},"
58 "{Intel,6300ESB},"
59 "{Intel,ESB2},"
60 "{Intel,MX440},"
61 "{SiS,SI7012},"
62 "{NVidia,nForce Audio},"
63 "{NVidia,nForce2 Audio},"
64 "{AMD,AMD768},"
65 "{AMD,AMD8111},"
66 "{ALI,M5455}}");
67
68#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
69//#define SUPPORT_JOYSTICK 1
70#endif
71#define SUPPORT_MIDI 1
72
73extern int midi_port;
74
75static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
76static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
77static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
78#ifdef TARGET_OS2
79static int ac97_clock[SNDRV_CARDS] = {REPEAT_SNDRV(0)};
80static char *ac97_quirk[SNDRV_CARDS];
81#else
82static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
83#endif
84#ifdef SUPPORT_JOYSTICK
85static int joystick[SNDRV_CARDS];
86#endif
87#ifdef SUPPORT_MIDI
88static int mpu_port[SNDRV_CARDS];// = {REPEAT_SNDRV(0x330)};;
89/* disabled */
90#endif
91
92static int buggy_semaphore;
93static int buggy_irq = -1; /* auto-check */
94
95MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
96MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard.");
97MODULE_PARM_SYNTAX(index, SNDRV_INDEX_DESC);
98MODULE_PARM(id, "1-" __MODULE_STRING(SNDRV_CARDS) "s");
99MODULE_PARM_DESC(id, "ID string for Intel i8x0 soundcard.");
100MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
101MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
102MODULE_PARM_DESC(enable, "Enable Intel i8x0 soundcard.");
103MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
104MODULE_PARM(ac97_clock, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
105MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
106MODULE_PARM_SYNTAX(ac97_clock, SNDRV_ENABLED ",default:0");
107MODULE_PARM(ac97_quirk, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
108MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
109MODULE_PARM_SYNTAX(ac97_quirk, SNDRV_ENABLED ",allows:{{-1,3}},dialog:list,default:-1");
110#ifdef SUPPORT_JOYSTICK
111MODULE_PARM(joystick, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
112MODULE_PARM_DESC(joystick, "Enable joystick for Intel i8x0 soundcard.");
113MODULE_PARM_SYNTAX(joystick, SNDRV_ENABLED "," SNDRV_BOOLEAN_FALSE_DESC);
114#endif
115#ifdef SUPPORT_MIDI
116MODULE_PARM(mpu_port, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
117MODULE_PARM_DESC(mpu_port, "MPU401 port # for Intel i8x0 driver.");
118MODULE_PARM_SYNTAX(mpu_port, SNDRV_ENABLED ",allows:{{0},{0x330},{0x300}},dialog:list");
119#endif
120
121/*
122 * Direct registers
123 */
124
125#ifndef PCI_DEVICE_ID_INTEL_82801
126#define PCI_DEVICE_ID_INTEL_82801 0x2415
127#endif
128#ifndef PCI_DEVICE_ID_INTEL_82901
129#define PCI_DEVICE_ID_INTEL_82901 0x2425
130#endif
131#ifndef PCI_DEVICE_ID_INTEL_82801BA
132#define PCI_DEVICE_ID_INTEL_82801BA 0x2445
133#endif
134#ifndef PCI_DEVICE_ID_INTEL_440MX
135#define PCI_DEVICE_ID_INTEL_440MX 0x7195
136#endif
137#ifndef PCI_DEVICE_ID_INTEL_ICH3
138#define PCI_DEVICE_ID_INTEL_ICH3 0x2485
139#endif
140#ifndef PCI_DEVICE_ID_INTEL_ICH4
141#define PCI_DEVICE_ID_INTEL_ICH4 0x24c5
142#endif
143#ifndef PCI_DEVICE_ID_INTEL_ICH5
144#define PCI_DEVICE_ID_INTEL_ICH5 0x24d5
145#endif
146#ifndef PCI_DEVICE_ID_INTEL_ESB_5
147#define PCI_DEVICE_ID_INTEL_ESB_5 0x25a6
148#endif
149#ifndef PCI_DEVICE_ID_INTEL_ICH6_18
150#define PCI_DEVICE_ID_INTEL_ICH6_18 0x266e
151#endif
152#ifndef PCI_DEVICE_ID_INTEL_ICH7_20
153#define PCI_DEVICE_ID_INTEL_ICH7_20 0x27de
154#endif
155#ifndef PCI_DEVICE_ID_INTEL_ESB2_14
156#define PCI_DEVICE_ID_INTEL_ESB2_14 0x2698
157#endif
158#ifndef PCI_DEVICE_ID_SI_7012
159#define PCI_DEVICE_ID_SI_7012 0x7012
160#endif
161#ifndef PCI_DEVICE_ID_NVIDIA_CK804_AUDIO
162#define PCI_DEVICE_ID_NVIDIA_CK804_AUDIO 0x0059
163#endif
164#ifndef PCI_DEVICE_ID_NVIDIA_MCP_AUDIO
165#define PCI_DEVICE_ID_NVIDIA_MCP_AUDIO 0x01b1
166#endif
167#ifndef PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO
168#define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO 0x006a
169#endif
170#ifndef PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO
171#define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO 0x00da
172#endif
173#ifndef PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO
174#define PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO 0x00ea
175#endif
176#ifndef PCI_DEVICE_ID_NVIDIA_CK8_AUDIO
177#define PCI_DEVICE_ID_NVIDIA_CK8_AUDIO 0x008a
178#endif
179
180enum { DEVICE_INTEL, DEVICE_INTEL_ICH4, DEVICE_INTEL_ICH5, DEVICE_SIS, DEVICE_ALI, DEVICE_NFORCE };
181
182#define ICHREG(x) ICH_REG_##x
183
184#define DEFINE_REGSET(name,base) \
185 enum { \
186 ICH_REG_##name##_BDBAR = base + 0x0, /* dword - buffer descriptor list base address */ \
187 ICH_REG_##name##_CIV = base + 0x04, /* byte - current index value */ \
188 ICH_REG_##name##_LVI = base + 0x05, /* byte - last valid index */ \
189 ICH_REG_##name##_SR = base + 0x06, /* byte - status register */ \
190 ICH_REG_##name##_PICB = base + 0x08, /* word - position in current buffer */ \
191 ICH_REG_##name##_PIV = base + 0x0a, /* byte - prefetched index value */ \
192 ICH_REG_##name##_CR = base + 0x0b, /* byte - control register */ \
193 };
194
195/* busmaster blocks */
196DEFINE_REGSET(OFF, 0); /* offset */
197DEFINE_REGSET(PI, 0x00); /* PCM in */
198DEFINE_REGSET(PO, 0x10); /* PCM out */
199DEFINE_REGSET(MC, 0x20); /* Mic in */
200
201/* ICH4 busmaster blocks */
202DEFINE_REGSET(MC2, 0x40); /* Mic in 2 */
203DEFINE_REGSET(PI2, 0x50); /* PCM in 2 */
204DEFINE_REGSET(SP, 0x60); /* SPDIF out */
205
206/* values for each busmaster block */
207
208/* LVI */
209#define ICH_REG_LVI_MASK 0x1f
210
211/* SR */
212#define ICH_FIFOE 0x10 /* FIFO error */
213#define ICH_BCIS 0x08 /* buffer completion interrupt status */
214#define ICH_LVBCI 0x04 /* last valid buffer completion interrupt */
215#define ICH_CELV 0x02 /* current equals last valid */
216#define ICH_DCH 0x01 /* DMA controller halted */
217
218/* PIV */
219#define ICH_REG_PIV_MASK 0x1f /* mask */
220
221/* CR */
222#define ICH_IOCE 0x10 /* interrupt on completion enable */
223#define ICH_FEIE 0x08 /* fifo error interrupt enable */
224#define ICH_LVBIE 0x04 /* last valid buffer interrupt enable */
225#define ICH_RESETREGS 0x02 /* reset busmaster registers */
226#define ICH_STARTBM 0x01 /* start busmaster operation */
227
228
229/* global block */
230#define ICH_REG_GLOB_CNT 0x2c /* dword - global control */
231#define ICH_PCM_SPDIF_MASK 0xc0000000 /* s/pdif pcm slot mask (ICH4) */
232#define ICH_PCM_SPDIF_NONE 0x00000000 /* reserved - undefined */
233#define ICH_PCM_SPDIF_78 0x40000000 /* s/pdif pcm on slots 7&8 */
234#define ICH_PCM_SPDIF_69 0x80000000 /* s/pdif pcm on slots 6&9 */
235#define ICH_PCM_SPDIF_1011 0xc0000000 /* s/pdif pcm on slots 10&11 */
236#define ICH_PCM_20BIT 0x00400000 /* 20-bit samples (ICH4) */
237#define ICH_PCM_246_MASK 0x00300000 /* 6 channels (not all chips) */
238#define ICH_PCM_6 0x00200000 /* 6 channels (not all chips) */
239#define ICH_PCM_4 0x00100000 /* 4 channels (not all chips) */
240#define ICH_PCM_2 0x00000000 /* 2 channels (stereo) */
241#define ICH_SIS_PCM_246_MASK 0x000000c0 /* 6 channels (SIS7012) */
242#define ICH_SIS_PCM_6 0x00000080 /* 6 channels (SIS7012) */
243#define ICH_SIS_PCM_4 0x00000040 /* 4 channels (SIS7012) */
244#define ICH_SIS_PCM_2 0x00000000 /* 2 channels (SIS7012) */
245#define ICH_TRIE 0x00000040 /* tertiary resume interrupt enable */
246#define ICH_SRIE 0x00000020 /* secondary resume interrupt enable */
247#define ICH_PRIE 0x00000010 /* primary resume interrupt enable */
248#define ICH_ACLINK 0x00000008 /* AClink shut off */
249#define ICH_AC97WARM 0x00000004 /* AC'97 warm reset */
250#define ICH_AC97COLD 0x00000002 /* AC'97 cold reset */
251#define ICH_GIE 0x00000001 /* GPI interrupt enable */
252#define ICH_REG_GLOB_STA 0x30 /* dword - global status */
253#define ICH_TRI 0x20000000 /* ICH4: tertiary (AC_SDIN2) resume interrupt */
254#define ICH_TCR 0x10000000 /* ICH4: tertiary (AC_SDIN2) codec ready */
255#define ICH_BCS 0x08000000 /* ICH4: bit clock stopped */
256#define ICH_SPINT 0x04000000 /* ICH4: S/PDIF interrupt */
257#define ICH_P2INT 0x02000000 /* ICH4: PCM2-In interrupt */
258#define ICH_M2INT 0x01000000 /* ICH4: Mic2-In interrupt */
259#define ICH_SAMPLE_CAP 0x00c00000 /* ICH4: sample capability bits (RO) */
260#define ICH_SAMPLE_16_20 0x00400000 /* ICH4: 16- and 20-bit samples */
261#define ICH_MULTICHAN_CAP 0x00300000 /* ICH4: multi-channel capability bits (RO) */
262#define ICH_MD3 0x00020000 /* modem power down semaphore */
263#define ICH_AD3 0x00010000 /* audio power down semaphore */
264#define ICH_RCS 0x00008000 /* read completion status */
265#define ICH_BIT3 0x00004000 /* bit 3 slot 12 */
266#define ICH_BIT2 0x00002000 /* bit 2 slot 12 */
267#define ICH_BIT1 0x00001000 /* bit 1 slot 12 */
268#define ICH_SRI 0x00000800 /* secondary (AC_SDIN1) resume interrupt */
269#define ICH_PRI 0x00000400 /* primary (AC_SDIN0) resume interrupt */
270#define ICH_SCR 0x00000200 /* secondary (AC_SDIN1) codec ready */
271#define ICH_PCR 0x00000100 /* primary (AC_SDIN0) codec ready */
272#define ICH_MCINT 0x00000080 /* MIC capture interrupt */
273#define ICH_POINT 0x00000040 /* playback interrupt */
274#define ICH_PIINT 0x00000020 /* capture interrupt */
275#define ICH_NVSPINT 0x00000010 /* nforce spdif interrupt */
276#define ICH_MOINT 0x00000004 /* modem playback interrupt */
277#define ICH_MIINT 0x00000002 /* modem capture interrupt */
278#define ICH_GSCI 0x00000001 /* GPI status change interrupt */
279#define ICH_REG_ACC_SEMA 0x34 /* byte - codec write semaphore */
280#define ICH_CAS 0x01 /* codec access semaphore */
281#define ICH_REG_SDM 0x80
282#define ICH_DI2L_MASK 0x000000c0 /* PCM In 2, Mic In 2 data in line */
283#define ICH_DI2L_SHIFT 6
284#define ICH_DI1L_MASK 0x00000030 /* PCM In 1, Mic In 1 data in line */
285#define ICH_DI1L_SHIFT 4
286#define ICH_SE 0x00000008 /* steer enable */
287#define ICH_LDI_MASK 0x00000003 /* last codec read data input */
288
289#define ICH_MAX_FRAGS 32 /* max hw frags */
290
291
292/*
293 * registers for Ali5455
294 */
295
296/* ALi 5455 busmaster blocks */
297DEFINE_REGSET(AL_PI, 0x40); /* ALi PCM in */
298DEFINE_REGSET(AL_PO, 0x50); /* Ali PCM out */
299DEFINE_REGSET(AL_MC, 0x60); /* Ali Mic in */
300DEFINE_REGSET(AL_CDC_SPO, 0x70); /* Ali Codec SPDIF out */
301DEFINE_REGSET(AL_CENTER, 0x80); /* Ali center out */
302DEFINE_REGSET(AL_LFE, 0x90); /* Ali center out */
303DEFINE_REGSET(AL_CLR_SPI, 0xa0); /* Ali Controller SPDIF in */
304DEFINE_REGSET(AL_CLR_SPO, 0xb0); /* Ali Controller SPDIF out */
305DEFINE_REGSET(AL_I2S, 0xc0); /* Ali I2S in */
306DEFINE_REGSET(AL_PI2, 0xd0); /* Ali PCM2 in */
307DEFINE_REGSET(AL_MC2, 0xe0); /* Ali Mic2 in */
308
309enum {
310 ICH_REG_ALI_SCR = 0x00, /* System Control Register */
311 ICH_REG_ALI_SSR = 0x04, /* System Status Register */
312 ICH_REG_ALI_DMACR = 0x08, /* DMA Control Register */
313 ICH_REG_ALI_FIFOCR1 = 0x0c, /* FIFO Control Register 1 */
314 ICH_REG_ALI_INTERFACECR = 0x10, /* Interface Control Register */
315 ICH_REG_ALI_INTERRUPTCR = 0x14, /* Interrupt control Register */
316 ICH_REG_ALI_INTERRUPTSR = 0x18, /* Interrupt Status Register */
317 ICH_REG_ALI_FIFOCR2 = 0x1c, /* FIFO Control Register 2 */
318 ICH_REG_ALI_CPR = 0x20, /* Command Port Register */
319 ICH_REG_ALI_CPR_ADDR = 0x22, /* ac97 addr write */
320 ICH_REG_ALI_SPR = 0x24, /* Status Port Register */
321 ICH_REG_ALI_SPR_ADDR = 0x26, /* ac97 addr read */
322 ICH_REG_ALI_FIFOCR3 = 0x2c, /* FIFO Control Register 3 */
323 ICH_REG_ALI_TTSR = 0x30, /* Transmit Tag Slot Register */
324 ICH_REG_ALI_RTSR = 0x34, /* Receive Tag Slot Register */
325 ICH_REG_ALI_CSPSR = 0x38, /* Command/Status Port Status Register */
326 ICH_REG_ALI_CAS = 0x3c, /* Codec Write Semaphore Register */
327 ICH_REG_ALI_HWVOL = 0xf0, /* hardware volume control/status */
328 ICH_REG_ALI_I2SCR = 0xf4, /* I2S control/status */
329 ICH_REG_ALI_SPDIFCSR = 0xf8, /* spdif channel status register */
330 ICH_REG_ALI_SPDIFICS = 0xfc, /* spdif interface control/status */
331};
332
333#define ALI_CAS_SEM_BUSY 0x80000000
334#define ALI_CPR_ADDR_SECONDARY 0x100
335#define ALI_CPR_ADDR_READ 0x80
336#define ALI_CSPSR_CODEC_READY 0x08
337#define ALI_CSPSR_READ_OK 0x02
338#define ALI_CSPSR_WRITE_OK 0x01
339
340/* interrupts for the whole chip by interrupt status register finish */
341
342#define ALI_INT_MICIN2 (1<<26)
343#define ALI_INT_PCMIN2 (1<<25)
344#define ALI_INT_I2SIN (1<<24)
345#define ALI_INT_SPDIFOUT (1<<23) /* controller spdif out INTERRUPT */
346#define ALI_INT_SPDIFIN (1<<22)
347#define ALI_INT_LFEOUT (1<<21)
348#define ALI_INT_CENTEROUT (1<<20)
349#define ALI_INT_CODECSPDIFOUT (1<<19)
350#define ALI_INT_MICIN (1<<18)
351#define ALI_INT_PCMOUT (1<<17)
352#define ALI_INT_PCMIN (1<<16)
353#define ALI_INT_CPRAIS (1<<7) /* command port available */
354#define ALI_INT_SPRAIS (1<<5) /* status port available */
355#define ALI_INT_GPIO (1<<1)
356#define ALI_INT_MASK (ALI_INT_SPDIFOUT|ALI_INT_CODECSPDIFOUT|ALI_INT_MICIN|ALI_INT_PCMOUT|ALI_INT_PCMIN)
357
358#define ICH_ALI_SC_RESET (1<<31) /* master reset */
359#define ICH_ALI_SC_AC97_DBL (1<<30)
360#define ICH_ALI_SC_CODEC_SPDF (3<<20) /* 1=7/8, 2=6/9, 3=10/11 */
361#define ICH_ALI_SC_IN_BITS (3<<18)
362#define ICH_ALI_SC_OUT_BITS (3<<16)
363#define ICH_ALI_SC_6CH_CFG (3<<14)
364#define ICH_ALI_SC_PCM_4 (1<<8)
365#define ICH_ALI_SC_PCM_6 (2<<8)
366#define ICH_ALI_SC_PCM_246_MASK (3<<8)
367
368#define ICH_ALI_SS_SEC_ID (3<<5)
369#define ICH_ALI_SS_PRI_ID (3<<3)
370
371#define ICH_ALI_IF_AC97SP (1<<21)
372#define ICH_ALI_IF_MC (1<<20)
373#define ICH_ALI_IF_PI (1<<19)
374#define ICH_ALI_IF_MC2 (1<<18)
375#define ICH_ALI_IF_PI2 (1<<17)
376#define ICH_ALI_IF_LINE_SRC (1<<15) /* 0/1 = slot 3/6 */
377#define ICH_ALI_IF_MIC_SRC (1<<14) /* 0/1 = slot 3/6 */
378#define ICH_ALI_IF_SPDF_SRC (3<<12) /* 00 = PCM, 01 = AC97-in, 10 = spdif-in, 11 = i2s */
379#define ICH_ALI_IF_AC97_OUT (3<<8) /* 00 = PCM, 10 = spdif-in, 11 = i2s */
380#define ICH_ALI_IF_PO_SPDF (1<<3)
381#define ICH_ALI_IF_PO (1<<1)
382
383/*
384 *
385 */
386
387enum { ICHD_PCMIN, ICHD_PCMOUT, ICHD_MIC, ICHD_MIC2, ICHD_PCM2IN, ICHD_SPBAR, ICHD_LAST = ICHD_SPBAR };
388enum { NVD_PCMIN, NVD_PCMOUT, NVD_MIC, NVD_SPBAR, NVD_LAST = NVD_SPBAR };
389enum { ALID_PCMIN, ALID_PCMOUT, ALID_MIC, ALID_AC97SPDIFOUT, ALID_SPDIFIN, ALID_SPDIFOUT, ALID_LAST = ALID_SPDIFOUT };
390
391#define get_ichdev(substream) (struct ichdev *)(substream->runtime->private_data)
392
393typedef struct ichdev {
394 unsigned int ichd; /* ich device number */
395 unsigned long reg_offset; /* offset to bmaddr */
396 u32 *bdbar; /* CPU address (32bit) */
397 unsigned int bdbar_addr; /* PCI bus address (32bit) */
398 snd_pcm_substream_t *substream;
399 unsigned int physbuf; /* physical address (32bit) */
400 unsigned int size;
401 unsigned int fragsize;
402 unsigned int fragsize1;
403 unsigned int position;
404 unsigned int pos_shift;
405 int frags;
406 int lvi;
407 int lvi_frag;
408 int civ;
409 int ack;
410 int ack_reload;
411 unsigned int ack_bit;
412 unsigned int roff_sr;
413 unsigned int roff_picb;
414 unsigned int int_sta_mask; /* interrupt status mask */
415 unsigned int ali_slot; /* ALI DMA slot */
416 struct ac97_pcm *pcm;
417 int pcm_open_flag;
418 unsigned int page_attr_changed: 1;
419 unsigned int suspended: 1;
420};
421
422struct intel8x0 {
423 unsigned int device_type;
424
425 int irq;
426
427 unsigned int mmio;
428 unsigned long addr;
429 unsigned long remap_addr;
430 unsigned int bm_mmio;
431 unsigned long bmaddr;
432 unsigned long remap_bmaddr;
433
434 struct pci_dev *pci;
435 snd_card_t *card;
436
437 int pcm_devs;
438 snd_pcm_t *pcm[6];
439 struct ichdev ichd[6];
440
441 int multi4: 1,
442 multi6: 1,
443 dra: 1,
444 smp20bit: 1;
445 int in_ac97_init: 1,
446 in_sdin_init: 1;
447 unsigned in_measurement: 1; /* during ac97 clock measurement */
448 unsigned fix_nocache: 1; /* workaround for 440MX */
449 unsigned buggy_irq: 1; /* workaround for buggy mobos */
450 unsigned xbox: 1; /* workaround for Xbox AC'97 detection */
451 unsigned buggy_semaphore: 1; /* workaround for buggy codec semaphore */
452
453 int spdif_idx; /* SPDIF BAR index; *_SPBAR or -1 if use PCMOUT */
454 unsigned int sdm_saved; /* SDM reg value */
455
456 ac97_bus_t *ac97_bus;
457 ac97_t *ac97[3];
458 unsigned int ac97_sdin[3];
459
460 snd_rawmidi_t *rmidi;
461
462 spinlock_t reg_lock;
463
464 u32 bdbars_count;
465 struct snd_dma_buffer bdbars;
466 u32 int_sta_reg; /* interrupt status register */
467 u32 int_sta_mask; /* interrupt status mask */
468};
469
470static struct pci_device_id snd_intel8x0_ids[] = {
471 { 0x8086, 0x2415, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801AA */
472 { 0x8086, 0x2425, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82901AB */
473 { 0x8086, 0x2445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801BA */
474 { 0x8086, 0x2485, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH3 */
475 { 0x8086, 0x24c5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ICH4 */
476 { 0x8086, 0x24d5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH5 }, /* ICH5 */
477 { 0x8086, 0x25a6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH5 }, /* ESB */
478 { 0x8086, 0x266e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH5 }, /* ICH6 */
479 { 0x8086, 0x27de, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH5 }, /* ICH7 */
480 { 0x8086, 0x2698, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ESB2 */
481 { 0x8086, 0x7195, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 440MX */
482 { 0x1039, 0x7012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_SIS }, /* SI7012 */
483 { 0x10de, 0x01b1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE */
484 { 0x10de, 0x003a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* MCP04 */
485 { 0x10de, 0x006a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE2 */
486 { 0x10de, 0x0059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* CK804 */
487 { 0x10de, 0x008a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* CK8 */
488 { 0x10de, 0x00da, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE3 */
489 { 0x10de, 0x00ea, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* CK8S */
490 { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
491 { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
492 { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
493 { 0 }
494};
495
496MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
497
498
499/*
500 * Lowlevel I/O - busmaster
501 */
502
503static u8 igetbyte(struct intel8x0 *chip, u32 offset)
504{
505 if (chip->bm_mmio)
506 return readb(chip->remap_bmaddr + offset);
507 else
508 return inb(chip->bmaddr + offset);
509}
510
511static u16 igetword(struct intel8x0 *chip, u32 offset)
512{
513 if (chip->bm_mmio)
514 return readw(chip->remap_bmaddr + offset);
515 else
516 return inw(chip->bmaddr + offset);
517}
518
519static u32 igetdword(struct intel8x0 *chip, u32 offset)
520{
521 if (chip->bm_mmio)
522 return readl(chip->remap_bmaddr + offset);
523 else
524 return inl(chip->bmaddr + offset);
525}
526
527static void iputbyte(struct intel8x0 *chip, u32 offset, u8 val)
528{
529 if (chip->bm_mmio)
530 writeb(val, chip->remap_bmaddr + offset);
531 else
532 outb(val, chip->bmaddr + offset);
533}
534
535static void iputword(struct intel8x0 *chip, u32 offset, u16 val)
536{
537 if (chip->bm_mmio)
538 writew(val, chip->remap_bmaddr + offset);
539 else
540 outw(val, chip->bmaddr + offset);
541}
542
543static void iputdword(struct intel8x0 *chip, u32 offset, u32 val)
544{
545 if (chip->bm_mmio)
546 writel(val, chip->remap_bmaddr + offset);
547 else
548 outl(val, chip->bmaddr + offset);
549}
550
551/*
552 * Lowlevel I/O - AC'97 registers
553 */
554
555static u16 iagetword(struct intel8x0 *chip, u32 offset)
556{
557 if (chip->mmio)
558 return readw(chip->remap_addr + offset);
559 else
560 return inw(chip->addr + offset);
561}
562
563static void iaputword(struct intel8x0 *chip, u32 offset, u16 val)
564{
565 if (chip->mmio)
566 writew(val, chip->remap_addr + offset);
567 else
568 outw(val, chip->addr + offset);
569}
570
571/*
572 * Basic I/O
573 */
574
575/*
576 * access to AC97 codec via normal i/o (for ICH and SIS7012)
577 */
578
579/* return the GLOB_STA bit for the corresponding codec */
580static unsigned int get_ich_codec_bit(struct intel8x0 *chip, unsigned int codec)
581{
582 static unsigned int codec_bit[3] = {
583 ICH_PCR, ICH_SCR, ICH_TCR
584 };
585 snd_assert(codec < 3, return ICH_PCR);
586 if (chip->device_type == DEVICE_INTEL_ICH4 ||
587 chip->device_type == DEVICE_INTEL_ICH5)
588 codec = chip->ac97_sdin[codec];
589 return codec_bit[codec];
590}
591
592static int snd_intel8x0_codec_semaphore(struct intel8x0 *chip, unsigned int codec)
593{
594 int time;
595
596 if (codec > 2)
597 return -EIO;
598 if (chip->in_sdin_init) {
599 /* we don't know the ready bit assignment at the moment */
600 /* so we check any */
601 codec = ICH_PCR | ICH_SCR | ICH_TCR;
602 } else {
603 codec = get_ich_codec_bit(chip, codec);
604 }
605
606 /* codec ready ? */
607 if ((igetdword(chip, ICHREG(GLOB_STA)) & codec) == 0)
608 return -EIO;
609
610 /* Anyone holding a semaphore for 1 msec should be shot... */
611 time = 100;
612 do {
613 if (!(igetbyte(chip, ICHREG(ACC_SEMA)) & ICH_CAS))
614 return 0;
615 udelay(10);
616 } while (time--);
617
618 /* access to some forbidden (non existant) ac97 registers will not
619 * reset the semaphore. So even if you don't get the semaphore, still
620 * continue the access. We don't need the semaphore anyway. */
621 snd_printk("codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
622 igetbyte(chip, ICHREG(ACC_SEMA)), igetdword(chip, ICHREG(GLOB_STA)));
623 iagetword(chip, 0); /* clear semaphore flag */
624 /* I don't care about the semaphore */
625 return -EBUSY;
626}
627
628static void snd_intel8x0_codec_write(ac97_t *ac97,
629 unsigned short reg,
630 unsigned short val)
631{
632 struct intel8x0 *chip = ac97->private_data;
633
634 if (snd_intel8x0_codec_semaphore(chip, ac97->num) < 0) {
635 if (! chip->in_ac97_init)
636 snd_printk("codec_write %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
637 }
638 iaputword(chip, reg + ac97->num * 0x80, val);
639}
640
641static unsigned short snd_intel8x0_codec_read(ac97_t *ac97,
642 unsigned short reg)
643{
644 struct intel8x0 *chip = ac97->private_data;
645 unsigned short res;
646 unsigned int tmp;
647
648 if (snd_intel8x0_codec_semaphore(chip, ac97->num) < 0) {
649 if (! chip->in_ac97_init)
650 snd_printk("codec_read %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
651 res = 0xffff;
652 } else {
653 res = iagetword(chip, reg + ac97->num * 0x80);
654 if ((tmp = igetdword(chip, ICHREG(GLOB_STA))) & ICH_RCS) {
655 /* reset RCS and preserve other R/WC bits */
656 iputdword(chip, ICHREG(GLOB_STA), tmp & ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI));
657 if (! chip->in_ac97_init)
658 snd_printk("codec_read %d: read timeout for register 0x%x\n", ac97->num, reg);
659 res = 0xffff;
660 }
661 }
662 return res;
663}
664
665static void snd_intel8x0_codec_read_test(struct intel8x0 *chip, unsigned int codec)
666{
667 unsigned int tmp;
668
669 if (snd_intel8x0_codec_semaphore(chip, codec) >= 0) {
670 iagetword(chip, codec * 0x80);
671 if ((tmp = igetdword(chip, ICHREG(GLOB_STA))) & ICH_RCS) {
672 /* reset RCS and preserve other R/WC bits */
673 iputdword(chip, ICHREG(GLOB_STA), tmp & ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI));
674 }
675 }
676}
677
678/*
679 * access to AC97 for Ali5455
680 */
681static int snd_intel8x0_ali_codec_ready(struct intel8x0 *chip, int mask)
682{
683 int count = 0;
684 for (count = 0; count < 0x7f; count++) {
685 int val = igetbyte(chip, ICHREG(ALI_CSPSR));
686 if (val & mask)
687 return 0;
688 }
689 if (! chip->in_ac97_init)
690 snd_printd(KERN_WARNING "intel8x0: AC97 codec ready timeout.\n");
691 return -EBUSY;
692}
693
694static int snd_intel8x0_ali_codec_semaphore(struct intel8x0 *chip)
695{
696 int time = 100;
697 if (chip->buggy_semaphore)
698 return 0; /* just ignore ... */
699 while (time-- && (igetdword(chip, ICHREG(ALI_CAS)) & ALI_CAS_SEM_BUSY))
700 udelay(1);
701 if (! time && ! chip->in_ac97_init)
702 snd_printk(KERN_WARNING "ali_codec_semaphore timeout\n");
703 return snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_CODEC_READY);
704}
705
706static unsigned short snd_intel8x0_ali_codec_read(ac97_t *ac97, unsigned short reg)
707{
708 struct intel8x0 *chip = ac97->private_data;
709 unsigned short data = 0xffff;
710
711 if (snd_intel8x0_ali_codec_semaphore(chip))
712 goto __err;
713 reg |= ALI_CPR_ADDR_READ;
714 if (ac97->num)
715 reg |= ALI_CPR_ADDR_SECONDARY;
716 iputword(chip, ICHREG(ALI_CPR_ADDR), reg);
717 if (snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_READ_OK))
718 goto __err;
719 data = igetword(chip, ICHREG(ALI_SPR));
720__err:
721 return data;
722}
723
724static void snd_intel8x0_ali_codec_write(ac97_t *ac97, unsigned short reg, unsigned short val)
725{
726 struct intel8x0 *chip = ac97->private_data;
727
728 if (snd_intel8x0_ali_codec_semaphore(chip))
729 return;
730 iputword(chip, ICHREG(ALI_CPR), val);
731 if (ac97->num)
732 reg |= ALI_CPR_ADDR_SECONDARY;
733 iputword(chip, ICHREG(ALI_CPR_ADDR), reg);
734 snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_WRITE_OK);
735}
736
737
738/*
739 * DMA I/O
740 */
741static void snd_intel8x0_setup_periods(struct intel8x0 *chip, struct ichdev *ichdev)
742{
743 int idx;
744 u32 *bdbar = ichdev->bdbar;
745 unsigned long port = ichdev->reg_offset;
746
747 iputdword(chip, port + ICH_REG_OFF_BDBAR, ichdev->bdbar_addr);
748 if (ichdev->size == ichdev->fragsize) {
749 ichdev->ack_reload = ichdev->ack = 2;
750 ichdev->fragsize1 = ichdev->fragsize >> 1;
751 for (idx = 0; idx < (ICH_REG_LVI_MASK + 1) * 2; idx += 4) {
752 bdbar[idx + 0] = cpu_to_le32(ichdev->physbuf);
753 bdbar[idx + 1] = cpu_to_le32(0x80000000 | /* interrupt on completion */
754 ichdev->fragsize1 >> ichdev->pos_shift);
755 bdbar[idx + 2] = cpu_to_le32(ichdev->physbuf + (ichdev->size >> 1));
756 bdbar[idx + 3] = cpu_to_le32(0x80000000 | /* interrupt on completion */
757 ichdev->fragsize1 >> ichdev->pos_shift);
758 }
759 ichdev->frags = 2;
760 } else {
761 ichdev->ack_reload = ichdev->ack = 1;
762 ichdev->fragsize1 = ichdev->fragsize;
763 for (idx = 0; idx < (ICH_REG_LVI_MASK + 1) * 2; idx += 2) {
764 bdbar[idx + 0] = cpu_to_le32(ichdev->physbuf + (((idx >> 1) * ichdev->fragsize) % ichdev->size));
765 bdbar[idx + 1] = cpu_to_le32(0x80000000 | /* interrupt on completion */
766 ichdev->fragsize >> ichdev->pos_shift);
767 // printk("bdbar[%i] = 0x%x [0x%x]\n", idx + 0, bdbar[idx + 0], bdbar[idx + 1]);
768 }
769 ichdev->frags = ichdev->size / ichdev->fragsize;
770 }
771 iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi = ICH_REG_LVI_MASK);
772 ichdev->civ = 0;
773 iputbyte(chip, port + ICH_REG_OFF_CIV, 0);
774 ichdev->lvi_frag = ICH_REG_LVI_MASK % ichdev->frags;
775 ichdev->position = 0;
776#if 0
777 printk("lvi_frag = %i, frags = %i, period_size = 0x%x, period_size1 = 0x%x\n",
778 ichdev->lvi_frag, ichdev->frags, ichdev->fragsize, ichdev->fragsize1);
779#endif
780 /* clear interrupts */
781 iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI);
782}
783
784/*
785 * Interrupt handler
786 */
787
788static inline void snd_intel8x0_update(struct intel8x0 *chip, struct ichdev *ichdev)
789{
790 unsigned long port = ichdev->reg_offset;
791 int status, civ, i, step;
792 int ack = 0;
793
794 spin_lock(&chip->reg_lock);
795 status = igetbyte(chip, port + ichdev->roff_sr);
796 civ = igetbyte(chip, port + ICH_REG_OFF_CIV);
797 if (!(status & ICH_BCIS)) {
798 step = 0;
799 } else if (civ == ichdev->civ) {
800 // snd_printd("civ same %d\n", civ);
801 step = 1;
802 ichdev->civ++;
803 ichdev->civ &= ICH_REG_LVI_MASK;
804 } else {
805 step = civ - ichdev->civ;
806 if (step < 0)
807 step += ICH_REG_LVI_MASK + 1;
808 // if (step != 1)
809 // snd_printd("step = %d, %d -> %d\n", step, ichdev->civ, civ);
810 ichdev->civ = civ;
811 }
812
813 ichdev->position += step * ichdev->fragsize1;
814 ichdev->position %= ichdev->size;
815 ichdev->lvi += step;
816 ichdev->lvi &= ICH_REG_LVI_MASK;
817 iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi);
818 for (i = 0; i < step; i++) {
819 ichdev->lvi_frag++;
820 ichdev->lvi_frag %= ichdev->frags;
821 ichdev->bdbar[ichdev->lvi * 2] = cpu_to_le32(ichdev->physbuf + ichdev->lvi_frag * ichdev->fragsize1);
822 // printk("new: bdbar[%i] = 0x%x [0x%x], prefetch = %i, all = 0x%x, 0x%x\n", ichdev->lvi * 2, ichdev->bdbar[ichdev->lvi * 2], ichdev->bdbar[ichdev->lvi * 2 + 1], inb(ICH_REG_OFF_PIV + port), inl(port + 4), inb(port + ICH_REG_OFF_CR));
823 if (--ichdev->ack == 0) {
824 ichdev->ack = ichdev->ack_reload;
825 ack = 1;
826 }
827 }
828 spin_unlock(&chip->reg_lock);
829 if (ack && ichdev->substream) {
830 snd_pcm_period_elapsed(ichdev->substream);
831 }
832 iputbyte(chip, port + ichdev->roff_sr,
833 status & (ICH_FIFOE | ICH_BCIS | ICH_LVBCI));
834}
835
836static irqreturn_t snd_intel8x0_interrupt(int irq, void *dev_id, struct pt_regs *regs)
837{
838 struct intel8x0 *chip = dev_id;
839 struct ichdev *ichdev;
840 unsigned int status;
841 unsigned int i;
842
843 status = igetdword(chip, chip->int_sta_reg);
844 if (status == 0xffffffff) /* we are not yet resumed */
845 return IRQ_NONE;
846
847 if ((status & chip->int_sta_mask) == 0) {
848 static int err_count = 10;
849 if (status) {
850 /* ack */
851 iputdword(chip, chip->int_sta_reg, status);
852 /* FIXME: on some ICH5 board shows the same
853 * problem. So we return IRQ_HANDLED
854 * in any cases.
855 * (or, maybe add a new module param to control this?)
856 */
857#if 0
858 if (chip->device_type != DEVICE_NFORCE)
859 status ^= igetdword(chip, chip->int_sta_reg);
860#endif
861 }
862 return IRQ_RETVAL(status);
863 }
864
865 for (i = 0; i < chip->bdbars_count; i++) {
866 ichdev = &chip->ichd[i];
867 if (status & ichdev->int_sta_mask)
868 snd_intel8x0_update(chip, ichdev);
869 }
870
871 /* ack them */
872 iputdword(chip, chip->int_sta_reg, status & chip->int_sta_mask);
873
874 return IRQ_HANDLED;
875}
876
877/*
878 * PCM part
879 */
880
881static int snd_intel8x0_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
882{
883 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
884 struct ichdev *ichdev = get_ichdev(substream);
885 unsigned char val = 0;
886 unsigned long port = ichdev->reg_offset;
887
888 switch (cmd) {
889 case SNDRV_PCM_TRIGGER_RESUME:
890 ichdev->suspended = 0;
891 /* fallthru */
892 case SNDRV_PCM_TRIGGER_START:
893 val = ICH_IOCE | ICH_STARTBM;
894 break;
895 case SNDRV_PCM_TRIGGER_SUSPEND:
896 ichdev->suspended = 1;
897 /* fallthru */
898 case SNDRV_PCM_TRIGGER_STOP:
899 val = 0;
900 break;
901 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
902 val = ICH_IOCE;
903 break;
904 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
905 val = ICH_IOCE | ICH_STARTBM;
906 break;
907 default:
908 return -EINVAL;
909 }
910 iputbyte(chip, port + ICH_REG_OFF_CR, val);
911 if (cmd == SNDRV_PCM_TRIGGER_STOP) {
912 /* wait until DMA stopped */
913 while (!(igetbyte(chip, port + ichdev->roff_sr) & ICH_DCH)) ;
914 /* reset whole DMA things */
915 iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS);
916 }
917 return 0;
918}
919
920static int snd_intel8x0_ali_trigger(snd_pcm_substream_t *substream, int cmd)
921{
922 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
923 struct ichdev *ichdev = get_ichdev(substream);
924 unsigned long port = ichdev->reg_offset;
925 static int fiforeg[] = { ICHREG(ALI_FIFOCR1), ICHREG(ALI_FIFOCR2), ICHREG(ALI_FIFOCR3) };
926 unsigned int val, fifo;
927
928 val = igetdword(chip, ICHREG(ALI_DMACR));
929 switch (cmd) {
930 case SNDRV_PCM_TRIGGER_RESUME:
931 ichdev->suspended = 0;
932 /* fallthru */
933 case SNDRV_PCM_TRIGGER_START:
934 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
935 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
936 /* clear FIFO for synchronization of channels */
937 fifo = igetdword(chip, fiforeg[ichdev->ali_slot / 4]);
938 fifo &= ~(0xff << (ichdev->ali_slot % 4));
939 fifo |= 0x83 << (ichdev->ali_slot % 4);
940 iputdword(chip, fiforeg[ichdev->ali_slot / 4], fifo);
941 }
942 iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE);
943 val &= ~(1 << (ichdev->ali_slot + 16)); /* clear PAUSE flag */
944 iputdword(chip, ICHREG(ALI_DMACR), val | (1 << ichdev->ali_slot)); /* start DMA */
945 break;
946 case SNDRV_PCM_TRIGGER_SUSPEND:
947 ichdev->suspended = 1;
948 /* fallthru */
949 case SNDRV_PCM_TRIGGER_STOP:
950 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
951 iputdword(chip, ICHREG(ALI_DMACR), val | (1 << (ichdev->ali_slot + 16))); /* pause */
952 iputbyte(chip, port + ICH_REG_OFF_CR, 0);
953 while (igetbyte(chip, port + ICH_REG_OFF_CR))
954 ;
955 if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
956 break;
957 /* reset whole DMA things */
958 iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS);
959 /* clear interrupts */
960 iputbyte(chip, port + ICH_REG_OFF_SR, igetbyte(chip, port + ICH_REG_OFF_SR) | 0x1e);
961 iputdword(chip, ICHREG(ALI_INTERRUPTSR),
962 igetdword(chip, ICHREG(ALI_INTERRUPTSR)) & ichdev->int_sta_mask);
963 break;
964 default:
965 return -EINVAL;
966 }
967 return 0;
968}
969
970static int snd_intel8x0_hw_params(snd_pcm_substream_t * substream,
971 snd_pcm_hw_params_t * hw_params)
972{
973 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
974 struct ichdev *ichdev = get_ichdev(substream);
975 int dbl = params_rate(hw_params) > 48000;
976 int err;
977
978 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
979 if (err < 0)
980 return err;
981 if (ichdev->pcm_open_flag) {
982 snd_ac97_pcm_close(ichdev->pcm);
983 ichdev->pcm_open_flag = 0;
984 }
985 err = snd_ac97_pcm_open(ichdev->pcm, params_rate(hw_params),
986 params_channels(hw_params),
987 ichdev->pcm->r[dbl].slots);
988 if (err >= 0) {
989 ichdev->pcm_open_flag = 1;
990 /* Force SPDIF setting */
991 if (ichdev->ichd == ICHD_PCMOUT && chip->spdif_idx < 0)
992 snd_ac97_set_rate(ichdev->pcm->r[0].codec[0], AC97_SPDIF, params_rate(hw_params));
993 }
994 return err;
995}
996
997static int snd_intel8x0_hw_free(snd_pcm_substream_t * substream)
998{
999 struct ichdev *ichdev = get_ichdev(substream);
1000
1001 if (ichdev->pcm_open_flag) {
1002 snd_ac97_pcm_close(ichdev->pcm);
1003 ichdev->pcm_open_flag = 0;
1004 }
1005 return snd_pcm_lib_free_pages(substream);
1006}
1007
1008static void snd_intel8x0_setup_pcm_out(struct intel8x0 *chip,
1009 snd_pcm_runtime_t *runtime)
1010{
1011 unsigned int cnt;
1012 int dbl = runtime->rate > 48000;
1013
1014 spin_lock_irq(&chip->reg_lock);
1015 switch (chip->device_type) {
1016 case DEVICE_ALI:
1017 cnt = igetdword(chip, ICHREG(ALI_SCR));
1018 cnt &= ~ICH_ALI_SC_PCM_246_MASK;
1019 if (runtime->channels == 4 || dbl)
1020 cnt |= ICH_ALI_SC_PCM_4;
1021 else if (runtime->channels == 6)
1022 cnt |= ICH_ALI_SC_PCM_6;
1023 iputdword(chip, ICHREG(ALI_SCR), cnt);
1024 break;
1025 case DEVICE_SIS:
1026 cnt = igetdword(chip, ICHREG(GLOB_CNT));
1027 cnt &= ~ICH_SIS_PCM_246_MASK;
1028 if (runtime->channels == 4 || dbl)
1029 cnt |= ICH_SIS_PCM_4;
1030 else if (runtime->channels == 6)
1031 cnt |= ICH_SIS_PCM_6;
1032 iputdword(chip, ICHREG(GLOB_CNT), cnt);
1033 break;
1034 default:
1035 cnt = igetdword(chip, ICHREG(GLOB_CNT));
1036 cnt &= ~(ICH_PCM_246_MASK | ICH_PCM_20BIT);
1037 if (runtime->channels == 4 || dbl)
1038 cnt |= ICH_PCM_4;
1039 else if (runtime->channels == 6)
1040 cnt |= ICH_PCM_6;
1041 if (chip->device_type == DEVICE_NFORCE) {
1042 /* reset to 2ch once to keep the 6 channel data in alignment,
1043 * to start from Front Left always
1044 */
1045 if (cnt & ICH_PCM_246_MASK) {
1046 iputdword(chip, ICHREG(GLOB_CNT), cnt & ~ICH_PCM_246_MASK);
1047 spin_unlock_irq(&chip->reg_lock);
1048 msleep(50); /* grrr... */
1049 spin_lock_irq(&chip->reg_lock);
1050 }
1051 } else if (chip->device_type == DEVICE_INTEL_ICH4 ||
1052 chip->device_type == DEVICE_INTEL_ICH5) {
1053 if (runtime->sample_bits > 16)
1054 cnt |= ICH_PCM_20BIT;
1055 }
1056 iputdword(chip, ICHREG(GLOB_CNT), cnt);
1057 break;
1058 }
1059 spin_unlock_irq(&chip->reg_lock);
1060}
1061
1062static int snd_intel8x0_pcm_prepare(snd_pcm_substream_t * substream)
1063{
1064 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
1065 snd_pcm_runtime_t *runtime = substream->runtime;
1066 struct ichdev *ichdev = get_ichdev(substream);
1067
1068 ichdev->physbuf = runtime->dma_addr;
1069 ichdev->size = snd_pcm_lib_buffer_bytes(substream);
1070 ichdev->fragsize = snd_pcm_lib_period_bytes(substream);
1071 if (ichdev->ichd == ICHD_PCMOUT) {
1072 snd_intel8x0_setup_pcm_out(chip, runtime);
1073 if (chip->device_type == DEVICE_INTEL_ICH4 ||
1074 chip->device_type == DEVICE_INTEL_ICH5)
1075 ichdev->pos_shift = (runtime->sample_bits > 16) ? 2 : 1;
1076 }
1077 snd_intel8x0_setup_periods(chip, ichdev);
1078 return 0;
1079}
1080
1081static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(snd_pcm_substream_t * substream)
1082{
1083 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
1084 struct ichdev *ichdev = get_ichdev(substream);
1085 size_t ptr1, ptr;
1086 int civ, timeout = 100;
1087 unsigned int position;
1088
1089 spin_lock(&chip->reg_lock);
1090 do {
1091 civ = igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV);
1092 ptr1 = igetword(chip, ichdev->reg_offset + ichdev->roff_picb);
1093 position = ichdev->position;
1094 if (ptr1 == 0) {
1095 udelay(10);
1096 continue;
1097 }
1098 if (civ == igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV) &&
1099 ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb))
1100 break;
1101 } while (timeout--);
1102 ptr1 <<= ichdev->pos_shift;
1103 ptr = ichdev->fragsize1 - ptr1;
1104 ptr += position;
1105 spin_unlock(&chip->reg_lock);
1106 if (ptr >= ichdev->size)
1107 return 0;
1108 return bytes_to_frames(substream->runtime, ptr);
1109}
1110
1111static snd_pcm_hardware_t snd_intel8x0_stream =
1112{
1113 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1114 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1115 SNDRV_PCM_INFO_MMAP_VALID |
1116 SNDRV_PCM_INFO_PAUSE |
1117 SNDRV_PCM_INFO_RESUME),
1118 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1119 .rates = SNDRV_PCM_RATE_48000,
1120 .rate_min = 48000,
1121 .rate_max = 48000,
1122 .channels_min = 2,
1123 .channels_max = 2,
1124 .buffer_bytes_max = 128 * 1024,
1125 .period_bytes_min = 32,
1126 .period_bytes_max = 128 * 1024,
1127 .periods_min = 1,
1128 .periods_max = 1024,
1129 .fifo_size = 0,
1130};
1131
1132static unsigned int channels4[] = {
1133 2, 4,
1134};
1135
1136static snd_pcm_hw_constraint_list_t hw_constraints_channels4 = {
1137 .count = ARRAY_SIZE(channels4),
1138 .list = channels4,
1139 .mask = 0,
1140};
1141
1142static unsigned int channels6[] = {
1143 2, 4, 6,
1144};
1145
1146static snd_pcm_hw_constraint_list_t hw_constraints_channels6 = {
1147 .count = ARRAY_SIZE(channels6),
1148 .list = channels6,
1149 .mask = 0,
1150};
1151
1152static int snd_intel8x0_pcm_open(snd_pcm_substream_t * substream, struct ichdev *ichdev)
1153{
1154 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
1155 snd_pcm_runtime_t *runtime = substream->runtime;
1156 int err;
1157
1158 ichdev->substream = substream;
1159 runtime->hw = snd_intel8x0_stream;
1160 runtime->hw.rates = ichdev->pcm->rates;
1161 snd_pcm_limit_hw_rates(runtime);
1162 if (chip->device_type == DEVICE_SIS) {
1163 // vladest workaround
1164 if (!runtime->hw.rates)
1165 runtime->hw.rates = SNDRV_PCM_RATE_48000;
1166 runtime->hw.buffer_bytes_max = 64*1024;
1167 runtime->hw.period_bytes_max = 64*1024;
1168 }
1169 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
1170 return err;
1171 runtime->private_data = ichdev;
1172 return 0;
1173}
1174
1175static int snd_intel8x0_playback_open(snd_pcm_substream_t * substream)
1176{
1177 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
1178 snd_pcm_runtime_t *runtime = substream->runtime;
1179 int err;
1180
1181 err = snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_PCMOUT]);
1182 if (err < 0)
1183 return err;
1184 if (chip->multi6) {
1185 runtime->hw.channels_max = 6;
1186 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels6);
1187 } else if (chip->multi4) {
1188 runtime->hw.channels_max = 4;
1189 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels4);
1190 }
1191 if (chip->dra) {
1192 snd_ac97_pcm_double_rate_rules(runtime);
1193 }
1194 if (chip->smp20bit)
1195 runtime->hw.formats |= SNDRV_PCM_FMTBIT_S32_LE;
1196 return 0;
1197}
1198
1199static int snd_intel8x0_playback_close(snd_pcm_substream_t * substream)
1200{
1201 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
1202
1203 chip->ichd[ICHD_PCMOUT].substream = NULL;
1204 return 0;
1205}
1206
1207static int snd_intel8x0_capture_open(snd_pcm_substream_t * substream)
1208{
1209 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
1210
1211 return snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_PCMIN]);
1212}
1213
1214static int snd_intel8x0_capture_close(snd_pcm_substream_t * substream)
1215{
1216 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
1217
1218 chip->ichd[ICHD_PCMIN].substream = NULL;
1219 return 0;
1220}
1221
1222static int snd_intel8x0_mic_open(snd_pcm_substream_t * substream)
1223{
1224 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
1225
1226 return snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_MIC]);
1227}
1228
1229static int snd_intel8x0_mic_close(snd_pcm_substream_t * substream)
1230{
1231 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
1232
1233 chip->ichd[ICHD_MIC].substream = NULL;
1234 return 0;
1235}
1236
1237static int snd_intel8x0_mic2_open(snd_pcm_substream_t * substream)
1238{
1239 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
1240
1241 return snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_MIC2]);
1242}
1243
1244static int snd_intel8x0_mic2_close(snd_pcm_substream_t * substream)
1245{
1246 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
1247
1248 chip->ichd[ICHD_MIC2].substream = NULL;
1249 return 0;
1250}
1251
1252static int snd_intel8x0_capture2_open(snd_pcm_substream_t * substream)
1253{
1254 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
1255
1256 return snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_PCM2IN]);
1257}
1258
1259static int snd_intel8x0_capture2_close(snd_pcm_substream_t * substream)
1260{
1261 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
1262
1263 chip->ichd[ICHD_PCM2IN].substream = NULL;
1264 return 0;
1265}
1266
1267static int snd_intel8x0_spdif_open(snd_pcm_substream_t * substream)
1268{
1269 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
1270 int idx = chip->device_type == DEVICE_NFORCE ? NVD_SPBAR : ICHD_SPBAR;
1271
1272 return snd_intel8x0_pcm_open(substream, &chip->ichd[idx]);
1273}
1274
1275static int snd_intel8x0_spdif_close(snd_pcm_substream_t * substream)
1276{
1277 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
1278 int idx = chip->device_type == DEVICE_NFORCE ? NVD_SPBAR : ICHD_SPBAR;
1279
1280 chip->ichd[idx].substream = NULL;
1281 return 0;
1282}
1283
1284static int snd_intel8x0_ali_ac97spdifout_open(snd_pcm_substream_t * substream)
1285{
1286 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
1287 unsigned int val;
1288
1289 spin_lock_irq(&chip->reg_lock);
1290 val = igetdword(chip, ICHREG(ALI_INTERFACECR));
1291 val |= ICH_ALI_IF_AC97SP;
1292 iputdword(chip, ICHREG(ALI_INTERFACECR), val);
1293 /* also needs to set ALI_SC_CODEC_SPDF correctly */
1294 spin_unlock_irq(&chip->reg_lock);
1295
1296 return snd_intel8x0_pcm_open(substream, &chip->ichd[ALID_AC97SPDIFOUT]);
1297}
1298
1299static int snd_intel8x0_ali_ac97spdifout_close(snd_pcm_substream_t * substream)
1300{
1301 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
1302 unsigned int val;
1303
1304 chip->ichd[ALID_AC97SPDIFOUT].substream = NULL;
1305 spin_lock_irq(&chip->reg_lock);
1306 val = igetdword(chip, ICHREG(ALI_INTERFACECR));
1307 val &= ~ICH_ALI_IF_AC97SP;
1308 iputdword(chip, ICHREG(ALI_INTERFACECR), val);
1309 spin_unlock_irq(&chip->reg_lock);
1310
1311 return 0;
1312}
1313
1314static int snd_intel8x0_ali_spdifin_open(snd_pcm_substream_t * substream)
1315{
1316 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
1317
1318 return snd_intel8x0_pcm_open(substream, &chip->ichd[ALID_SPDIFIN]);
1319}
1320
1321static int snd_intel8x0_ali_spdifin_close(snd_pcm_substream_t * substream)
1322{
1323 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
1324
1325 chip->ichd[ALID_SPDIFIN].substream = NULL;
1326 return 0;
1327}
1328
1329#if 0 // NYI
1330static int snd_intel8x0_ali_spdifout_open(snd_pcm_substream_t * substream)
1331{
1332 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
1333
1334 return snd_intel8x0_pcm_open(substream, &chip->ichd[ALID_SPDIFOUT]);
1335}
1336
1337static int snd_intel8x0_ali_spdifout_close(snd_pcm_substream_t * substream)
1338{
1339 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
1340
1341 chip->ichd[ALID_SPDIFOUT].substream = NULL;
1342 return 0;
1343}
1344#endif
1345
1346static snd_pcm_ops_t snd_intel8x0_playback_ops = {
1347 .open = snd_intel8x0_playback_open,
1348 .close = snd_intel8x0_playback_close,
1349 .ioctl = snd_pcm_lib_ioctl,
1350 .hw_params = snd_intel8x0_hw_params,
1351 .hw_free = snd_intel8x0_hw_free,
1352 .prepare = snd_intel8x0_pcm_prepare,
1353 .trigger = snd_intel8x0_pcm_trigger,
1354 .pointer = snd_intel8x0_pcm_pointer,
1355};
1356
1357static snd_pcm_ops_t snd_intel8x0_capture_ops = {
1358 .open = snd_intel8x0_capture_open,
1359 .close = snd_intel8x0_capture_close,
1360 .ioctl = snd_pcm_lib_ioctl,
1361 .hw_params = snd_intel8x0_hw_params,
1362 .hw_free = snd_intel8x0_hw_free,
1363 .prepare = snd_intel8x0_pcm_prepare,
1364 .trigger = snd_intel8x0_pcm_trigger,
1365 .pointer = snd_intel8x0_pcm_pointer,
1366};
1367
1368static snd_pcm_ops_t snd_intel8x0_capture_mic_ops = {
1369 .open = snd_intel8x0_mic_open,
1370 .close = snd_intel8x0_mic_close,
1371 .ioctl = snd_pcm_lib_ioctl,
1372 .hw_params = snd_intel8x0_hw_params,
1373 .hw_free = snd_intel8x0_hw_free,
1374 .prepare = snd_intel8x0_pcm_prepare,
1375 .trigger = snd_intel8x0_pcm_trigger,
1376 .pointer = snd_intel8x0_pcm_pointer,
1377};
1378
1379static snd_pcm_ops_t snd_intel8x0_capture_mic2_ops = {
1380 .open = snd_intel8x0_mic2_open,
1381 .close = snd_intel8x0_mic2_close,
1382 .ioctl = snd_pcm_lib_ioctl,
1383 .hw_params = snd_intel8x0_hw_params,
1384 .hw_free = snd_intel8x0_hw_free,
1385 .prepare = snd_intel8x0_pcm_prepare,
1386 .trigger = snd_intel8x0_pcm_trigger,
1387 .pointer = snd_intel8x0_pcm_pointer,
1388};
1389
1390static snd_pcm_ops_t snd_intel8x0_capture2_ops = {
1391 .open = snd_intel8x0_capture2_open,
1392 .close = snd_intel8x0_capture2_close,
1393 .ioctl = snd_pcm_lib_ioctl,
1394 .hw_params = snd_intel8x0_hw_params,
1395 .hw_free = snd_intel8x0_hw_free,
1396 .prepare = snd_intel8x0_pcm_prepare,
1397 .trigger = snd_intel8x0_pcm_trigger,
1398 .pointer = snd_intel8x0_pcm_pointer,
1399};
1400
1401static snd_pcm_ops_t snd_intel8x0_spdif_ops = {
1402 .open = snd_intel8x0_spdif_open,
1403 .close = snd_intel8x0_spdif_close,
1404 .ioctl = snd_pcm_lib_ioctl,
1405 .hw_params = snd_intel8x0_hw_params,
1406 .hw_free = snd_intel8x0_hw_free,
1407 .prepare = snd_intel8x0_pcm_prepare,
1408 .trigger = snd_intel8x0_pcm_trigger,
1409 .pointer = snd_intel8x0_pcm_pointer,
1410};
1411
1412static snd_pcm_ops_t snd_intel8x0_ali_playback_ops = {
1413 .open = snd_intel8x0_playback_open,
1414 .close = snd_intel8x0_playback_close,
1415 .ioctl = snd_pcm_lib_ioctl,
1416 .hw_params = snd_intel8x0_hw_params,
1417 .hw_free = snd_intel8x0_hw_free,
1418 .prepare = snd_intel8x0_pcm_prepare,
1419 .trigger = snd_intel8x0_ali_trigger,
1420 .pointer = snd_intel8x0_pcm_pointer,
1421};
1422
1423static snd_pcm_ops_t snd_intel8x0_ali_capture_ops = {
1424 .open = snd_intel8x0_capture_open,
1425 .close = snd_intel8x0_capture_close,
1426 .ioctl = snd_pcm_lib_ioctl,
1427 .hw_params = snd_intel8x0_hw_params,
1428 .hw_free = snd_intel8x0_hw_free,
1429 .prepare = snd_intel8x0_pcm_prepare,
1430 .trigger = snd_intel8x0_ali_trigger,
1431 .pointer = snd_intel8x0_pcm_pointer,
1432};
1433
1434static snd_pcm_ops_t snd_intel8x0_ali_capture_mic_ops = {
1435 .open = snd_intel8x0_mic_open,
1436 .close = snd_intel8x0_mic_close,
1437 .ioctl = snd_pcm_lib_ioctl,
1438 .hw_params = snd_intel8x0_hw_params,
1439 .hw_free = snd_intel8x0_hw_free,
1440 .prepare = snd_intel8x0_pcm_prepare,
1441 .trigger = snd_intel8x0_ali_trigger,
1442 .pointer = snd_intel8x0_pcm_pointer,
1443};
1444
1445static snd_pcm_ops_t snd_intel8x0_ali_ac97spdifout_ops = {
1446 .open = snd_intel8x0_ali_ac97spdifout_open,
1447 .close = snd_intel8x0_ali_ac97spdifout_close,
1448 .ioctl = snd_pcm_lib_ioctl,
1449 .hw_params = snd_intel8x0_hw_params,
1450 .hw_free = snd_intel8x0_hw_free,
1451 .prepare = snd_intel8x0_pcm_prepare,
1452 .trigger = snd_intel8x0_ali_trigger,
1453 .pointer = snd_intel8x0_pcm_pointer,
1454};
1455
1456static snd_pcm_ops_t snd_intel8x0_ali_spdifin_ops = {
1457 .open = snd_intel8x0_ali_spdifin_open,
1458 .close = snd_intel8x0_ali_spdifin_close,
1459 .ioctl = snd_pcm_lib_ioctl,
1460 .hw_params = snd_intel8x0_hw_params,
1461 .hw_free = snd_intel8x0_hw_free,
1462 .prepare = snd_intel8x0_pcm_prepare,
1463 .trigger = snd_intel8x0_pcm_trigger,
1464 .pointer = snd_intel8x0_pcm_pointer,
1465};
1466
1467#if 0 // NYI
1468static snd_pcm_ops_t snd_intel8x0_ali_spdifout_ops = {
1469 .open = snd_intel8x0_ali_spdifout_open,
1470 .close = snd_intel8x0_ali_spdifout_close,
1471 .ioctl = snd_pcm_lib_ioctl,
1472 .hw_params = snd_intel8x0_hw_params,
1473 .hw_free = snd_intel8x0_hw_free,
1474 .prepare = snd_intel8x0_pcm_prepare,
1475 .trigger = snd_intel8x0_pcm_trigger,
1476 .pointer = snd_intel8x0_pcm_pointer,
1477};
1478#endif // NYI
1479
1480
1481struct ich_pcm_table {
1482 char *suffix;
1483 snd_pcm_ops_t *playback_ops;
1484 snd_pcm_ops_t *capture_ops;
1485 size_t prealloc_size;
1486 size_t prealloc_max_size;
1487 int ac97_idx;
1488};
1489
1490static int __devinit snd_intel8x0_pcm1(struct intel8x0 *chip, int device, struct ich_pcm_table *rec)
1491{
1492 snd_pcm_t *pcm;
1493 int err;
1494 char name[32];
1495
1496 if (rec->suffix)
1497 sprintf(name, "Intel ICH - %s", rec->suffix);
1498 else
1499 strcpy(name, "Intel ICH");
1500 err = snd_pcm_new(chip->card, name, device,
1501 rec->playback_ops ? 1 : 0,
1502 rec->capture_ops ? 1 : 0, &pcm);
1503 if (err < 0)
1504 return err;
1505
1506 if (rec->playback_ops)
1507 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, rec->playback_ops);
1508 if (rec->capture_ops)
1509 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, rec->capture_ops);
1510
1511 pcm->private_data = chip;
1512 pcm->info_flags = 0;
1513 if (rec->suffix)
1514 sprintf(pcm->name, "%s - %s", chip->card->shortname, rec->suffix);
1515 else
1516 strcpy(pcm->name, chip->card->shortname);
1517 chip->pcm[device] = pcm;
1518
1519 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
1520 rec->prealloc_size, rec->prealloc_max_size);
1521
1522 return 0;
1523}
1524
1525static struct ich_pcm_table intel_pcms[] __devinitdata = {
1526 {
1527 .playback_ops = &snd_intel8x0_playback_ops,
1528 .capture_ops = &snd_intel8x0_capture_ops,
1529 .prealloc_size = 64 * 1024,
1530 .prealloc_max_size = 128 * 1024,
1531 },
1532 {
1533 .suffix = "MIC ADC",
1534 .capture_ops = &snd_intel8x0_capture_mic_ops,
1535 .prealloc_size = 0,
1536 .prealloc_max_size = 128 * 1024,
1537 .ac97_idx = ICHD_MIC,
1538 },
1539 {
1540 .suffix = "MIC2 ADC",
1541 .capture_ops = &snd_intel8x0_capture_mic2_ops,
1542 .prealloc_size = 0,
1543 .prealloc_max_size = 128 * 1024,
1544 .ac97_idx = ICHD_MIC2,
1545 },
1546 {
1547 .suffix = "ADC2",
1548 .capture_ops = &snd_intel8x0_capture2_ops,
1549 .prealloc_size = 0,
1550 .prealloc_max_size = 128 * 1024,
1551 .ac97_idx = ICHD_PCM2IN,
1552 },
1553 {
1554 .suffix = "IEC958",
1555 .playback_ops = &snd_intel8x0_spdif_ops,
1556 .prealloc_size = 64 * 1024,
1557 .prealloc_max_size = 128 * 1024,
1558 .ac97_idx = ICHD_SPBAR,
1559 },
1560};
1561
1562static struct ich_pcm_table nforce_pcms[] __devinitdata = {
1563 {
1564 .playback_ops = &snd_intel8x0_playback_ops,
1565 .capture_ops = &snd_intel8x0_capture_ops,
1566 .prealloc_size = 64 * 1024,
1567 .prealloc_max_size = 128 * 1024,
1568 },
1569 {
1570 .suffix = "MIC ADC",
1571 .capture_ops = &snd_intel8x0_capture_mic_ops,
1572 .prealloc_size = 0,
1573 .prealloc_max_size = 128 * 1024,
1574 .ac97_idx = NVD_MIC,
1575 },
1576 {
1577 .suffix = "IEC958",
1578 .playback_ops = &snd_intel8x0_spdif_ops,
1579 .prealloc_size = 64 * 1024,
1580 .prealloc_max_size = 128 * 1024,
1581 .ac97_idx = NVD_SPBAR,
1582 },
1583};
1584
1585static struct ich_pcm_table ali_pcms[] __devinitdata = {
1586 {
1587 .playback_ops = &snd_intel8x0_ali_playback_ops,
1588 .capture_ops = &snd_intel8x0_ali_capture_ops,
1589 .prealloc_size = 64 * 1024,
1590 .prealloc_max_size = 128 * 1024,
1591 },
1592 {
1593 .suffix = "MIC ADC",
1594 .capture_ops = &snd_intel8x0_ali_capture_mic_ops,
1595 .prealloc_size = 0,
1596 .prealloc_max_size = 128 * 1024,
1597 .ac97_idx = ALID_MIC,
1598 },
1599 {
1600 .suffix = "IEC958",
1601 .playback_ops = &snd_intel8x0_ali_ac97spdifout_ops,
1602 .capture_ops = &snd_intel8x0_ali_spdifin_ops,
1603 .prealloc_size = 64 * 1024,
1604 .prealloc_max_size = 128 * 1024,
1605 .ac97_idx = ALID_AC97SPDIFOUT,
1606 },
1607#if 0 // NYI
1608 {
1609 .suffix = "HW IEC958",
1610 .playback_ops = &snd_intel8x0_ali_spdifout_ops,
1611 .prealloc_size = 64 * 1024,
1612 .prealloc_max_size = 128 * 1024,
1613 },
1614#endif
1615};
1616
1617
1618static int __devinit snd_intel8x0_pcm(struct intel8x0 *chip)
1619{
1620 int i, tblsize, device, err;
1621 struct ich_pcm_table *tbl, *rec;
1622
1623 switch (chip->device_type) {
1624 case DEVICE_INTEL_ICH4:
1625 case DEVICE_INTEL_ICH5:
1626 tbl = intel_pcms;
1627 tblsize = ARRAY_SIZE(intel_pcms);
1628 break;
1629 case DEVICE_NFORCE:
1630 tbl = nforce_pcms;
1631 tblsize = ARRAY_SIZE(nforce_pcms);
1632 break;
1633 case DEVICE_ALI:
1634 tbl = ali_pcms;
1635 tblsize = ARRAY_SIZE(ali_pcms);
1636 break;
1637 default:
1638 tbl = intel_pcms;
1639 tblsize = 2;
1640 break;
1641 }
1642
1643 device = 0;
1644 for (i = 0; i < tblsize; i++) {
1645 rec = tbl + i;
1646 if (i > 0 && rec->ac97_idx) {
1647 /* activate PCM only when associated AC'97 codec */
1648 if (! chip->ichd[rec->ac97_idx].pcm)
1649 continue;
1650 }
1651 err = snd_intel8x0_pcm1(chip, device, rec);
1652 if (err < 0)
1653 return err;
1654 device++;
1655 }
1656
1657 chip->pcm_devs = device;
1658 return 0;
1659}
1660
1661
1662/*
1663 * Mixer part
1664 */
1665
1666static void snd_intel8x0_mixer_free_ac97_bus(ac97_bus_t *bus)
1667{
1668 struct intel8x0 *chip = bus->private_data;
1669 chip->ac97_bus = NULL;
1670}
1671
1672static void snd_intel8x0_mixer_free_ac97(ac97_t *ac97)
1673{
1674 struct intel8x0 *chip = ac97->private_data;
1675 chip->ac97[ac97->num] = NULL;
1676}
1677
1678static struct ac97_pcm ac97_pcm_defs[] __devinitdata = {
1679 /* front PCM */
1680 {
1681 .exclusive = 1,
1682 .r =
1683 {
1684 {
1685 .slots = (1 << AC97_SLOT_PCM_LEFT) |
1686 (1 << AC97_SLOT_PCM_RIGHT) |
1687 (1 << AC97_SLOT_PCM_CENTER) |
1688 (1 << AC97_SLOT_PCM_SLEFT) |
1689 (1 << AC97_SLOT_PCM_SRIGHT) |
1690 (1 << AC97_SLOT_LFE)
1691 },
1692 {
1693 .slots = (1 << AC97_SLOT_PCM_LEFT) |
1694 (1 << AC97_SLOT_PCM_RIGHT) |
1695 (1 << AC97_SLOT_PCM_LEFT_0) |
1696 (1 << AC97_SLOT_PCM_RIGHT_0)
1697 }
1698 }
1699 },
1700 /* PCM IN #1 */
1701 {
1702 .stream = 1,
1703 .exclusive = 1,
1704 .r = { {
1705 .slots = (1 << AC97_SLOT_PCM_LEFT) |
1706 (1 << AC97_SLOT_PCM_RIGHT)
1707 }
1708 }
1709 },
1710 /* MIC IN #1 */
1711 {
1712 .stream = 1,
1713 .exclusive = 1,
1714 .r = { {
1715 .slots = (1 << AC97_SLOT_MIC)
1716 }
1717 }
1718 },
1719 /* S/PDIF PCM */
1720 {
1721 .exclusive = 1,
1722 .spdif = 1,
1723 .r = { {
1724 .slots = (1 << AC97_SLOT_SPDIF_LEFT2) |
1725 (1 << AC97_SLOT_SPDIF_RIGHT2)
1726 }
1727 }
1728 },
1729 /* PCM IN #2 */
1730 {
1731 .stream = 1,
1732 .exclusive = 1,
1733 .r = { {
1734 .slots = (1 << AC97_SLOT_PCM_LEFT) |
1735 (1 << AC97_SLOT_PCM_RIGHT)
1736 }
1737 }
1738 },
1739 /* MIC IN #2 */
1740 {
1741 .stream = 1,
1742 .exclusive = 1,
1743 .r = { {
1744 .slots = (1 << AC97_SLOT_MIC)
1745 }
1746 }
1747 },
1748};
1749
1750static struct ac97_quirk ac97_quirks[] __devinitdata = {
1751 {
1752 .subvendor = 0x0e11,
1753 .subdevice = 0x008a,
1754 .name = "Compaq Evo W4000", /* AD1885 */
1755 .type = AC97_TUNE_HP_ONLY
1756 },
1757 {
1758 .subvendor = 0x0e11,
1759 .subdevice = 0x00b8,
1760 .name = "Compaq Evo D510C",
1761 .type = AC97_TUNE_HP_ONLY
1762 },
1763 {
1764 .subvendor = 0x0e11,
1765 .subdevice = 0x0860,
1766 .name = "HP/Compaq nx7010",
1767 .type = AC97_TUNE_MUTE_LED
1768 },
1769 {
1770 .subvendor = 0x1014,
1771 .subdevice = 0x1f00,
1772 .name = "MS-9128",
1773 .type = AC97_TUNE_ALC_JACK
1774 },
1775 {
1776 .subvendor = 0x1014,
1777 .subdevice = 0x0267,
1778 .name = "IBM NetVista A30p", /* AD1981B */
1779 .type = AC97_TUNE_HP_ONLY
1780 },
1781 {
1782 .subvendor = 0x1025,
1783 .subdevice = 0x0083,
1784 .name = "Acer Aspire 3003LCi",
1785 .type = AC97_TUNE_HP_ONLY
1786 },
1787 {
1788 .subvendor = 0x1028,
1789 .subdevice = 0x00d8,
1790 .name = "Dell Precision 530", /* AD1885 */
1791 .type = AC97_TUNE_HP_ONLY
1792 },
1793 {
1794 .subvendor = 0x1028,
1795 .subdevice = 0x010d,
1796 .name = "Dell", /* which model? AD1885 */
1797 .type = AC97_TUNE_HP_ONLY
1798 },
1799 {
1800 .subvendor = 0x1028,
1801 .subdevice = 0x0126,
1802 .name = "Dell Optiplex GX260", /* AD1981A */
1803 .type = AC97_TUNE_HP_ONLY
1804 },
1805 {
1806 .subvendor = 0x1028,
1807 .subdevice = 0x012c,
1808 .name = "Dell Precision 650", /* AD1981A */
1809 .type = AC97_TUNE_HP_ONLY
1810 },
1811 {
1812 .subvendor = 0x1028,
1813 .subdevice = 0x012d,
1814 .name = "Dell Precision 450", /* AD1981B*/
1815 .type = AC97_TUNE_HP_ONLY
1816 },
1817 {
1818 .subvendor = 0x1028,
1819 .subdevice = 0x0147,
1820 .name = "Dell", /* which model? AD1981B*/
1821 .type = AC97_TUNE_HP_ONLY
1822 },
1823 {
1824 .subvendor = 0x1028,
1825 .subdevice = 0x0163,
1826 .name = "Dell Unknown", /* STAC9750/51 */
1827 .type = AC97_TUNE_HP_ONLY
1828 },
1829 {
1830 .subvendor = 0x1028,
1831 .subdevice = 0x0191,
1832 .name = "Dell Inspiron 8600",
1833 .type = AC97_TUNE_HP_ONLY
1834 },
1835 {
1836 .subvendor = 0x103c,
1837 .subdevice = 0x006d,
1838 .name = "HP zv5000",
1839 .type = AC97_TUNE_MUTE_LED /*AD1981B*/
1840 },
1841 { /* FIXME: which codec? */
1842 .subvendor = 0x103c,
1843 .subdevice = 0x00c3,
1844 .name = "HP xw6000",
1845 .type = AC97_TUNE_HP_ONLY
1846 },
1847 {
1848 .subvendor = 0x103c,
1849 .subdevice = 0x088c,
1850 .name = "HP nc8000",
1851 .type = AC97_TUNE_MUTE_LED
1852 },
1853 {
1854 .subvendor = 0x103c,
1855 .subdevice = 0x0890,
1856 .name = "HP nc6000",
1857 .type = AC97_TUNE_MUTE_LED
1858 },
1859 {
1860 .subvendor = 0x103c,
1861 .subdevice = 0x0934,
1862 .name = "HP nx8220",
1863 .type = AC97_TUNE_MUTE_LED
1864 },
1865 {
1866 .subvendor = 0x103c,
1867 .subdevice = 0x099c,
1868 .name = "HP nx6110", /* AD1981B */
1869 .type = AC97_TUNE_HP_ONLY
1870 },
1871 {
1872 .subvendor = 0x103c,
1873 .subdevice = 0x129d,
1874 .name = "HP xw8000",
1875 .type = AC97_TUNE_HP_ONLY
1876 },
1877 {
1878 .subvendor = 0x103c,
1879 .subdevice = 0x0938,
1880 .name = "HP nc4200",
1881 .type = AC97_TUNE_HP_MUTE_LED
1882 },
1883 {
1884 .subvendor = 0x103c,
1885 .subdevice = 0x099c,
1886 .name = "HP nc6120",
1887 .type = AC97_TUNE_HP_MUTE_LED
1888 },
1889 {
1890 .subvendor = 0x103c,
1891 .subdevice = 0x0944,
1892 .name = "HP nc6220",
1893 .type = AC97_TUNE_HP_MUTE_LED
1894 },
1895 {
1896 .subvendor = 0x103c,
1897 .subdevice = 0x0934,
1898 .name = "HP nc8220",
1899 .type = AC97_TUNE_HP_MUTE_LED
1900 },
1901 {
1902 .subvendor = 0x103c,
1903 .subdevice = 0x12f1,
1904 .name = "HP xw8200", /* AD1981B*/
1905 .type = AC97_TUNE_HP_ONLY
1906 },
1907 {
1908 .subvendor = 0x103c,
1909 .subdevice = 0x12f2,
1910 .name = "HP xw6200",
1911 .type = AC97_TUNE_HP_ONLY
1912 },
1913 {
1914 .subvendor = 0x103c,
1915 .subdevice = 0x3008,
1916 .name = "HP xw4200", /* AD1981B*/
1917 .type = AC97_TUNE_HP_ONLY
1918 },
1919 {
1920 .subvendor = 0x104d,
1921 .subdevice = 0x8197,
1922 .name = "Sony S1XP",
1923 .type = AC97_TUNE_INV_EAPD
1924 },
1925 {
1926 .subvendor = 0x1043,
1927 .subdevice = 0x80f3,
1928 .name = "ASUS ICH5/AD1985",
1929 .type = AC97_TUNE_AD_SHARING
1930 },
1931 {
1932 .subvendor = 0x10cf,
1933 .subdevice = 0x11c3,
1934 .name = "Fujitsu-Siemens E4010",
1935 .type = AC97_TUNE_HP_ONLY
1936 },
1937 {
1938 .subvendor = 0x10cf,
1939 .subdevice = 0x1225,
1940 .name = "Fujitsu-Siemens T3010",
1941 .type = AC97_TUNE_HP_ONLY
1942 },
1943 {
1944 .subvendor = 0x10cf,
1945 .subdevice = 0x1253,
1946 .name = "Fujitsu S6210", /* STAC9750/51 */
1947 .type = AC97_TUNE_HP_ONLY
1948 },
1949 {
1950 .subvendor = 0x10cf,
1951 .subdevice = 0x12ec,
1952 .name = "Fujitsu-Siemens 4010",
1953 .type = AC97_TUNE_HP_ONLY
1954 },
1955 {
1956 .subvendor = 0x10cf,
1957 .subdevice = 0x12f2,
1958 .name = "Fujitsu-Siemens Celsius H320",
1959 .type = AC97_TUNE_SWAP_HP
1960 },
1961 {
1962 .subvendor = 0x10f1,
1963 .subdevice = 0x2665,
1964 .name = "Fujitsu-Siemens Celsius", /* AD1981? */
1965 .type = AC97_TUNE_HP_ONLY
1966 },
1967 {
1968 .subvendor = 0x10f1,
1969 .subdevice = 0x2885,
1970 .name = "AMD64 Mobo", /* ALC650 */
1971 .type = AC97_TUNE_HP_ONLY
1972 },
1973 {
1974 .subvendor = 0x110a,
1975 .subdevice = 0x0056,
1976 .name = "Fujitsu-Siemens Scenic", /* AD1981? */
1977 .type = AC97_TUNE_HP_ONLY
1978 },
1979 {
1980 .subvendor = 0x11d4,
1981 .subdevice = 0x5375,
1982 .name = "ADI AD1985 (discrete)",
1983 .type = AC97_TUNE_HP_ONLY
1984 },
1985 {
1986 .subvendor = 0x1462,
1987 .subdevice = 0x5470,
1988 .name = "MSI P4 ATX 645 Ultra",
1989 .type = AC97_TUNE_HP_ONLY
1990 },
1991 {
1992 .subvendor = 0x1734,
1993 .subdevice = 0x0088,
1994 .name = "Fujitsu-Siemens D1522", /* AD1981 */
1995 .type = AC97_TUNE_HP_ONLY
1996 },
1997 {
1998 .subvendor = 0x8086,
1999 .subdevice = 0x2000,
2000 .mask = 0xfff0,
2001 .name = "Intel ICH5/AD1985",
2002 .type = AC97_TUNE_AD_SHARING
2003 },
2004 {
2005 .subvendor = 0x8086,
2006 .subdevice = 0x4000,
2007 .mask = 0xfff0,
2008 .name = "Intel ICH5/AD1985",
2009 .type = AC97_TUNE_AD_SHARING
2010 },
2011 {
2012 .subvendor = 0x8086,
2013 .subdevice = 0x4856,
2014 .name = "Intel D845WN (82801BA)",
2015 .type = AC97_TUNE_SWAP_HP
2016 },
2017 {
2018 .subvendor = 0x8086,
2019 .subdevice = 0x4d44,
2020 .name = "Intel D850EMV2", /* AD1885 */
2021 .type = AC97_TUNE_HP_ONLY
2022 },
2023 {
2024 .subvendor = 0x8086,
2025 .subdevice = 0x4d56,
2026 .name = "Intel ICH/AD1885",
2027 .type = AC97_TUNE_HP_ONLY
2028 },
2029 {
2030 .subvendor = 0x8086,
2031 .subdevice = 0x6000,
2032 .mask = 0xfff0,
2033 .name = "Intel ICH5/AD1985",
2034 .type = AC97_TUNE_AD_SHARING
2035 },
2036 {
2037 .subvendor = 0x8086,
2038 .subdevice = 0xe000,
2039 .mask = 0xfff0,
2040 .name = "Intel ICH5/AD1985",
2041 .type = AC97_TUNE_AD_SHARING
2042 },
2043#if 0 /* FIXME: this seems wrong on most boards */
2044 {
2045 .subvendor = 0x8086,
2046 .subdevice = 0xa000,
2047 .mask = 0xfff0,
2048 .name = "Intel ICH5/AD1985",
2049 .type = AC97_TUNE_HP_ONLY
2050 },
2051#endif
2052 {0} /* terminator */
2053};
2054
2055static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock, char *quirk_override)
2056{
2057 ac97_bus_t *pbus;
2058 ac97_template_t ac97;
2059 int err;
2060 unsigned int i, codecs;
2061 unsigned int glob_sta = 0;
2062 ac97_bus_ops_t *ops;
2063 static ac97_bus_ops_t standard_bus_ops = {
2064 0,snd_intel8x0_codec_write,
2065 snd_intel8x0_codec_read,0,0
2066 };
2067 static ac97_bus_ops_t ali_bus_ops = {
2068 0,snd_intel8x0_ali_codec_write,
2069 snd_intel8x0_ali_codec_read,0,0
2070 };
2071 chip->spdif_idx = -1; /* use PCMOUT (or disabled) */
2072 switch (chip->device_type) {
2073 case DEVICE_NFORCE:
2074 chip->spdif_idx = NVD_SPBAR;
2075 break;
2076 case DEVICE_ALI:
2077 chip->spdif_idx = ALID_AC97SPDIFOUT;
2078 break;
2079 case DEVICE_INTEL_ICH4:
2080 case DEVICE_INTEL_ICH5:
2081 chip->spdif_idx = ICHD_SPBAR;
2082 break;
2083 };
2084
2085 chip->in_ac97_init = 1;
2086
2087 memset(&ac97, 0, sizeof(ac97));
2088 ac97.private_data = chip;
2089 ac97.private_free = snd_intel8x0_mixer_free_ac97;
2090 ac97.scaps = AC97_SCAP_SKIP_MODEM;
2091 if (chip->device_type != DEVICE_ALI) {
2092 glob_sta = igetdword(chip, ICHREG(GLOB_STA));
2093 ops = &standard_bus_ops;
2094 if (chip->device_type == DEVICE_INTEL_ICH4 ||
2095 chip->device_type == DEVICE_INTEL_ICH5) {
2096 codecs = 0;
2097 if (glob_sta & ICH_PCR)
2098 codecs++;
2099 if (glob_sta & ICH_SCR)
2100 codecs++;
2101 if (glob_sta & ICH_TCR)
2102 codecs++;
2103 chip->in_sdin_init = 1;
2104#if 1 //vladest 06.10.2003 15:55 - bull shit!!! it doesnt works here
2105 for (i = 0; i < codecs; i++) {
2106 printk("codec %i read test begins...", i);
2107 snd_intel8x0_codec_read_test(chip, i);
2108 chip->ac97_sdin[i] = igetbyte(chip, ICHREG(SDM)) & ICH_LDI_MASK;
2109 printk("finished\n");
2110 }
2111#endif
2112 chip->in_sdin_init = 0;
2113 } else {
2114 codecs = glob_sta & ICH_SCR ? 2 : 1;
2115 }
2116 } else {
2117 ops = &ali_bus_ops;
2118 codecs = 1;
2119 /* detect the secondary codec */
2120 for (i = 0; i < 100; i++) {
2121 unsigned int reg = igetdword(chip, ICHREG(ALI_RTSR));
2122 if (reg & 0x40) {
2123 codecs = 2;
2124 break;
2125 }
2126 iputdword(chip, ICHREG(ALI_RTSR), reg | 0x40);
2127 udelay(1);
2128 }
2129 }
2130 if ((err = snd_ac97_bus(chip->card, 0, ops, chip, &pbus)) < 0)
2131 goto __err;
2132 pbus->private_free = snd_intel8x0_mixer_free_ac97_bus;
2133 pbus->shared_type = AC97_SHARED_TYPE_ICH; /* shared with modem driver */
2134 if (ac97_clock >= 8000 && ac97_clock <= 48000)
2135 pbus->clock = ac97_clock;
2136 /* FIXME: my test board doesn't work well with VRA... */
2137 if (chip->device_type == DEVICE_ALI)
2138 pbus->no_vra = 1;
2139 else
2140 pbus->dra = 1;
2141 chip->ac97_bus = pbus;
2142
2143 ac97.pci = chip->pci;
2144 for (i = 0; i < codecs; i++) {
2145 ac97.num = i;
2146 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) {
2147 if (err != -EACCES)
2148 snd_printk(KERN_ERR "Unable to initialize codec #%d\n", i);
2149 if (i == 0)
2150 goto __err;
2151 continue;
2152 }
2153 }
2154 /* tune up the primary codec */
2155 snd_ac97_tune_hardware(chip->ac97[0], ac97_quirks, quirk_override);
2156 /* enable separate SDINs for ICH4 */
2157 if (chip->device_type == DEVICE_INTEL_ICH4 ||
2158 chip->device_type == DEVICE_INTEL_ICH5)
2159 pbus->isdin = 1;
2160 /* find the available PCM streams */
2161 i = ARRAY_SIZE(ac97_pcm_defs);
2162 if (chip->device_type != DEVICE_INTEL_ICH4 &&
2163 chip->device_type != DEVICE_INTEL_ICH5)
2164 i -= 2; /* do not allocate PCM2IN and MIC2 */
2165 if (chip->spdif_idx < 0)
2166 i--; /* do not allocate S/PDIF */
2167 err = snd_ac97_pcm_assign(pbus, i, ac97_pcm_defs);
2168 if (err < 0)
2169 goto __err;
2170 chip->ichd[ICHD_PCMOUT].pcm = &pbus->pcms[0];
2171 chip->ichd[ICHD_PCMIN].pcm = &pbus->pcms[1];
2172 chip->ichd[ICHD_MIC].pcm = &pbus->pcms[2];
2173 if (chip->spdif_idx >= 0)
2174 chip->ichd[chip->spdif_idx].pcm = &pbus->pcms[3];
2175 if (chip->device_type == DEVICE_INTEL_ICH4 ||
2176 chip->device_type == DEVICE_INTEL_ICH5) {
2177 chip->ichd[ICHD_PCM2IN].pcm = &pbus->pcms[4];
2178 chip->ichd[ICHD_MIC2].pcm = &pbus->pcms[5];
2179 }
2180 /* enable separate SDINs for ICH4 */
2181 if (chip->device_type == DEVICE_INTEL_ICH4 ||
2182 chip->device_type == DEVICE_INTEL_ICH5) {
2183 struct ac97_pcm *pcm = chip->ichd[ICHD_PCM2IN].pcm;
2184 u8 tmp = igetbyte(chip, ICHREG(SDM));
2185 tmp &= ~(ICH_DI2L_MASK|ICH_DI1L_MASK);
2186 if (pcm) {
2187 tmp |= ICH_SE; /* steer enable for multiple SDINs */
2188 tmp |= chip->ac97_sdin[0] << ICH_DI1L_SHIFT;
2189 for (i = 1; i < 4; i++) {
2190 if (pcm->r[0].codec[i]) {
2191 tmp |= chip->ac97_sdin[pcm->r[0].codec[1]->num] << ICH_DI2L_SHIFT;
2192 break;
2193 }
2194 }
2195 } else {
2196 tmp &= ~ICH_SE; /* steer disable */
2197 }
2198 iputbyte(chip, ICHREG(SDM), tmp);
2199 }
2200 if (pbus->pcms[0].r[0].slots & (1 << AC97_SLOT_PCM_SLEFT)) {
2201 chip->multi4 = 1;
2202 if (pbus->pcms[0].r[0].slots & (1 << AC97_SLOT_LFE))
2203 chip->multi6 = 1;
2204 }
2205 if (pbus->pcms[0].r[1].rslots[0]) {
2206 chip->dra = 1;
2207 }
2208 if (chip->device_type == DEVICE_INTEL_ICH4 ||
2209 chip->device_type == DEVICE_INTEL_ICH5) {
2210 if ((igetdword(chip, ICHREG(GLOB_STA)) & ICH_SAMPLE_CAP) == ICH_SAMPLE_16_20)
2211 chip->smp20bit = 1;
2212 }
2213 if (chip->device_type == DEVICE_NFORCE) {
2214 /* 48kHz only */
2215 chip->ichd[chip->spdif_idx].pcm->rates = SNDRV_PCM_RATE_48000;
2216 }
2217
2218 if (chip->device_type == DEVICE_INTEL_ICH4 ||
2219 chip->device_type == DEVICE_INTEL_ICH5) {
2220 /* use slot 10/11 for SPDIF */
2221 u32 val;
2222 val = igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_PCM_SPDIF_MASK;
2223 val |= ICH_PCM_SPDIF_1011;
2224 iputdword(chip, ICHREG(GLOB_CNT), val);
2225 snd_ac97_update_bits(chip->ac97[0], AC97_EXTENDED_STATUS, 0x03 << 4, 0x03 << 4);
2226 }
2227 chip->in_ac97_init = 0;
2228 return 0;
2229
2230 __err:
2231 /* clear the cold-reset bit for the next chance */
2232 if (chip->device_type != DEVICE_ALI)
2233 iputdword(chip, ICHREG(GLOB_CNT), igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_AC97COLD);
2234 return err;
2235}
2236
2237
2238/*
2239 *
2240 */
2241
2242static void do_ali_reset(struct intel8x0 *chip)
2243{
2244 iputdword(chip, ICHREG(ALI_SCR), ICH_ALI_SC_RESET);
2245 iputdword(chip, ICHREG(ALI_FIFOCR1), 0x83838383);
2246 iputdword(chip, ICHREG(ALI_FIFOCR2), 0x83838383);
2247 iputdword(chip, ICHREG(ALI_FIFOCR3), 0x83838383);
2248 iputdword(chip, ICHREG(ALI_INTERFACECR),
2249 ICH_ALI_IF_PI|ICH_ALI_IF_PO);
2250 iputdword(chip, ICHREG(ALI_INTERRUPTCR), 0x00000000);
2251 iputdword(chip, ICHREG(ALI_INTERRUPTSR), 0x00000000);
2252}
2253
2254#define do_delay(chip) do {\
2255 set_current_state(TASK_UNINTERRUPTIBLE);\
2256 schedule_timeout(1);\
2257 } while (0)
2258
2259static int snd_intel8x0_ich_chip_init(struct intel8x0 *chip, int probing)
2260{
2261 unsigned long end_time;
2262 unsigned int cnt, status, nstatus,i;
2263
2264#ifdef DEBUG
2265 dprintf(("ICH chip init begins"));
2266#endif
2267 /* put logic to right state */
2268 /* first clear status bits */
2269#if 1 // noone do it. wtf? //vladest 06.10.2003 13:51
2270 status = ICH_RCS | ICH_MCINT | ICH_POINT | ICH_PIINT;
2271 if (chip->device_type == DEVICE_NFORCE)
2272 status |= ICH_NVSPINT;
2273 cnt = igetdword(chip, ICHREG(GLOB_STA));
2274 iputdword(chip, ICHREG(GLOB_STA), cnt & status);
2275#endif
2276 // hmm. at least we should try
2277 //iputdword(chip, ICHREG(GLOB_CNT), igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_AC97COLD);
2278 /* ACLink on, 2 channels */
2279 cnt = igetdword(chip, ICHREG(GLOB_CNT));
2280 // added by vladest
2281 // cnt &= ~ICH_ACLINK;
2282 cnt &= ~(ICH_ACLINK | ICH_PCM_246_MASK);
2283 cnt |= (cnt & ICH_AC97COLD) == 0 ? ICH_AC97COLD : ICH_AC97WARM;
2284
2285 // ??? 25.03.2004 by vladest cnt &= ~(ICH_ACLINK | ICH_PCM_246_MASK);
2286 // FIXME!!! cmi drivers didnt uses ICH_PCM_246_MASK
2287 /* finish cold or do warm reset */
2288#ifdef DEBUG
2289 dprintf(("ICH chip init try to wake up ACLink with %x",cnt));
2290#endif
2291 iputdword(chip, ICHREG(GLOB_CNT), cnt);
2292// mdelay(500); //vladest 06.10.2003 15:08
2293 end_time = (jiffies + (HZ / 4)) + 1;
2294 i = 0;
2295 do {
2296 cnt=igetdword(chip, ICHREG(GLOB_CNT));
2297 if ((cnt & ICH_AC97WARM) == 0)
2298 goto __ok;
2299#ifdef DEBUG
2300 dprintf(("ICH chip init ACLink ON. try no %d got %x",i,cnt));
2301#endif
2302 do_delay(chip);
2303 i++;
2304 } while (i<100); //(time_after_eq(end_time, jiffies));
2305 snd_printk("AC'97 warm reset still in progress? [0x%x]\n", igetdword(chip, ICHREG(GLOB_CNT)));
2306 return -EIO;
2307__ok:
2308#ifdef DEBUG
2309 dprintf(("ICH chip init ACLink ON"));
2310#endif
2311
2312// mdelay(50);
2313
2314 if (probing) {
2315 /* wait for any codec ready status.
2316 * Once it becomes ready it should remain ready
2317 * as long as we do not disable the ac97 link.
2318 */
2319 end_time = jiffies + HZ;
2320 i = 0;
2321 do {
2322 status = igetdword(chip, ICHREG(GLOB_STA)) & (ICH_PCR | ICH_SCR | ICH_TCR);
2323 if (status)
2324 break;
2325 mdelay(1);
2326 //do_delay(chip);
2327 i++;
2328 } while (i<100);/*(time_after_eq(end_time, jiffies));*/
2329
2330 if (! status) {
2331 /* no codec is found */
2332 snd_printk(KERN_ERR "codec_ready: codec is not ready [0x%x]\n", igetdword(chip, ICHREG(GLOB_STA)));
2333 return -EIO;
2334 }
2335#ifdef DEBUG
2336 dprintf(("ICH chip init codec ready"));
2337#endif
2338// mdelay(50);
2339
2340 if (chip->device_type == DEVICE_INTEL_ICH4 ||
2341 chip->device_type == DEVICE_INTEL_ICH5)
2342 /* ICH4 can have three codecs */
2343 nstatus = ICH_PCR | ICH_SCR | ICH_TCR;
2344 else
2345 /* others up to two codecs */
2346 nstatus = ICH_PCR | ICH_SCR;
2347 /* wait for other codecs ready status. */
2348 end_time = jiffies + HZ / 4;
2349 while (status != nstatus && time_after_eq(end_time, jiffies)) {
2350 do_delay(chip);
2351 status |= igetdword(chip, ICHREG(GLOB_STA)) & nstatus;
2352 }
2353 } else {
2354 /* resume phase */
2355 int i;
2356 status = 0;
2357 for (i = 0; i < 3; i++)
2358 if (chip->ac97[i])
2359 status |= get_ich_codec_bit(chip, i);
2360 /* wait until all the probed codecs are ready */
2361 end_time = jiffies + HZ;
2362 do {
2363 nstatus = igetdword(chip, ICHREG(GLOB_STA)) & (ICH_PCR | ICH_SCR | ICH_TCR);
2364 if (status == nstatus)
2365 break;
2366 do_delay(chip);
2367 } while (time_after_eq(end_time, jiffies));
2368 }
2369
2370 if (chip->device_type == DEVICE_SIS) {
2371 /* unmute the output on SIS7012 */
2372 iputword(chip, 0x4c, igetword(chip, 0x4c) | 1);
2373 }
2374 if (chip->device_type == DEVICE_NFORCE) {
2375 /* enable SPDIF interrupt */
2376 unsigned int val;
2377 pci_read_config_dword(chip->pci, 0x4c, &val);
2378 val |= 0x1000000;
2379 pci_write_config_dword(chip->pci, 0x4c, val);
2380 }
2381#ifdef DEBUG
2382 dprintf(("ICH chip init finished"));
2383#endif
2384
2385 return 0;
2386}
2387
2388static int snd_intel8x0_ali_chip_init(struct intel8x0 *chip, int probing)
2389{
2390 u32 reg;
2391 int i = 0;
2392
2393 reg = igetdword(chip, ICHREG(ALI_SCR));
2394 if ((reg & 2) == 0) /* Cold required */
2395 reg |= 2;
2396 else
2397 reg |= 1; /* Warm */
2398 reg &= ~0x80000000; /* ACLink on */
2399 iputdword(chip, ICHREG(ALI_SCR), reg);
2400
2401 for (i = 0; i < HZ / 2; i++) {
2402 if (! (igetdword(chip, ICHREG(ALI_INTERRUPTSR)) & ALI_INT_GPIO))
2403 goto __ok;
2404 do_delay(chip);
2405 }
2406 snd_printk(KERN_ERR "AC'97 reset failed.\n");
2407 if (probing)
2408 return -EIO;
2409
2410 __ok:
2411 for (i = 0; i < HZ / 2; i++) {
2412 reg = igetdword(chip, ICHREG(ALI_RTSR));
2413 if (reg & 0x80) /* primary codec */
2414 break;
2415 iputdword(chip, ICHREG(ALI_RTSR), reg | 0x80);
2416 do_delay(chip);
2417 }
2418
2419 do_ali_reset(chip);
2420 return 0;
2421}
2422
2423static int snd_intel8x0_chip_init(struct intel8x0 *chip, int probing)
2424{
2425 unsigned int i;
2426 int err;
2427
2428 if (chip->device_type != DEVICE_ALI) {
2429 if ((err = snd_intel8x0_ich_chip_init(chip, probing)) < 0)
2430 return err;
2431 iagetword(chip, 0); /* clear semaphore flag */
2432 } else {
2433 if ((err = snd_intel8x0_ali_chip_init(chip, probing)) < 0)
2434 return err;
2435 }
2436
2437 /* disable interrupts */
2438 for (i = 0; i < chip->bdbars_count; i++)
2439 iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, 0x00);
2440 /* reset channels */
2441 for (i = 0; i < chip->bdbars_count; i++)
2442 iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS);
2443 /* initialize Buffer Descriptor Lists */
2444 for (i = 0; i < chip->bdbars_count; i++)
2445 iputdword(chip, ICH_REG_OFF_BDBAR + chip->ichd[i].reg_offset, chip->ichd[i].bdbar_addr);
2446 return 0;
2447}
2448
2449static int snd_intel8x0_free(struct intel8x0 *chip)
2450{
2451 unsigned int i;
2452
2453 if (chip->irq < 0)
2454 goto __hw_end;
2455 /* disable interrupts */
2456 for (i = 0; i < chip->bdbars_count; i++)
2457 iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, 0x00);
2458 /* reset channels */
2459 for (i = 0; i < chip->bdbars_count; i++)
2460 iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS);
2461 if (chip->device_type == DEVICE_NFORCE) {
2462 /* stop the spdif interrupt */
2463 unsigned int val;
2464 pci_read_config_dword(chip->pci, 0x4c, &val);
2465 val &= ~0x1000000;
2466 pci_write_config_dword(chip->pci, 0x4c, val);
2467 }
2468 /* --- */
2469 synchronize_irq(chip->irq);
2470__hw_end:
2471 if (chip->irq >= 0)
2472 free_irq(chip->irq, (void *)chip);
2473 if (chip->bdbars.area)
2474 snd_dma_free_pages(&chip->bdbars);
2475 if (chip->remap_addr)
2476 iounmap((void *) chip->remap_addr);
2477 if (chip->remap_bmaddr)
2478 iounmap((void *) chip->remap_bmaddr);
2479 pci_release_regions(chip->pci);
2480 kfree(chip);
2481 return 0;
2482}
2483
2484#ifdef CONFIG_PM
2485/*
2486 * power management
2487 */
2488static int intel8x0_suspend(struct pci_dev *pci, pm_message_t state)
2489{
2490 struct snd_card *card = pci_get_drvdata(pci);
2491 struct intel8x0 *chip = card->private_data;
2492 int i;
2493
2494 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2495
2496 for (i = 0; i < chip->pcm_devs; i++)
2497 snd_pcm_suspend_all(chip->pcm[i]);
2498
2499 for (i = 0; i < 3; i++)
2500 snd_ac97_suspend(chip->ac97[i]);
2501 if (chip->device_type == DEVICE_INTEL_ICH4 ||
2502 chip->device_type == DEVICE_INTEL_ICH5)
2503 chip->sdm_saved = igetbyte(chip, ICHREG(SDM));
2504
2505 if (chip->irq >= 0)
2506 free_irq(chip->irq, (void *)chip);
2507 pci_disable_device(pci);
2508 pci_save_state(pci);
2509 return 0;
2510}
2511
2512static int intel8x0_resume(struct pci_dev *pci)
2513{
2514 struct snd_card *card = pci_get_drvdata(pci);
2515 struct intel8x0 *chip = card->private_data;
2516 int i;
2517
2518 pci_restore_state(pci);
2519 pci_enable_device(pci);
2520 pci_set_master(pci);
2521 request_irq(pci->irq, snd_intel8x0_interrupt, SA_INTERRUPT|SA_SHIRQ,
2522 card->shortname, (void *)chip);
2523 chip->irq = pci->irq;
2524 synchronize_irq(chip->irq);
2525 snd_intel8x0_chip_init(chip, 1);
2526 /* re-initialize mixer stuff */
2527 if (chip->device_type == DEVICE_INTEL_ICH4 ||
2528 chip->device_type == DEVICE_INTEL_ICH5) {
2529 /* enable separate SDINs for ICH4 */
2530 iputbyte(chip, ICHREG(SDM), chip->sdm_saved);
2531 /* use slot 10/11 for SPDIF */
2532 iputdword(chip, ICHREG(GLOB_CNT),
2533 (igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_PCM_SPDIF_MASK) |
2534 ICH_PCM_SPDIF_1011);
2535 }
2536
2537 for (i = 0; i < 3; i++)
2538 snd_ac97_resume(chip->ac97[i]);
2539 /* resume status */
2540 for (i = 0; i < chip->bdbars_count; i++) {
2541 struct ichdev *ichdev = &chip->ichd[i];
2542 unsigned long port = ichdev->reg_offset;
2543 if (! ichdev->substream || ! ichdev->suspended)
2544 continue;
2545 if (ichdev->ichd == ICHD_PCMOUT)
2546 snd_intel8x0_setup_pcm_out(chip, ichdev->substream->runtime);
2547 iputdword(chip, port + ICH_REG_OFF_BDBAR, ichdev->bdbar_addr);
2548 iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi);
2549 iputbyte(chip, port + ICH_REG_OFF_CIV, ichdev->civ);
2550 iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI);
2551 }
2552 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2553 return 0;
2554}
2555
2556#endif /* CONFIG_PM */
2557
2558#define INTEL8X0_TESTBUF_SIZE 32768 /* enough large for one shot */
2559
2560static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip)
2561{
2562 snd_pcm_substream_t *subs;
2563 struct ichdev *ichdev;
2564 unsigned long port;
2565 unsigned long pos, t;
2566 struct timeval start_time, stop_time;
2567
2568 if (chip->ac97_bus->clock != 48000)
2569 return; /* specified in module option */
2570
2571 subs = chip->pcm[0]->streams[0].substream;
2572 if (! subs || subs->dma_buffer.bytes < INTEL8X0_TESTBUF_SIZE) {
2573 snd_printk("no playback buffer allocated - aborting measure ac97 clock\n");
2574 return;
2575 }
2576 ichdev = &chip->ichd[ICHD_PCMOUT];
2577 ichdev->physbuf = subs->dma_buffer.addr;
2578 ichdev->size = chip->ichd[ICHD_PCMOUT].fragsize = INTEL8X0_TESTBUF_SIZE;
2579 ichdev->substream = NULL; /* don't process interrupts */
2580
2581 /* set rate */
2582 if (snd_ac97_set_rate(chip->ac97[0], AC97_PCM_FRONT_DAC_RATE, 48000) < 0) {
2583 snd_printk(KERN_ERR "cannot set ac97 rate: clock = %d\n", chip->ac97_bus->clock);
2584 return;
2585 }
2586 snd_intel8x0_setup_periods(chip, ichdev);
2587 port = ichdev->reg_offset;
2588 spin_lock_irq(&chip->reg_lock);
2589 /* trigger */
2590 if (chip->device_type != DEVICE_ALI)
2591 iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE | ICH_STARTBM);
2592 else {
2593 iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE);
2594 iputdword(chip, ICHREG(ALI_DMACR), 1 << ichdev->ali_slot);
2595 }
2596 do_gettimeofday(&start_time);
2597 spin_unlock_irq(&chip->reg_lock);
2598 mdelay(50);
2599
2600 spin_lock_irq(&chip->reg_lock);
2601 /* check the position */
2602 pos = ichdev->fragsize1;
2603 pos -= igetword(chip, ichdev->reg_offset + ichdev->roff_picb) << ichdev->pos_shift;
2604 pos += ichdev->position;
2605 do_gettimeofday(&stop_time);
2606 /* stop */
2607 if (chip->device_type == DEVICE_ALI) {
2608 iputdword(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 16));
2609 iputbyte(chip, port + ICH_REG_OFF_CR, 0);
2610 while (igetbyte(chip, port + ICH_REG_OFF_CR))
2611 ;
2612 } else {
2613 iputbyte(chip, port + ICH_REG_OFF_CR, 0);
2614 while (!(igetbyte(chip, port + ichdev->roff_sr) & ICH_DCH))
2615 ;
2616 }
2617 iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS);
2618 spin_unlock_irq(&chip->reg_lock);
2619
2620 t = stop_time.tv_sec - start_time.tv_sec;
2621 t *= 1000000;
2622 t += stop_time.tv_usec - start_time.tv_usec;
2623 printk(KERN_INFO "%s: measured %lu usecs\n", __FUNCTION__, t);
2624 if (t == 0) {
2625 snd_printk(KERN_ERR "?? calculation error..\n");
2626 return;
2627 }
2628 pos = (pos / 4) * 1000;
2629 pos = (pos / t) * 1000 + ((pos % t) * 1000) / t;
2630 if (pos < 40000 || pos >= 60000)
2631 /* abnormal value. hw problem? */
2632 printk(KERN_INFO "intel8x0: measured clock %ld rejected\n", pos);
2633 else if (pos < 47500 || pos > 48500)
2634 /* not 48000Hz, tuning the clock.. */
2635 chip->ac97_bus->clock = (chip->ac97_bus->clock * 48000) / pos;
2636 printk(KERN_INFO "intel8x0: clocking to %d\n", chip->ac97_bus->clock);
2637}
2638
2639#ifdef CONFIG_PROC_FS
2640static void snd_intel8x0_proc_read(snd_info_entry_t * entry,
2641 snd_info_buffer_t * buffer)
2642{
2643 struct intel8x0 *chip = entry->private_data;
2644 unsigned int tmp;
2645
2646 snd_iprintf(buffer, "Intel8x0\n\n");
2647 if (chip->device_type == DEVICE_ALI)
2648 return;
2649 tmp = igetdword(chip, ICHREG(GLOB_STA));
2650 snd_iprintf(buffer, "Global control : 0x%08x\n", igetdword(chip, ICHREG(GLOB_CNT)));
2651 snd_iprintf(buffer, "Global status : 0x%08x\n", tmp);
2652 if (chip->device_type == DEVICE_INTEL_ICH4 ||
2653 chip->device_type == DEVICE_INTEL_ICH5)
2654 snd_iprintf(buffer, "SDM : 0x%08x\n", igetdword(chip, ICHREG(SDM)));
2655 snd_iprintf(buffer, "AC'97 codecs ready :%s%s%s%s\n",
2656 tmp & ICH_PCR ? " primary" : "",
2657 tmp & ICH_SCR ? " secondary" : "",
2658 tmp & ICH_TCR ? " tertiary" : "",
2659 (tmp & (ICH_PCR | ICH_SCR | ICH_TCR)) == 0 ? " none" : "");
2660 if (chip->device_type == DEVICE_INTEL_ICH4 ||
2661 chip->device_type == DEVICE_INTEL_ICH5)
2662 snd_iprintf(buffer, "AC'97 codecs SDIN : %i %i %i\n",
2663 chip->ac97_sdin[0],
2664 chip->ac97_sdin[1],
2665 chip->ac97_sdin[2]);
2666}
2667
2668static void __devinit snd_intel8x0_proc_init(struct intel8x0 * chip)
2669{
2670 snd_info_entry_t *entry;
2671
2672 if (! snd_card_proc_new(chip->card, "intel8x0", &entry))
2673 snd_info_set_text_ops(entry, chip, 1024, snd_intel8x0_proc_read);
2674}
2675#else
2676#define snd_intel8x0_proc_init(x)
2677#endif
2678
2679static int snd_intel8x0_dev_free(snd_device_t *device)
2680{
2681 struct intel8x0 *chip = device->device_data;
2682 return snd_intel8x0_free(chip);
2683}
2684
2685struct ich_reg_info {
2686 unsigned int int_sta_mask;
2687 unsigned int offset;
2688};
2689
2690
2691static int __devinit snd_intel8x0_create(snd_card_t * card,
2692 struct pci_dev *pci,
2693 unsigned long device_type,
2694 struct intel8x0 ** r_intel8x0)
2695{
2696 struct intel8x0 *chip;
2697 int err;
2698 unsigned int i,pci_dword;
2699 unsigned int int_sta_masks;
2700 unsigned short pci_word;
2701 unsigned char pci_byte;
2702
2703 struct ichdev *ichdev;
2704#ifdef TARGET_OS2
2705 static snd_device_ops_t ops = {
2706 snd_intel8x0_dev_free,0,0,0
2707 };
2708#else
2709 static snd_device_ops_t ops = {
2710 .dev_free = snd_intel8x0_dev_free,
2711 };
2712#endif
2713 static unsigned int bdbars[] = {
2714 3, /* DEVICE_INTEL */
2715 6, /* DEVICE_INTEL_ICH4 */
2716 6, /* DEVICE_INTEL_ICH5 */
2717 3, /* DEVICE_SIS */
2718 6, /* DEVICE_ALI */
2719 4, /* DEVICE_NFORCE */
2720 };
2721 static struct ich_reg_info intel_regs[6] = {
2722 { ICH_PIINT, 0 },
2723 { ICH_POINT, 0x10 },
2724 { ICH_MCINT, 0x20 },
2725 { ICH_M2INT, 0x40 },
2726 { ICH_P2INT, 0x50 },
2727 { ICH_SPINT, 0x60 },
2728 };
2729 static struct ich_reg_info nforce_regs[4] = {
2730 { ICH_PIINT, 0 },
2731 { ICH_POINT, 0x10 },
2732 { ICH_MCINT, 0x20 },
2733 { ICH_NVSPINT, 0x70 },
2734 };
2735 static struct ich_reg_info ali_regs[6] = {
2736 { ALI_INT_PCMIN, 0x40 },
2737 { ALI_INT_PCMOUT, 0x50 },
2738 { ALI_INT_MICIN, 0x60 },
2739 { ALI_INT_CODECSPDIFOUT, 0x70 },
2740 { ALI_INT_SPDIFIN, 0xa0 },
2741 { ALI_INT_SPDIFOUT, 0xb0 },
2742 };
2743 struct ich_reg_info *tbl;
2744
2745 *r_intel8x0 = NULL;
2746
2747 if ((err = pci_enable_device(pci)) < 0)
2748 return err;
2749 pci_set_master(pci);
2750
2751// pci_write_config_byte(pci, 0x40, 0xff); // added by vladest
2752
2753 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
2754 if (chip == NULL)
2755 return -ENOMEM;
2756 spin_lock_init(&chip->reg_lock);
2757 chip->device_type = device_type;
2758 chip->card = card;
2759 chip->pci = pci;
2760 chip->irq = -1;
2761 if ((err = pci_request_regions(pci, card->shortname)) < 0) {
2762 kfree(chip);
2763 return err;
2764 }
2765 if (device_type == DEVICE_ALI) {
2766 /* ALI5455 has no ac97 region */
2767 chip->bmaddr = pci_resource_start(pci, 0);
2768 goto port_inited;
2769 }
2770 /*
2771 ¥áâì €¢  ­î ­á .  €® ᬮâà¥âì. ¥à¢®¥: pci_cfg_space 54h,
2772 €¢  ¬« €èšå ¡šâ  㪠§ë¢ îâ á®áâ®ï­š¥ 皯 . ¥á«š â ¬ 11, â®
2773 ªà®¬¥ ª®­äš£á¯¥©á  ¡®«ìè¥ ­š å७  ­¥ à ¡®â ¥â.
2774 ’〠 ­ €® § ¯šá âì 00.
2775 ‚â®à®¥: ॣšáâà PCICMD, íâ® 16-¡šâ­ë© ॣšáâà ¯® ᬥ饭šî 04h
2776 ¢ cfg_space. šâ 1 ¢ëáâ ¢šâì ¢ 1
2777 */
2778#if 1
2779 if (chip->device_type == DEVICE_INTEL_ICH5 ||
2780 chip->device_type == DEVICE_INTEL_ICH4)
2781 {
2782 pci_read_config_dword(pci, 0x40, &pci_dword);
2783 printk("acpi_base %x\n", pci_dword);
2784 pci_read_config_byte(pci, 0x44, &pci_byte);
2785 printk("acpi_cntl %i\n", pci_byte);
2786// pci_write_config_byte(pci, 0x44, pci_byte & ~(0x10));
2787 pci_read_config_word(pci, 0x54, &pci_word);
2788// pci_write_config_word(pci, 0x54, pci_word & ~(0x3));
2789
2790 pci_read_config_word(pci, PCI_COMMAND, &pci_word);
2791// pci_write_config_word(pci, PCI_COMMAND, pci_word | (PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
2792
2793 pci_read_config_byte(pci, 0x55, &pci_byte);
2794 printk("pci config at 0x55 %i\n", pci_byte);
2795
2796 pci_write_config_byte(pci, 0x55, 0x01);
2797 }
2798#endif
2799 // make sure that pci allow mmio operations
2800
2801 if (pci_resource_flags(pci, /*2*/0) & IORESOURCE_MEM) { /* ICH4 and Nforce */
2802 chip->mmio = 1;
2803 chip->addr = pci_resource_start(pci, /*2*/0);
2804 chip->remap_addr = (unsigned long)
2805 ioremap_nocache(chip->addr, pci_resource_len(pci, /*2*/0));
2806 if (chip->remap_addr == 0) {
2807 snd_printk("AC'97 space ioremap problem\n");
2808 snd_intel8x0_free(chip);
2809 return -EIO;
2810 }
2811 printk("ioremap %x len %i remap addr: %x\n",
2812 chip->addr, pci_resource_len(pci, /*2*/0), chip->remap_addr);
2813 }
2814 else if (pci_resource_flags(pci, 2) & IORESOURCE_MEM) { /* ICH4 and Nforce */
2815 chip->mmio = 1;
2816 chip->addr = pci_resource_start(pci, 2);
2817 chip->remap_addr = (unsigned long)
2818 ioremap_nocache(chip->addr, pci_resource_len(pci, 2));
2819 if (chip->remap_addr == 0) {
2820 snd_printk("AC'97 space ioremap problem\n");
2821 snd_intel8x0_free(chip);
2822 return -EIO;
2823 }
2824 printk("ioremap %x len %i remap addr: %x\n",
2825 chip->addr, pci_resource_len(pci, 2), chip->remap_addr);
2826 } else {
2827 chip->addr = pci_resource_start(pci, 0);
2828 }
2829
2830 if (pci_resource_flags(pci, /*3*/1) & IORESOURCE_MEM) { /* ICH4 */
2831 chip->bm_mmio = 1;
2832 chip->bmaddr = pci_resource_start(pci, /*3*/1);
2833 chip->remap_bmaddr = (unsigned long)
2834 ioremap_nocache(chip->bmaddr, pci_resource_len(pci, /*3*/1));
2835 if (chip->remap_bmaddr == 0) {
2836 snd_printk("Controller space ioremap problem\n");
2837 snd_intel8x0_free(chip);
2838 return -EIO;
2839 }
2840 printk("ioremap bm %x len %i remap addr: %x\n",
2841 chip->bmaddr, pci_resource_len(pci, /*3*/1), chip->remap_bmaddr);
2842 }
2843 else if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) { /* ICH4 */
2844 chip->bm_mmio = 1;
2845 chip->bmaddr = pci_resource_start(pci, 3);
2846 chip->remap_bmaddr = (unsigned long)
2847 ioremap_nocache(chip->bmaddr, pci_resource_len(pci, 3));
2848 if (chip->remap_bmaddr == 0) {
2849 snd_printk("Controller space ioremap problem\n");
2850 snd_intel8x0_free(chip);
2851 return -EIO;
2852 }
2853 printk("ioremap bm %x len %i remap addr: %x\n",
2854 chip->bmaddr, pci_resource_len(pci, 3), chip->remap_bmaddr);
2855 } else {
2856 chip->bmaddr = pci_resource_start(pci, 1);
2857 }
2858
2859port_inited:
2860 chip->bdbars_count = bdbars[device_type];
2861
2862 /* initialize offsets */
2863 switch (device_type) {
2864 case DEVICE_NFORCE:
2865 tbl = nforce_regs;
2866 break;
2867 case DEVICE_ALI:
2868 tbl = ali_regs;
2869 break;
2870 default:
2871 tbl = intel_regs;
2872 break;
2873 }
2874 for (i = 0; i < chip->bdbars_count; i++) {
2875 ichdev = &chip->ichd[i];
2876 ichdev->ichd = i;
2877 ichdev->reg_offset = tbl[i].offset;
2878 ichdev->int_sta_mask = tbl[i].int_sta_mask;
2879 if (device_type == DEVICE_SIS) {
2880 /* SiS 7012 swaps the registers */
2881 ichdev->roff_sr = ICH_REG_OFF_PICB;
2882 ichdev->roff_picb = ICH_REG_OFF_SR;
2883 } else {
2884 ichdev->roff_sr = ICH_REG_OFF_SR;
2885 ichdev->roff_picb = ICH_REG_OFF_PICB;
2886 }
2887 if (device_type == DEVICE_ALI)
2888 ichdev->ali_slot = (ichdev->reg_offset - 0x40) / 0x10;
2889 /* SIS7012 handles the pcm data in bytes, others are in samples */
2890 ichdev->pos_shift = (device_type == DEVICE_SIS) ? 0 : 1;
2891 }
2892
2893 /* allocate buffer descriptor lists */
2894 /* the start of each lists must be aligned to 8 bytes */
2895 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
2896 chip->bdbars_count * sizeof(u32) * ICH_MAX_FRAGS * 2,
2897 &chip->bdbars) < 0) {
2898 snd_intel8x0_free(chip);
2899 snd_printk(KERN_ERR "intel8x0: cannot allocate buffer descriptors\n");
2900 return -ENOMEM;
2901 }
2902 /* tables must be aligned to 8 bytes here, but the kernel pages
2903 are much bigger, so we don't care (on i386) */
2904
2905 int_sta_masks = 0;
2906 for (i = 0; i < chip->bdbars_count; i++) {
2907 ichdev = &chip->ichd[i];
2908 ichdev->bdbar = ((u32 *)chip->bdbars.area) +
2909 (i * ICH_MAX_FRAGS * 2);
2910 ichdev->bdbar_addr = chip->bdbars.addr +
2911 (i * sizeof(u32) * ICH_MAX_FRAGS * 2);
2912 int_sta_masks |= ichdev->int_sta_mask;
2913 }
2914 chip->int_sta_reg = device_type == DEVICE_ALI ?
2915 ICH_REG_ALI_INTERRUPTSR : ICH_REG_GLOB_STA;
2916 chip->int_sta_mask = int_sta_masks;
2917
2918 /* request irq after initializaing int_sta_mask, etc */
2919 if (request_irq(pci->irq, snd_intel8x0_interrupt,
2920 SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
2921 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
2922 snd_intel8x0_free(chip);
2923 return -EBUSY;
2924 }
2925 chip->irq = pci->irq;
2926 pci_set_master(pci);
2927 synchronize_irq(chip->irq);
2928
2929 if ((err = snd_intel8x0_chip_init(chip, 1)) < 0) {
2930 snd_intel8x0_free(chip);
2931 return err;
2932 }
2933
2934 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
2935 snd_intel8x0_free(chip);
2936 return err;
2937 }
2938
2939 *r_intel8x0 = chip;
2940 return 0;
2941}
2942
2943static struct shortname_table {
2944 unsigned int id;
2945 const char *s;
2946} shortnames[] __devinitdata = {
2947 { PCI_DEVICE_ID_INTEL_82801, "Intel 82801AA-ICH" },
2948 { PCI_DEVICE_ID_INTEL_82901, "Intel 82901AB-ICH0" },
2949 { PCI_DEVICE_ID_INTEL_82801BA, "Intel 82801BA-ICH2" },
2950 { PCI_DEVICE_ID_INTEL_440MX, "Intel 440MX" },
2951 { PCI_DEVICE_ID_INTEL_ICH3, "Intel 82801CA-ICH3" },
2952 { PCI_DEVICE_ID_INTEL_ICH4, "Intel 82801DB-ICH4" },
2953 { PCI_DEVICE_ID_INTEL_ICH5, "Intel ICH5" },
2954 { PCI_DEVICE_ID_INTEL_ESB_5, "Intel ICH 6300ESB" },
2955 { PCI_DEVICE_ID_INTEL_ICH6_18, "Intel ICH6" },
2956 { PCI_DEVICE_ID_INTEL_ICH7_20, "Intel ICH7" },
2957 { PCI_DEVICE_ID_INTEL_ESB2_14, "Intel ESB2" },
2958 { PCI_DEVICE_ID_SI_7012, "SiS SI7012" },
2959 { PCI_DEVICE_ID_NVIDIA_MCP_AUDIO, "NVidia nForce" },
2960 { PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO, "NVidia nForce2" },
2961 { PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO, "NVidia nForce3" },
2962 { PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO, "NVidia CK8S" },
2963 { PCI_DEVICE_ID_NVIDIA_CK804_AUDIO, "NVidia CK804" },
2964 { PCI_DEVICE_ID_NVIDIA_CK8_AUDIO, "NVidia CK8" },
2965 { 0x003a, "NVidia MCP04" },
2966 { 0x746d, "AMD AMD8111" },
2967 { 0x7445, "AMD AMD768" },
2968 { 0x5455, "ALi M5455" },
2969 { 0, 0 },
2970};
2971
2972static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
2973 const struct pci_device_id *pci_id)
2974{
2975 static int dev;
2976 snd_card_t *card;
2977 struct intel8x0 *chip;
2978 int err;
2979 struct shortname_table *name;
2980
2981 if (dev >= SNDRV_CARDS)
2982 return -ENODEV;
2983 if (!enable[dev]) {
2984 dev++;
2985 return -ENOENT;
2986 }
2987
2988 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
2989 if (card == NULL)
2990 return -ENOMEM;
2991 switch (pci_id->driver_data) {
2992 case DEVICE_NFORCE:
2993 strcpy(card->driver, "NFORCE");
2994 break;
2995 case DEVICE_INTEL_ICH4:
2996 strcpy(card->driver, "ICH4");
2997 break;
2998 case DEVICE_INTEL_ICH5:
2999 strcpy(card->driver, "ICH5");
3000 break;
3001 default:
3002 strcpy(card->driver, "ICH");
3003 break;
3004 }
3005
3006 strcpy(card->shortname, "Intel ICH");
3007 for (name = shortnames; name->id; name++) {
3008 if (pci->device == name->id) {
3009 strcpy(card->shortname, name->s);
3010 break;
3011 }
3012 }
3013 // card->dev = &pci->dev;
3014 if (buggy_irq < 0) {
3015 /* some Nforce[2] and ICH boards have problems with IRQ handling.
3016 * Needs to return IRQ_HANDLED for unknown irqs.
3017 */
3018 if (pci_id->driver_data == DEVICE_NFORCE)
3019 buggy_irq = 1;
3020 else
3021 buggy_irq = 0;
3022 }
3023
3024 if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data, &chip)) < 0) {
3025 snd_card_free(card);
3026 printk(KERN_ERR "ICH: create error. err = %x\n",err);
3027 return err;
3028 }
3029
3030 card->private_data = chip;
3031
3032 if ((err = snd_intel8x0_mixer(chip, ac97_clock[dev], ac97_quirk[dev])) < 0){
3033 snd_card_free(card);
3034 // printk(KERN_ERR "ICH: mixer error. err = %x\n",err);
3035 return err;
3036 }
3037 if ((err = snd_intel8x0_pcm(chip)) < 0) {
3038 snd_card_free(card);
3039 printk(KERN_ERR "ICH: pcm error. err = %x\n",err);
3040 return err;
3041 }
3042
3043 if (mpu_port[dev] == 0x300 || mpu_port[dev] == 0x330) {
3044 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_INTEL8X0,
3045 mpu_port[dev], 0,
3046 -1, 0, &chip->rmidi)) < 0) {
3047 printk(KERN_ERR "intel8x0: no UART401 device at 0x%x, skipping.\n", mpu_port[dev]);
3048 mpu_port[dev] = 0;
3049 }
3050 } else
3051 mpu_port[dev] = 0;
3052
3053 snd_intel8x0_proc_init(chip);
3054
3055 sprintf(card->longname, "%s at 0x%lx, irq %i",
3056 card->shortname, chip->addr, chip->irq);
3057
3058 if (! ac97_clock[dev])
3059 intel8x0_measure_ac97_clock(chip);
3060
3061 if ((err = snd_card_register(card)) < 0) {
3062 snd_card_free(card);
3063 printk(KERN_ERR "ICH: card register error. err = %x\n",err);
3064 return err;
3065 }
3066 pci_set_drvdata(pci, card);
3067 dev++;
3068 return 0;
3069}
3070
3071static void __devexit snd_intel8x0_remove(struct pci_dev *pci)
3072{
3073 snd_card_free(pci_get_drvdata(pci));
3074 pci_set_drvdata(pci, NULL);
3075}
3076
3077static struct pci_driver driver = {
3078 .name = "Intel ICH",
3079 .id_table = snd_intel8x0_ids,
3080 .probe = snd_intel8x0_probe,
3081 .remove = snd_intel8x0_remove,
3082#ifdef CONFIG_PM
3083 .suspend = intel8x0_suspend,
3084 .resume = intel8x0_resume,
3085#endif
3086};
3087
3088#if defined(SUPPORT_JOYSTICK) || defined(SUPPORT_MIDI)
3089/*
3090 * initialize joystick/midi addresses
3091 */
3092#ifdef SUPPORT_JOYSTICK
3093/* there is only one available device, so we keep it here */
3094static struct pci_dev *ich_gameport_pci;
3095static struct gameport ich_gameport = { .io = 0x200 };
3096#endif
3097
3098
3099static int __devinit snd_intel8x0_joystick_probe(struct pci_dev *pci,
3100 const struct pci_device_id *id)
3101{
3102 u16 val;
3103 static int dev;
3104 if (dev >= SNDRV_CARDS)
3105 return -ENODEV;
3106 if (!enable[dev]) {
3107 dev++;
3108 return -ENOENT;
3109 }
3110
3111 pci_read_config_word(pci, 0xe6, &val);
3112#ifdef SUPPORT_JOYSTICK
3113 if (joystick[dev]) {
3114 if (! request_region(ich_gameport.io, 8, "ICH gameport")) {
3115 printk(KERN_WARNING "intel8x0: cannot grab gameport 0x%x\n", ich_gameport.io);
3116 joystick[dev] = 0;
3117 } else {
3118 ich_gameport_pci = pci;
3119 gameport_register_port(&ich_gameport);
3120 val |= 0x100;
3121 }
3122 }
3123#endif
3124#ifdef SUPPORT_MIDI
3125 if (mpu_port[dev] > 0) {
3126 if (mpu_port[dev] == 0x300 || mpu_port[dev] == 0x330) {
3127 u8 b;
3128 val |= 0x20;
3129 pci_read_config_byte(pci, 0xe2, &b);
3130 if (mpu_port[dev] == 0x300)
3131 b |= 0x08;
3132 else
3133 b &= ~0x08;
3134 pci_write_config_byte(pci, 0xe2, b);
3135 }
3136 }
3137#endif
3138 pci_write_config_word(pci, 0xe6, val);
3139 return 0;
3140}
3141
3142static void __devexit snd_intel8x0_joystick_remove(struct pci_dev *pci)
3143{
3144 u16 val;
3145#ifdef SUPPORT_JOYSTICK
3146 if (ich_gameport_pci == pci) {
3147 gameport_unregister_port(&ich_gameport);
3148 release_region(ich_gameport.io, 8);
3149 ich_gameport_pci = NULL;
3150 }
3151#endif
3152 /* disable joystick and MIDI */
3153 pci_read_config_word(pci, 0xe6, &val);
3154 val &= ~0x120;
3155 pci_write_config_word(pci, 0xe6, val);
3156}
3157
3158static struct pci_device_id snd_intel8x0_joystick_ids[] = {
3159 { 0x8086, 0x2410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 82801AA */
3160 { 0x8086, 0x2420, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 82901AB */
3161 { 0x8086, 0x2440, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICH2 */
3162 { 0x8086, 0x244c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICH2M */
3163 { 0x8086, 0x248c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICH3 */
3164 // { 0x8086, 0x7195, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 440MX */
3165 // { 0x1039, 0x7012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SI7012 */
3166 { 0x10de, 0x01b2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* NFORCE */
3167 // { 0x10de, 0x006b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* NFORCE2 */
3168 { 0x10de, 0x00db, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* NFORCE3 */
3169 { 0, }
3170};
3171
3172static struct pci_driver joystick_driver = {
3173 0, 0, 0,
3174 /* name: */ "Intel ICH Joystick",
3175 /* id_table: */ snd_intel8x0_joystick_ids,
3176 /* probe: */ snd_intel8x0_joystick_probe,
3177 0,0,0
3178};
3179static int have_joystick;
3180#endif
3181
3182static int __init alsa_card_intel8x0_init(void)
3183{
3184 int err = 0;
3185
3186 // printk(KERN_ERR "alsa_card_intel8x0_init\n");
3187#ifdef TARGET_OS2
3188 if (midi_port > 0) mpu_port[0] = midi_port;
3189#endif
3190
3191 if ((err = pci_module_init(&driver)) < 0) {
3192#ifdef MODULE
3193 // printk(KERN_ERR "Intel ICH soundcard not found or device busy. err = %x\n",err);
3194#endif
3195 return err;
3196 }
3197#if defined(SUPPORT_JOYSTICK) || defined(SUPPORT_MIDI)
3198 if (pci_module_init(&joystick_driver) < 0) {
3199 snd_printdd(KERN_INFO "no joystick found\n");
3200 have_joystick = 0;
3201 } else {
3202 snd_printdd(KERN_INFO "joystick(s) found\n");
3203 have_joystick = 1;
3204 }
3205#endif
3206 return 0;
3207}
3208
3209static void __exit alsa_card_intel8x0_exit(void)
3210{
3211 pci_unregister_driver(&driver);
3212#if defined(SUPPORT_JOYSTICK) || defined(SUPPORT_MIDI)
3213 if (have_joystick)
3214 pci_unregister_driver(&joystick_driver);
3215#endif
3216}
3217
3218module_init(alsa_card_intel8x0_init)
3219module_exit(alsa_card_intel8x0_exit)
3220
3221#ifndef MODULE
3222
3223/* format is: snd-intel8x0=enable,index,id,ac97_clock,mpu_port,joystick */
3224
3225static int __init alsa_card_intel8x0_setup(char *str)
3226{
3227 static unsigned __initdata nr_dev = 0;
3228
3229 if (nr_dev >= SNDRV_CARDS)
3230 return 0;
3231 (void)(get_option(&str,&enable[nr_dev]) == 2 &&
3232 get_option(&str,&index[nr_dev]) == 2 &&
3233 get_id(&str,&id[nr_dev]) == 2 &&
3234 get_option(&str,&ac97_clock[nr_dev]) == 2 &&
3235 get_option(&str,&ac97_quirk[nr_dev]) == 2
3236#ifdef SUPPORT_MIDI
3237 && get_option(&str,&mpu_port[nr_dev]) == 2
3238#endif
3239#ifdef SUPPORT_JOYSTICK
3240 && get_option(&str,&joystick[nr_dev]) == 2
3241#endif
3242 );
3243 nr_dev++;
3244 return 1;
3245}
3246
3247__setup("snd-intel8x0=", alsa_card_intel8x0_setup);
3248
3249#endif /* ifndef MODULE */
Note: See TracBrowser for help on using the repository browser.