[ALSA] highlanderize motherboard AC97/HDA drivers
[safe/jmp/linux-2.6] / sound / pci / via82xx_modem.c
1 /*
2  *   ALSA modem driver for VIA VT82xx (South Bridge)
3  *
4  *   VT82C686A/B/C, VT8233A/C, VT8235
5  *
6  *      Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
7  *                         Tjeerd.Mulder <Tjeerd.Mulder@fujitsu-siemens.com>
8  *                    2002 Takashi Iwai <tiwai@suse.de>
9  *
10  *   This program is free software; you can redistribute it and/or modify
11  *   it under the terms of the GNU General Public License as published by
12  *   the Free Software Foundation; either version 2 of the License, or
13  *   (at your option) any later version.
14  *
15  *   This program is distributed in the hope that it will be useful,
16  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *   GNU General Public License for more details.
19  *
20  *   You should have received a copy of the GNU General Public License
21  *   along with this program; if not, write to the Free Software
22  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23  *
24  */
25
26 /*
27  * Changes:
28  *
29  * Sep. 2,  2004  Sasha Khapyorsky <sashak@smlink.com>
30  *      Modified from original audio driver 'via82xx.c' to support AC97
31  *      modems.
32  */
33
34 #include <sound/driver.h>
35 #include <asm/io.h>
36 #include <linux/delay.h>
37 #include <linux/interrupt.h>
38 #include <linux/init.h>
39 #include <linux/pci.h>
40 #include <linux/slab.h>
41 #include <linux/moduleparam.h>
42 #include <sound/core.h>
43 #include <sound/pcm.h>
44 #include <sound/pcm_params.h>
45 #include <sound/info.h>
46 #include <sound/ac97_codec.h>
47 #include <sound/initval.h>
48
49 #if 0
50 #define POINTER_DEBUG
51 #endif
52
53 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
54 MODULE_DESCRIPTION("VIA VT82xx modem");
55 MODULE_LICENSE("GPL");
56 MODULE_SUPPORTED_DEVICE("{{VIA,VT82C686A/B/C modem,pci}}");
57
58 static int index = -2; /* Exclude the first card */
59 static char *id = SNDRV_DEFAULT_STR1;   /* ID for this card */
60 static int ac97_clock = 48000;
61
62 module_param(index, int, 0444);
63 MODULE_PARM_DESC(index, "Index value for VIA 82xx bridge.");
64 module_param(id, charp, 0444);
65 MODULE_PARM_DESC(id, "ID string for VIA 82xx bridge.");
66 module_param(ac97_clock, int, 0444);
67 MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
68
69
70 /*
71  *  Direct registers
72  */
73
74 #define VIAREG(via, x) ((via)->port + VIA_REG_##x)
75 #define VIADEV_REG(viadev, x) ((viadev)->port + VIA_REG_##x)
76
77 /* common offsets */
78 #define VIA_REG_OFFSET_STATUS           0x00    /* byte - channel status */
79 #define   VIA_REG_STAT_ACTIVE           0x80    /* RO */
80 #define   VIA_REG_STAT_PAUSED           0x40    /* RO */
81 #define   VIA_REG_STAT_TRIGGER_QUEUED   0x08    /* RO */
82 #define   VIA_REG_STAT_STOPPED          0x04    /* RWC */
83 #define   VIA_REG_STAT_EOL              0x02    /* RWC */
84 #define   VIA_REG_STAT_FLAG             0x01    /* RWC */
85 #define VIA_REG_OFFSET_CONTROL          0x01    /* byte - channel control */
86 #define   VIA_REG_CTRL_START            0x80    /* WO */
87 #define   VIA_REG_CTRL_TERMINATE        0x40    /* WO */
88 #define   VIA_REG_CTRL_AUTOSTART        0x20
89 #define   VIA_REG_CTRL_PAUSE            0x08    /* RW */
90 #define   VIA_REG_CTRL_INT_STOP         0x04            
91 #define   VIA_REG_CTRL_INT_EOL          0x02
92 #define   VIA_REG_CTRL_INT_FLAG         0x01
93 #define   VIA_REG_CTRL_RESET            0x01    /* RW - probably reset? undocumented */
94 #define   VIA_REG_CTRL_INT (VIA_REG_CTRL_INT_FLAG | VIA_REG_CTRL_INT_EOL | VIA_REG_CTRL_AUTOSTART)
95 #define VIA_REG_OFFSET_TYPE             0x02    /* byte - channel type (686 only) */
96 #define   VIA_REG_TYPE_AUTOSTART        0x80    /* RW - autostart at EOL */
97 #define   VIA_REG_TYPE_16BIT            0x20    /* RW */
98 #define   VIA_REG_TYPE_STEREO           0x10    /* RW */
99 #define   VIA_REG_TYPE_INT_LLINE        0x00
100 #define   VIA_REG_TYPE_INT_LSAMPLE      0x04
101 #define   VIA_REG_TYPE_INT_LESSONE      0x08
102 #define   VIA_REG_TYPE_INT_MASK         0x0c
103 #define   VIA_REG_TYPE_INT_EOL          0x02
104 #define   VIA_REG_TYPE_INT_FLAG         0x01
105 #define VIA_REG_OFFSET_TABLE_PTR        0x04    /* dword - channel table pointer */
106 #define VIA_REG_OFFSET_CURR_PTR         0x04    /* dword - channel current pointer */
107 #define VIA_REG_OFFSET_STOP_IDX         0x08    /* dword - stop index, channel type, sample rate */
108 #define VIA_REG_OFFSET_CURR_COUNT       0x0c    /* dword - channel current count (24 bit) */
109 #define VIA_REG_OFFSET_CURR_INDEX       0x0f    /* byte - channel current index (for via8233 only) */
110
111 #define DEFINE_VIA_REGSET(name,val) \
112 enum {\
113         VIA_REG_##name##_STATUS         = (val),\
114         VIA_REG_##name##_CONTROL        = (val) + 0x01,\
115         VIA_REG_##name##_TYPE           = (val) + 0x02,\
116         VIA_REG_##name##_TABLE_PTR      = (val) + 0x04,\
117         VIA_REG_##name##_CURR_PTR       = (val) + 0x04,\
118         VIA_REG_##name##_STOP_IDX       = (val) + 0x08,\
119         VIA_REG_##name##_CURR_COUNT     = (val) + 0x0c,\
120 }
121
122 /* modem block */
123 DEFINE_VIA_REGSET(MO, 0x40);
124 DEFINE_VIA_REGSET(MI, 0x50);
125
126 /* AC'97 */
127 #define VIA_REG_AC97                    0x80    /* dword */
128 #define   VIA_REG_AC97_CODEC_ID_MASK    (3<<30)
129 #define   VIA_REG_AC97_CODEC_ID_SHIFT   30
130 #define   VIA_REG_AC97_CODEC_ID_PRIMARY 0x00
131 #define   VIA_REG_AC97_CODEC_ID_SECONDARY 0x01
132 #define   VIA_REG_AC97_SECONDARY_VALID  (1<<27)
133 #define   VIA_REG_AC97_PRIMARY_VALID    (1<<25)
134 #define   VIA_REG_AC97_BUSY             (1<<24)
135 #define   VIA_REG_AC97_READ             (1<<23)
136 #define   VIA_REG_AC97_CMD_SHIFT        16
137 #define   VIA_REG_AC97_CMD_MASK         0x7e
138 #define   VIA_REG_AC97_DATA_SHIFT       0
139 #define   VIA_REG_AC97_DATA_MASK        0xffff
140
141 #define VIA_REG_SGD_SHADOW              0x84    /* dword */
142 #define   VIA_REG_SGD_STAT_PB_FLAG      (1<<0)
143 #define   VIA_REG_SGD_STAT_CP_FLAG      (1<<1)
144 #define   VIA_REG_SGD_STAT_FM_FLAG      (1<<2)
145 #define   VIA_REG_SGD_STAT_PB_EOL       (1<<4)
146 #define   VIA_REG_SGD_STAT_CP_EOL       (1<<5)
147 #define   VIA_REG_SGD_STAT_FM_EOL       (1<<6)
148 #define   VIA_REG_SGD_STAT_PB_STOP      (1<<8)
149 #define   VIA_REG_SGD_STAT_CP_STOP      (1<<9)
150 #define   VIA_REG_SGD_STAT_FM_STOP      (1<<10)
151 #define   VIA_REG_SGD_STAT_PB_ACTIVE    (1<<12)
152 #define   VIA_REG_SGD_STAT_CP_ACTIVE    (1<<13)
153 #define   VIA_REG_SGD_STAT_FM_ACTIVE    (1<<14)
154 #define   VIA_REG_SGD_STAT_MR_FLAG      (1<<16)
155 #define   VIA_REG_SGD_STAT_MW_FLAG      (1<<17)
156 #define   VIA_REG_SGD_STAT_MR_EOL       (1<<20)
157 #define   VIA_REG_SGD_STAT_MW_EOL       (1<<21)
158 #define   VIA_REG_SGD_STAT_MR_STOP      (1<<24)
159 #define   VIA_REG_SGD_STAT_MW_STOP      (1<<25)
160 #define   VIA_REG_SGD_STAT_MR_ACTIVE    (1<<28)
161 #define   VIA_REG_SGD_STAT_MW_ACTIVE    (1<<29)
162
163 #define VIA_REG_GPI_STATUS              0x88
164 #define VIA_REG_GPI_INTR                0x8c
165
166 #define VIA_TBL_BIT_FLAG        0x40000000
167 #define VIA_TBL_BIT_EOL         0x80000000
168
169 /* pci space */
170 #define VIA_ACLINK_STAT         0x40
171 #define  VIA_ACLINK_C11_READY   0x20
172 #define  VIA_ACLINK_C10_READY   0x10
173 #define  VIA_ACLINK_C01_READY   0x04 /* secondary codec ready */
174 #define  VIA_ACLINK_LOWPOWER    0x02 /* low-power state */
175 #define  VIA_ACLINK_C00_READY   0x01 /* primary codec ready */
176 #define VIA_ACLINK_CTRL         0x41
177 #define  VIA_ACLINK_CTRL_ENABLE 0x80 /* 0: disable, 1: enable */
178 #define  VIA_ACLINK_CTRL_RESET  0x40 /* 0: assert, 1: de-assert */
179 #define  VIA_ACLINK_CTRL_SYNC   0x20 /* 0: release SYNC, 1: force SYNC hi */
180 #define  VIA_ACLINK_CTRL_SDO    0x10 /* 0: release SDO, 1: force SDO hi */
181 #define  VIA_ACLINK_CTRL_VRA    0x08 /* 0: disable VRA, 1: enable VRA */
182 #define  VIA_ACLINK_CTRL_PCM    0x04 /* 0: disable PCM, 1: enable PCM */
183 #define  VIA_ACLINK_CTRL_FM     0x02 /* via686 only */
184 #define  VIA_ACLINK_CTRL_SB     0x01 /* via686 only */
185 #define  VIA_ACLINK_CTRL_INIT   (VIA_ACLINK_CTRL_ENABLE|\
186                                  VIA_ACLINK_CTRL_RESET|\
187                                  VIA_ACLINK_CTRL_PCM)
188 #define VIA_FUNC_ENABLE         0x42
189 #define  VIA_FUNC_MIDI_PNP      0x80 /* FIXME: it's 0x40 in the datasheet! */
190 #define  VIA_FUNC_MIDI_IRQMASK  0x40 /* FIXME: not documented! */
191 #define  VIA_FUNC_RX2C_WRITE    0x20
192 #define  VIA_FUNC_SB_FIFO_EMPTY 0x10
193 #define  VIA_FUNC_ENABLE_GAME   0x08
194 #define  VIA_FUNC_ENABLE_FM     0x04
195 #define  VIA_FUNC_ENABLE_MIDI   0x02
196 #define  VIA_FUNC_ENABLE_SB     0x01
197 #define VIA_PNP_CONTROL         0x43
198 #define VIA_MC97_CTRL           0x44
199 #define  VIA_MC97_CTRL_ENABLE   0x80
200 #define  VIA_MC97_CTRL_SECONDARY 0x40
201 #define  VIA_MC97_CTRL_INIT     (VIA_MC97_CTRL_ENABLE|\
202                                  VIA_MC97_CTRL_SECONDARY)
203
204
205 typedef struct _snd_via82xx_modem via82xx_t;
206 typedef struct via_dev viadev_t;
207
208 /*
209  * pcm stream
210  */
211
212 struct snd_via_sg_table {
213         unsigned int offset;
214         unsigned int size;
215 } ;
216
217 #define VIA_TABLE_SIZE  255
218
219 struct via_dev {
220         unsigned int reg_offset;
221         unsigned long port;
222         int direction;  /* playback = 0, capture = 1 */
223         snd_pcm_substream_t *substream;
224         int running;
225         unsigned int tbl_entries; /* # descriptors */
226         struct snd_dma_buffer table;
227         struct snd_via_sg_table *idx_table;
228         /* for recovery from the unexpected pointer */
229         unsigned int lastpos;
230         unsigned int bufsize;
231         unsigned int bufsize2;
232 };
233
234 enum { TYPE_CARD_VIA82XX_MODEM = 1 };
235
236 #define VIA_MAX_MODEM_DEVS      2
237
238 struct _snd_via82xx_modem {
239         int irq;
240
241         unsigned long port;
242
243         unsigned int intr_mask; /* SGD_SHADOW mask to check interrupts */
244
245         struct pci_dev *pci;
246         snd_card_t *card;
247
248         unsigned int num_devs;
249         unsigned int playback_devno, capture_devno;
250         viadev_t devs[VIA_MAX_MODEM_DEVS];
251
252         snd_pcm_t *pcms[2];
253
254         ac97_bus_t *ac97_bus;
255         ac97_t *ac97;
256         unsigned int ac97_clock;
257         unsigned int ac97_secondary;    /* secondary AC'97 codec is present */
258
259         spinlock_t reg_lock;
260         snd_info_entry_t *proc_entry;
261 };
262
263 static struct pci_device_id snd_via82xx_modem_ids[] = {
264         { 0x1106, 0x3068, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA82XX_MODEM, },
265         { 0, }
266 };
267
268 MODULE_DEVICE_TABLE(pci, snd_via82xx_modem_ids);
269
270 /*
271  */
272
273 /*
274  * allocate and initialize the descriptor buffers
275  * periods = number of periods
276  * fragsize = period size in bytes
277  */
278 static int build_via_table(viadev_t *dev, snd_pcm_substream_t *substream,
279                            struct pci_dev *pci,
280                            unsigned int periods, unsigned int fragsize)
281 {
282         unsigned int i, idx, ofs, rest;
283         via82xx_t *chip = snd_pcm_substream_chip(substream);
284         struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
285
286         if (dev->table.area == NULL) {
287                 /* the start of each lists must be aligned to 8 bytes,
288                  * but the kernel pages are much bigger, so we don't care
289                  */
290                 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
291                                         PAGE_ALIGN(VIA_TABLE_SIZE * 2 * 8),
292                                         &dev->table) < 0)
293                         return -ENOMEM;
294         }
295         if (! dev->idx_table) {
296                 dev->idx_table = kmalloc(sizeof(*dev->idx_table) * VIA_TABLE_SIZE, GFP_KERNEL);
297                 if (! dev->idx_table)
298                         return -ENOMEM;
299         }
300
301         /* fill the entries */
302         idx = 0;
303         ofs = 0;
304         for (i = 0; i < periods; i++) {
305                 rest = fragsize;
306                 /* fill descriptors for a period.
307                  * a period can be split to several descriptors if it's
308                  * over page boundary.
309                  */
310                 do {
311                         unsigned int r;
312                         unsigned int flag;
313
314                         if (idx >= VIA_TABLE_SIZE) {
315                                 snd_printk(KERN_ERR "via82xx: too much table size!\n");
316                                 return -EINVAL;
317                         }
318                         ((u32 *)dev->table.area)[idx << 1] = cpu_to_le32((u32)snd_pcm_sgbuf_get_addr(sgbuf, ofs));
319                         r = PAGE_SIZE - (ofs % PAGE_SIZE);
320                         if (rest < r)
321                                 r = rest;
322                         rest -= r;
323                         if (! rest) {
324                                 if (i == periods - 1)
325                                         flag = VIA_TBL_BIT_EOL; /* buffer boundary */
326                                 else
327                                         flag = VIA_TBL_BIT_FLAG; /* period boundary */
328                         } else
329                                 flag = 0; /* period continues to the next */
330                         // printk("via: tbl %d: at %d  size %d (rest %d)\n", idx, ofs, r, rest);
331                         ((u32 *)dev->table.area)[(idx<<1) + 1] = cpu_to_le32(r | flag);
332                         dev->idx_table[idx].offset = ofs;
333                         dev->idx_table[idx].size = r;
334                         ofs += r;
335                         idx++;
336                 } while (rest > 0);
337         }
338         dev->tbl_entries = idx;
339         dev->bufsize = periods * fragsize;
340         dev->bufsize2 = dev->bufsize / 2;
341         return 0;
342 }
343
344
345 static int clean_via_table(viadev_t *dev, snd_pcm_substream_t *substream,
346                            struct pci_dev *pci)
347 {
348         if (dev->table.area) {
349                 snd_dma_free_pages(&dev->table);
350                 dev->table.area = NULL;
351         }
352         kfree(dev->idx_table);
353         dev->idx_table = NULL;
354         return 0;
355 }
356
357 /*
358  *  Basic I/O
359  */
360
361 static inline unsigned int snd_via82xx_codec_xread(via82xx_t *chip)
362 {
363         return inl(VIAREG(chip, AC97));
364 }
365  
366 static inline void snd_via82xx_codec_xwrite(via82xx_t *chip, unsigned int val)
367 {
368         outl(val, VIAREG(chip, AC97));
369 }
370  
371 static int snd_via82xx_codec_ready(via82xx_t *chip, int secondary)
372 {
373         unsigned int timeout = 1000;    /* 1ms */
374         unsigned int val;
375         
376         while (timeout-- > 0) {
377                 udelay(1);
378                 if (!((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY))
379                         return val & 0xffff;
380         }
381         snd_printk(KERN_ERR "codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_via82xx_codec_xread(chip));
382         return -EIO;
383 }
384  
385 static int snd_via82xx_codec_valid(via82xx_t *chip, int secondary)
386 {
387         unsigned int timeout = 1000;    /* 1ms */
388         unsigned int val, val1;
389         unsigned int stat = !secondary ? VIA_REG_AC97_PRIMARY_VALID :
390                                          VIA_REG_AC97_SECONDARY_VALID;
391         
392         while (timeout-- > 0) {
393                 val = snd_via82xx_codec_xread(chip);
394                 val1 = val & (VIA_REG_AC97_BUSY | stat);
395                 if (val1 == stat)
396                         return val & 0xffff;
397                 udelay(1);
398         }
399         return -EIO;
400 }
401  
402 static void snd_via82xx_codec_wait(ac97_t *ac97)
403 {
404         via82xx_t *chip = ac97->private_data;
405         int err;
406         err = snd_via82xx_codec_ready(chip, ac97->num);
407         /* here we need to wait fairly for long time.. */
408         msleep(500);
409 }
410
411 static void snd_via82xx_codec_write(ac97_t *ac97,
412                                     unsigned short reg,
413                                     unsigned short val)
414 {
415         via82xx_t *chip = ac97->private_data;
416         unsigned int xval;
417         if(reg == AC97_GPIO_STATUS) {
418                 outl(val, VIAREG(chip, GPI_STATUS));
419                 return;
420         }       
421         xval = !ac97->num ? VIA_REG_AC97_CODEC_ID_PRIMARY : VIA_REG_AC97_CODEC_ID_SECONDARY;
422         xval <<= VIA_REG_AC97_CODEC_ID_SHIFT;
423         xval |= reg << VIA_REG_AC97_CMD_SHIFT;
424         xval |= val << VIA_REG_AC97_DATA_SHIFT;
425         snd_via82xx_codec_xwrite(chip, xval);
426         snd_via82xx_codec_ready(chip, ac97->num);
427 }
428
429 static unsigned short snd_via82xx_codec_read(ac97_t *ac97, unsigned short reg)
430 {
431         via82xx_t *chip = ac97->private_data;
432         unsigned int xval, val = 0xffff;
433         int again = 0;
434
435         xval = ac97->num << VIA_REG_AC97_CODEC_ID_SHIFT;
436         xval |= ac97->num ? VIA_REG_AC97_SECONDARY_VALID : VIA_REG_AC97_PRIMARY_VALID;
437         xval |= VIA_REG_AC97_READ;
438         xval |= (reg & 0x7f) << VIA_REG_AC97_CMD_SHIFT;
439         while (1) {
440                 if (again++ > 3) {
441                         snd_printk(KERN_ERR "codec_read: codec %i is not valid [0x%x]\n", ac97->num, snd_via82xx_codec_xread(chip));
442                         return 0xffff;
443                 }
444                 snd_via82xx_codec_xwrite(chip, xval);
445                 udelay (20);
446                 if (snd_via82xx_codec_valid(chip, ac97->num) >= 0) {
447                         udelay(25);
448                         val = snd_via82xx_codec_xread(chip);
449                         break;
450                 }
451         }
452         return val & 0xffff;
453 }
454
455 static void snd_via82xx_channel_reset(via82xx_t *chip, viadev_t *viadev)
456 {
457         outb(VIA_REG_CTRL_PAUSE | VIA_REG_CTRL_TERMINATE | VIA_REG_CTRL_RESET,
458              VIADEV_REG(viadev, OFFSET_CONTROL));
459         inb(VIADEV_REG(viadev, OFFSET_CONTROL));
460         udelay(50);
461         /* disable interrupts */
462         outb(0x00, VIADEV_REG(viadev, OFFSET_CONTROL));
463         /* clear interrupts */
464         outb(0x03, VIADEV_REG(viadev, OFFSET_STATUS));
465         outb(0x00, VIADEV_REG(viadev, OFFSET_TYPE)); /* for via686 */
466         // outl(0, VIADEV_REG(viadev, OFFSET_CURR_PTR));
467         viadev->lastpos = 0;
468 }
469
470
471 /*
472  *  Interrupt handler
473  */
474
475 static irqreturn_t snd_via82xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
476 {
477         via82xx_t *chip = dev_id;
478         unsigned int status;
479         unsigned int i;
480
481         status = inl(VIAREG(chip, SGD_SHADOW));
482         if (! (status & chip->intr_mask)) {
483                 return IRQ_NONE;
484         }
485 // _skip_sgd:
486
487         /* check status for each stream */
488         spin_lock(&chip->reg_lock);
489         for (i = 0; i < chip->num_devs; i++) {
490                 viadev_t *viadev = &chip->devs[i];
491                 unsigned char c_status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
492                 c_status &= (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG|VIA_REG_STAT_STOPPED);
493                 if (! c_status)
494                         continue;
495                 if (viadev->substream && viadev->running) {
496                         spin_unlock(&chip->reg_lock);
497                         snd_pcm_period_elapsed(viadev->substream);
498                         spin_lock(&chip->reg_lock);
499                 }
500                 outb(c_status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
501         }
502         spin_unlock(&chip->reg_lock);
503         return IRQ_HANDLED;
504 }
505
506 /*
507  *  PCM callbacks
508  */
509
510 /*
511  * trigger callback
512  */
513 static int snd_via82xx_pcm_trigger(snd_pcm_substream_t * substream, int cmd)
514 {
515         via82xx_t *chip = snd_pcm_substream_chip(substream);
516         viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
517         unsigned char val = 0;
518
519         switch (cmd) {
520         case SNDRV_PCM_TRIGGER_START:
521         case SNDRV_PCM_TRIGGER_SUSPEND:
522                 val |= VIA_REG_CTRL_START;
523                 viadev->running = 1;
524                 break;
525         case SNDRV_PCM_TRIGGER_STOP:
526                 val = VIA_REG_CTRL_TERMINATE;
527                 viadev->running = 0;
528                 break;
529         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
530                 val |= VIA_REG_CTRL_PAUSE;
531                 viadev->running = 0;
532                 break;
533         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
534                 viadev->running = 1;
535                 break;
536         default:
537                 return -EINVAL;
538         }
539         outb(val, VIADEV_REG(viadev, OFFSET_CONTROL));
540         if (cmd == SNDRV_PCM_TRIGGER_STOP)
541                 snd_via82xx_channel_reset(chip, viadev);
542         return 0;
543 }
544
545 /*
546  * pointer callbacks
547  */
548
549 /*
550  * calculate the linear position at the given sg-buffer index and the rest count
551  */
552
553 #define check_invalid_pos(viadev,pos) \
554         ((pos) < viadev->lastpos && ((pos) >= viadev->bufsize2 || viadev->lastpos < viadev->bufsize2))
555
556 static inline unsigned int calc_linear_pos(viadev_t *viadev, unsigned int idx, unsigned int count)
557 {
558         unsigned int size, res;
559
560         size = viadev->idx_table[idx].size;
561         res = viadev->idx_table[idx].offset + size - count;
562
563         /* check the validity of the calculated position */
564         if (size < count) {
565                 snd_printd(KERN_ERR "invalid via82xx_cur_ptr (size = %d, count = %d)\n", (int)size, (int)count);
566                 res = viadev->lastpos;
567         } else if (check_invalid_pos(viadev, res)) {
568 #ifdef POINTER_DEBUG
569                 printk("fail: idx = %i/%i, lastpos = 0x%x, bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos, viadev->bufsize2, viadev->idx_table[idx].offset, viadev->idx_table[idx].size, count);
570 #endif
571                 if (count && size < count) {
572                         snd_printd(KERN_ERR "invalid via82xx_cur_ptr, using last valid pointer\n");
573                         res = viadev->lastpos;
574                 } else {
575                         if (! count)
576                                 /* bogus count 0 on the DMA boundary? */
577                                 res = viadev->idx_table[idx].offset;
578                         else
579                                 /* count register returns full size when end of buffer is reached */
580                                 res = viadev->idx_table[idx].offset + size;
581                         if (check_invalid_pos(viadev, res)) {
582                                 snd_printd(KERN_ERR "invalid via82xx_cur_ptr (2), using last valid pointer\n");
583                                 res = viadev->lastpos;
584                         }
585                 }
586         }
587         viadev->lastpos = res; /* remember the last position */
588         if (res >= viadev->bufsize)
589                 res -= viadev->bufsize;
590         return res;
591 }
592
593 /*
594  * get the current pointer on via686
595  */
596 static snd_pcm_uframes_t snd_via686_pcm_pointer(snd_pcm_substream_t *substream)
597 {
598         via82xx_t *chip = snd_pcm_substream_chip(substream);
599         viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
600         unsigned int idx, ptr, count, res;
601
602         snd_assert(viadev->tbl_entries, return 0);
603         if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE))
604                 return 0;
605
606         spin_lock(&chip->reg_lock);
607         count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT)) & 0xffffff;
608         /* The via686a does not have the current index register,
609          * so we need to calculate the index from CURR_PTR.
610          */
611         ptr = inl(VIADEV_REG(viadev, OFFSET_CURR_PTR));
612         if (ptr <= (unsigned int)viadev->table.addr)
613                 idx = 0;
614         else /* CURR_PTR holds the address + 8 */
615                 idx = ((ptr - (unsigned int)viadev->table.addr) / 8 - 1) % viadev->tbl_entries;
616         res = calc_linear_pos(viadev, idx, count);
617         spin_unlock(&chip->reg_lock);
618
619         return bytes_to_frames(substream->runtime, res);
620 }
621
622 /*
623  * hw_params callback:
624  * allocate the buffer and build up the buffer description table
625  */
626 static int snd_via82xx_hw_params(snd_pcm_substream_t * substream,
627                                  snd_pcm_hw_params_t * hw_params)
628 {
629         via82xx_t *chip = snd_pcm_substream_chip(substream);
630         viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
631         int err;
632
633         err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
634         if (err < 0)
635                 return err;
636         err = build_via_table(viadev, substream, chip->pci,
637                               params_periods(hw_params),
638                               params_period_bytes(hw_params));
639         if (err < 0)
640                 return err;
641
642         snd_ac97_write(chip->ac97, AC97_LINE1_RATE, params_rate(hw_params));
643         snd_ac97_write(chip->ac97, AC97_LINE1_LEVEL, 0);
644
645         return 0;
646 }
647
648 /*
649  * hw_free callback:
650  * clean up the buffer description table and release the buffer
651  */
652 static int snd_via82xx_hw_free(snd_pcm_substream_t * substream)
653 {
654         via82xx_t *chip = snd_pcm_substream_chip(substream);
655         viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
656
657         clean_via_table(viadev, substream, chip->pci);
658         snd_pcm_lib_free_pages(substream);
659         return 0;
660 }
661
662
663 /*
664  * set up the table pointer
665  */
666 static void snd_via82xx_set_table_ptr(via82xx_t *chip, viadev_t *viadev)
667 {
668         snd_via82xx_codec_ready(chip, chip->ac97_secondary);
669         outl((u32)viadev->table.addr, VIADEV_REG(viadev, OFFSET_TABLE_PTR));
670         udelay(20);
671         snd_via82xx_codec_ready(chip, chip->ac97_secondary);
672 }
673
674 /*
675  * prepare callback for playback and capture
676  */
677 static int snd_via82xx_pcm_prepare(snd_pcm_substream_t *substream)
678 {
679         via82xx_t *chip = snd_pcm_substream_chip(substream);
680         viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
681
682         snd_via82xx_channel_reset(chip, viadev);
683         /* this must be set after channel_reset */
684         snd_via82xx_set_table_ptr(chip, viadev);
685         outb(VIA_REG_TYPE_AUTOSTART|VIA_REG_TYPE_INT_EOL|VIA_REG_TYPE_INT_FLAG,
686              VIADEV_REG(viadev, OFFSET_TYPE));
687         return 0;
688 }
689
690 /*
691  * pcm hardware definition, identical for both playback and capture
692  */
693 static snd_pcm_hardware_t snd_via82xx_hw =
694 {
695         .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
696                                  SNDRV_PCM_INFO_BLOCK_TRANSFER |
697                                  SNDRV_PCM_INFO_MMAP_VALID |
698                                  /* SNDRV_PCM_INFO_RESUME | */
699                                  SNDRV_PCM_INFO_PAUSE),
700         .formats =              SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
701         .rates =                SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_KNOT,
702         .rate_min =             8000,
703         .rate_max =             16000,
704         .channels_min =         1,
705         .channels_max =         1,
706         .buffer_bytes_max =     128 * 1024,
707         .period_bytes_min =     32,
708         .period_bytes_max =     128 * 1024,
709         .periods_min =          2,
710         .periods_max =          VIA_TABLE_SIZE / 2,
711         .fifo_size =            0,
712 };
713
714
715 /*
716  * open callback skeleton
717  */
718 static int snd_via82xx_modem_pcm_open(via82xx_t *chip, viadev_t *viadev, snd_pcm_substream_t * substream)
719 {
720         snd_pcm_runtime_t *runtime = substream->runtime;
721         int err;
722         static unsigned int rates[] = { 8000,  9600, 12000, 16000 };
723         static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
724                 .count = ARRAY_SIZE(rates),
725                 .list = rates,
726                 .mask = 0,
727         };
728
729         runtime->hw = snd_via82xx_hw;
730         
731         if ((err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates)) < 0)
732                 return err;
733
734         /* we may remove following constaint when we modify table entries
735            in interrupt */
736         if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
737                 return err;
738
739         runtime->private_data = viadev;
740         viadev->substream = substream;
741
742         return 0;
743 }
744
745
746 /*
747  * open callback for playback
748  */
749 static int snd_via82xx_playback_open(snd_pcm_substream_t * substream)
750 {
751         via82xx_t *chip = snd_pcm_substream_chip(substream);
752         viadev_t *viadev = &chip->devs[chip->playback_devno + substream->number];
753
754         return snd_via82xx_modem_pcm_open(chip, viadev, substream);
755 }
756
757 /*
758  * open callback for capture
759  */
760 static int snd_via82xx_capture_open(snd_pcm_substream_t * substream)
761 {
762         via82xx_t *chip = snd_pcm_substream_chip(substream);
763         viadev_t *viadev = &chip->devs[chip->capture_devno + substream->pcm->device];
764
765         return snd_via82xx_modem_pcm_open(chip, viadev, substream);
766 }
767
768 /*
769  * close callback
770  */
771 static int snd_via82xx_pcm_close(snd_pcm_substream_t * substream)
772 {
773         viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
774
775         viadev->substream = NULL;
776         return 0;
777 }
778
779
780 /* via686 playback callbacks */
781 static snd_pcm_ops_t snd_via686_playback_ops = {
782         .open =         snd_via82xx_playback_open,
783         .close =        snd_via82xx_pcm_close,
784         .ioctl =        snd_pcm_lib_ioctl,
785         .hw_params =    snd_via82xx_hw_params,
786         .hw_free =      snd_via82xx_hw_free,
787         .prepare =      snd_via82xx_pcm_prepare,
788         .trigger =      snd_via82xx_pcm_trigger,
789         .pointer =      snd_via686_pcm_pointer,
790         .page =         snd_pcm_sgbuf_ops_page,
791 };
792
793 /* via686 capture callbacks */
794 static snd_pcm_ops_t snd_via686_capture_ops = {
795         .open =         snd_via82xx_capture_open,
796         .close =        snd_via82xx_pcm_close,
797         .ioctl =        snd_pcm_lib_ioctl,
798         .hw_params =    snd_via82xx_hw_params,
799         .hw_free =      snd_via82xx_hw_free,
800         .prepare =      snd_via82xx_pcm_prepare,
801         .trigger =      snd_via82xx_pcm_trigger,
802         .pointer =      snd_via686_pcm_pointer,
803         .page =         snd_pcm_sgbuf_ops_page,
804 };
805
806
807 static void init_viadev(via82xx_t *chip, int idx, unsigned int reg_offset, int direction)
808 {
809         chip->devs[idx].reg_offset = reg_offset;
810         chip->devs[idx].direction = direction;
811         chip->devs[idx].port = chip->port + reg_offset;
812 }
813
814 /*
815  * create a pcm instance for via686a/b
816  */
817 static int __devinit snd_via686_pcm_new(via82xx_t *chip)
818 {
819         snd_pcm_t *pcm;
820         int err;
821
822         chip->playback_devno = 0;
823         chip->capture_devno = 1;
824         chip->num_devs = 2;
825         chip->intr_mask = 0x330000; /* FLAGS | EOL for MR, MW */
826
827         err = snd_pcm_new(chip->card, chip->card->shortname, 0, 1, 1, &pcm);
828         if (err < 0)
829                 return err;
830         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via686_playback_ops);
831         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via686_capture_ops);
832         pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
833         pcm->private_data = chip;
834         strcpy(pcm->name, chip->card->shortname);
835         chip->pcms[0] = pcm;
836         init_viadev(chip, 0, VIA_REG_MO_STATUS, 0);
837         init_viadev(chip, 1, VIA_REG_MI_STATUS, 1);
838
839         if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
840                                                          snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
841                 return err;
842
843         return 0;
844 }
845
846
847 /*
848  *  Mixer part
849  */
850
851
852 static void snd_via82xx_mixer_free_ac97_bus(ac97_bus_t *bus)
853 {
854         via82xx_t *chip = bus->private_data;
855         chip->ac97_bus = NULL;
856 }
857
858 static void snd_via82xx_mixer_free_ac97(ac97_t *ac97)
859 {
860         via82xx_t *chip = ac97->private_data;
861         chip->ac97 = NULL;
862 }
863
864
865 static int __devinit snd_via82xx_mixer_new(via82xx_t *chip)
866 {
867         ac97_template_t ac97;
868         int err;
869         static ac97_bus_ops_t ops = {
870                 .write = snd_via82xx_codec_write,
871                 .read = snd_via82xx_codec_read,
872                 .wait = snd_via82xx_codec_wait,
873         };
874
875         if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0)
876                 return err;
877         chip->ac97_bus->private_free = snd_via82xx_mixer_free_ac97_bus;
878         chip->ac97_bus->clock = chip->ac97_clock;
879
880         memset(&ac97, 0, sizeof(ac97));
881         ac97.private_data = chip;
882         ac97.private_free = snd_via82xx_mixer_free_ac97;
883         ac97.pci = chip->pci;
884         ac97.scaps = AC97_SCAP_SKIP_AUDIO;
885         ac97.num = chip->ac97_secondary;
886
887         if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
888                 return err;
889
890         return 0;
891 }
892
893
894 /*
895  * proc interface
896  */
897 static void snd_via82xx_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
898 {
899         via82xx_t *chip = entry->private_data;
900         int i;
901         
902         snd_iprintf(buffer, "%s\n\n", chip->card->longname);
903         for (i = 0; i < 0xa0; i += 4) {
904                 snd_iprintf(buffer, "%02x: %08x\n", i, inl(chip->port + i));
905         }
906 }
907
908 static void __devinit snd_via82xx_proc_init(via82xx_t *chip)
909 {
910         snd_info_entry_t *entry;
911
912         if (! snd_card_proc_new(chip->card, "via82xx", &entry))
913                 snd_info_set_text_ops(entry, chip, 1024, snd_via82xx_proc_read);
914 }
915
916 /*
917  *
918  */
919
920 static int snd_via82xx_chip_init(via82xx_t *chip)
921 {
922         unsigned int val;
923         unsigned long end_time;
924         unsigned char pval;
925
926         pci_read_config_byte(chip->pci, VIA_MC97_CTRL, &pval);
927         if((pval & VIA_MC97_CTRL_INIT) != VIA_MC97_CTRL_INIT) {
928                 pci_write_config_byte(chip->pci, 0x44, pval|VIA_MC97_CTRL_INIT);
929                 udelay(100);
930         }
931
932         pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
933         if (! (pval & VIA_ACLINK_C00_READY)) { /* codec not ready? */
934                 /* deassert ACLink reset, force SYNC */
935                 pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL,
936                                       VIA_ACLINK_CTRL_ENABLE |
937                                       VIA_ACLINK_CTRL_RESET |
938                                       VIA_ACLINK_CTRL_SYNC);
939                 udelay(100);
940 #if 1 /* FIXME: should we do full reset here for all chip models? */
941                 pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, 0x00);
942                 udelay(100);
943 #else
944                 /* deassert ACLink reset, force SYNC (warm AC'97 reset) */
945                 pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL,
946                                       VIA_ACLINK_CTRL_RESET|VIA_ACLINK_CTRL_SYNC);
947                 udelay(2);
948 #endif
949                 /* ACLink on, deassert ACLink reset, VSR, SGD data out */
950                 pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, VIA_ACLINK_CTRL_INIT);
951                 udelay(100);
952         }
953         
954         pci_read_config_byte(chip->pci, VIA_ACLINK_CTRL, &pval);
955         if ((pval & VIA_ACLINK_CTRL_INIT) != VIA_ACLINK_CTRL_INIT) {
956                 /* ACLink on, deassert ACLink reset, VSR, SGD data out */
957                 pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, VIA_ACLINK_CTRL_INIT);
958                 udelay(100);
959         }
960
961         /* wait until codec ready */
962         end_time = jiffies + msecs_to_jiffies(750);
963         do {
964                 pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
965                 if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */
966                         break;
967                 set_current_state(TASK_UNINTERRUPTIBLE);
968                 schedule_timeout(1);
969         } while (time_before(jiffies, end_time));
970
971         if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
972                 snd_printk("AC'97 codec is not ready [0x%x]\n", val);
973
974         snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
975                                  VIA_REG_AC97_SECONDARY_VALID |
976                                  (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT));
977         end_time = jiffies + msecs_to_jiffies(750);
978         snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
979                                  VIA_REG_AC97_SECONDARY_VALID |
980                                  (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT));
981         do {
982                 if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_SECONDARY_VALID) {
983                         chip->ac97_secondary = 1;
984                         goto __ac97_ok2;
985                 }
986                 set_current_state(TASK_INTERRUPTIBLE);
987                 schedule_timeout(1);
988         } while (time_before(jiffies, end_time));
989         /* This is ok, the most of motherboards have only one codec */
990
991       __ac97_ok2:
992
993         /* route FM trap to IRQ, disable FM trap */
994         // pci_write_config_byte(chip->pci, VIA_FM_NMI_CTRL, 0);
995         /* disable all GPI interrupts */
996         outl(0, VIAREG(chip, GPI_INTR));
997
998         return 0;
999 }
1000
1001 #ifdef CONFIG_PM
1002 /*
1003  * power management
1004  */
1005 static int snd_via82xx_suspend(snd_card_t *card, pm_message_t state)
1006 {
1007         via82xx_t *chip = card->pm_private_data;
1008         int i;
1009
1010         for (i = 0; i < 2; i++)
1011                 if (chip->pcms[i])
1012                         snd_pcm_suspend_all(chip->pcms[i]);
1013         for (i = 0; i < chip->num_devs; i++)
1014                 snd_via82xx_channel_reset(chip, &chip->devs[i]);
1015         synchronize_irq(chip->irq);
1016         snd_ac97_suspend(chip->ac97);
1017         pci_set_power_state(chip->pci, 3);
1018         pci_disable_device(chip->pci);
1019         return 0;
1020 }
1021
1022 static int snd_via82xx_resume(snd_card_t *card)
1023 {
1024         via82xx_t *chip = card->pm_private_data;
1025         int i;
1026
1027         pci_enable_device(chip->pci);
1028         pci_set_power_state(chip->pci, 0);
1029         pci_set_master(chip->pci);
1030
1031         snd_via82xx_chip_init(chip);
1032
1033         snd_ac97_resume(chip->ac97);
1034
1035         for (i = 0; i < chip->num_devs; i++)
1036                 snd_via82xx_channel_reset(chip, &chip->devs[i]);
1037
1038         return 0;
1039 }
1040 #endif /* CONFIG_PM */
1041
1042 static int snd_via82xx_free(via82xx_t *chip)
1043 {
1044         unsigned int i;
1045
1046         if (chip->irq < 0)
1047                 goto __end_hw;
1048         /* disable interrupts */
1049         for (i = 0; i < chip->num_devs; i++)
1050                 snd_via82xx_channel_reset(chip, &chip->devs[i]);
1051         synchronize_irq(chip->irq);
1052       __end_hw:
1053         if (chip->irq >= 0)
1054                 free_irq(chip->irq, (void *)chip);
1055         pci_release_regions(chip->pci);
1056         pci_disable_device(chip->pci);
1057         kfree(chip);
1058         return 0;
1059 }
1060
1061 static int snd_via82xx_dev_free(snd_device_t *device)
1062 {
1063         via82xx_t *chip = device->device_data;
1064         return snd_via82xx_free(chip);
1065 }
1066
1067 static int __devinit snd_via82xx_create(snd_card_t * card,
1068                                         struct pci_dev *pci,
1069                                         int chip_type,
1070                                         int revision,
1071                                         unsigned int ac97_clock,
1072                                         via82xx_t ** r_via)
1073 {
1074         via82xx_t *chip;
1075         int err;
1076         static snd_device_ops_t ops = {
1077                 .dev_free =     snd_via82xx_dev_free,
1078         };
1079
1080         if ((err = pci_enable_device(pci)) < 0)
1081                 return err;
1082
1083         if ((chip = kzalloc(sizeof(*chip), GFP_KERNEL)) == NULL) {
1084                 pci_disable_device(pci);
1085                 return -ENOMEM;
1086         }
1087
1088         spin_lock_init(&chip->reg_lock);
1089         chip->card = card;
1090         chip->pci = pci;
1091         chip->irq = -1;
1092
1093         if ((err = pci_request_regions(pci, card->driver)) < 0) {
1094                 kfree(chip);
1095                 pci_disable_device(pci);
1096                 return err;
1097         }
1098         chip->port = pci_resource_start(pci, 0);
1099         if (request_irq(pci->irq, snd_via82xx_interrupt, SA_INTERRUPT|SA_SHIRQ,
1100                         card->driver, (void *)chip)) {
1101                 snd_printk("unable to grab IRQ %d\n", pci->irq);
1102                 snd_via82xx_free(chip);
1103                 return -EBUSY;
1104         }
1105         chip->irq = pci->irq;
1106         if (ac97_clock >= 8000 && ac97_clock <= 48000)
1107                 chip->ac97_clock = ac97_clock;
1108         synchronize_irq(chip->irq);
1109
1110         if ((err = snd_via82xx_chip_init(chip)) < 0) {
1111                 snd_via82xx_free(chip);
1112                 return err;
1113         }
1114
1115         if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
1116                 snd_via82xx_free(chip);
1117                 return err;
1118         }
1119
1120         /* The 8233 ac97 controller does not implement the master bit
1121          * in the pci command register. IMHO this is a violation of the PCI spec.
1122          * We call pci_set_master here because it does not hurt. */
1123         pci_set_master(pci);
1124
1125         snd_card_set_dev(card, &pci->dev);
1126
1127         *r_via = chip;
1128         return 0;
1129 }
1130
1131
1132 static int __devinit snd_via82xx_probe(struct pci_dev *pci,
1133                                        const struct pci_device_id *pci_id)
1134 {
1135         snd_card_t *card;
1136         via82xx_t *chip;
1137         unsigned char revision;
1138         int chip_type = 0, card_type;
1139         unsigned int i;
1140         int err;
1141
1142         card = snd_card_new(index, id, THIS_MODULE, 0);
1143         if (card == NULL)
1144                 return -ENOMEM;
1145
1146         card_type = pci_id->driver_data;
1147         pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
1148         switch (card_type) {
1149         case TYPE_CARD_VIA82XX_MODEM:
1150                 strcpy(card->driver, "VIA82XX-MODEM");
1151                 sprintf(card->shortname, "VIA 82XX modem");
1152                 break;
1153         default:
1154                 snd_printk(KERN_ERR "invalid card type %d\n", card_type);
1155                 err = -EINVAL;
1156                 goto __error;
1157         }
1158                 
1159         if ((err = snd_via82xx_create(card, pci, chip_type, revision,
1160                                       ac97_clock, &chip)) < 0)
1161                 goto __error;
1162         if ((err = snd_via82xx_mixer_new(chip)) < 0)
1163                 goto __error;
1164
1165         if ((err = snd_via686_pcm_new(chip)) < 0 )
1166                 goto __error;
1167
1168         snd_card_set_pm_callback(card, snd_via82xx_suspend, snd_via82xx_resume, chip);
1169
1170         /* disable interrupts */
1171         for (i = 0; i < chip->num_devs; i++)
1172                 snd_via82xx_channel_reset(chip, &chip->devs[i]);
1173
1174         sprintf(card->longname, "%s at 0x%lx, irq %d",
1175                 card->shortname, chip->port, chip->irq);
1176
1177         snd_via82xx_proc_init(chip);
1178
1179         if ((err = snd_card_register(card)) < 0) {
1180                 snd_card_free(card);
1181                 return err;
1182         }
1183         pci_set_drvdata(pci, card);
1184         return 0;
1185
1186  __error:
1187         snd_card_free(card);
1188         return err;
1189 }
1190
1191 static void __devexit snd_via82xx_remove(struct pci_dev *pci)
1192 {
1193         snd_card_free(pci_get_drvdata(pci));
1194         pci_set_drvdata(pci, NULL);
1195 }
1196
1197 static struct pci_driver driver = {
1198         .name = "VIA 82xx Modem",
1199         .owner = THIS_MODULE,
1200         .id_table = snd_via82xx_modem_ids,
1201         .probe = snd_via82xx_probe,
1202         .remove = __devexit_p(snd_via82xx_remove),
1203         SND_PCI_PM_CALLBACKS
1204 };
1205
1206 static int __init alsa_card_via82xx_init(void)
1207 {
1208         return pci_register_driver(&driver);
1209 }
1210
1211 static void __exit alsa_card_via82xx_exit(void)
1212 {
1213         pci_unregister_driver(&driver);
1214 }
1215
1216 module_init(alsa_card_via82xx_init)
1217 module_exit(alsa_card_via82xx_exit)