]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - sound/pci/ali5451/ali5451.c
eb5c36d31a52ae75a7e802407b71d7f760529796
[linux-2.6.git] / sound / pci / ali5451 / ali5451.c
1 /*
2  *  Matt Wu <Matt_Wu@acersoftech.com.cn>
3  *  Apr 26, 2001
4  *  Routines for control of ALi pci audio M5451
5  *
6  *  BUGS:
7  *    --
8  *
9  *  TODO:
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 Lcodecnse as published by
14  *   the Free Software Foundation; either version 2 of the Lcodecnse, 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 Lcodecnse for more details.
21  *
22  *   You should have received a copy of the GNU General Public Lcodecnse
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 #include <sound/driver.h>
29 #include <asm/io.h>
30 #include <linux/delay.h>
31 #include <linux/interrupt.h>
32 #include <linux/init.h>
33 #include <linux/pci.h>
34 #include <linux/slab.h>
35 #include <linux/moduleparam.h>
36 #include <sound/core.h>
37 #include <sound/pcm.h>
38 #include <sound/info.h>
39 #include <sound/ac97_codec.h>
40 #include <sound/mpu401.h>
41 #include <sound/initval.h>
42
43 MODULE_AUTHOR("Matt Wu <Matt_Wu@acersoftech.com.cn>");
44 MODULE_DESCRIPTION("ALI M5451");
45 MODULE_LICENSE("GPL");
46 MODULE_SUPPORTED_DEVICE("{{ALI,M5451,pci},{ALI,M5451}}");
47
48 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;      /* Index 0-MAX */
49 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;       /* ID for this card */
50 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
51 static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 32};
52 static int spdif[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
53
54 module_param_array(index, int, NULL, 0444);
55 MODULE_PARM_DESC(index, "Index value for ALI M5451 PCI Audio.");
56 module_param_array(id, charp, NULL, 0444);
57 MODULE_PARM_DESC(id, "ID string for ALI M5451 PCI Audio.");
58 module_param_array(enable, bool, NULL, 0444);
59 MODULE_PARM_DESC(enable, "Enable ALI 5451 PCI Audio.");
60 module_param_array(pcm_channels, int, NULL, 0444);
61 MODULE_PARM_DESC(pcm_channels, "PCM Channels");
62 module_param_array(spdif, bool, NULL, 0444);
63 MODULE_PARM_DESC(spdif, "Support SPDIF I/O");
64
65 /*
66  *  Debug part definitions
67  */
68
69 //#define ALI_DEBUG
70
71 #ifdef ALI_DEBUG
72 #define snd_ali_printk(format, args...) printk(format, ##args);
73 #else
74 #define snd_ali_printk(format, args...)
75 #endif
76
77 /*
78  *  Constants definition
79  */
80
81 #ifndef PCI_VENDOR_ID_ALI
82 #define PCI_VENDOR_ID_ALI       0x10b9
83 #endif
84
85 #ifndef PCI_DEVICE_ID_ALI_5451
86 #define PCI_DEVICE_ID_ALI_5451  0x5451
87 #endif
88
89 #define DEVICE_ID_ALI5451       ((PCI_VENDOR_ID_ALI<<16)|PCI_DEVICE_ID_ALI_5451)
90
91
92 #define ALI_CHANNELS            32
93
94 #define ALI_PCM_IN_CHANNEL      31
95 #define ALI_SPDIF_IN_CHANNEL    19
96 #define ALI_SPDIF_OUT_CHANNEL   15
97 #define ALI_CENTER_CHANNEL      24
98 #define ALI_LEF_CHANNEL         23
99 #define ALI_SURR_LEFT_CHANNEL   26
100 #define ALI_SURR_RIGHT_CHANNEL  25
101 #define ALI_MODEM_IN_CHANNEL    21
102 #define ALI_MODEM_OUT_CHANNEL   20
103
104 #define SNDRV_ALI_VOICE_TYPE_PCM        01
105 #define SNDRV_ALI_VOICE_TYPE_OTH        02
106
107 #define ALI_5451_V02            0x02
108
109 /*
110  *  Direct Registers
111  */
112
113 #define ALI_LEGACY_DMAR0        0x00  // ADR0
114 #define ALI_LEGACY_DMAR4        0x04  // CNT0
115 #define ALI_LEGACY_DMAR11       0x0b  // MOD 
116 #define ALI_LEGACY_DMAR15       0x0f  // MMR 
117 #define ALI_MPUR0               0x20
118 #define ALI_MPUR1               0x21
119 #define ALI_MPUR2               0x22
120 #define ALI_MPUR3               0x23
121
122 #define ALI_AC97_WRITE          0x40
123 #define ALI_AC97_READ           0x44
124
125 #define ALI_SCTRL               0x48
126 #define   ALI_SPDIF_OUT_ENABLE          0x20
127 #define   ALI_SCTRL_LINE_IN2            (1 << 9)
128 #define   ALI_SCTRL_GPIO_IN2            (1 << 13)
129 #define   ALI_SCTRL_LINE_OUT_EN         (1 << 20)
130 #define   ALI_SCTRL_GPIO_OUT_EN         (1 << 23)
131 #define   ALI_SCTRL_CODEC1_READY        (1 << 24)
132 #define   ALI_SCTRL_CODEC2_READY        (1 << 25)
133 #define ALI_AC97_GPIO           0x4c
134 #define   ALI_AC97_GPIO_ENABLE          0x8000
135 #define   ALI_AC97_GPIO_DATA_SHIFT      16
136 #define ALI_SPDIF_CS            0x70
137 #define ALI_SPDIF_CTRL          0x74
138 #define   ALI_SPDIF_IN_FUNC_ENABLE      0x02
139 #define   ALI_SPDIF_IN_CH_STATUS        0x40
140 #define   ALI_SPDIF_OUT_CH_STATUS       0xbf
141 #define ALI_START               0x80
142 #define ALI_STOP                0x84
143 #define ALI_CSPF                0x90
144 #define ALI_AINT                0x98
145 #define ALI_GC_CIR              0xa0
146         #define ENDLP_IE                0x00001000
147         #define MIDLP_IE                0x00002000
148 #define ALI_AINTEN              0xa4
149 #define ALI_VOLUME              0xa8
150 #define ALI_SBDELTA_DELTA_R     0xac
151 #define ALI_MISCINT             0xb0
152         #define ADDRESS_IRQ             0x00000020
153         #define TARGET_REACHED          0x00008000
154         #define MIXER_OVERFLOW          0x00000800
155         #define MIXER_UNDERFLOW         0x00000400
156         #define GPIO_IRQ                0x01000000
157 #define ALI_SBBL_SBCL           0xc0
158 #define ALI_SBCTRL_SBE2R_SBDD   0xc4
159 #define ALI_STIMER              0xc8
160 #define ALI_GLOBAL_CONTROL      0xd4
161 #define   ALI_SPDIF_OUT_SEL_PCM         0x00000400 /* bit 10 */
162 #define   ALI_SPDIF_IN_SUPPORT          0x00000800 /* bit 11 */
163 #define   ALI_SPDIF_OUT_CH_ENABLE       0x00008000 /* bit 15 */
164 #define   ALI_SPDIF_IN_CH_ENABLE        0x00080000 /* bit 19 */
165 #define   ALI_PCM_IN_ENABLE             0x80000000 /* bit 31 */
166
167 #define ALI_CSO_ALPHA_FMS       0xe0
168 #define ALI_LBA                 0xe4
169 #define ALI_ESO_DELTA           0xe8
170 #define ALI_GVSEL_PAN_VOC_CTRL_EC       0xf0
171 #define ALI_EBUF1               0xf4
172 #define ALI_EBUF2               0xf8
173
174 #define ALI_REG(codec, x) ((codec)->port + x)
175
176 #define MAX_CODECS 2
177
178
179 typedef struct snd_stru_ali ali_t;
180 typedef struct snd_ali_stru_voice snd_ali_voice_t;
181
182 typedef struct snd_ali_channel_control {
183         // register data
184         struct REGDATA {
185                 unsigned int start;
186                 unsigned int stop;
187                 unsigned int aint;
188                 unsigned int ainten;
189         } data;
190                 
191         // register addresses
192         struct REGS {
193                 unsigned int start;
194                 unsigned int stop;
195                 unsigned int aint;
196                 unsigned int ainten;
197                 unsigned int ac97read;
198                 unsigned int ac97write;
199         } regs;
200
201 } snd_ali_channel_control_t;
202
203 struct snd_ali_stru_voice {
204         unsigned int number;
205         unsigned int use: 1,
206             pcm: 1,
207             midi: 1,
208             mode: 1,
209             synth: 1;
210
211         /* PCM data */
212         ali_t *codec;
213         snd_pcm_substream_t *substream;
214         snd_ali_voice_t *extra;
215         
216         unsigned int running: 1;
217
218         int eso;                /* final ESO value for channel */
219         int count;              /* runtime->period_size */
220
221         /* --- */
222
223         void *private_data;
224         void (*private_free)(void *private_data);
225 };
226
227
228 typedef struct snd_stru_alidev {
229
230         snd_ali_voice_t voices[ALI_CHANNELS];   
231
232         unsigned int    chcnt;                  /* num of opened channels */
233         unsigned int    chmap;                  /* bitmap for opened channels */
234         unsigned int synthcount;
235
236 } alidev_t;
237
238
239 #ifdef CONFIG_PM
240 #define ALI_GLOBAL_REGS         56
241 #define ALI_CHANNEL_REGS        8
242 typedef struct snd_ali_image {
243         unsigned long regs[ALI_GLOBAL_REGS];
244         unsigned long channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS];
245 } ali_image_t;
246 #endif
247
248
249 struct snd_stru_ali {
250         unsigned long   irq;
251         unsigned long   port;
252         unsigned char   revision;
253
254         unsigned int hw_initialized: 1;
255         unsigned int spdif_support: 1;
256
257         struct pci_dev  *pci;
258         struct pci_dev  *pci_m1533;
259         struct pci_dev  *pci_m7101;
260
261         snd_card_t      *card;
262         snd_pcm_t       *pcm[MAX_CODECS];
263         alidev_t        synth;
264         snd_ali_channel_control_t chregs;
265
266         /* S/PDIF Mask */
267         unsigned int    spdif_mask;
268
269         unsigned int spurious_irq_count;
270         unsigned int spurious_irq_max_delta;
271
272         unsigned int num_of_codecs;
273
274         ac97_bus_t *ac97_bus;
275         ac97_t *ac97[MAX_CODECS];
276         unsigned short  ac97_ext_id;
277         unsigned short  ac97_ext_status;
278
279         spinlock_t      reg_lock;
280         spinlock_t      voice_alloc;
281
282 #ifdef CONFIG_PM
283         ali_image_t *image;
284 #endif
285 };
286
287 static struct pci_device_id snd_ali_ids[] = {
288         {0x10b9, 0x5451, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
289         {0, }
290 };
291 MODULE_DEVICE_TABLE(pci, snd_ali_ids);
292
293 static void snd_ali_clear_voices(ali_t *, unsigned int, unsigned int);
294 static unsigned short snd_ali_codec_peek(ali_t *, int, unsigned short);
295 static void snd_ali_codec_poke(ali_t *, int, unsigned short, unsigned short);
296
297 /*
298  *  Debug Part
299  */
300
301 #ifdef ALI_DEBUG
302
303 static void ali_read_regs(ali_t *codec, int channel)
304 {
305         int i,j;
306         unsigned int dwVal;
307
308         printk("channel %d registers map:\n", channel);
309         outb((unsigned char)(channel & 0x001f), ALI_REG(codec,ALI_GC_CIR));
310
311         printk("    ");
312         for(j=0;j<8;j++)
313                 printk("%2.2x       ", j*4);
314         printk("\n");
315
316         for (i=0; i<=0xf8/4;i++) {
317                 if(i%8 == 0)
318                         printk("%2.2x  ", (i*4/0x10)*0x10);
319                 dwVal = inl(ALI_REG(codec,i*4));
320                 printk("%8.8x ", dwVal);
321                 if ((i+1)%8 == 0)
322                         printk("\n");
323         }
324         printk("\n");
325 }
326 static void ali_read_cfg(unsigned int vendor, unsigned deviceid)
327 {
328         unsigned int dwVal;
329         struct pci_dev *pci_dev = NULL;
330         int i,j;
331
332
333         pci_dev = pci_find_device(vendor, deviceid, pci_dev);
334         if (pci_dev == NULL)
335                 return ;
336
337         printk("\nM%x PCI CFG\n", deviceid);
338         printk("    ");
339         for(j=0;j<8;j++)
340                 printk("%d        ",j);
341         printk("\n");
342
343         for(i=0;i<8;i++) {
344                 printk("%d   ",i);
345                 for(j=0;j<8;j++)
346                 {
347                         pci_read_config_dword(pci_dev, i*0x20+j*4, &dwVal);
348                         printk("%8.8x ", dwVal);
349                 }
350                 printk("\n");
351         }
352  }
353 static void ali_read_ac97regs(ali_t *codec, int secondary)
354 {
355         unsigned short i,j;
356         unsigned short wVal;
357
358         printk("\ncodec %d registers map:\n", secondary);
359
360         printk("    ");
361         for(j=0;j<8;j++)
362                 printk("%2.2x   ",j*2);
363         printk("\n");
364
365         for (i=0; i<64;i++) {
366                 if(i%8 == 0)
367                         printk("%2.2x  ", (i/8)*0x10);
368                 wVal = snd_ali_codec_peek(codec, secondary, i*2);
369                 printk("%4.4x ", wVal);
370                 if ((i+1)%8 == 0)
371                         printk("\n");
372         }
373         printk("\n");
374 }
375
376 #endif
377
378 /*
379  *  AC97 ACCESS
380  */
381
382 static inline unsigned int snd_ali_5451_peek(ali_t *codec,
383                                                 unsigned int port )
384 {
385         return (unsigned int)inl(ALI_REG(codec, port)); 
386 }
387
388 static inline void snd_ali_5451_poke(   ali_t *codec,
389                                         unsigned int port,
390                                         unsigned int val )
391 {
392         outl((unsigned int)val, ALI_REG(codec, port));
393 }
394
395 static int snd_ali_codec_ready( ali_t *codec,
396                                 unsigned int port,
397                                 int sched )
398 {
399         unsigned long end_time;
400         unsigned int res;
401         
402         end_time = jiffies + 10 * (HZ >> 2);
403         do {
404                 res = snd_ali_5451_peek(codec,port);
405                 if (! (res & 0x8000))
406                         return 0;
407                 if (sched) {
408                         set_current_state(TASK_UNINTERRUPTIBLE);
409                         schedule_timeout(1);
410                 }
411         } while (time_after_eq(end_time, jiffies));
412         snd_ali_5451_poke(codec, port, res & ~0x8000);
413         snd_printdd("ali_codec_ready: codec is not ready.\n ");
414         return -EIO;
415 }
416
417 static int snd_ali_stimer_ready(ali_t *codec, int sched)
418 {
419         unsigned long end_time;
420         unsigned long dwChk1,dwChk2;
421         
422         dwChk1 = snd_ali_5451_peek(codec, ALI_STIMER);
423         dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER);
424
425         end_time = jiffies + 10 * (HZ >> 2);
426         do {
427                 dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER);
428                 if (dwChk2 != dwChk1)
429                         return 0;
430                 if (sched) {
431                         set_current_state(TASK_UNINTERRUPTIBLE);
432                         schedule_timeout(1);
433                 }
434         } while (time_after_eq(end_time, jiffies));
435         snd_printk("ali_stimer_read: stimer is not ready.\n");
436         return -EIO;
437 }
438
439 static void snd_ali_codec_poke(ali_t *codec,int secondary,
440                                      unsigned short reg,
441                                      unsigned short val)
442 {
443         unsigned int dwVal = 0;
444         unsigned int port = 0;
445
446         if (reg >= 0x80) {
447                 snd_printk("ali_codec_poke: reg(%xh) invalid.\n", reg);
448                 return;
449         }
450
451         port = codec->chregs.regs.ac97write;
452
453         if (snd_ali_codec_ready(codec, port, 0) < 0)
454                 return;
455         if (snd_ali_stimer_ready(codec, 0) < 0)
456                 return;
457
458         dwVal  = (unsigned int) (reg & 0xff);
459         dwVal |= 0x8000 | (val << 16);
460         if (secondary) dwVal |= 0x0080;
461         if (codec->revision == ALI_5451_V02) dwVal |= 0x0100;
462
463         snd_ali_5451_poke(codec,port,dwVal);
464
465         return ;
466 }
467
468 static unsigned short snd_ali_codec_peek( ali_t *codec,
469                                           int secondary,
470                                           unsigned short reg)
471 {
472         unsigned int dwVal = 0;
473         unsigned int port = 0;
474
475         if (reg >= 0x80) {
476                 snd_printk("ali_codec_peek: reg(%xh) invalid.\n", reg);
477                 return ~0;
478         }
479
480         port = codec->chregs.regs.ac97read;
481
482         if (snd_ali_codec_ready(codec, port, 0) < 0)
483                 return ~0;
484         if (snd_ali_stimer_ready(codec, 0) < 0)
485                 return ~0;
486
487         dwVal  = (unsigned int) (reg & 0xff);
488         dwVal |= 0x8000;                                /* bit 15*/
489         if (secondary) dwVal |= 0x0080;
490
491         snd_ali_5451_poke(codec, port, dwVal);
492
493         if (snd_ali_stimer_ready(codec, 0) < 0)
494                 return ~0;
495         if (snd_ali_codec_ready(codec, port, 0) < 0)
496                 return ~0;
497         
498         return (snd_ali_5451_peek(codec, port) & 0xffff0000)>>16;
499 }
500
501 static void snd_ali_codec_write(ac97_t *ac97,
502                                 unsigned short reg,
503                                 unsigned short val )
504 {
505         ali_t *codec = ac97->private_data;
506
507         snd_ali_printk("codec_write: reg=%xh data=%xh.\n", reg, val);
508         if(reg == AC97_GPIO_STATUS) {
509                 outl((val << ALI_AC97_GPIO_DATA_SHIFT)|ALI_AC97_GPIO_ENABLE,
510                         ALI_REG(codec, ALI_AC97_GPIO));
511                 return;
512         }
513         snd_ali_codec_poke(codec, ac97->num, reg, val);
514         return ;
515 }
516
517
518 static unsigned short snd_ali_codec_read(ac97_t *ac97, unsigned short reg)
519 {
520         ali_t *codec = ac97->private_data;
521
522         snd_ali_printk("codec_read reg=%xh.\n", reg);
523         return (snd_ali_codec_peek(codec, ac97->num, reg));
524 }
525
526 /*
527  *      AC97 Reset
528  */
529
530 static int snd_ali_reset_5451(ali_t *codec)
531 {
532         struct pci_dev *pci_dev = NULL;
533         unsigned short wCount, wReg;
534         unsigned int   dwVal;
535         
536         if ((pci_dev = codec->pci_m1533) != NULL) {
537                 pci_read_config_dword(pci_dev, 0x7c, &dwVal);
538                 pci_write_config_dword(pci_dev, 0x7c, dwVal | 0x08000000);
539                 udelay(5000);
540                 pci_read_config_dword(pci_dev, 0x7c, &dwVal);
541                 pci_write_config_dword(pci_dev, 0x7c, dwVal & 0xf7ffffff);
542                 udelay(5000);
543         }
544         
545         pci_dev = codec->pci;
546         pci_read_config_dword(pci_dev, 0x44, &dwVal);
547         pci_write_config_dword(pci_dev, 0x44, dwVal | 0x000c0000);
548         udelay(500);
549         pci_read_config_dword(pci_dev, 0x44, &dwVal);
550         pci_write_config_dword(pci_dev, 0x44, dwVal & 0xfffbffff);
551         udelay(5000);
552         
553         wCount = 200;
554         while(wCount--) {
555                 wReg = snd_ali_codec_peek(codec, 0, AC97_POWERDOWN);
556                 if((wReg & 0x000f) == 0x000f)
557                         return 0;
558                 udelay(5000);
559         }
560
561         /* non-fatal if you have a non PM capable codec */
562         /* snd_printk(KERN_WARNING "ali5451: reset time out\n"); */
563         return 0;
564 }
565
566 #ifdef CODEC_RESET
567
568 static int snd_ali_reset_codec(ali_t *codec)
569 {
570         struct pci_dev *pci_dev = NULL;
571         unsigned char bVal = 0;
572         unsigned int   dwVal;
573         unsigned short wCount, wReg;
574
575         pci_dev = codec->pci_m1533;
576         
577         pci_read_config_dword(pci_dev, 0x7c, &dwVal);
578         pci_write_config_dword(pci_dev, 0x7c, dwVal | 0x08000000);
579         udelay(5000);
580         pci_read_config_dword(pci_dev, 0x7c, &dwVal);
581         pci_write_config_dword(pci_dev, 0x7c, dwVal & 0xf7ffffff);
582         udelay(5000);
583
584         bVal = inb(ALI_REG(codec,ALI_SCTRL));
585         bVal |= 0x02;
586         outb(ALI_REG(codec,ALI_SCTRL),bVal);
587         udelay(5000);
588         bVal = inb(ALI_REG(codec,ALI_SCTRL));
589         bVal &= 0xfd;
590         outb(ALI_REG(codec,ALI_SCTRL),bVal);
591         udelay(15000);
592
593         wCount = 200;
594         while(wCount--) {
595                 wReg = snd_ali_codec_read(codec->ac97, AC97_POWERDOWN);
596                 if((wReg & 0x000f) == 0x000f)
597                         return 0;
598                 udelay(5000);
599         }
600         return -1;
601 }
602
603 #endif
604
605 /*
606  *  ALI 5451 Controller
607  */
608
609 static void snd_ali_enable_special_channel(ali_t *codec, unsigned int channel)
610 {
611         unsigned long dwVal = 0;
612
613         dwVal  = inl(ALI_REG(codec,ALI_GLOBAL_CONTROL));
614         dwVal |= 1 << (channel & 0x0000001f);
615         outl(dwVal, ALI_REG(codec,ALI_GLOBAL_CONTROL));
616 }
617
618 static void snd_ali_disable_special_channel(ali_t *codec, unsigned int channel)
619 {
620         unsigned long dwVal = 0;
621
622         dwVal  = inl(ALI_REG(codec,ALI_GLOBAL_CONTROL));
623         dwVal &= ~(1 << (channel & 0x0000001f));
624         outl(dwVal, ALI_REG(codec,ALI_GLOBAL_CONTROL));
625 }
626
627 static void snd_ali_enable_address_interrupt(ali_t * codec)
628 {
629         unsigned int gc;
630
631         gc  = inl(ALI_REG(codec, ALI_GC_CIR));
632         gc |= ENDLP_IE;
633         gc |= MIDLP_IE;
634         outl( gc, ALI_REG(codec, ALI_GC_CIR));
635 }
636
637 static void snd_ali_disable_address_interrupt(ali_t * codec)
638 {
639         unsigned int gc;
640
641         gc  = inl(ALI_REG(codec, ALI_GC_CIR));
642         gc &= ~ENDLP_IE;
643         gc &= ~MIDLP_IE;
644         outl(gc, ALI_REG(codec, ALI_GC_CIR));
645 }
646
647 #if 0 // not used
648 static void snd_ali_enable_voice_irq(ali_t *codec, unsigned int channel)
649 {
650         unsigned int mask;
651         snd_ali_channel_control_t *pchregs = &(codec->chregs);
652
653         snd_ali_printk("enable_voice_irq channel=%d\n",channel);
654         
655         mask = 1 << (channel & 0x1f);
656         pchregs->data.ainten  = inl(ALI_REG(codec,pchregs->regs.ainten));
657         pchregs->data.ainten |= mask;
658         outl(pchregs->data.ainten,ALI_REG(codec,pchregs->regs.ainten));
659 }
660 #endif
661
662 static void snd_ali_disable_voice_irq(ali_t *codec, unsigned int channel)
663 {
664         unsigned int mask;
665         snd_ali_channel_control_t *pchregs = &(codec->chregs);
666
667         snd_ali_printk("disable_voice_irq channel=%d\n",channel);
668
669         mask = 1 << (channel & 0x1f);
670         pchregs->data.ainten  = inl(ALI_REG(codec,pchregs->regs.ainten));
671         pchregs->data.ainten &= ~mask;
672         outl(pchregs->data.ainten,ALI_REG(codec,pchregs->regs.ainten));
673 }
674
675 static int snd_ali_alloc_pcm_channel(ali_t *codec, int channel)
676 {
677         unsigned int idx =  channel & 0x1f;
678
679         if (codec->synth.chcnt >= ALI_CHANNELS){
680                 snd_printk("ali_alloc_pcm_channel: no free channels.\n");
681                 return -1;
682         }
683
684         if (!(codec->synth.chmap & (1 << idx))) {
685                 codec->synth.chmap |= 1 << idx;
686                 codec->synth.chcnt++;
687                 snd_ali_printk("alloc_pcm_channel no. %d.\n",idx);
688                 return idx;
689         }
690         return -1;
691 }
692
693 static int snd_ali_find_free_channel(ali_t * codec, int rec)
694 {
695         int idx;
696         int result = -1;
697
698         snd_ali_printk("find_free_channel: for %s\n",rec ? "rec" : "pcm");
699
700         // recording
701         if (rec) {
702                 if (codec->spdif_support &&
703                     (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_IN_SUPPORT))
704                         idx = ALI_SPDIF_IN_CHANNEL;
705                 else
706                         idx = ALI_PCM_IN_CHANNEL;
707
708                 if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) {
709                         return result;
710                 } else {
711                         snd_printk("ali_find_free_channel: record channel is busy now.\n");
712                         return -1;
713                 }
714         }
715
716         //playback...
717         if (codec->spdif_support &&
718             (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_OUT_CH_ENABLE)) {
719                 idx = ALI_SPDIF_OUT_CHANNEL;
720                 if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) {
721                         return result;
722                 } else {
723                         snd_printk("ali_find_free_channel: S/PDIF out channel is in busy now.\n");
724                 }
725         }
726
727         for (idx = 0; idx < ALI_CHANNELS; idx++) {
728                 if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0)
729                         return result;
730         }
731         snd_printk("ali_find_free_channel: no free channels.\n");
732         return -1;
733 }
734
735 static void snd_ali_free_channel_pcm(ali_t *codec, int channel)
736 {
737         unsigned int idx = channel & 0x0000001f;
738
739         snd_ali_printk("free_channel_pcm channel=%d\n",channel);
740
741         if (channel < 0 || channel >= ALI_CHANNELS)
742                 return;
743
744         if (!(codec->synth.chmap & (1 << idx))) {
745                 snd_printk("ali_free_channel_pcm: channel %d is not in use.\n",channel);
746                 return;
747         } else {
748                 codec->synth.chmap &= ~(1 << idx);
749                 codec->synth.chcnt--;
750         }
751 }
752
753 #if 0 // not used
754 static void snd_ali_start_voice(ali_t * codec, unsigned int channel)
755 {
756         unsigned int mask = 1 << (channel & 0x1f);
757         
758         snd_ali_printk("start_voice: channel=%d\n",channel);
759         outl(mask, ALI_REG(codec,codec->chregs.regs.start));
760 }
761 #endif
762
763 static void snd_ali_stop_voice(ali_t * codec, unsigned int channel)
764 {
765         unsigned int mask = 1 << (channel & 0x1f);
766
767         snd_ali_printk("stop_voice: channel=%d\n",channel);
768         outl(mask, ALI_REG(codec, codec->chregs.regs.stop));
769 }
770
771 /*
772  *    S/PDIF Part
773  */
774
775 static void snd_ali_delay(ali_t *codec,int interval)
776 {
777         unsigned long  begintimer,currenttimer;
778
779         begintimer   = inl(ALI_REG(codec, ALI_STIMER));
780         currenttimer = inl(ALI_REG(codec, ALI_STIMER));
781
782         while (currenttimer < begintimer + interval) {
783                 if(snd_ali_stimer_ready(codec, 1) < 0)
784                         break;
785                 currenttimer = inl(ALI_REG(codec,  ALI_STIMER));
786         }
787 }
788
789 static void snd_ali_detect_spdif_rate(ali_t *codec)
790 {
791         u16 wval  = 0;
792         u16 count = 0;
793         u8  bval = 0, R1 = 0, R2 = 0;
794
795         bval  = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1));
796         bval |= 0x1F;
797         outb(bval,ALI_REG(codec,ALI_SPDIF_CTRL + 1));
798
799         while (((R1 < 0x0B )||(R1 > 0x0E)) && (R1 != 0x12) && count <= 50000) {
800                 count ++;
801                 snd_ali_delay(codec, 6);
802                 bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1));
803                 R1 = bval & 0x1F;
804         }
805
806         if (count > 50000) {
807                 snd_printk("ali_detect_spdif_rate: timeout!\n");
808                 return;
809         }
810
811         count = 0;
812         while (count++ <= 50000) {
813                 snd_ali_delay(codec, 6);
814                 bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1));
815                 R2 = bval & 0x1F;
816                 if (R2 != R1) R1 = R2; else break;
817         }
818
819         if (count > 50000) {
820                 snd_printk("ali_detect_spdif_rate: timeout!\n");
821                 return;
822         }
823
824         if (R2 >= 0x0b && R2 <= 0x0e) {
825                 wval  = inw(ALI_REG(codec,ALI_SPDIF_CTRL + 2));
826                 wval &= 0xE0F0;
827                 wval |= (u16)0x09 << 8 | (u16)0x05;
828                 outw(wval,ALI_REG(codec,ALI_SPDIF_CTRL + 2));
829
830                 bval  = inb(ALI_REG(codec,ALI_SPDIF_CS +3)) & 0xF0;
831                 outb(bval|0x02,ALI_REG(codec,ALI_SPDIF_CS + 3));
832         } else if (R2 == 0x12) {
833                 wval  = inw(ALI_REG(codec,ALI_SPDIF_CTRL + 2));
834                 wval &= 0xE0F0;
835                 wval |= (u16)0x0E << 8 | (u16)0x08;
836                 outw(wval,ALI_REG(codec,ALI_SPDIF_CTRL + 2));
837
838                 bval  = inb(ALI_REG(codec,ALI_SPDIF_CS +3)) & 0xF0;
839                 outb(bval|0x03,ALI_REG(codec,ALI_SPDIF_CS + 3));
840         }
841 }
842
843 static unsigned int snd_ali_get_spdif_in_rate(ali_t *codec)
844 {
845         u32     dwRate = 0;
846         u8      bval = 0;
847
848         bval  = inb(ALI_REG(codec,ALI_SPDIF_CTRL));
849         bval &= 0x7F;
850         bval |= 0x40;
851         outb(bval, ALI_REG(codec,ALI_SPDIF_CTRL));
852
853         snd_ali_detect_spdif_rate(codec);
854
855         bval  = inb(ALI_REG(codec,ALI_SPDIF_CS + 3));
856         bval &= 0x0F;
857
858         if (bval == 0) dwRate = 44100;
859         if (bval == 1) dwRate = 48000;
860         if (bval == 2) dwRate = 32000;
861
862         return dwRate;
863 }
864
865 static void snd_ali_enable_spdif_in(ali_t *codec)
866 {       
867         unsigned int dwVal;
868
869         dwVal = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL));
870         dwVal |= ALI_SPDIF_IN_SUPPORT;
871         outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
872
873         dwVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL));
874         dwVal |= 0x02;
875         outb(dwVal, ALI_REG(codec, ALI_SPDIF_CTRL));
876
877         snd_ali_enable_special_channel(codec, ALI_SPDIF_IN_CHANNEL);
878 }
879
880 static void snd_ali_disable_spdif_in(ali_t *codec)
881 {
882         unsigned int dwVal;
883         
884         dwVal = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL));
885         dwVal &= ~ALI_SPDIF_IN_SUPPORT;
886         outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
887         
888         snd_ali_disable_special_channel(codec, ALI_SPDIF_IN_CHANNEL);   
889 }
890
891
892 static void snd_ali_set_spdif_out_rate(ali_t *codec, unsigned int rate)
893 {
894         unsigned char  bVal;
895         unsigned int  dwRate = 0;
896         
897         if (rate == 32000) dwRate = 0x300;
898         if (rate == 44100) dwRate = 0;
899         if (rate == 48000) dwRate = 0x200;
900         
901         bVal  = inb(ALI_REG(codec, ALI_SPDIF_CTRL));
902         bVal &= (unsigned char)(~(1<<6));
903         
904         bVal |= 0x80;           //select right
905         outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL));
906         outb(dwRate | 0x20, ALI_REG(codec, ALI_SPDIF_CS + 2));
907         
908         bVal &= (~0x80);        //select left
909         outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL));
910         outw(rate | 0x10, ALI_REG(codec, ALI_SPDIF_CS + 2));
911 }
912
913 static void snd_ali_enable_spdif_out(ali_t *codec)
914 {
915         unsigned short wVal;
916         unsigned char bVal;
917
918         struct pci_dev *pci_dev = NULL;
919
920         pci_dev = codec->pci_m1533;
921         if (pci_dev == NULL)
922                 return;
923         pci_read_config_byte(pci_dev, 0x61, &bVal);
924         bVal |= 0x40;
925         pci_write_config_byte(pci_dev, 0x61, bVal);
926         pci_read_config_byte(pci_dev, 0x7d, &bVal);
927         bVal |= 0x01;
928         pci_write_config_byte(pci_dev, 0x7d, bVal);
929
930         pci_read_config_byte(pci_dev, 0x7e, &bVal);
931         bVal &= (~0x20);
932         bVal |= 0x10;
933         pci_write_config_byte(pci_dev, 0x7e, bVal);
934
935         bVal = inb(ALI_REG(codec, ALI_SCTRL));
936         outb(bVal | ALI_SPDIF_OUT_ENABLE, ALI_REG(codec, ALI_SCTRL));
937
938         bVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL));
939         outb(bVal & ALI_SPDIF_OUT_CH_STATUS, ALI_REG(codec, ALI_SPDIF_CTRL));
940    
941         {
942                 wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL));
943                 wVal |= ALI_SPDIF_OUT_SEL_PCM;
944                 outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
945                 snd_ali_disable_special_channel(codec,ALI_SPDIF_OUT_CHANNEL);
946         }
947 }
948
949 static void snd_ali_enable_spdif_chnout(ali_t *codec)
950 {
951         unsigned short wVal = 0;
952
953         wVal  = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL));
954         wVal &= ~ALI_SPDIF_OUT_SEL_PCM;
955         outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
956 /*
957         wVal = inw(ALI_REG(codec, ALI_SPDIF_CS));
958         if (flag & ALI_SPDIF_OUT_NON_PCM)
959                 wVal |= 0x0002;
960         else    
961                 wVal &= (~0x0002);
962         outw(wVal, ALI_REG(codec, ALI_SPDIF_CS));
963 */
964         snd_ali_enable_special_channel(codec,ALI_SPDIF_OUT_CHANNEL);
965 }
966
967 static void snd_ali_disable_spdif_chnout(ali_t *codec)
968 {
969         unsigned short wVal = 0;
970         wVal  = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL));
971         wVal |= ALI_SPDIF_OUT_SEL_PCM;
972         outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
973
974         snd_ali_enable_special_channel(codec, ALI_SPDIF_OUT_CHANNEL);
975 }
976
977 static void snd_ali_disable_spdif_out(ali_t *codec)
978 {
979         unsigned char  bVal;
980
981         bVal = inb(ALI_REG(codec, ALI_SCTRL));
982         outb(bVal & ~ALI_SPDIF_OUT_ENABLE, ALI_REG(codec, ALI_SCTRL));
983
984         snd_ali_disable_spdif_chnout(codec);
985 }
986
987 static void snd_ali_update_ptr(ali_t *codec,int channel)
988 {
989         snd_ali_voice_t *pvoice = NULL;
990         snd_pcm_runtime_t *runtime;
991         snd_ali_channel_control_t *pchregs = NULL;
992         unsigned int old, mask;
993 #ifdef ALI_DEBUG
994         unsigned int temp, cspf;
995 #endif
996
997         pchregs = &(codec->chregs);
998
999         // check if interrupt occurred for channel
1000         old  = pchregs->data.aint;
1001         mask = ((unsigned int) 1L) << (channel & 0x1f);
1002
1003         if (!(old & mask))
1004                 return;
1005
1006         pvoice = &codec->synth.voices[channel];
1007         runtime = pvoice->substream->runtime;
1008
1009         udelay(100);
1010         spin_lock(&codec->reg_lock);
1011
1012         if (pvoice->pcm && pvoice->substream) {
1013                 /* pcm interrupt */
1014 #ifdef ALI_DEBUG
1015                 outb((u8)(pvoice->number), ALI_REG(codec, ALI_GC_CIR));
1016                 temp = inw(ALI_REG(codec, ALI_CSO_ALPHA_FMS + 2));
1017                 cspf = (inl(ALI_REG(codec, ALI_CSPF)) & mask) == mask;
1018 #endif
1019                 if (pvoice->running) {
1020                         snd_ali_printk("update_ptr: cso=%4.4x cspf=%d.\n",(u16)temp,cspf);
1021                         spin_unlock(&codec->reg_lock);
1022                         snd_pcm_period_elapsed(pvoice->substream);
1023                         spin_lock(&codec->reg_lock);
1024                 } else {
1025                         snd_ali_stop_voice(codec, channel);
1026                         snd_ali_disable_voice_irq(codec, channel);
1027                 }       
1028         } else if (codec->synth.voices[channel].synth) {
1029                 /* synth interrupt */
1030         } else if (codec->synth.voices[channel].midi) {
1031                 /* midi interrupt */
1032         } else {
1033                 /* unknown interrupt */
1034                 snd_ali_stop_voice(codec, channel);
1035                 snd_ali_disable_voice_irq(codec, channel);
1036         }
1037         spin_unlock(&codec->reg_lock);
1038         outl(mask,ALI_REG(codec,pchregs->regs.aint));
1039         pchregs->data.aint = old & (~mask);
1040 }
1041
1042 static void snd_ali_interrupt(ali_t * codec)
1043 {
1044         int channel;
1045         unsigned int audio_int;
1046         snd_ali_channel_control_t *pchregs = NULL;
1047         pchregs = &(codec->chregs);
1048
1049         audio_int = inl(ALI_REG(codec, ALI_MISCINT));
1050         if (audio_int & ADDRESS_IRQ) {
1051                 // get interrupt status for all channels
1052                 pchregs->data.aint = inl(ALI_REG(codec,pchregs->regs.aint));
1053                 for (channel = 0; channel < ALI_CHANNELS; channel++) {
1054                         snd_ali_update_ptr(codec, channel);
1055                 }
1056         }
1057         outl((TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW),
1058                 ALI_REG(codec,ALI_MISCINT));
1059 }
1060
1061
1062 static irqreturn_t snd_ali_card_interrupt(int irq,
1063                                    void *dev_id,
1064                                    struct pt_regs *regs)
1065 {
1066         ali_t   *codec = dev_id;
1067
1068         if (codec == NULL)
1069                 return IRQ_NONE;
1070         snd_ali_interrupt(codec);
1071         return IRQ_HANDLED;
1072 }
1073
1074
1075 static snd_ali_voice_t *snd_ali_alloc_voice(ali_t * codec, int type, int rec, int channel)
1076 {
1077         snd_ali_voice_t *pvoice = NULL;
1078         unsigned long flags;
1079         int idx;
1080
1081         snd_ali_printk("alloc_voice: type=%d rec=%d\n",type,rec);
1082
1083         spin_lock_irqsave(&codec->voice_alloc, flags);
1084         if (type == SNDRV_ALI_VOICE_TYPE_PCM) {
1085                 idx = channel > 0 ? snd_ali_alloc_pcm_channel(codec, channel) :
1086                         snd_ali_find_free_channel(codec,rec);
1087                 if(idx < 0) {
1088                         snd_printk("ali_alloc_voice: err.\n");
1089                         spin_unlock_irqrestore(&codec->voice_alloc, flags);
1090                         return NULL;
1091                 }
1092                 pvoice = &(codec->synth.voices[idx]);
1093                 pvoice->use = 1;
1094                 pvoice->pcm = 1;
1095                 pvoice->mode = rec;
1096                 spin_unlock_irqrestore(&codec->voice_alloc, flags);
1097                 return pvoice;
1098         }
1099         spin_unlock_irqrestore(&codec->voice_alloc, flags);
1100         return NULL;
1101 }
1102
1103
1104 static void snd_ali_free_voice(ali_t * codec, snd_ali_voice_t *pvoice)
1105 {
1106         unsigned long flags;
1107         void (*private_free)(void *);
1108         void *private_data;
1109
1110         snd_ali_printk("free_voice: channel=%d\n",pvoice->number);
1111         if (pvoice == NULL || !pvoice->use)
1112                 return;
1113         snd_ali_clear_voices(codec, pvoice->number, pvoice->number);
1114         spin_lock_irqsave(&codec->voice_alloc, flags);
1115         private_free = pvoice->private_free;
1116         private_data = pvoice->private_data;
1117         pvoice->private_free = NULL;
1118         pvoice->private_data = NULL;
1119         if (pvoice->pcm) {
1120                 snd_ali_free_channel_pcm(codec, pvoice->number);
1121         }
1122         pvoice->use = pvoice->pcm = pvoice->synth = 0;
1123         pvoice->substream = NULL;
1124         spin_unlock_irqrestore(&codec->voice_alloc, flags);
1125         if (private_free)
1126                 private_free(private_data);
1127 }
1128
1129
1130 static void snd_ali_clear_voices(ali_t * codec,
1131                           unsigned int v_min,
1132                           unsigned int v_max)
1133 {
1134         unsigned int i;
1135
1136         for (i = v_min; i <= v_max; i++) {
1137                 snd_ali_stop_voice(codec, i);
1138                 snd_ali_disable_voice_irq(codec, i);
1139         }
1140 }
1141
1142 static void snd_ali_write_voice_regs(ali_t * codec,
1143                          unsigned int Channel,
1144                          unsigned int LBA,
1145                          unsigned int CSO,
1146                          unsigned int ESO,
1147                          unsigned int DELTA,
1148                          unsigned int ALPHA_FMS,
1149                          unsigned int GVSEL,
1150                          unsigned int PAN,
1151                          unsigned int VOL,
1152                          unsigned int CTRL,
1153                          unsigned int EC)
1154 {
1155         unsigned int ctlcmds[4];
1156         
1157         outb((unsigned char)(Channel & 0x001f),ALI_REG(codec,ALI_GC_CIR));
1158
1159         ctlcmds[0] =  (CSO << 16) | (ALPHA_FMS & 0x0000ffff);
1160         ctlcmds[1] =  LBA;
1161         ctlcmds[2] =  (ESO << 16) | (DELTA & 0x0ffff);
1162         ctlcmds[3] =  (GVSEL << 31) |
1163                       ((PAN & 0x0000007f) << 24) |
1164                       ((VOL & 0x000000ff) << 16) |
1165                       ((CTRL & 0x0000000f) << 12) |
1166                       (EC & 0x00000fff);
1167
1168         outb(Channel, ALI_REG(codec, ALI_GC_CIR));
1169
1170         outl(ctlcmds[0], ALI_REG(codec,ALI_CSO_ALPHA_FMS));
1171         outl(ctlcmds[1], ALI_REG(codec,ALI_LBA));
1172         outl(ctlcmds[2], ALI_REG(codec,ALI_ESO_DELTA));
1173         outl(ctlcmds[3], ALI_REG(codec,ALI_GVSEL_PAN_VOC_CTRL_EC));
1174
1175         outl(0x30000000, ALI_REG(codec, ALI_EBUF1));    /* Still Mode */
1176         outl(0x30000000, ALI_REG(codec, ALI_EBUF2));    /* Still Mode */
1177 }
1178
1179 static unsigned int snd_ali_convert_rate(unsigned int rate, int rec)
1180 {
1181         unsigned int delta;
1182
1183         if (rate < 4000)  rate = 4000;
1184         if (rate > 48000) rate = 48000;
1185
1186         if (rec) {
1187                 if (rate == 44100)
1188                         delta = 0x116a;
1189                 else if (rate == 8000)
1190                         delta = 0x6000;
1191                 else if (rate == 48000)
1192                         delta = 0x1000;
1193                 else
1194                         delta = ((48000 << 12) / rate) & 0x0000ffff;
1195         } else {
1196                 if (rate == 44100)
1197                         delta = 0xeb3;
1198                 else if (rate == 8000)
1199                         delta = 0x2ab;
1200                 else if (rate == 48000)
1201                         delta = 0x1000;
1202                 else 
1203                         delta = (((rate << 12) + rate) / 48000) & 0x0000ffff;
1204         }
1205
1206         return delta;
1207 }
1208
1209 static unsigned int snd_ali_control_mode(snd_pcm_substream_t *substream)
1210 {
1211         unsigned int CTRL;
1212         snd_pcm_runtime_t *runtime = substream->runtime;
1213
1214         /* set ctrl mode
1215            CTRL default: 8-bit (unsigned) mono, loop mode enabled
1216          */
1217         CTRL = 0x00000001;
1218         if (snd_pcm_format_width(runtime->format) == 16)
1219                 CTRL |= 0x00000008;     // 16-bit data
1220         if (!snd_pcm_format_unsigned(runtime->format))
1221                 CTRL |= 0x00000002;     // signed data
1222         if (runtime->channels > 1)
1223                 CTRL |= 0x00000004;     // stereo data
1224         return CTRL;
1225 }
1226
1227 /*
1228  *  PCM part
1229  */
1230
1231 static int snd_ali_ioctl(snd_pcm_substream_t * substream,
1232                                   unsigned int cmd, void *arg)
1233 {
1234         return snd_pcm_lib_ioctl(substream, cmd, arg);
1235 }
1236
1237 static int snd_ali_trigger(snd_pcm_substream_t *substream,
1238                                int cmd)
1239                                     
1240 {
1241         ali_t *codec = snd_pcm_substream_chip(substream);
1242         struct list_head *pos;
1243         snd_pcm_substream_t *s;
1244         unsigned int what, whati, capture_flag;
1245         snd_ali_voice_t *pvoice = NULL, *evoice = NULL;
1246         unsigned int val;
1247         int do_start;
1248
1249         switch (cmd) {
1250         case SNDRV_PCM_TRIGGER_START:
1251         case SNDRV_PCM_TRIGGER_RESUME:
1252                 do_start = 1; break;
1253         case SNDRV_PCM_TRIGGER_STOP:
1254         case SNDRV_PCM_TRIGGER_SUSPEND:
1255                 do_start = 0; break;
1256         default:
1257                 return -EINVAL;
1258         }
1259
1260         what = whati = capture_flag = 0;
1261         snd_pcm_group_for_each(pos, substream) {
1262                 s = snd_pcm_group_substream_entry(pos);
1263                 if ((ali_t *) snd_pcm_substream_chip(s) == codec) {
1264                         pvoice = (snd_ali_voice_t *) s->runtime->private_data;
1265                         evoice = pvoice->extra;
1266                         what |= 1 << (pvoice->number & 0x1f);
1267                         if (evoice == NULL) {
1268                                 whati |= 1 << (pvoice->number & 0x1f);
1269                         } else {
1270                                 whati |= 1 << (evoice->number & 0x1f);
1271                                 what |= 1 << (evoice->number & 0x1f);
1272                         }
1273                         if (do_start) {
1274                                 pvoice->running = 1;
1275                                 if (evoice != NULL)
1276                                         evoice->running = 1;
1277                         } else {
1278                                 pvoice->running = 0;
1279                                 if (evoice != NULL)
1280                                         evoice->running = 0;
1281                         }
1282                         snd_pcm_trigger_done(s, substream);
1283                         if (pvoice->mode)
1284                                 capture_flag = 1;
1285                 }
1286         }
1287         spin_lock(&codec->reg_lock);
1288         if (! do_start) {
1289                 outl(what, ALI_REG(codec, ALI_STOP));
1290         }
1291         val = inl(ALI_REG(codec, ALI_AINTEN));
1292         if (do_start) {
1293                 val |= whati;
1294         } else {
1295                 val &= ~whati;
1296         }
1297         outl(val, ALI_REG(codec, ALI_AINTEN));
1298         if (do_start) {
1299                 outl(what, ALI_REG(codec, ALI_START));
1300         }
1301         snd_ali_printk("trigger: what=%xh whati=%xh\n",what,whati);
1302         spin_unlock(&codec->reg_lock);
1303
1304         return 0;
1305 }
1306
1307 static int snd_ali_playback_hw_params(snd_pcm_substream_t * substream,
1308                                  snd_pcm_hw_params_t * hw_params)
1309 {
1310         ali_t *codec = snd_pcm_substream_chip(substream);
1311         snd_pcm_runtime_t *runtime = substream->runtime;
1312         snd_ali_voice_t *pvoice = (snd_ali_voice_t *) runtime->private_data;
1313         snd_ali_voice_t *evoice = pvoice->extra;
1314         int err;
1315         err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
1316         if (err < 0) return err;
1317         
1318         /* voice management */
1319
1320         if (params_buffer_size(hw_params)/2 != params_period_size(hw_params)) {
1321                 if (evoice == NULL) {
1322                         evoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, 0, -1);
1323                         if (evoice == NULL)
1324                                 return -ENOMEM;
1325                         pvoice->extra = evoice;
1326                         evoice->substream = substream;
1327                 }
1328         } else {
1329                 if (evoice != NULL) {
1330                         snd_ali_free_voice(codec, evoice);
1331                         pvoice->extra = evoice = NULL;
1332                 }
1333         }
1334
1335         return 0;
1336 }
1337
1338 static int snd_ali_playback_hw_free(snd_pcm_substream_t * substream)
1339 {
1340         ali_t *codec = snd_pcm_substream_chip(substream);
1341         snd_pcm_runtime_t *runtime = substream->runtime;
1342         snd_ali_voice_t *pvoice = (snd_ali_voice_t *) runtime->private_data;
1343         snd_ali_voice_t *evoice = pvoice ? pvoice->extra : NULL;
1344
1345         snd_pcm_lib_free_pages(substream);
1346         if (evoice != NULL) {
1347                 snd_ali_free_voice(codec, evoice);
1348                 pvoice->extra = NULL;
1349         }
1350         return 0;
1351 }
1352
1353 static int snd_ali_hw_params(snd_pcm_substream_t * substream,
1354                                  snd_pcm_hw_params_t * hw_params)
1355 {
1356         return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
1357 }
1358
1359 static int snd_ali_hw_free(snd_pcm_substream_t * substream)
1360 {
1361         return snd_pcm_lib_free_pages(substream);
1362 }
1363
1364 static int snd_ali_playback_prepare(snd_pcm_substream_t * substream)
1365 {
1366         ali_t *codec = snd_pcm_substream_chip(substream);
1367         snd_pcm_runtime_t *runtime = substream->runtime;
1368         snd_ali_voice_t *pvoice = (snd_ali_voice_t *) runtime->private_data;
1369         snd_ali_voice_t *evoice = pvoice->extra;
1370         unsigned long flags;
1371
1372         unsigned int LBA;
1373         unsigned int Delta;
1374         unsigned int ESO;
1375         unsigned int CTRL;
1376         unsigned int GVSEL;
1377         unsigned int PAN;
1378         unsigned int VOL;
1379         unsigned int EC;
1380         
1381         snd_ali_printk("playback_prepare ...\n");
1382
1383         spin_lock_irqsave(&codec->reg_lock, flags);     
1384         
1385         /* set Delta (rate) value */
1386         Delta = snd_ali_convert_rate(runtime->rate, 0);
1387
1388         if ((pvoice->number == ALI_SPDIF_IN_CHANNEL) || 
1389             (pvoice->number == ALI_PCM_IN_CHANNEL))
1390                 snd_ali_disable_special_channel(codec, pvoice->number);
1391         else if (codec->spdif_support &&
1392                  (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_OUT_CH_ENABLE)
1393                  && (pvoice->number == ALI_SPDIF_OUT_CHANNEL)) {
1394                 snd_ali_set_spdif_out_rate(codec, runtime->rate);
1395                 Delta = 0x1000;
1396         }
1397         
1398         /* set Loop Back Address */
1399         LBA = runtime->dma_addr;
1400
1401         /* set interrupt count size */
1402         pvoice->count = runtime->period_size;
1403
1404         /* set target ESO for channel */
1405         pvoice->eso = runtime->buffer_size; 
1406
1407         snd_ali_printk("playback_prepare: eso=%xh count=%xh\n",pvoice->eso,pvoice->count);
1408
1409         /* set ESO to capture first MIDLP interrupt */
1410         ESO = pvoice->eso -1;
1411         /* set ctrl mode */
1412         CTRL = snd_ali_control_mode(substream);
1413
1414         GVSEL = 1;
1415         PAN = 0;
1416         VOL = 0;
1417         EC = 0;
1418         snd_ali_printk("playback_prepare:\n    ch=%d, Rate=%d Delta=%xh,GVSEL=%xh,PAN=%xh,CTRL=%xh\n",pvoice->number,runtime->rate,Delta,GVSEL,PAN,CTRL);
1419         snd_ali_write_voice_regs(    codec,
1420                                      pvoice->number,
1421                                      LBA,
1422                                      0, /* cso */
1423                                      ESO,
1424                                      Delta,
1425                                      0, /* alpha */
1426                                      GVSEL,
1427                                      PAN,
1428                                      VOL,
1429                                      CTRL,
1430                                      EC);
1431         if (evoice != NULL) {
1432                 evoice->count = pvoice->count;
1433                 evoice->eso = pvoice->count << 1;
1434                 ESO = evoice->eso - 1;
1435                 snd_ali_write_voice_regs(codec,
1436                                      evoice->number,
1437                                      LBA,
1438                                      0, /* cso */
1439                                      ESO,
1440                                      Delta,
1441                                      0, /* alpha */
1442                                      GVSEL,
1443                                      (unsigned int)0x7f,
1444                                      (unsigned int)0x3ff,
1445                                      CTRL,
1446                                      EC);
1447         }
1448         spin_unlock_irqrestore(&codec->reg_lock, flags);
1449         return 0;
1450 }
1451
1452
1453 static int snd_ali_prepare(snd_pcm_substream_t * substream)
1454 {
1455         ali_t *codec = snd_pcm_substream_chip(substream);
1456         snd_pcm_runtime_t *runtime = substream->runtime;
1457         snd_ali_voice_t *pvoice = (snd_ali_voice_t *) runtime->private_data;
1458         unsigned long flags;
1459         unsigned int LBA;
1460         unsigned int Delta;
1461         unsigned int ESO;
1462         unsigned int CTRL;
1463         unsigned int GVSEL;
1464         unsigned int PAN;
1465         unsigned int VOL;
1466         unsigned int EC;
1467         u8       bValue;
1468
1469         spin_lock_irqsave(&codec->reg_lock, flags);
1470
1471         snd_ali_printk("ali_prepare...\n");
1472
1473         snd_ali_enable_special_channel(codec,pvoice->number);
1474
1475         Delta = (pvoice->number == ALI_MODEM_IN_CHANNEL ||
1476                  pvoice->number == ALI_MODEM_OUT_CHANNEL) ? 
1477                 0x1000 : snd_ali_convert_rate(runtime->rate, pvoice->mode);
1478
1479         // Prepare capture intr channel
1480         if (pvoice->number == ALI_SPDIF_IN_CHANNEL) {
1481
1482                 unsigned int rate;
1483                 
1484                 if (codec->revision != ALI_5451_V02) {
1485                         spin_unlock_irqrestore(&codec->reg_lock, flags);                        
1486                         return -1;
1487                 }
1488                 rate = snd_ali_get_spdif_in_rate(codec);
1489                 if (rate == 0) {
1490                         snd_printk("ali_capture_preapre: spdif rate detect err!\n");
1491                         rate = 48000;
1492                 }
1493                 bValue = inb(ALI_REG(codec,ALI_SPDIF_CTRL));
1494                 if (bValue & 0x10) {
1495                         outb(bValue,ALI_REG(codec,ALI_SPDIF_CTRL));
1496                         printk("clear SPDIF parity error flag.\n");
1497                 }
1498
1499                 if (rate != 48000)
1500                         Delta = ((rate << 12)/runtime->rate)&0x00ffff;
1501         }
1502
1503         // set target ESO for channel 
1504         pvoice->eso = runtime->buffer_size; 
1505
1506         // set interrupt count size 
1507         pvoice->count = runtime->period_size;
1508
1509         // set Loop Back Address 
1510         LBA = runtime->dma_addr;
1511
1512         // set ESO to capture first MIDLP interrupt 
1513         ESO = pvoice->eso - 1;
1514         CTRL = snd_ali_control_mode(substream);
1515         GVSEL = 0;
1516         PAN = 0x00;
1517         VOL = 0x00;
1518         EC = 0;
1519
1520         snd_ali_write_voice_regs(    codec,
1521                                      pvoice->number,
1522                                      LBA,
1523                                      0, /* cso */
1524                                      ESO,
1525                                      Delta,
1526                                      0, /* alpha */
1527                                      GVSEL,
1528                                      PAN,
1529                                      VOL,
1530                                      CTRL,
1531                                      EC);
1532
1533
1534         spin_unlock_irqrestore(&codec->reg_lock, flags);
1535
1536         return 0;
1537 }
1538
1539
1540 static snd_pcm_uframes_t snd_ali_playback_pointer(snd_pcm_substream_t *substream)
1541 {
1542         ali_t *codec = snd_pcm_substream_chip(substream);
1543         snd_pcm_runtime_t *runtime = substream->runtime;
1544         snd_ali_voice_t *pvoice = (snd_ali_voice_t *) runtime->private_data;
1545         unsigned int cso;
1546
1547         spin_lock(&codec->reg_lock);
1548         if (!pvoice->running) {
1549                 spin_unlock(&codec->reg_lock);
1550                 return 0;
1551         }
1552         outb(pvoice->number, ALI_REG(codec, ALI_GC_CIR));
1553         cso = inw(ALI_REG(codec, ALI_CSO_ALPHA_FMS + 2));
1554         spin_unlock(&codec->reg_lock);
1555         snd_ali_printk("playback pointer returned cso=%xh.\n", cso);
1556
1557         return cso;
1558 }
1559
1560
1561 static snd_pcm_uframes_t snd_ali_pointer(snd_pcm_substream_t *substream)
1562 {
1563         ali_t *codec = snd_pcm_substream_chip(substream);
1564         snd_pcm_runtime_t *runtime = substream->runtime;
1565         snd_ali_voice_t *pvoice = (snd_ali_voice_t *) runtime->private_data;
1566         unsigned int cso;
1567         unsigned long flags;
1568
1569         spin_lock_irqsave(&codec->reg_lock, flags);
1570         if (!pvoice->running) {
1571                 spin_unlock_irqrestore(&codec->reg_lock, flags);
1572                 return 0;
1573         }
1574         outb(pvoice->number, ALI_REG(codec, ALI_GC_CIR));
1575         cso = inw(ALI_REG(codec, ALI_CSO_ALPHA_FMS + 2));
1576         spin_unlock_irqrestore(&codec->reg_lock, flags);
1577
1578         return cso;
1579 }
1580
1581 static snd_pcm_hardware_t snd_ali_playback =
1582 {
1583         .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1584                                  SNDRV_PCM_INFO_BLOCK_TRANSFER |
1585                                  SNDRV_PCM_INFO_MMAP_VALID |
1586                                  SNDRV_PCM_INFO_RESUME |
1587                                  SNDRV_PCM_INFO_SYNC_START),
1588         .formats =              (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
1589                                  SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
1590         .rates =                SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1591         .rate_min =             4000,
1592         .rate_max =             48000,
1593         .channels_min =         1,
1594         .channels_max =         2,
1595         .buffer_bytes_max =     (256*1024),
1596         .period_bytes_min =     64,
1597         .period_bytes_max =     (256*1024),
1598         .periods_min =          1,
1599         .periods_max =          1024,
1600         .fifo_size =            0,
1601 };
1602
1603 /*
1604  *  Capture support device description
1605  */
1606
1607 static snd_pcm_hardware_t snd_ali_capture =
1608 {
1609         .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1610                                  SNDRV_PCM_INFO_BLOCK_TRANSFER |
1611                                  SNDRV_PCM_INFO_MMAP_VALID |
1612                                  SNDRV_PCM_INFO_RESUME |
1613                                  SNDRV_PCM_INFO_SYNC_START),
1614         .formats =              (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
1615                                  SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
1616         .rates =                SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1617         .rate_min =             4000,
1618         .rate_max =             48000,
1619         .channels_min =         1,
1620         .channels_max =         2,
1621         .buffer_bytes_max =     (128*1024),
1622         .period_bytes_min =     64,
1623         .period_bytes_max =     (128*1024),
1624         .periods_min =          1,
1625         .periods_max =          1024,
1626         .fifo_size =            0,
1627 };
1628
1629 static void snd_ali_pcm_free_substream(snd_pcm_runtime_t *runtime)
1630 {
1631         unsigned long flags;
1632         snd_ali_voice_t *pvoice = (snd_ali_voice_t *) runtime->private_data;
1633         ali_t *codec;
1634
1635         if (pvoice) {
1636                 codec = pvoice->codec;
1637                 spin_lock_irqsave(&codec->reg_lock, flags);
1638                 snd_ali_free_voice(pvoice->codec, pvoice);
1639                 spin_unlock_irqrestore(&codec->reg_lock, flags);
1640         }
1641 }
1642
1643 static int snd_ali_open(snd_pcm_substream_t * substream, int rec, int channel,
1644                 snd_pcm_hardware_t *phw)
1645 {
1646         ali_t *codec = snd_pcm_substream_chip(substream);
1647         snd_pcm_runtime_t *runtime = substream->runtime;
1648         snd_ali_voice_t *pvoice;
1649         unsigned long flags = 0;
1650
1651         spin_lock_irqsave(&codec->reg_lock, flags);
1652         pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, rec, channel);
1653         if (pvoice == NULL) {
1654                 spin_unlock_irqrestore(&codec->reg_lock, flags);
1655                 return -EAGAIN;
1656         }
1657         pvoice->codec = codec;
1658         spin_unlock_irqrestore(&codec->reg_lock, flags);
1659
1660         pvoice->substream = substream;
1661         runtime->private_data = pvoice;
1662         runtime->private_free = snd_ali_pcm_free_substream;
1663
1664         runtime->hw = *phw;
1665         snd_pcm_set_sync(substream);
1666         snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
1667         return 0;
1668 }
1669
1670 static int snd_ali_playback_open(snd_pcm_substream_t * substream)
1671 {
1672         return snd_ali_open(substream, 0, -1, &snd_ali_playback);
1673 }
1674
1675 static int snd_ali_capture_open(snd_pcm_substream_t * substream)
1676 {
1677         return snd_ali_open(substream, 1, -1, &snd_ali_capture);
1678 }
1679
1680 static int snd_ali_playback_close(snd_pcm_substream_t * substream)
1681 {
1682         return 0;
1683 }
1684
1685 static int snd_ali_close(snd_pcm_substream_t * substream)
1686 {
1687         ali_t *codec = snd_pcm_substream_chip(substream);
1688         snd_ali_voice_t *pvoice = (snd_ali_voice_t *) substream->runtime->private_data;
1689
1690         snd_ali_disable_special_channel(codec,pvoice->number);
1691
1692         return 0;
1693 }
1694
1695 static snd_pcm_ops_t snd_ali_playback_ops = {
1696         .open =         snd_ali_playback_open,
1697         .close =        snd_ali_playback_close,
1698         .ioctl =        snd_ali_ioctl,
1699         .hw_params =    snd_ali_playback_hw_params,
1700         .hw_free =      snd_ali_playback_hw_free,
1701         .prepare =      snd_ali_playback_prepare,
1702         .trigger =      snd_ali_trigger,
1703         .pointer =      snd_ali_playback_pointer,
1704 };
1705
1706 static snd_pcm_ops_t snd_ali_capture_ops = {
1707         .open =         snd_ali_capture_open,
1708         .close =        snd_ali_close,
1709         .ioctl =        snd_ali_ioctl,
1710         .hw_params =    snd_ali_hw_params,
1711         .hw_free =      snd_ali_hw_free,
1712         .prepare =      snd_ali_prepare,
1713         .trigger =      snd_ali_trigger,
1714         .pointer =      snd_ali_pointer,
1715 };
1716
1717 /*
1718  * Modem PCM
1719  */
1720
1721 static int snd_ali_modem_hw_params(snd_pcm_substream_t * substream,
1722                                  snd_pcm_hw_params_t * hw_params)
1723 {
1724         ali_t *chip = snd_pcm_substream_chip(substream);
1725         unsigned int modem_num = chip->num_of_codecs - 1;
1726         snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_RATE, params_rate(hw_params));
1727         snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_LEVEL, 0);
1728         return snd_ali_hw_params(substream, hw_params);
1729 }
1730
1731 static snd_pcm_hardware_t snd_ali_modem =
1732 {
1733         .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1734                                  SNDRV_PCM_INFO_BLOCK_TRANSFER |
1735                                  SNDRV_PCM_INFO_MMAP_VALID |
1736                                  SNDRV_PCM_INFO_RESUME |
1737                                  SNDRV_PCM_INFO_SYNC_START),
1738         .formats =              SNDRV_PCM_FMTBIT_S16_LE,
1739         .rates =                SNDRV_PCM_RATE_KNOT|SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000,
1740         .rate_min =             8000,
1741         .rate_max =             16000,
1742         .channels_min =         1,
1743         .channels_max =         1,
1744         .buffer_bytes_max =     (256*1024),
1745         .period_bytes_min =     64,
1746         .period_bytes_max =     (256*1024),
1747         .periods_min =          1,
1748         .periods_max =          1024,
1749         .fifo_size =            0,
1750 };
1751
1752 static int snd_ali_modem_open(snd_pcm_substream_t * substream, int rec, int channel)
1753 {
1754         static unsigned int rates [] = {8000,9600,12000,16000};
1755         static snd_pcm_hw_constraint_list_t hw_constraint_rates = {
1756                 .count = ARRAY_SIZE(rates),
1757                 .list = rates,
1758                 .mask = 0,
1759         };
1760         int err = snd_ali_open(substream, rec, channel, &snd_ali_modem);
1761         if (err)
1762                 return err;
1763         return snd_pcm_hw_constraint_list(substream->runtime, 0,
1764                         SNDRV_PCM_HW_PARAM_RATE, &hw_constraint_rates);
1765 }
1766
1767 static int snd_ali_modem_playback_open(snd_pcm_substream_t * substream)
1768 {
1769         return snd_ali_modem_open(substream, 0, ALI_MODEM_OUT_CHANNEL);
1770 }
1771
1772 static int snd_ali_modem_capture_open(snd_pcm_substream_t * substream)
1773 {
1774         return snd_ali_modem_open(substream, 1, ALI_MODEM_IN_CHANNEL);
1775 }
1776
1777 static snd_pcm_ops_t snd_ali_modem_playback_ops = {
1778         .open =         snd_ali_modem_playback_open,
1779         .close =        snd_ali_close,
1780         .ioctl =        snd_pcm_lib_ioctl,
1781         .hw_params =    snd_ali_modem_hw_params,
1782         .hw_free =      snd_ali_hw_free,
1783         .prepare =      snd_ali_prepare,
1784         .trigger =      snd_ali_trigger,
1785         .pointer =      snd_ali_pointer,
1786 };
1787
1788 static snd_pcm_ops_t snd_ali_modem_capture_ops = {
1789         .open =         snd_ali_modem_capture_open,
1790         .close =        snd_ali_close,
1791         .ioctl =        snd_pcm_lib_ioctl,
1792         .hw_params =    snd_ali_modem_hw_params,
1793         .hw_free =      snd_ali_hw_free,
1794         .prepare =      snd_ali_prepare,
1795         .trigger =      snd_ali_trigger,
1796         .pointer =      snd_ali_pointer,
1797 };
1798
1799
1800 struct ali_pcm_description {
1801         char *name;
1802         unsigned int playback_num;
1803         unsigned int capture_num;
1804         snd_pcm_ops_t *playback_ops;
1805         snd_pcm_ops_t *capture_ops;
1806 };
1807
1808
1809 static void snd_ali_pcm_free(snd_pcm_t *pcm)
1810 {
1811         ali_t *codec = pcm->private_data;
1812         codec->pcm[pcm->device] = NULL;
1813 }
1814
1815
1816 static int __devinit snd_ali_pcm(ali_t * codec, int device, struct ali_pcm_description *desc)
1817 {
1818         snd_pcm_t *pcm;
1819         int err;
1820
1821         err = snd_pcm_new(codec->card, desc->name, device,
1822                           desc->playback_num, desc->capture_num, &pcm);
1823         if (err < 0) {
1824                 snd_printk("snd_ali_pcm: err called snd_pcm_new.\n");
1825                 return err;
1826         }
1827         pcm->private_data = codec;
1828         pcm->private_free = snd_ali_pcm_free;
1829         pcm->info_flags = 0;
1830         if (desc->playback_ops)
1831                 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, desc->playback_ops);
1832         if (desc->capture_ops)
1833                 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, desc->capture_ops);
1834
1835         snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1836                                               snd_dma_pci_data(codec->pci), 64*1024, 128*1024);
1837
1838         pcm->info_flags = 0;
1839         pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
1840         strcpy(pcm->name, desc->name);
1841         codec->pcm[0] = pcm;
1842         return 0;
1843 }
1844
1845 struct ali_pcm_description ali_pcms[] = {
1846         { "ALI 5451", ALI_CHANNELS, 1, &snd_ali_playback_ops, &snd_ali_capture_ops },
1847         { "ALI 5451 modem", 1, 1, &snd_ali_modem_playback_ops, &snd_ali_modem_capture_ops }
1848 };
1849
1850 static int __devinit snd_ali_build_pcms(ali_t *codec)
1851 {
1852         int i, err;
1853         for(i = 0 ; i < codec->num_of_codecs && i < ARRAY_SIZE(ali_pcms) ; i++)
1854                 if((err = snd_ali_pcm(codec, i, &ali_pcms[i])) < 0)
1855                         return err;
1856         return 0;
1857 }
1858
1859
1860 #define ALI5451_SPDIF(xname, xindex, value) \
1861 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex,\
1862 .info = snd_ali5451_spdif_info, .get = snd_ali5451_spdif_get, \
1863 .put = snd_ali5451_spdif_put, .private_value = value}
1864
1865 static int snd_ali5451_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1866 {
1867         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1868         uinfo->count = 1;
1869         uinfo->value.integer.min = 0;
1870         uinfo->value.integer.max = 1;
1871         return 0;
1872 }
1873
1874 static int snd_ali5451_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1875 {
1876         unsigned long flags;
1877         ali_t *codec = kcontrol->private_data;
1878         unsigned int enable;
1879
1880         enable = ucontrol->value.integer.value[0] ? 1 : 0;
1881
1882         spin_lock_irqsave(&codec->reg_lock, flags);
1883         switch(kcontrol->private_value) {
1884         case 0:
1885                 enable = (codec->spdif_mask & 0x02) ? 1 : 0;
1886                 break;
1887         case 1:
1888                 enable = ((codec->spdif_mask & 0x02) && (codec->spdif_mask & 0x04)) ? 1 : 0;
1889                 break;
1890         case 2:
1891                 enable = (codec->spdif_mask & 0x01) ? 1 : 0;
1892                 break;
1893         default:
1894                 break;
1895         }
1896         ucontrol->value.integer.value[0] = enable;
1897         spin_unlock_irqrestore(&codec->reg_lock, flags);
1898         return 0;
1899 }
1900
1901 static int snd_ali5451_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1902 {
1903         unsigned long flags;
1904         ali_t *codec = kcontrol->private_data;
1905         unsigned int change = 0, enable = 0;
1906
1907         enable = ucontrol->value.integer.value[0] ? 1 : 0;
1908
1909         spin_lock_irqsave(&codec->reg_lock, flags);
1910         switch (kcontrol->private_value) {
1911         case 0:
1912                 change = (codec->spdif_mask & 0x02) ? 1 : 0;
1913                 change = change ^ enable;
1914                 if (change) {
1915                         if (enable) {
1916                                 codec->spdif_mask |= 0x02;
1917                                 snd_ali_enable_spdif_out(codec);
1918                         } else {
1919                                 codec->spdif_mask &= ~(0x02);
1920                                 codec->spdif_mask &= ~(0x04);
1921                                 snd_ali_disable_spdif_out(codec);
1922                         }
1923                 }
1924                 break;
1925         case 1: 
1926                 change = (codec->spdif_mask & 0x04) ? 1 : 0;
1927                 change = change ^ enable;
1928                 if (change && (codec->spdif_mask & 0x02)) {
1929                         if (enable) {
1930                                 codec->spdif_mask |= 0x04;
1931                                 snd_ali_enable_spdif_chnout(codec);
1932                         } else {
1933                                 codec->spdif_mask &= ~(0x04);
1934                                 snd_ali_disable_spdif_chnout(codec);
1935                         }
1936                 }
1937                 break;
1938         case 2:
1939                 change = (codec->spdif_mask & 0x01) ? 1 : 0;
1940                 change = change ^ enable;
1941                 if (change) {
1942                         if (enable) {
1943                                 codec->spdif_mask |= 0x01;
1944                                 snd_ali_enable_spdif_in(codec);
1945                         } else {
1946                                 codec->spdif_mask &= ~(0x01);
1947                                 snd_ali_disable_spdif_in(codec);
1948                         }
1949                 }
1950                 break;
1951         default:
1952                 break;
1953         }
1954         spin_unlock_irqrestore(&codec->reg_lock, flags);
1955         
1956         return change;
1957 }
1958
1959 static snd_kcontrol_new_t snd_ali5451_mixer_spdif[] __devinitdata = {
1960         /* spdif aplayback switch */
1961         /* FIXME: "IEC958 Playback Switch" may conflict with one on ac97_codec */
1962         ALI5451_SPDIF("IEC958 Output switch", 0, 0),
1963         /* spdif out to spdif channel */
1964         ALI5451_SPDIF("IEC958 Channel Output Switch", 0, 1),
1965         /* spdif in from spdif channel */
1966         ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, 2)
1967 };
1968
1969 static void snd_ali_mixer_free_ac97_bus(ac97_bus_t *bus)
1970 {
1971         ali_t *codec = bus->private_data;
1972         codec->ac97_bus = NULL;
1973 }
1974
1975 static void snd_ali_mixer_free_ac97(ac97_t *ac97)
1976 {
1977         ali_t *codec = ac97->private_data;
1978         codec->ac97[ac97->num] = NULL;
1979 }
1980
1981 static int __devinit snd_ali_mixer(ali_t * codec)
1982 {
1983         ac97_template_t ac97;
1984         unsigned int idx;
1985         int i, err;
1986         static ac97_bus_ops_t ops = {
1987                 .write = snd_ali_codec_write,
1988                 .read = snd_ali_codec_read,
1989         };
1990
1991         if ((err = snd_ac97_bus(codec->card, 0, &ops, codec, &codec->ac97_bus)) < 0)
1992                 return err;
1993         codec->ac97_bus->private_free = snd_ali_mixer_free_ac97_bus;
1994
1995         memset(&ac97, 0, sizeof(ac97));
1996         ac97.private_data = codec;
1997         ac97.private_free = snd_ali_mixer_free_ac97;
1998
1999         for ( i = 0 ; i < codec->num_of_codecs ; i++) {
2000                 ac97.num = i;
2001                 if ((err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i])) < 0) {
2002                         snd_printk("ali mixer %d creating error.\n", i);
2003                         if(i == 0)
2004                 return err;
2005         }
2006         }
2007
2008         if (codec->spdif_support) {
2009                 for(idx = 0; idx < ARRAY_SIZE(snd_ali5451_mixer_spdif); idx++) {
2010                         err=snd_ctl_add(codec->card, snd_ctl_new1(&snd_ali5451_mixer_spdif[idx], codec));
2011                         if (err < 0) return err;
2012                 }
2013         }
2014         return 0;
2015 }
2016
2017 #ifdef CONFIG_PM
2018 static int ali_suspend(snd_card_t *card, pm_message_t state)
2019 {
2020         ali_t *chip = card->pm_private_data;
2021         ali_image_t *im;
2022         int i, j;
2023
2024         im = chip->image;
2025         if (! im)
2026                 return 0;
2027
2028         for(i = 0 ; i < chip->num_of_codecs ; i++) {
2029                 if (chip->pcm[i])
2030                         snd_pcm_suspend_all(chip->pcm[i]);
2031                 if(chip->ac97[i])
2032                         snd_ac97_suspend(chip->ac97[i]);
2033         }
2034
2035         spin_lock_irq(&chip->reg_lock);
2036         
2037         im->regs[ALI_MISCINT >> 2] = inl(ALI_REG(chip, ALI_MISCINT));
2038         // im->regs[ALI_START >> 2] = inl(ALI_REG(chip, ALI_START));
2039         im->regs[ALI_STOP >> 2] = inl(ALI_REG(chip, ALI_STOP));
2040         
2041         // disable all IRQ bits
2042         outl(0, ALI_REG(chip, ALI_MISCINT));
2043         
2044         for (i = 0; i < ALI_GLOBAL_REGS; i++) { 
2045                 if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP))
2046                         continue;
2047                 im->regs[i] = inl(ALI_REG(chip, i*4));
2048         }
2049         
2050         for (i = 0; i < ALI_CHANNELS; i++) {
2051                 outb(i, ALI_REG(chip, ALI_GC_CIR));
2052                 for (j = 0; j < ALI_CHANNEL_REGS; j++) 
2053                         im->channel_regs[i][j] = inl(ALI_REG(chip, j*4 + 0xe0));
2054         }
2055
2056         // stop all HW channel
2057         outl(0xffffffff, ALI_REG(chip, ALI_STOP));
2058
2059         spin_unlock_irq(&chip->reg_lock);
2060         pci_disable_device(chip->pci);
2061         return 0;
2062 }
2063
2064 static int ali_resume(snd_card_t *card)
2065 {
2066         ali_t *chip = card->pm_private_data;
2067         ali_image_t *im;
2068         int i, j;
2069
2070         im = chip->image;
2071         if (! im)
2072                 return 0;
2073
2074         pci_enable_device(chip->pci);
2075
2076         spin_lock_irq(&chip->reg_lock);
2077         
2078         for (i = 0; i < ALI_CHANNELS; i++) {
2079                 outb(i, ALI_REG(chip, ALI_GC_CIR));
2080                 for (j = 0; j < ALI_CHANNEL_REGS; j++) 
2081                         outl(im->channel_regs[i][j], ALI_REG(chip, j*4 + 0xe0));
2082         }
2083         
2084         for (i = 0; i < ALI_GLOBAL_REGS; i++) { 
2085                 if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) || (i*4 == ALI_START))
2086                         continue;
2087                 outl(im->regs[i], ALI_REG(chip, i*4));
2088         }
2089         
2090         // start HW channel
2091         outl(im->regs[ALI_START >> 2], ALI_REG(chip, ALI_START));
2092         // restore IRQ enable bits
2093         outl(im->regs[ALI_MISCINT >> 2], ALI_REG(chip, ALI_MISCINT));
2094         
2095         spin_unlock_irq(&chip->reg_lock);
2096
2097         for(i = 0 ; i < chip->num_of_codecs ; i++)
2098                 if(chip->ac97[i])
2099                         snd_ac97_resume(chip->ac97[i]);
2100         
2101         return 0;
2102 }
2103 #endif /* CONFIG_PM */
2104
2105 static int snd_ali_free(ali_t * codec)
2106 {
2107         if (codec->hw_initialized)
2108                 snd_ali_disable_address_interrupt(codec);
2109         if (codec->irq >= 0) {
2110                 synchronize_irq(codec->irq);
2111                 free_irq(codec->irq, (void *)codec);
2112         }
2113         if (codec->port)
2114                 pci_release_regions(codec->pci);
2115         pci_disable_device(codec->pci);
2116 #ifdef CONFIG_PM
2117         kfree(codec->image);
2118 #endif
2119         kfree(codec);
2120         return 0;
2121 }
2122
2123 static int snd_ali_chip_init(ali_t *codec)
2124 {
2125         unsigned int legacy;
2126         unsigned char temp;
2127         struct pci_dev *pci_dev = NULL;
2128
2129         snd_ali_printk("chip initializing ... \n");
2130
2131         if (snd_ali_reset_5451(codec)) {
2132                 snd_printk("ali_chip_init: reset 5451 error.\n");
2133                 return -1;
2134         }
2135
2136         if (codec->revision == ALI_5451_V02) {
2137                 pci_dev = codec->pci_m1533;
2138                 pci_read_config_byte(pci_dev, 0x59, &temp);
2139                 temp |= 0x80;
2140                 pci_write_config_byte(pci_dev, 0x59, temp);
2141         
2142                 pci_dev = codec->pci_m7101;
2143                 pci_read_config_byte(pci_dev, 0xb8, &temp);
2144                 temp |= 0x20;
2145                 pci_write_config_byte(pci_dev, 0xB8, temp);
2146         }
2147
2148         pci_read_config_dword(codec->pci, 0x44, &legacy);
2149         legacy &= 0xff00ff00;
2150         legacy |= 0x000800aa;
2151         pci_write_config_dword(codec->pci, 0x44, legacy);
2152
2153         outl(0x80000001, ALI_REG(codec, ALI_GLOBAL_CONTROL));
2154         outl(0x00000000, ALI_REG(codec, ALI_AINTEN));
2155         outl(0xffffffff, ALI_REG(codec, ALI_AINT));
2156         outl(0x00000000, ALI_REG(codec, ALI_VOLUME));
2157         outb(0x10,       ALI_REG(codec, ALI_MPUR2));
2158
2159         codec->ac97_ext_id = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_ID);
2160         codec->ac97_ext_status = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_STATUS);
2161         if (codec->spdif_support) {
2162                 snd_ali_enable_spdif_out(codec);
2163                 codec->spdif_mask = 0x00000002;
2164         }
2165
2166         codec->num_of_codecs = 1;
2167
2168         /* secondary codec - modem */
2169         if (inl(ALI_REG(codec, ALI_SCTRL)) & ALI_SCTRL_CODEC2_READY) {
2170                 codec->num_of_codecs++;
2171                 outl(inl(ALI_REG(codec, ALI_SCTRL)) |
2172                         (ALI_SCTRL_LINE_IN2|ALI_SCTRL_GPIO_IN2|ALI_SCTRL_LINE_OUT_EN),
2173                         ALI_REG(codec, ALI_SCTRL));
2174         }
2175
2176         snd_ali_printk("chip initialize succeed.\n");
2177         return 0;
2178
2179 }
2180
2181 /* proc for register dump */
2182 static void snd_ali_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buf)
2183 {
2184         ali_t *codec = entry->private_data;
2185         int i;
2186         for(i = 0 ; i < 256 ; i+= 4)
2187                 snd_iprintf(buf, "%02x: %08x\n", i, inl(ALI_REG(codec, i)));
2188 }
2189
2190 static void __devinit snd_ali_proc_init(ali_t *codec)
2191 {
2192         snd_info_entry_t *entry;
2193         if(!snd_card_proc_new(codec->card, "ali5451", &entry))
2194                 snd_info_set_text_ops(entry, codec, 1024, snd_ali_proc_read);
2195 }
2196
2197 static int __devinit snd_ali_resources(ali_t *codec)
2198 {
2199         int err;
2200
2201         snd_ali_printk("resouces allocation ...\n");
2202         if ((err = pci_request_regions(codec->pci, "ALI 5451")) < 0)
2203                 return err;
2204         codec->port = pci_resource_start(codec->pci, 0);
2205
2206         if (request_irq(codec->pci->irq, snd_ali_card_interrupt, SA_INTERRUPT|SA_SHIRQ, "ALI 5451", (void *)codec)) {
2207                 snd_printk("Unable to request irq.\n");
2208                 return -EBUSY;
2209         }
2210         codec->irq = codec->pci->irq;
2211         snd_ali_printk("resouces allocated.\n");
2212         return 0;
2213 }
2214 static int snd_ali_dev_free(snd_device_t *device) 
2215 {
2216         ali_t *codec=device->device_data;
2217         snd_ali_free(codec);
2218         return 0;
2219 }
2220
2221 static int __devinit snd_ali_create(snd_card_t * card,
2222                                     struct pci_dev *pci,
2223                                     int pcm_streams,
2224                                     int spdif_support,
2225                                     ali_t ** r_ali)
2226 {
2227         ali_t *codec;
2228         int i, err;
2229         unsigned short cmdw = 0;
2230         struct pci_dev *pci_dev = NULL;
2231         static snd_device_ops_t ops = {
2232                 (snd_dev_free_t *)snd_ali_dev_free,
2233                 NULL,
2234                 NULL
2235         };
2236
2237         *r_ali = NULL;
2238
2239         snd_ali_printk("creating ...\n");
2240
2241         /* enable PCI device */
2242         if ((err = pci_enable_device(pci)) < 0)
2243                 return err;
2244         /* check, if we can restrict PCI DMA transfers to 31 bits */
2245         if (pci_set_dma_mask(pci, 0x7fffffff) < 0 ||
2246             pci_set_consistent_dma_mask(pci, 0x7fffffff) < 0) {
2247                 snd_printk("architecture does not support 31bit PCI busmaster DMA\n");
2248                 pci_disable_device(pci);
2249                 return -ENXIO;
2250         }
2251
2252         if ((codec = kcalloc(1, sizeof(*codec), GFP_KERNEL)) == NULL) {
2253                 pci_disable_device(pci);
2254                 return -ENOMEM;
2255         }
2256
2257         spin_lock_init(&codec->reg_lock);
2258         spin_lock_init(&codec->voice_alloc);
2259
2260         codec->card = card;
2261         codec->pci = pci;
2262         codec->irq = -1;
2263         pci_read_config_byte(pci, PCI_REVISION_ID, &codec->revision);
2264         codec->spdif_support = spdif_support;
2265
2266         if (pcm_streams < 1)
2267                 pcm_streams = 1;
2268         if (pcm_streams > 32)
2269                 pcm_streams = 32;
2270         
2271         pci_set_master(pci);
2272         pci_read_config_word(pci, PCI_COMMAND, &cmdw);
2273         if ((cmdw & PCI_COMMAND_IO) != PCI_COMMAND_IO) {
2274                 cmdw |= PCI_COMMAND_IO;
2275                 pci_write_config_word(pci, PCI_COMMAND, cmdw);
2276         }
2277         pci_set_master(pci);
2278         
2279         if (snd_ali_resources(codec)) {
2280                 snd_ali_free(codec);
2281                 return -EBUSY;
2282         }
2283
2284         synchronize_irq(pci->irq);
2285
2286         codec->synth.chmap = 0;
2287         codec->synth.chcnt = 0;
2288         codec->spdif_mask = 0;
2289         codec->synth.synthcount = 0;
2290
2291         if (codec->revision == ALI_5451_V02)
2292                 codec->chregs.regs.ac97read = ALI_AC97_WRITE;
2293         else
2294                 codec->chregs.regs.ac97read = ALI_AC97_READ;
2295         codec->chregs.regs.ac97write = ALI_AC97_WRITE;
2296
2297         codec->chregs.regs.start  = ALI_START;
2298         codec->chregs.regs.stop   = ALI_STOP;
2299         codec->chregs.regs.aint   = ALI_AINT;
2300         codec->chregs.regs.ainten = ALI_AINTEN;
2301
2302         codec->chregs.data.start  = 0x00;
2303         codec->chregs.data.stop   = 0x00;
2304         codec->chregs.data.aint   = 0x00;
2305         codec->chregs.data.ainten = 0x00;
2306
2307         /* M1533: southbridge */
2308         pci_dev = pci_find_device(0x10b9, 0x1533, NULL);
2309         codec->pci_m1533 = pci_dev;
2310         if (! codec->pci_m1533) {
2311                 snd_printk(KERN_ERR "ali5451: cannot find ALi 1533 chip.\n");
2312                 snd_ali_free(codec);
2313                 return -ENODEV;
2314         }
2315         /* M7101: power management */
2316         pci_dev = pci_find_device(0x10b9, 0x7101, NULL);
2317         codec->pci_m7101 = pci_dev;
2318         if (! codec->pci_m7101 && codec->revision == ALI_5451_V02) {
2319                 snd_printk(KERN_ERR "ali5451: cannot find ALi 7101 chip.\n");
2320                 snd_ali_free(codec);
2321                 return -ENODEV;
2322         }
2323
2324         snd_ali_printk("snd_device_new is called.\n");
2325         if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops)) < 0) {
2326                 snd_ali_free(codec);
2327                 return err;
2328         }
2329
2330         /* initialise synth voices*/
2331         for (i = 0; i < ALI_CHANNELS; i++ ) {
2332                 codec->synth.voices[i].number = i;
2333         }
2334
2335         if ((err = snd_ali_chip_init(codec)) < 0) {
2336                 snd_printk("ali create: chip init error.\n");
2337                 return err;
2338         }
2339
2340 #ifdef CONFIG_PM
2341         codec->image = kmalloc(sizeof(*codec->image), GFP_KERNEL);
2342         if (! codec->image)
2343                 snd_printk(KERN_WARNING "can't allocate apm buffer\n");
2344         else
2345                 snd_card_set_pm_callback(card, ali_suspend, ali_resume, codec);
2346 #endif
2347
2348         snd_ali_enable_address_interrupt(codec);
2349         codec->hw_initialized = 1;
2350
2351         *r_ali = codec;
2352         snd_ali_printk("created.\n");
2353         return 0;
2354 }
2355
2356 static int __devinit snd_ali_probe(struct pci_dev *pci,
2357                                    const struct pci_device_id *pci_id)
2358 {
2359         static int dev;
2360         snd_card_t *card;
2361         ali_t *codec;
2362         int err;
2363
2364         snd_ali_printk("probe ...\n");
2365
2366         if (dev >= SNDRV_CARDS)
2367                 return -ENODEV;
2368         if (!enable[dev]) {
2369                 dev++;
2370                 return -ENOENT;
2371         }
2372
2373         card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
2374         if (card == NULL)
2375                 return -ENOMEM;
2376
2377         if ((err = snd_ali_create(card, pci, pcm_channels[dev], spdif[dev], &codec)) < 0) {
2378                 snd_card_free(card);
2379                 return err;
2380         }
2381
2382         snd_ali_printk("mixer building ...\n");
2383         if ((err = snd_ali_mixer(codec)) < 0) {
2384                 snd_card_free(card);
2385                 return err;
2386         }
2387         
2388         snd_ali_printk("pcm building ...\n");
2389         if ((err = snd_ali_build_pcms(codec)) < 0) {
2390                 snd_card_free(card);
2391                 return err;
2392         }
2393
2394         snd_ali_proc_init(codec);
2395
2396         strcpy(card->driver, "ALI5451");
2397         strcpy(card->shortname, "ALI 5451");
2398         
2399         sprintf(card->longname, "%s at 0x%lx, irq %li",
2400                 card->shortname, codec->port, codec->irq);
2401
2402         snd_ali_printk("register card.\n");
2403         if ((err = snd_card_register(card)) < 0) {
2404                 snd_card_free(card);
2405                 return err;
2406         }
2407         pci_set_drvdata(pci, card);
2408         dev++;
2409         return 0;
2410 }
2411
2412 static void __devexit snd_ali_remove(struct pci_dev *pci)
2413 {
2414         snd_card_free(pci_get_drvdata(pci));
2415         pci_set_drvdata(pci, NULL);
2416 }
2417
2418 static struct pci_driver driver = {
2419         .name = "ALI 5451",
2420         .id_table = snd_ali_ids,
2421         .probe = snd_ali_probe,
2422         .remove = __devexit_p(snd_ali_remove),
2423         SND_PCI_PM_CALLBACKS
2424 };                                
2425
2426 static int __init alsa_card_ali_init(void)
2427 {
2428         return pci_register_driver(&driver);
2429 }
2430
2431 static void __exit alsa_card_ali_exit(void)
2432 {
2433         pci_unregister_driver(&driver);
2434 }
2435
2436 module_init(alsa_card_ali_init)
2437 module_exit(alsa_card_ali_exit)