]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - sound/isa/wss/wss_lib.c
ALSA: wss_lib: use wss mixer code instead of ad1848 one
[linux-2.6-omap-h63xx.git] / sound / isa / wss / wss_lib.c
1 /*
2  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
3  *  Routines for control of CS4231(A)/CS4232/InterWave & compatible chips
4  *
5  *  Bugs:
6  *     - sometimes record brokes playback with WSS portion of
7  *       Yamaha OPL3-SA3 chip
8  *     - CS4231 (GUS MAX) - still trouble with occasional noises
9  *                        - broken initialization?
10  *
11  *   This program is free software; you can redistribute it and/or modify
12  *   it under the terms of the GNU General Public License as published by
13  *   the Free Software Foundation; either version 2 of the License, or
14  *   (at your option) any later version.
15  *
16  *   This program is distributed in the hope that it will be useful,
17  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *   GNU General Public License for more details.
20  *
21  *   You should have received a copy of the GNU General Public License
22  *   along with this program; if not, write to the Free Software
23  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
24  *
25  */
26
27 #include <linux/delay.h>
28 #include <linux/pm.h>
29 #include <linux/init.h>
30 #include <linux/interrupt.h>
31 #include <linux/slab.h>
32 #include <linux/ioport.h>
33 #include <sound/core.h>
34 #include <sound/wss.h>
35 #include <sound/pcm_params.h>
36 #include <sound/tlv.h>
37
38 #include <asm/io.h>
39 #include <asm/dma.h>
40 #include <asm/irq.h>
41
42 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
43 MODULE_DESCRIPTION("Routines for control of CS4231(A)/CS4232/InterWave & compatible chips");
44 MODULE_LICENSE("GPL");
45
46 #if 0
47 #define SNDRV_DEBUG_MCE
48 #endif
49
50 /*
51  *  Some variables
52  */
53
54 static unsigned char freq_bits[14] = {
55         /* 5510 */      0x00 | CS4231_XTAL2,
56         /* 6620 */      0x0E | CS4231_XTAL2,
57         /* 8000 */      0x00 | CS4231_XTAL1,
58         /* 9600 */      0x0E | CS4231_XTAL1,
59         /* 11025 */     0x02 | CS4231_XTAL2,
60         /* 16000 */     0x02 | CS4231_XTAL1,
61         /* 18900 */     0x04 | CS4231_XTAL2,
62         /* 22050 */     0x06 | CS4231_XTAL2,
63         /* 27042 */     0x04 | CS4231_XTAL1,
64         /* 32000 */     0x06 | CS4231_XTAL1,
65         /* 33075 */     0x0C | CS4231_XTAL2,
66         /* 37800 */     0x08 | CS4231_XTAL2,
67         /* 44100 */     0x0A | CS4231_XTAL2,
68         /* 48000 */     0x0C | CS4231_XTAL1
69 };
70
71 static unsigned int rates[14] = {
72         5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050,
73         27042, 32000, 33075, 37800, 44100, 48000
74 };
75
76 static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
77         .count = ARRAY_SIZE(rates),
78         .list = rates,
79         .mask = 0,
80 };
81
82 static int snd_wss_xrate(struct snd_pcm_runtime *runtime)
83 {
84         return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
85                                           &hw_constraints_rates);
86 }
87
88 static unsigned char snd_wss_original_image[32] =
89 {
90         0x00,                   /* 00/00 - lic */
91         0x00,                   /* 01/01 - ric */
92         0x9f,                   /* 02/02 - la1ic */
93         0x9f,                   /* 03/03 - ra1ic */
94         0x9f,                   /* 04/04 - la2ic */
95         0x9f,                   /* 05/05 - ra2ic */
96         0xbf,                   /* 06/06 - loc */
97         0xbf,                   /* 07/07 - roc */
98         0x20,                   /* 08/08 - pdfr */
99         CS4231_AUTOCALIB,       /* 09/09 - ic */
100         0x00,                   /* 0a/10 - pc */
101         0x00,                   /* 0b/11 - ti */
102         CS4231_MODE2,           /* 0c/12 - mi */
103         0xfc,                   /* 0d/13 - lbc */
104         0x00,                   /* 0e/14 - pbru */
105         0x00,                   /* 0f/15 - pbrl */
106         0x80,                   /* 10/16 - afei */
107         0x01,                   /* 11/17 - afeii */
108         0x9f,                   /* 12/18 - llic */
109         0x9f,                   /* 13/19 - rlic */
110         0x00,                   /* 14/20 - tlb */
111         0x00,                   /* 15/21 - thb */
112         0x00,                   /* 16/22 - la3mic/reserved */
113         0x00,                   /* 17/23 - ra3mic/reserved */
114         0x00,                   /* 18/24 - afs */
115         0x00,                   /* 19/25 - lamoc/version */
116         0xcf,                   /* 1a/26 - mioc */
117         0x00,                   /* 1b/27 - ramoc/reserved */
118         0x20,                   /* 1c/28 - cdfr */
119         0x00,                   /* 1d/29 - res4 */
120         0x00,                   /* 1e/30 - cbru */
121         0x00,                   /* 1f/31 - cbrl */
122 };
123
124 static unsigned char snd_opti93x_original_image[32] =
125 {
126         0x00,           /* 00/00 - l_mixout_outctrl */
127         0x00,           /* 01/01 - r_mixout_outctrl */
128         0x88,           /* 02/02 - l_cd_inctrl */
129         0x88,           /* 03/03 - r_cd_inctrl */
130         0x88,           /* 04/04 - l_a1/fm_inctrl */
131         0x88,           /* 05/05 - r_a1/fm_inctrl */
132         0x80,           /* 06/06 - l_dac_inctrl */
133         0x80,           /* 07/07 - r_dac_inctrl */
134         0x00,           /* 08/08 - ply_dataform_reg */
135         0x00,           /* 09/09 - if_conf */
136         0x00,           /* 0a/10 - pin_ctrl */
137         0x00,           /* 0b/11 - err_init_reg */
138         0x0a,           /* 0c/12 - id_reg */
139         0x00,           /* 0d/13 - reserved */
140         0x00,           /* 0e/14 - ply_upcount_reg */
141         0x00,           /* 0f/15 - ply_lowcount_reg */
142         0x88,           /* 10/16 - reserved/l_a1_inctrl */
143         0x88,           /* 11/17 - reserved/r_a1_inctrl */
144         0x88,           /* 12/18 - l_line_inctrl */
145         0x88,           /* 13/19 - r_line_inctrl */
146         0x88,           /* 14/20 - l_mic_inctrl */
147         0x88,           /* 15/21 - r_mic_inctrl */
148         0x80,           /* 16/22 - l_out_outctrl */
149         0x80,           /* 17/23 - r_out_outctrl */
150         0x00,           /* 18/24 - reserved */
151         0x00,           /* 19/25 - reserved */
152         0x00,           /* 1a/26 - reserved */
153         0x00,           /* 1b/27 - reserved */
154         0x00,           /* 1c/28 - cap_dataform_reg */
155         0x00,           /* 1d/29 - reserved */
156         0x00,           /* 1e/30 - cap_upcount_reg */
157         0x00            /* 1f/31 - cap_lowcount_reg */
158 };
159
160 /*
161  *  Basic I/O functions
162  */
163
164 static inline void wss_outb(struct snd_wss *chip, u8 offset, u8 val)
165 {
166         outb(val, chip->port + offset);
167 }
168
169 static inline u8 wss_inb(struct snd_wss *chip, u8 offset)
170 {
171         return inb(chip->port + offset);
172 }
173
174 static void snd_wss_wait(struct snd_wss *chip)
175 {
176         int timeout;
177
178         for (timeout = 250;
179              timeout > 0 && (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
180              timeout--)
181                 udelay(100);
182 }
183
184 static void snd_wss_outm(struct snd_wss *chip, unsigned char reg,
185                             unsigned char mask, unsigned char value)
186 {
187         unsigned char tmp = (chip->image[reg] & mask) | value;
188
189         snd_wss_wait(chip);
190 #ifdef CONFIG_SND_DEBUG
191         if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
192                 snd_printk("outm: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
193 #endif
194         chip->image[reg] = tmp;
195         if (!chip->calibrate_mute) {
196                 wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
197                 wmb();
198                 wss_outb(chip, CS4231P(REG), tmp);
199                 mb();
200         }
201 }
202
203 static void snd_wss_dout(struct snd_wss *chip, unsigned char reg,
204                          unsigned char value)
205 {
206         int timeout;
207
208         for (timeout = 250;
209              timeout > 0 && (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
210              timeout--)
211                 udelay(10);
212         wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
213         wss_outb(chip, CS4231P(REG), value);
214         mb();
215 }
216
217 void snd_wss_out(struct snd_wss *chip, unsigned char reg, unsigned char value)
218 {
219         snd_wss_wait(chip);
220 #ifdef CONFIG_SND_DEBUG
221         if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
222                 snd_printk("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
223 #endif
224         wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
225         wss_outb(chip, CS4231P(REG), value);
226         chip->image[reg] = value;
227         mb();
228         snd_printdd("codec out - reg 0x%x = 0x%x\n",
229                         chip->mce_bit | reg, value);
230 }
231 EXPORT_SYMBOL(snd_wss_out);
232
233 unsigned char snd_wss_in(struct snd_wss *chip, unsigned char reg)
234 {
235         snd_wss_wait(chip);
236 #ifdef CONFIG_SND_DEBUG
237         if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
238                 snd_printk("in: auto calibration time out - reg = 0x%x\n", reg);
239 #endif
240         wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
241         mb();
242         return wss_inb(chip, CS4231P(REG));
243 }
244 EXPORT_SYMBOL(snd_wss_in);
245
246 void snd_cs4236_ext_out(struct snd_wss *chip, unsigned char reg,
247                         unsigned char val)
248 {
249         wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17);
250         wss_outb(chip, CS4231P(REG),
251                  reg | (chip->image[CS4236_EXT_REG] & 0x01));
252         wss_outb(chip, CS4231P(REG), val);
253         chip->eimage[CS4236_REG(reg)] = val;
254 #if 0
255         printk("ext out : reg = 0x%x, val = 0x%x\n", reg, val);
256 #endif
257 }
258 EXPORT_SYMBOL(snd_cs4236_ext_out);
259
260 unsigned char snd_cs4236_ext_in(struct snd_wss *chip, unsigned char reg)
261 {
262         wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17);
263         wss_outb(chip, CS4231P(REG),
264                  reg | (chip->image[CS4236_EXT_REG] & 0x01));
265 #if 1
266         return wss_inb(chip, CS4231P(REG));
267 #else
268         {
269                 unsigned char res;
270                 res = wss_inb(chip, CS4231P(REG));
271                 printk("ext in : reg = 0x%x, val = 0x%x\n", reg, res);
272                 return res;
273         }
274 #endif
275 }
276 EXPORT_SYMBOL(snd_cs4236_ext_in);
277
278 #if 0
279
280 static void snd_wss_debug(struct snd_wss *chip)
281 {
282         printk(KERN_DEBUG
283                 "CS4231 REGS:      INDEX = 0x%02x  "
284                 "                 STATUS = 0x%02x\n",
285                                         wss_inb(chip, CS4231P(REGSEL),
286                                         wss_inb(chip, CS4231P(STATUS)));
287         printk(KERN_DEBUG
288                 "  0x00: left input      = 0x%02x  "
289                 "  0x10: alt 1 (CFIG 2)  = 0x%02x\n",
290                                         snd_wss_in(chip, 0x00),
291                                         snd_wss_in(chip, 0x10));
292         printk(KERN_DEBUG
293                 "  0x01: right input     = 0x%02x  "
294                 "  0x11: alt 2 (CFIG 3)  = 0x%02x\n",
295                                         snd_wss_in(chip, 0x01),
296                                         snd_wss_in(chip, 0x11));
297         printk(KERN_DEBUG
298                 "  0x02: GF1 left input  = 0x%02x  "
299                 "  0x12: left line in    = 0x%02x\n",
300                                         snd_wss_in(chip, 0x02),
301                                         snd_wss_in(chip, 0x12));
302         printk(KERN_DEBUG
303                 "  0x03: GF1 right input = 0x%02x  "
304                 "  0x13: right line in   = 0x%02x\n",
305                                         snd_wss_in(chip, 0x03),
306                                         snd_wss_in(chip, 0x13));
307         printk(KERN_DEBUG
308                 "  0x04: CD left input   = 0x%02x  "
309                 "  0x14: timer low       = 0x%02x\n",
310                                         snd_wss_in(chip, 0x04),
311                                         snd_wss_in(chip, 0x14));
312         printk(KERN_DEBUG
313                 "  0x05: CD right input  = 0x%02x  "
314                 "  0x15: timer high      = 0x%02x\n",
315                                         snd_wss_in(chip, 0x05),
316                                         snd_wss_in(chip, 0x15));
317         printk(KERN_DEBUG
318                 "  0x06: left output     = 0x%02x  "
319                 "  0x16: left MIC (PnP)  = 0x%02x\n",
320                                         snd_wss_in(chip, 0x06),
321                                         snd_wss_in(chip, 0x16));
322         printk(KERN_DEBUG
323                 "  0x07: right output    = 0x%02x  "
324                 "  0x17: right MIC (PnP) = 0x%02x\n",
325                                         snd_wss_in(chip, 0x07),
326                                         snd_wss_in(chip, 0x17));
327         printk(KERN_DEBUG
328                 "  0x08: playback format = 0x%02x  "
329                 "  0x18: IRQ status      = 0x%02x\n",
330                                         snd_wss_in(chip, 0x08),
331                                         snd_wss_in(chip, 0x18));
332         printk(KERN_DEBUG
333                 "  0x09: iface (CFIG 1)  = 0x%02x  "
334                 "  0x19: left line out   = 0x%02x\n",
335                                         snd_wss_in(chip, 0x09),
336                                         snd_wss_in(chip, 0x19));
337         printk(KERN_DEBUG
338                 "  0x0a: pin control     = 0x%02x  "
339                 "  0x1a: mono control    = 0x%02x\n",
340                                         snd_wss_in(chip, 0x0a),
341                                         snd_wss_in(chip, 0x1a));
342         printk(KERN_DEBUG
343                 "  0x0b: init & status   = 0x%02x  "
344                 "  0x1b: right line out  = 0x%02x\n",
345                                         snd_wss_in(chip, 0x0b),
346                                         snd_wss_in(chip, 0x1b));
347         printk(KERN_DEBUG
348                 "  0x0c: revision & mode = 0x%02x  "
349                 "  0x1c: record format   = 0x%02x\n",
350                                         snd_wss_in(chip, 0x0c),
351                                         snd_wss_in(chip, 0x1c));
352         printk(KERN_DEBUG
353                 "  0x0d: loopback        = 0x%02x  "
354                 "  0x1d: var freq (PnP)  = 0x%02x\n",
355                                         snd_wss_in(chip, 0x0d),
356                                         snd_wss_in(chip, 0x1d));
357         printk(KERN_DEBUG
358                 "  0x0e: ply upr count   = 0x%02x  "
359                 "  0x1e: ply lwr count   = 0x%02x\n",
360                                         snd_wss_in(chip, 0x0e),
361                                         snd_wss_in(chip, 0x1e));
362         printk(KERN_DEBUG
363                 "  0x0f: rec upr count   = 0x%02x  "
364                 "  0x1f: rec lwr count   = 0x%02x\n",
365                                         snd_wss_in(chip, 0x0f),
366                                         snd_wss_in(chip, 0x1f));
367 }
368
369 #endif
370
371 /*
372  *  CS4231 detection / MCE routines
373  */
374
375 static void snd_wss_busy_wait(struct snd_wss *chip)
376 {
377         int timeout;
378
379         /* huh.. looks like this sequence is proper for CS4231A chip (GUS MAX) */
380         for (timeout = 5; timeout > 0; timeout--)
381                 wss_inb(chip, CS4231P(REGSEL));
382         /* end of cleanup sequence */
383         for (timeout = 250;
384              timeout > 0 && (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
385              timeout--)
386                 udelay(10);
387 }
388
389 void snd_wss_mce_up(struct snd_wss *chip)
390 {
391         unsigned long flags;
392         int timeout;
393
394         snd_wss_wait(chip);
395 #ifdef CONFIG_SND_DEBUG
396         if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
397                 snd_printk("mce_up - auto calibration time out (0)\n");
398 #endif
399         spin_lock_irqsave(&chip->reg_lock, flags);
400         chip->mce_bit |= CS4231_MCE;
401         timeout = wss_inb(chip, CS4231P(REGSEL));
402         if (timeout == 0x80)
403                 snd_printk("mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port);
404         if (!(timeout & CS4231_MCE))
405                 wss_outb(chip, CS4231P(REGSEL),
406                          chip->mce_bit | (timeout & 0x1f));
407         spin_unlock_irqrestore(&chip->reg_lock, flags);
408 }
409 EXPORT_SYMBOL(snd_wss_mce_up);
410
411 void snd_wss_mce_down(struct snd_wss *chip)
412 {
413         unsigned long flags;
414         unsigned long end_time;
415         int timeout;
416
417         snd_wss_busy_wait(chip);
418
419 #ifdef CONFIG_SND_DEBUG
420         if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
421                 snd_printk("mce_down [0x%lx] - auto calibration time out (0)\n", (long)CS4231P(REGSEL));
422 #endif
423         spin_lock_irqsave(&chip->reg_lock, flags);
424         chip->mce_bit &= ~CS4231_MCE;
425         timeout = wss_inb(chip, CS4231P(REGSEL));
426         wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
427         spin_unlock_irqrestore(&chip->reg_lock, flags);
428         if (timeout == 0x80)
429                 snd_printk("mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port);
430         if ((timeout & CS4231_MCE) == 0 ||
431             !(chip->hardware & (WSS_HW_CS4231_MASK | WSS_HW_CS4232_MASK))) {
432                 return;
433         }
434
435         /*
436          * Wait for (possible -- during init auto-calibration may not be set)
437          * calibration process to start. Needs upto 5 sample periods on AD1848
438          * which at the slowest possible rate of 5.5125 kHz means 907 us.
439          */
440         msleep(1);
441
442         snd_printdd("(1) jiffies = %lu\n", jiffies);
443
444         /* check condition up to 250 ms */
445         end_time = jiffies + msecs_to_jiffies(250);
446         while (snd_wss_in(chip, CS4231_TEST_INIT) &
447                 CS4231_CALIB_IN_PROGRESS) {
448
449                 if (time_after(jiffies, end_time)) {
450                         snd_printk(KERN_ERR "mce_down - "
451                                         "auto calibration time out (2)\n");
452                         return;
453                 }
454                 msleep(1);
455         }
456
457         snd_printdd("(2) jiffies = %lu\n", jiffies);
458
459         /* check condition up to 100 ms */
460         end_time = jiffies + msecs_to_jiffies(100);
461         while (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) {
462                 if (time_after(jiffies, end_time)) {
463                         snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n");
464                         return;
465                 }
466                 msleep(1);
467         }
468
469         snd_printdd("(3) jiffies = %lu\n", jiffies);
470         snd_printd("mce_down - exit = 0x%x\n", wss_inb(chip, CS4231P(REGSEL)));
471 }
472 EXPORT_SYMBOL(snd_wss_mce_down);
473
474 static unsigned int snd_wss_get_count(unsigned char format, unsigned int size)
475 {
476         switch (format & 0xe0) {
477         case CS4231_LINEAR_16:
478         case CS4231_LINEAR_16_BIG:
479                 size >>= 1;
480                 break;
481         case CS4231_ADPCM_16:
482                 return size >> 2;
483         }
484         if (format & CS4231_STEREO)
485                 size >>= 1;
486         return size;
487 }
488
489 static int snd_wss_trigger(struct snd_pcm_substream *substream,
490                            int cmd)
491 {
492         struct snd_wss *chip = snd_pcm_substream_chip(substream);
493         int result = 0;
494         unsigned int what;
495         struct snd_pcm_substream *s;
496         int do_start;
497
498         switch (cmd) {
499         case SNDRV_PCM_TRIGGER_START:
500         case SNDRV_PCM_TRIGGER_RESUME:
501                 do_start = 1; break;
502         case SNDRV_PCM_TRIGGER_STOP:
503         case SNDRV_PCM_TRIGGER_SUSPEND:
504                 do_start = 0; break;
505         default:
506                 return -EINVAL;
507         }
508
509         what = 0;
510         snd_pcm_group_for_each_entry(s, substream) {
511                 if (s == chip->playback_substream) {
512                         what |= CS4231_PLAYBACK_ENABLE;
513                         snd_pcm_trigger_done(s, substream);
514                 } else if (s == chip->capture_substream) {
515                         what |= CS4231_RECORD_ENABLE;
516                         snd_pcm_trigger_done(s, substream);
517                 }
518         }
519         spin_lock(&chip->reg_lock);
520         if (do_start) {
521                 chip->image[CS4231_IFACE_CTRL] |= what;
522                 if (chip->trigger)
523                         chip->trigger(chip, what, 1);
524         } else {
525                 chip->image[CS4231_IFACE_CTRL] &= ~what;
526                 if (chip->trigger)
527                         chip->trigger(chip, what, 0);
528         }
529         snd_wss_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
530         spin_unlock(&chip->reg_lock);
531 #if 0
532         snd_wss_debug(chip);
533 #endif
534         return result;
535 }
536
537 /*
538  *  CODEC I/O
539  */
540
541 static unsigned char snd_wss_get_rate(unsigned int rate)
542 {
543         int i;
544
545         for (i = 0; i < ARRAY_SIZE(rates); i++)
546                 if (rate == rates[i])
547                         return freq_bits[i];
548         // snd_BUG();
549         return freq_bits[ARRAY_SIZE(rates) - 1];
550 }
551
552 static unsigned char snd_wss_get_format(struct snd_wss *chip,
553                                         int format,
554                                         int channels)
555 {
556         unsigned char rformat;
557
558         rformat = CS4231_LINEAR_8;
559         switch (format) {
560         case SNDRV_PCM_FORMAT_MU_LAW:   rformat = CS4231_ULAW_8; break;
561         case SNDRV_PCM_FORMAT_A_LAW:    rformat = CS4231_ALAW_8; break;
562         case SNDRV_PCM_FORMAT_S16_LE:   rformat = CS4231_LINEAR_16; break;
563         case SNDRV_PCM_FORMAT_S16_BE:   rformat = CS4231_LINEAR_16_BIG; break;
564         case SNDRV_PCM_FORMAT_IMA_ADPCM:        rformat = CS4231_ADPCM_16; break;
565         }
566         if (channels > 1)
567                 rformat |= CS4231_STEREO;
568 #if 0
569         snd_printk("get_format: 0x%x (mode=0x%x)\n", format, mode);
570 #endif
571         return rformat;
572 }
573
574 static void snd_wss_calibrate_mute(struct snd_wss *chip, int mute)
575 {
576         unsigned long flags;
577
578         mute = mute ? 1 : 0;
579         spin_lock_irqsave(&chip->reg_lock, flags);
580         if (chip->calibrate_mute == mute) {
581                 spin_unlock_irqrestore(&chip->reg_lock, flags);
582                 return;
583         }
584         if (!mute) {
585                 snd_wss_dout(chip, CS4231_LEFT_INPUT,
586                              chip->image[CS4231_LEFT_INPUT]);
587                 snd_wss_dout(chip, CS4231_RIGHT_INPUT,
588                              chip->image[CS4231_RIGHT_INPUT]);
589                 snd_wss_dout(chip, CS4231_LOOPBACK,
590                              chip->image[CS4231_LOOPBACK]);
591         }
592         snd_wss_dout(chip, CS4231_AUX1_LEFT_INPUT,
593                      mute ? 0x80 : chip->image[CS4231_AUX1_LEFT_INPUT]);
594         snd_wss_dout(chip, CS4231_AUX1_RIGHT_INPUT,
595                      mute ? 0x80 : chip->image[CS4231_AUX1_RIGHT_INPUT]);
596         snd_wss_dout(chip, CS4231_AUX2_LEFT_INPUT,
597                      mute ? 0x80 : chip->image[CS4231_AUX2_LEFT_INPUT]);
598         snd_wss_dout(chip, CS4231_AUX2_RIGHT_INPUT,
599                      mute ? 0x80 : chip->image[CS4231_AUX2_RIGHT_INPUT]);
600         snd_wss_dout(chip, CS4231_LEFT_OUTPUT,
601                      mute ? 0x80 : chip->image[CS4231_LEFT_OUTPUT]);
602         snd_wss_dout(chip, CS4231_RIGHT_OUTPUT,
603                      mute ? 0x80 : chip->image[CS4231_RIGHT_OUTPUT]);
604         snd_wss_dout(chip, CS4231_LEFT_LINE_IN,
605                      mute ? 0x80 : chip->image[CS4231_LEFT_LINE_IN]);
606         snd_wss_dout(chip, CS4231_RIGHT_LINE_IN,
607                      mute ? 0x80 : chip->image[CS4231_RIGHT_LINE_IN]);
608         snd_wss_dout(chip, CS4231_MONO_CTRL,
609                      mute ? 0xc0 : chip->image[CS4231_MONO_CTRL]);
610         if (chip->hardware == WSS_HW_INTERWAVE) {
611                 snd_wss_dout(chip, CS4231_LEFT_MIC_INPUT,
612                              mute ? 0x80 : chip->image[CS4231_LEFT_MIC_INPUT]);
613                 snd_wss_dout(chip, CS4231_RIGHT_MIC_INPUT,
614                              mute ? 0x80 : chip->image[CS4231_RIGHT_MIC_INPUT]);
615                 snd_wss_dout(chip, CS4231_LINE_LEFT_OUTPUT,
616                         mute ? 0x80 : chip->image[CS4231_LINE_LEFT_OUTPUT]);
617                 snd_wss_dout(chip, CS4231_LINE_RIGHT_OUTPUT,
618                         mute ? 0x80 : chip->image[CS4231_LINE_RIGHT_OUTPUT]);
619         }
620         chip->calibrate_mute = mute;
621         spin_unlock_irqrestore(&chip->reg_lock, flags);
622 }
623
624 static void snd_wss_playback_format(struct snd_wss *chip,
625                                        struct snd_pcm_hw_params *params,
626                                        unsigned char pdfr)
627 {
628         unsigned long flags;
629         int full_calib = 1;
630
631         mutex_lock(&chip->mce_mutex);
632         snd_wss_calibrate_mute(chip, 1);
633         if (chip->hardware == WSS_HW_CS4231A ||
634             (chip->hardware & WSS_HW_CS4232_MASK)) {
635                 spin_lock_irqsave(&chip->reg_lock, flags);
636                 if ((chip->image[CS4231_PLAYBK_FORMAT] & 0x0f) == (pdfr & 0x0f)) {      /* rate is same? */
637                         snd_wss_out(chip, CS4231_ALT_FEATURE_1,
638                                     chip->image[CS4231_ALT_FEATURE_1] | 0x10);
639                         chip->image[CS4231_PLAYBK_FORMAT] = pdfr;
640                         snd_wss_out(chip, CS4231_PLAYBK_FORMAT,
641                                     chip->image[CS4231_PLAYBK_FORMAT]);
642                         snd_wss_out(chip, CS4231_ALT_FEATURE_1,
643                                     chip->image[CS4231_ALT_FEATURE_1] &= ~0x10);
644                         udelay(100); /* Fixes audible clicks at least on GUS MAX */
645                         full_calib = 0;
646                 }
647                 spin_unlock_irqrestore(&chip->reg_lock, flags);
648         }
649         if (full_calib) {
650                 snd_wss_mce_up(chip);
651                 spin_lock_irqsave(&chip->reg_lock, flags);
652                 if (chip->hardware != WSS_HW_INTERWAVE && !chip->single_dma) {
653                         if (chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE)
654                                 pdfr = (pdfr & 0xf0) |
655                                        (chip->image[CS4231_REC_FORMAT] & 0x0f);
656                 } else {
657                         chip->image[CS4231_PLAYBK_FORMAT] = pdfr;
658                 }
659                 snd_wss_out(chip, CS4231_PLAYBK_FORMAT, pdfr);
660                 spin_unlock_irqrestore(&chip->reg_lock, flags);
661                 if (chip->hardware == WSS_HW_OPL3SA2)
662                         udelay(100);    /* this seems to help */
663                 snd_wss_mce_down(chip);
664         }
665         snd_wss_calibrate_mute(chip, 0);
666         mutex_unlock(&chip->mce_mutex);
667 }
668
669 static void snd_wss_capture_format(struct snd_wss *chip,
670                                    struct snd_pcm_hw_params *params,
671                                    unsigned char cdfr)
672 {
673         unsigned long flags;
674         int full_calib = 1;
675
676         mutex_lock(&chip->mce_mutex);
677         snd_wss_calibrate_mute(chip, 1);
678         if (chip->hardware == WSS_HW_CS4231A ||
679             (chip->hardware & WSS_HW_CS4232_MASK)) {
680                 spin_lock_irqsave(&chip->reg_lock, flags);
681                 if ((chip->image[CS4231_PLAYBK_FORMAT] & 0x0f) == (cdfr & 0x0f) ||      /* rate is same? */
682                     (chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) {
683                         snd_wss_out(chip, CS4231_ALT_FEATURE_1,
684                                 chip->image[CS4231_ALT_FEATURE_1] | 0x20);
685                         snd_wss_out(chip, CS4231_REC_FORMAT,
686                                 chip->image[CS4231_REC_FORMAT] = cdfr);
687                         snd_wss_out(chip, CS4231_ALT_FEATURE_1,
688                                 chip->image[CS4231_ALT_FEATURE_1] &= ~0x20);
689                         full_calib = 0;
690                 }
691                 spin_unlock_irqrestore(&chip->reg_lock, flags);
692         }
693         if (full_calib) {
694                 snd_wss_mce_up(chip);
695                 spin_lock_irqsave(&chip->reg_lock, flags);
696                 if (chip->hardware != WSS_HW_INTERWAVE &&
697                     !(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) {
698                         if (chip->single_dma)
699                                 snd_wss_out(chip, CS4231_PLAYBK_FORMAT, cdfr);
700                         else
701                                 snd_wss_out(chip, CS4231_PLAYBK_FORMAT,
702                                    (chip->image[CS4231_PLAYBK_FORMAT] & 0xf0) |
703                                    (cdfr & 0x0f));
704                         spin_unlock_irqrestore(&chip->reg_lock, flags);
705                         snd_wss_mce_down(chip);
706                         snd_wss_mce_up(chip);
707                         spin_lock_irqsave(&chip->reg_lock, flags);
708                 }
709                 snd_wss_out(chip, CS4231_REC_FORMAT, cdfr);
710                 spin_unlock_irqrestore(&chip->reg_lock, flags);
711                 snd_wss_mce_down(chip);
712         }
713         snd_wss_calibrate_mute(chip, 0);
714         mutex_unlock(&chip->mce_mutex);
715 }
716
717 /*
718  *  Timer interface
719  */
720
721 static unsigned long snd_wss_timer_resolution(struct snd_timer *timer)
722 {
723         struct snd_wss *chip = snd_timer_chip(timer);
724         if (chip->hardware & WSS_HW_CS4236B_MASK)
725                 return 14467;
726         else
727                 return chip->image[CS4231_PLAYBK_FORMAT] & 1 ? 9969 : 9920;
728 }
729
730 static int snd_wss_timer_start(struct snd_timer *timer)
731 {
732         unsigned long flags;
733         unsigned int ticks;
734         struct snd_wss *chip = snd_timer_chip(timer);
735         spin_lock_irqsave(&chip->reg_lock, flags);
736         ticks = timer->sticks;
737         if ((chip->image[CS4231_ALT_FEATURE_1] & CS4231_TIMER_ENABLE) == 0 ||
738             (unsigned char)(ticks >> 8) != chip->image[CS4231_TIMER_HIGH] ||
739             (unsigned char)ticks != chip->image[CS4231_TIMER_LOW]) {
740                 chip->image[CS4231_TIMER_HIGH] = (unsigned char) (ticks >> 8);
741                 snd_wss_out(chip, CS4231_TIMER_HIGH,
742                             chip->image[CS4231_TIMER_HIGH]);
743                 chip->image[CS4231_TIMER_LOW] = (unsigned char) ticks;
744                 snd_wss_out(chip, CS4231_TIMER_LOW,
745                             chip->image[CS4231_TIMER_LOW]);
746                 snd_wss_out(chip, CS4231_ALT_FEATURE_1,
747                             chip->image[CS4231_ALT_FEATURE_1] |
748                             CS4231_TIMER_ENABLE);
749         }
750         spin_unlock_irqrestore(&chip->reg_lock, flags);
751         return 0;
752 }
753
754 static int snd_wss_timer_stop(struct snd_timer *timer)
755 {
756         unsigned long flags;
757         struct snd_wss *chip = snd_timer_chip(timer);
758         spin_lock_irqsave(&chip->reg_lock, flags);
759         chip->image[CS4231_ALT_FEATURE_1] &= ~CS4231_TIMER_ENABLE;
760         snd_wss_out(chip, CS4231_ALT_FEATURE_1,
761                     chip->image[CS4231_ALT_FEATURE_1]);
762         spin_unlock_irqrestore(&chip->reg_lock, flags);
763         return 0;
764 }
765
766 static void snd_wss_init(struct snd_wss *chip)
767 {
768         unsigned long flags;
769
770         snd_wss_mce_down(chip);
771
772 #ifdef SNDRV_DEBUG_MCE
773         snd_printk("init: (1)\n");
774 #endif
775         snd_wss_mce_up(chip);
776         spin_lock_irqsave(&chip->reg_lock, flags);
777         chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE |
778                                             CS4231_PLAYBACK_PIO |
779                                             CS4231_RECORD_ENABLE |
780                                             CS4231_RECORD_PIO |
781                                             CS4231_CALIB_MODE);
782         chip->image[CS4231_IFACE_CTRL] |= CS4231_AUTOCALIB;
783         snd_wss_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
784         spin_unlock_irqrestore(&chip->reg_lock, flags);
785         snd_wss_mce_down(chip);
786
787 #ifdef SNDRV_DEBUG_MCE
788         snd_printk("init: (2)\n");
789 #endif
790
791         snd_wss_mce_up(chip);
792         spin_lock_irqsave(&chip->reg_lock, flags);
793         snd_wss_out(chip,
794                     CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1]);
795         spin_unlock_irqrestore(&chip->reg_lock, flags);
796         snd_wss_mce_down(chip);
797
798 #ifdef SNDRV_DEBUG_MCE
799         snd_printk("init: (3) - afei = 0x%x\n",
800                    chip->image[CS4231_ALT_FEATURE_1]);
801 #endif
802
803         spin_lock_irqsave(&chip->reg_lock, flags);
804         snd_wss_out(chip, CS4231_ALT_FEATURE_2,
805                     chip->image[CS4231_ALT_FEATURE_2]);
806         spin_unlock_irqrestore(&chip->reg_lock, flags);
807
808         snd_wss_mce_up(chip);
809         spin_lock_irqsave(&chip->reg_lock, flags);
810         snd_wss_out(chip, CS4231_PLAYBK_FORMAT,
811                     chip->image[CS4231_PLAYBK_FORMAT]);
812         spin_unlock_irqrestore(&chip->reg_lock, flags);
813         snd_wss_mce_down(chip);
814
815 #ifdef SNDRV_DEBUG_MCE
816         snd_printk("init: (4)\n");
817 #endif
818
819         snd_wss_mce_up(chip);
820         spin_lock_irqsave(&chip->reg_lock, flags);
821         snd_wss_out(chip, CS4231_REC_FORMAT, chip->image[CS4231_REC_FORMAT]);
822         spin_unlock_irqrestore(&chip->reg_lock, flags);
823         snd_wss_mce_down(chip);
824
825 #ifdef SNDRV_DEBUG_MCE
826         snd_printk("init: (5)\n");
827 #endif
828 }
829
830 static int snd_wss_open(struct snd_wss *chip, unsigned int mode)
831 {
832         unsigned long flags;
833
834         mutex_lock(&chip->open_mutex);
835         if ((chip->mode & mode) ||
836             ((chip->mode & WSS_MODE_OPEN) && chip->single_dma)) {
837                 mutex_unlock(&chip->open_mutex);
838                 return -EAGAIN;
839         }
840         if (chip->mode & WSS_MODE_OPEN) {
841                 chip->mode |= mode;
842                 mutex_unlock(&chip->open_mutex);
843                 return 0;
844         }
845         /* ok. now enable and ack CODEC IRQ */
846         spin_lock_irqsave(&chip->reg_lock, flags);
847         snd_wss_out(chip, CS4231_IRQ_STATUS,
848                     CS4231_PLAYBACK_IRQ |
849                     CS4231_RECORD_IRQ |
850                     CS4231_TIMER_IRQ);
851         snd_wss_out(chip, CS4231_IRQ_STATUS, 0);
852         wss_outb(chip, CS4231P(STATUS), 0);     /* clear IRQ */
853         wss_outb(chip, CS4231P(STATUS), 0);     /* clear IRQ */
854         chip->image[CS4231_PIN_CTRL] |= CS4231_IRQ_ENABLE;
855         snd_wss_out(chip, CS4231_PIN_CTRL, chip->image[CS4231_PIN_CTRL]);
856         snd_wss_out(chip, CS4231_IRQ_STATUS,
857                     CS4231_PLAYBACK_IRQ |
858                     CS4231_RECORD_IRQ |
859                     CS4231_TIMER_IRQ);
860         snd_wss_out(chip, CS4231_IRQ_STATUS, 0);
861         spin_unlock_irqrestore(&chip->reg_lock, flags);
862
863         chip->mode = mode;
864         mutex_unlock(&chip->open_mutex);
865         return 0;
866 }
867
868 static void snd_wss_close(struct snd_wss *chip, unsigned int mode)
869 {
870         unsigned long flags;
871
872         mutex_lock(&chip->open_mutex);
873         chip->mode &= ~mode;
874         if (chip->mode & WSS_MODE_OPEN) {
875                 mutex_unlock(&chip->open_mutex);
876                 return;
877         }
878         snd_wss_calibrate_mute(chip, 1);
879
880         /* disable IRQ */
881         spin_lock_irqsave(&chip->reg_lock, flags);
882         snd_wss_out(chip, CS4231_IRQ_STATUS, 0);
883         wss_outb(chip, CS4231P(STATUS), 0);     /* clear IRQ */
884         wss_outb(chip, CS4231P(STATUS), 0);     /* clear IRQ */
885         chip->image[CS4231_PIN_CTRL] &= ~CS4231_IRQ_ENABLE;
886         snd_wss_out(chip, CS4231_PIN_CTRL, chip->image[CS4231_PIN_CTRL]);
887
888         /* now disable record & playback */
889
890         if (chip->image[CS4231_IFACE_CTRL] & (CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO |
891                                                CS4231_RECORD_ENABLE | CS4231_RECORD_PIO)) {
892                 spin_unlock_irqrestore(&chip->reg_lock, flags);
893                 snd_wss_mce_up(chip);
894                 spin_lock_irqsave(&chip->reg_lock, flags);
895                 chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO |
896                                                      CS4231_RECORD_ENABLE | CS4231_RECORD_PIO);
897                 snd_wss_out(chip, CS4231_IFACE_CTRL,
898                             chip->image[CS4231_IFACE_CTRL]);
899                 spin_unlock_irqrestore(&chip->reg_lock, flags);
900                 snd_wss_mce_down(chip);
901                 spin_lock_irqsave(&chip->reg_lock, flags);
902         }
903
904         /* clear IRQ again */
905         snd_wss_out(chip, CS4231_IRQ_STATUS, 0);
906         wss_outb(chip, CS4231P(STATUS), 0);     /* clear IRQ */
907         wss_outb(chip, CS4231P(STATUS), 0);     /* clear IRQ */
908         spin_unlock_irqrestore(&chip->reg_lock, flags);
909
910         snd_wss_calibrate_mute(chip, 0);
911
912         chip->mode = 0;
913         mutex_unlock(&chip->open_mutex);
914 }
915
916 /*
917  *  timer open/close
918  */
919
920 static int snd_wss_timer_open(struct snd_timer *timer)
921 {
922         struct snd_wss *chip = snd_timer_chip(timer);
923         snd_wss_open(chip, WSS_MODE_TIMER);
924         return 0;
925 }
926
927 static int snd_wss_timer_close(struct snd_timer *timer)
928 {
929         struct snd_wss *chip = snd_timer_chip(timer);
930         snd_wss_close(chip, WSS_MODE_TIMER);
931         return 0;
932 }
933
934 static struct snd_timer_hardware snd_wss_timer_table =
935 {
936         .flags =        SNDRV_TIMER_HW_AUTO,
937         .resolution =   9945,
938         .ticks =        65535,
939         .open =         snd_wss_timer_open,
940         .close =        snd_wss_timer_close,
941         .c_resolution = snd_wss_timer_resolution,
942         .start =        snd_wss_timer_start,
943         .stop =         snd_wss_timer_stop,
944 };
945
946 /*
947  *  ok.. exported functions..
948  */
949
950 static int snd_wss_playback_hw_params(struct snd_pcm_substream *substream,
951                                          struct snd_pcm_hw_params *hw_params)
952 {
953         struct snd_wss *chip = snd_pcm_substream_chip(substream);
954         unsigned char new_pdfr;
955         int err;
956
957         if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
958                 return err;
959         new_pdfr = snd_wss_get_format(chip, params_format(hw_params),
960                                 params_channels(hw_params)) |
961                                 snd_wss_get_rate(params_rate(hw_params));
962         chip->set_playback_format(chip, hw_params, new_pdfr);
963         return 0;
964 }
965
966 static int snd_wss_playback_hw_free(struct snd_pcm_substream *substream)
967 {
968         return snd_pcm_lib_free_pages(substream);
969 }
970
971 static int snd_wss_playback_prepare(struct snd_pcm_substream *substream)
972 {
973         struct snd_wss *chip = snd_pcm_substream_chip(substream);
974         struct snd_pcm_runtime *runtime = substream->runtime;
975         unsigned long flags;
976         unsigned int size = snd_pcm_lib_buffer_bytes(substream);
977         unsigned int count = snd_pcm_lib_period_bytes(substream);
978
979         spin_lock_irqsave(&chip->reg_lock, flags);
980         chip->p_dma_size = size;
981         chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO);
982         snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
983         count = snd_wss_get_count(chip->image[CS4231_PLAYBK_FORMAT], count) - 1;
984         snd_wss_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count);
985         snd_wss_out(chip, CS4231_PLY_UPR_CNT, (unsigned char) (count >> 8));
986         spin_unlock_irqrestore(&chip->reg_lock, flags);
987 #if 0
988         snd_wss_debug(chip);
989 #endif
990         return 0;
991 }
992
993 static int snd_wss_capture_hw_params(struct snd_pcm_substream *substream,
994                                         struct snd_pcm_hw_params *hw_params)
995 {
996         struct snd_wss *chip = snd_pcm_substream_chip(substream);
997         unsigned char new_cdfr;
998         int err;
999
1000         if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
1001                 return err;
1002         new_cdfr = snd_wss_get_format(chip, params_format(hw_params),
1003                            params_channels(hw_params)) |
1004                            snd_wss_get_rate(params_rate(hw_params));
1005         chip->set_capture_format(chip, hw_params, new_cdfr);
1006         return 0;
1007 }
1008
1009 static int snd_wss_capture_hw_free(struct snd_pcm_substream *substream)
1010 {
1011         return snd_pcm_lib_free_pages(substream);
1012 }
1013
1014 static int snd_wss_capture_prepare(struct snd_pcm_substream *substream)
1015 {
1016         struct snd_wss *chip = snd_pcm_substream_chip(substream);
1017         struct snd_pcm_runtime *runtime = substream->runtime;
1018         unsigned long flags;
1019         unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1020         unsigned int count = snd_pcm_lib_period_bytes(substream);
1021
1022         spin_lock_irqsave(&chip->reg_lock, flags);
1023         chip->c_dma_size = size;
1024         chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE | CS4231_RECORD_PIO);
1025         snd_dma_program(chip->dma2, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
1026         count = snd_wss_get_count(chip->image[CS4231_REC_FORMAT], count) - 1;
1027         if (chip->single_dma && chip->hardware != WSS_HW_INTERWAVE) {
1028                 snd_wss_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count);
1029                 snd_wss_out(chip, CS4231_PLY_UPR_CNT,
1030                             (unsigned char) (count >> 8));
1031         } else {
1032                 snd_wss_out(chip, CS4231_REC_LWR_CNT, (unsigned char) count);
1033                 snd_wss_out(chip, CS4231_REC_UPR_CNT,
1034                             (unsigned char) (count >> 8));
1035         }
1036         spin_unlock_irqrestore(&chip->reg_lock, flags);
1037         return 0;
1038 }
1039
1040 void snd_wss_overrange(struct snd_wss *chip)
1041 {
1042         unsigned long flags;
1043         unsigned char res;
1044
1045         spin_lock_irqsave(&chip->reg_lock, flags);
1046         res = snd_wss_in(chip, CS4231_TEST_INIT);
1047         spin_unlock_irqrestore(&chip->reg_lock, flags);
1048         if (res & (0x08 | 0x02))        /* detect overrange only above 0dB; may be user selectable? */
1049                 chip->capture_substream->runtime->overrange++;
1050 }
1051 EXPORT_SYMBOL(snd_wss_overrange);
1052
1053 irqreturn_t snd_wss_interrupt(int irq, void *dev_id)
1054 {
1055         struct snd_wss *chip = dev_id;
1056         unsigned char status;
1057
1058         status = snd_wss_in(chip, CS4231_IRQ_STATUS);
1059         if (status & CS4231_TIMER_IRQ) {
1060                 if (chip->timer)
1061                         snd_timer_interrupt(chip->timer, chip->timer->sticks);
1062         }
1063         if (chip->single_dma && chip->hardware != WSS_HW_INTERWAVE) {
1064                 if (status & CS4231_PLAYBACK_IRQ) {
1065                         if (chip->mode & WSS_MODE_PLAY) {
1066                                 if (chip->playback_substream)
1067                                         snd_pcm_period_elapsed(chip->playback_substream);
1068                         }
1069                         if (chip->mode & WSS_MODE_RECORD) {
1070                                 if (chip->capture_substream) {
1071                                         snd_wss_overrange(chip);
1072                                         snd_pcm_period_elapsed(chip->capture_substream);
1073                                 }
1074                         }
1075                 }
1076         } else {
1077                 if (status & CS4231_PLAYBACK_IRQ) {
1078                         if (chip->playback_substream)
1079                                 snd_pcm_period_elapsed(chip->playback_substream);
1080                 }
1081                 if (status & CS4231_RECORD_IRQ) {
1082                         if (chip->capture_substream) {
1083                                 snd_wss_overrange(chip);
1084                                 snd_pcm_period_elapsed(chip->capture_substream);
1085                         }
1086                 }
1087         }
1088
1089         spin_lock(&chip->reg_lock);
1090         snd_wss_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0);
1091         spin_unlock(&chip->reg_lock);
1092         return IRQ_HANDLED;
1093 }
1094 EXPORT_SYMBOL(snd_wss_interrupt);
1095
1096 static snd_pcm_uframes_t snd_wss_playback_pointer(struct snd_pcm_substream *substream)
1097 {
1098         struct snd_wss *chip = snd_pcm_substream_chip(substream);
1099         size_t ptr;
1100
1101         if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE))
1102                 return 0;
1103         ptr = snd_dma_pointer(chip->dma1, chip->p_dma_size);
1104         return bytes_to_frames(substream->runtime, ptr);
1105 }
1106
1107 static snd_pcm_uframes_t snd_wss_capture_pointer(struct snd_pcm_substream *substream)
1108 {
1109         struct snd_wss *chip = snd_pcm_substream_chip(substream);
1110         size_t ptr;
1111
1112         if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE))
1113                 return 0;
1114         ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size);
1115         return bytes_to_frames(substream->runtime, ptr);
1116 }
1117
1118 /*
1119
1120  */
1121
1122 static int snd_wss_probe(struct snd_wss *chip)
1123 {
1124         unsigned long flags;
1125         int i, id, rev;
1126         unsigned char *ptr;
1127         unsigned int hw;
1128
1129 #if 0
1130         snd_wss_debug(chip);
1131 #endif
1132         id = 0;
1133         for (i = 0; i < 50; i++) {
1134                 mb();
1135                 if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
1136                         udelay(2000);
1137                 else {
1138                         spin_lock_irqsave(&chip->reg_lock, flags);
1139                         snd_wss_out(chip, CS4231_MISC_INFO, CS4231_MODE2);
1140                         id = snd_wss_in(chip, CS4231_MISC_INFO) & 0x0f;
1141                         spin_unlock_irqrestore(&chip->reg_lock, flags);
1142                         if (id == 0x0a)
1143                                 break;  /* this is valid value */
1144                 }
1145         }
1146         snd_printdd("wss: port = 0x%lx, id = 0x%x\n", chip->port, id);
1147         if (id != 0x0a)
1148                 return -ENODEV; /* no valid device found */
1149
1150         hw = chip->hardware;
1151         if ((hw & WSS_HW_TYPE_MASK) == WSS_HW_DETECT) {
1152                 rev = snd_wss_in(chip, CS4231_VERSION) & 0xe7;
1153                 snd_printdd("CS4231: VERSION (I25) = 0x%x\n", rev);
1154                 if (rev == 0x80) {
1155                         unsigned char tmp = snd_wss_in(chip, 23);
1156                         snd_wss_out(chip, 23, ~tmp);
1157                         if (snd_wss_in(chip, 23) != tmp)
1158                                 chip->hardware = WSS_HW_AD1845;
1159                         else
1160                                 chip->hardware = WSS_HW_CS4231;
1161                 } else if (rev == 0xa0) {
1162                         chip->hardware = WSS_HW_CS4231A;
1163                 } else if (rev == 0xa2) {
1164                         chip->hardware = WSS_HW_CS4232;
1165                 } else if (rev == 0xb2) {
1166                         chip->hardware = WSS_HW_CS4232A;
1167                 } else if (rev == 0x83) {
1168                         chip->hardware = WSS_HW_CS4236;
1169                 } else if (rev == 0x03) {
1170                         chip->hardware = WSS_HW_CS4236B;
1171                 } else {
1172                         snd_printk("unknown CS chip with version 0x%x\n", rev);
1173                         return -ENODEV;         /* unknown CS4231 chip? */
1174                 }
1175         }
1176         spin_lock_irqsave(&chip->reg_lock, flags);
1177         wss_inb(chip, CS4231P(STATUS)); /* clear any pendings IRQ */
1178         wss_outb(chip, CS4231P(STATUS), 0);
1179         mb();
1180         spin_unlock_irqrestore(&chip->reg_lock, flags);
1181
1182         chip->image[CS4231_MISC_INFO] = CS4231_MODE2;
1183         switch (chip->hardware) {
1184         case WSS_HW_INTERWAVE:
1185                 chip->image[CS4231_MISC_INFO] = CS4231_IW_MODE3;
1186                 break;
1187         case WSS_HW_CS4235:
1188         case WSS_HW_CS4236B:
1189         case WSS_HW_CS4237B:
1190         case WSS_HW_CS4238B:
1191         case WSS_HW_CS4239:
1192                 if (hw == WSS_HW_DETECT3)
1193                         chip->image[CS4231_MISC_INFO] = CS4231_4236_MODE3;
1194                 else
1195                         chip->hardware = WSS_HW_CS4236;
1196                 break;
1197         }
1198
1199         chip->image[CS4231_IFACE_CTRL] =
1200             (chip->image[CS4231_IFACE_CTRL] & ~CS4231_SINGLE_DMA) |
1201             (chip->single_dma ? CS4231_SINGLE_DMA : 0);
1202         if (chip->hardware != WSS_HW_OPTI93X) {
1203                 chip->image[CS4231_ALT_FEATURE_1] = 0x80;
1204                 chip->image[CS4231_ALT_FEATURE_2] =
1205                         chip->hardware == WSS_HW_INTERWAVE ? 0xc2 : 0x01;
1206         }
1207         ptr = (unsigned char *) &chip->image;
1208         snd_wss_mce_down(chip);
1209         spin_lock_irqsave(&chip->reg_lock, flags);
1210         for (i = 0; i < 32; i++)        /* ok.. fill all CS4231 registers */
1211                 snd_wss_out(chip, i, *ptr++);
1212         spin_unlock_irqrestore(&chip->reg_lock, flags);
1213         snd_wss_mce_up(chip);
1214         snd_wss_mce_down(chip);
1215
1216         mdelay(2);
1217
1218         /* ok.. try check hardware version for CS4236+ chips */
1219         if ((hw & WSS_HW_TYPE_MASK) == WSS_HW_DETECT) {
1220                 if (chip->hardware == WSS_HW_CS4236B) {
1221                         rev = snd_cs4236_ext_in(chip, CS4236_VERSION);
1222                         snd_cs4236_ext_out(chip, CS4236_VERSION, 0xff);
1223                         id = snd_cs4236_ext_in(chip, CS4236_VERSION);
1224                         snd_cs4236_ext_out(chip, CS4236_VERSION, rev);
1225                         snd_printdd("CS4231: ext version; rev = 0x%x, id = 0x%x\n", rev, id);
1226                         if ((id & 0x1f) == 0x1d) {      /* CS4235 */
1227                                 chip->hardware = WSS_HW_CS4235;
1228                                 switch (id >> 5) {
1229                                 case 4:
1230                                 case 5:
1231                                 case 6:
1232                                         break;
1233                                 default:
1234                                         snd_printk("unknown CS4235 chip (enhanced version = 0x%x)\n", id);
1235                                 }
1236                         } else if ((id & 0x1f) == 0x0b) {       /* CS4236/B */
1237                                 switch (id >> 5) {
1238                                 case 4:
1239                                 case 5:
1240                                 case 6:
1241                                 case 7:
1242                                         chip->hardware = WSS_HW_CS4236B;
1243                                         break;
1244                                 default:
1245                                         snd_printk("unknown CS4236 chip (enhanced version = 0x%x)\n", id);
1246                                 }
1247                         } else if ((id & 0x1f) == 0x08) {       /* CS4237B */
1248                                 chip->hardware = WSS_HW_CS4237B;
1249                                 switch (id >> 5) {
1250                                 case 4:
1251                                 case 5:
1252                                 case 6:
1253                                 case 7:
1254                                         break;
1255                                 default:
1256                                         snd_printk("unknown CS4237B chip (enhanced version = 0x%x)\n", id);
1257                                 }
1258                         } else if ((id & 0x1f) == 0x09) {       /* CS4238B */
1259                                 chip->hardware = WSS_HW_CS4238B;
1260                                 switch (id >> 5) {
1261                                 case 5:
1262                                 case 6:
1263                                 case 7:
1264                                         break;
1265                                 default:
1266                                         snd_printk("unknown CS4238B chip (enhanced version = 0x%x)\n", id);
1267                                 }
1268                         } else if ((id & 0x1f) == 0x1e) {       /* CS4239 */
1269                                 chip->hardware = WSS_HW_CS4239;
1270                                 switch (id >> 5) {
1271                                 case 4:
1272                                 case 5:
1273                                 case 6:
1274                                         break;
1275                                 default:
1276                                         snd_printk("unknown CS4239 chip (enhanced version = 0x%x)\n", id);
1277                                 }
1278                         } else {
1279                                 snd_printk("unknown CS4236/CS423xB chip (enhanced version = 0x%x)\n", id);
1280                         }
1281                 }
1282         }
1283         return 0;               /* all things are ok.. */
1284 }
1285
1286 /*
1287
1288  */
1289
1290 static struct snd_pcm_hardware snd_wss_playback =
1291 {
1292         .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1293                                  SNDRV_PCM_INFO_MMAP_VALID |
1294                                  SNDRV_PCM_INFO_RESUME |
1295                                  SNDRV_PCM_INFO_SYNC_START),
1296         .formats =              (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
1297                                  SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
1298         .rates =                SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
1299         .rate_min =             5510,
1300         .rate_max =             48000,
1301         .channels_min =         1,
1302         .channels_max =         2,
1303         .buffer_bytes_max =     (128*1024),
1304         .period_bytes_min =     64,
1305         .period_bytes_max =     (128*1024),
1306         .periods_min =          1,
1307         .periods_max =          1024,
1308         .fifo_size =            0,
1309 };
1310
1311 static struct snd_pcm_hardware snd_wss_capture =
1312 {
1313         .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1314                                  SNDRV_PCM_INFO_MMAP_VALID |
1315                                  SNDRV_PCM_INFO_RESUME |
1316                                  SNDRV_PCM_INFO_SYNC_START),
1317         .formats =              (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
1318                                  SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
1319         .rates =                SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
1320         .rate_min =             5510,
1321         .rate_max =             48000,
1322         .channels_min =         1,
1323         .channels_max =         2,
1324         .buffer_bytes_max =     (128*1024),
1325         .period_bytes_min =     64,
1326         .period_bytes_max =     (128*1024),
1327         .periods_min =          1,
1328         .periods_max =          1024,
1329         .fifo_size =            0,
1330 };
1331
1332 /*
1333
1334  */
1335
1336 static int snd_wss_playback_open(struct snd_pcm_substream *substream)
1337 {
1338         struct snd_wss *chip = snd_pcm_substream_chip(substream);
1339         struct snd_pcm_runtime *runtime = substream->runtime;
1340         int err;
1341
1342         runtime->hw = snd_wss_playback;
1343
1344         /* hardware bug in InterWave chipset */
1345         if (chip->hardware == WSS_HW_INTERWAVE && chip->dma1 > 3)
1346                 runtime->hw.formats &= ~SNDRV_PCM_FMTBIT_MU_LAW;
1347
1348         /* hardware limitation of cheap chips */
1349         if (chip->hardware == WSS_HW_CS4235 ||
1350             chip->hardware == WSS_HW_CS4239)
1351                 runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE;
1352
1353         snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max);
1354         snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.period_bytes_max);
1355
1356         if (chip->claim_dma) {
1357                 if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma1)) < 0)
1358                         return err;
1359         }
1360
1361         err = snd_wss_open(chip, WSS_MODE_PLAY);
1362         if (err < 0) {
1363                 if (chip->release_dma)
1364                         chip->release_dma(chip, chip->dma_private_data, chip->dma1);
1365                 snd_free_pages(runtime->dma_area, runtime->dma_bytes);
1366                 return err;
1367         }
1368         chip->playback_substream = substream;
1369         snd_pcm_set_sync(substream);
1370         chip->rate_constraint(runtime);
1371         return 0;
1372 }
1373
1374 static int snd_wss_capture_open(struct snd_pcm_substream *substream)
1375 {
1376         struct snd_wss *chip = snd_pcm_substream_chip(substream);
1377         struct snd_pcm_runtime *runtime = substream->runtime;
1378         int err;
1379
1380         runtime->hw = snd_wss_capture;
1381
1382         /* hardware limitation of cheap chips */
1383         if (chip->hardware == WSS_HW_CS4235 ||
1384             chip->hardware == WSS_HW_CS4239)
1385                 runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE;
1386
1387         snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max);
1388         snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max);
1389
1390         if (chip->claim_dma) {
1391                 if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma2)) < 0)
1392                         return err;
1393         }
1394
1395         err = snd_wss_open(chip, WSS_MODE_RECORD);
1396         if (err < 0) {
1397                 if (chip->release_dma)
1398                         chip->release_dma(chip, chip->dma_private_data, chip->dma2);
1399                 snd_free_pages(runtime->dma_area, runtime->dma_bytes);
1400                 return err;
1401         }
1402         chip->capture_substream = substream;
1403         snd_pcm_set_sync(substream);
1404         chip->rate_constraint(runtime);
1405         return 0;
1406 }
1407
1408 static int snd_wss_playback_close(struct snd_pcm_substream *substream)
1409 {
1410         struct snd_wss *chip = snd_pcm_substream_chip(substream);
1411
1412         chip->playback_substream = NULL;
1413         snd_wss_close(chip, WSS_MODE_PLAY);
1414         return 0;
1415 }
1416
1417 static int snd_wss_capture_close(struct snd_pcm_substream *substream)
1418 {
1419         struct snd_wss *chip = snd_pcm_substream_chip(substream);
1420
1421         chip->capture_substream = NULL;
1422         snd_wss_close(chip, WSS_MODE_RECORD);
1423         return 0;
1424 }
1425
1426 #ifdef CONFIG_PM
1427
1428 /* lowlevel suspend callback for CS4231 */
1429 static void snd_wss_suspend(struct snd_wss *chip)
1430 {
1431         int reg;
1432         unsigned long flags;
1433
1434         snd_pcm_suspend_all(chip->pcm);
1435         spin_lock_irqsave(&chip->reg_lock, flags);
1436         for (reg = 0; reg < 32; reg++)
1437                 chip->image[reg] = snd_wss_in(chip, reg);
1438         spin_unlock_irqrestore(&chip->reg_lock, flags);
1439 }
1440
1441 /* lowlevel resume callback for CS4231 */
1442 static void snd_wss_resume(struct snd_wss *chip)
1443 {
1444         int reg;
1445         unsigned long flags;
1446         /* int timeout; */
1447
1448         snd_wss_mce_up(chip);
1449         spin_lock_irqsave(&chip->reg_lock, flags);
1450         for (reg = 0; reg < 32; reg++) {
1451                 switch (reg) {
1452                 case CS4231_VERSION:
1453                         break;
1454                 default:
1455                         snd_wss_out(chip, reg, chip->image[reg]);
1456                         break;
1457                 }
1458         }
1459         spin_unlock_irqrestore(&chip->reg_lock, flags);
1460 #if 1
1461         snd_wss_mce_down(chip);
1462 #else
1463         /* The following is a workaround to avoid freeze after resume on TP600E.
1464            This is the first half of copy of snd_wss_mce_down(), but doesn't
1465            include rescheduling.  -- iwai
1466            */
1467         snd_wss_busy_wait(chip);
1468         spin_lock_irqsave(&chip->reg_lock, flags);
1469         chip->mce_bit &= ~CS4231_MCE;
1470         timeout = wss_inb(chip, CS4231P(REGSEL));
1471         wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
1472         spin_unlock_irqrestore(&chip->reg_lock, flags);
1473         if (timeout == 0x80)
1474                 snd_printk("down [0x%lx]: serious init problem - codec still busy\n", chip->port);
1475         if ((timeout & CS4231_MCE) == 0 ||
1476             !(chip->hardware & (WSS_HW_CS4231_MASK | WSS_HW_CS4232_MASK))) {
1477                 return;
1478         }
1479         snd_wss_busy_wait(chip);
1480 #endif
1481 }
1482 #endif /* CONFIG_PM */
1483
1484 static int snd_wss_free(struct snd_wss *chip)
1485 {
1486         release_and_free_resource(chip->res_port);
1487         release_and_free_resource(chip->res_cport);
1488         if (chip->irq >= 0) {
1489                 disable_irq(chip->irq);
1490                 if (!(chip->hwshare & WSS_HWSHARE_IRQ))
1491                         free_irq(chip->irq, (void *) chip);
1492         }
1493         if (!(chip->hwshare & WSS_HWSHARE_DMA1) && chip->dma1 >= 0) {
1494                 snd_dma_disable(chip->dma1);
1495                 free_dma(chip->dma1);
1496         }
1497         if (!(chip->hwshare & WSS_HWSHARE_DMA2) &&
1498             chip->dma2 >= 0 && chip->dma2 != chip->dma1) {
1499                 snd_dma_disable(chip->dma2);
1500                 free_dma(chip->dma2);
1501         }
1502         if (chip->timer)
1503                 snd_device_free(chip->card, chip->timer);
1504         kfree(chip);
1505         return 0;
1506 }
1507
1508 static int snd_wss_dev_free(struct snd_device *device)
1509 {
1510         struct snd_wss *chip = device->device_data;
1511         return snd_wss_free(chip);
1512 }
1513
1514 const char *snd_wss_chip_id(struct snd_wss *chip)
1515 {
1516         switch (chip->hardware) {
1517         case WSS_HW_CS4231:
1518                 return "CS4231";
1519         case WSS_HW_CS4231A:
1520                 return "CS4231A";
1521         case WSS_HW_CS4232:
1522                 return "CS4232";
1523         case WSS_HW_CS4232A:
1524                 return "CS4232A";
1525         case WSS_HW_CS4235:
1526                 return "CS4235";
1527         case WSS_HW_CS4236:
1528                 return "CS4236";
1529         case WSS_HW_CS4236B:
1530                 return "CS4236B";
1531         case WSS_HW_CS4237B:
1532                 return "CS4237B";
1533         case WSS_HW_CS4238B:
1534                 return "CS4238B";
1535         case WSS_HW_CS4239:
1536                 return "CS4239";
1537         case WSS_HW_INTERWAVE:
1538                 return "AMD InterWave";
1539         case WSS_HW_OPL3SA2:
1540                 return chip->card->shortname;
1541         case WSS_HW_AD1845:
1542                 return "AD1845";
1543         case WSS_HW_OPTI93X:
1544                 return "OPTi 93x";
1545         default:
1546                 return "???";
1547         }
1548 }
1549 EXPORT_SYMBOL(snd_wss_chip_id);
1550
1551 static int snd_wss_new(struct snd_card *card,
1552                           unsigned short hardware,
1553                           unsigned short hwshare,
1554                           struct snd_wss **rchip)
1555 {
1556         struct snd_wss *chip;
1557
1558         *rchip = NULL;
1559         chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1560         if (chip == NULL)
1561                 return -ENOMEM;
1562         chip->hardware = hardware;
1563         chip->hwshare = hwshare;
1564
1565         spin_lock_init(&chip->reg_lock);
1566         mutex_init(&chip->mce_mutex);
1567         mutex_init(&chip->open_mutex);
1568         chip->card = card;
1569         chip->rate_constraint = snd_wss_xrate;
1570         chip->set_playback_format = snd_wss_playback_format;
1571         chip->set_capture_format = snd_wss_capture_format;
1572         if (chip->hardware == WSS_HW_OPTI93X)
1573                 memcpy(&chip->image, &snd_opti93x_original_image,
1574                        sizeof(snd_opti93x_original_image));
1575         else
1576                 memcpy(&chip->image, &snd_wss_original_image,
1577                        sizeof(snd_wss_original_image));
1578
1579         *rchip = chip;
1580         return 0;
1581 }
1582
1583 int snd_wss_create(struct snd_card *card,
1584                       unsigned long port,
1585                       unsigned long cport,
1586                       int irq, int dma1, int dma2,
1587                       unsigned short hardware,
1588                       unsigned short hwshare,
1589                       struct snd_wss **rchip)
1590 {
1591         static struct snd_device_ops ops = {
1592                 .dev_free =     snd_wss_dev_free,
1593         };
1594         struct snd_wss *chip;
1595         int err;
1596
1597         err = snd_wss_new(card, hardware, hwshare, &chip);
1598         if (err < 0)
1599                 return err;
1600
1601         chip->irq = -1;
1602         chip->dma1 = -1;
1603         chip->dma2 = -1;
1604
1605         chip->res_port = request_region(port, 4, "CS4231");
1606         if (!chip->res_port) {
1607                 snd_printk(KERN_ERR "wss: can't grab port 0x%lx\n", port);
1608                 snd_wss_free(chip);
1609                 return -EBUSY;
1610         }
1611         chip->port = port;
1612         if ((long)cport >= 0) {
1613                 chip->res_cport = request_region(cport, 8, "CS4232 Control");
1614                 if (!chip->res_cport) {
1615                         snd_printk(KERN_ERR
1616                                 "wss: can't grab control port 0x%lx\n", cport);
1617                         snd_wss_free(chip);
1618                         return -ENODEV;
1619                 }
1620         }
1621         chip->cport = cport;
1622         if (!(hwshare & WSS_HWSHARE_IRQ))
1623                 if (request_irq(irq, snd_wss_interrupt, IRQF_DISABLED,
1624                                 "CS4231", (void *) chip)) {
1625                         snd_printk(KERN_ERR "wss: can't grab IRQ %d\n", irq);
1626                         snd_wss_free(chip);
1627                         return -EBUSY;
1628                 }
1629         chip->irq = irq;
1630         if (!(hwshare & WSS_HWSHARE_DMA1) && request_dma(dma1, "CS4231 - 1")) {
1631                 snd_printk(KERN_ERR "wss: can't grab DMA1 %d\n", dma1);
1632                 snd_wss_free(chip);
1633                 return -EBUSY;
1634         }
1635         chip->dma1 = dma1;
1636         if (!(hwshare & WSS_HWSHARE_DMA2) && dma1 != dma2 &&
1637               dma2 >= 0 && request_dma(dma2, "CS4231 - 2")) {
1638                 snd_printk(KERN_ERR "wss: can't grab DMA2 %d\n", dma2);
1639                 snd_wss_free(chip);
1640                 return -EBUSY;
1641         }
1642         if (dma1 == dma2 || dma2 < 0) {
1643                 chip->single_dma = 1;
1644                 chip->dma2 = chip->dma1;
1645         } else
1646                 chip->dma2 = dma2;
1647
1648         /* global setup */
1649         if (snd_wss_probe(chip) < 0) {
1650                 snd_wss_free(chip);
1651                 return -ENODEV;
1652         }
1653         snd_wss_init(chip);
1654
1655 #if 0
1656         if (chip->hardware & WSS_HW_CS4232_MASK) {
1657                 if (chip->res_cport == NULL)
1658                         snd_printk("CS4232 control port features are not accessible\n");
1659         }
1660 #endif
1661
1662         /* Register device */
1663         err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
1664         if (err < 0) {
1665                 snd_wss_free(chip);
1666                 return err;
1667         }
1668
1669 #ifdef CONFIG_PM
1670         /* Power Management */
1671         chip->suspend = snd_wss_suspend;
1672         chip->resume = snd_wss_resume;
1673 #endif
1674
1675         *rchip = chip;
1676         return 0;
1677 }
1678 EXPORT_SYMBOL(snd_wss_create);
1679
1680 static struct snd_pcm_ops snd_wss_playback_ops = {
1681         .open =         snd_wss_playback_open,
1682         .close =        snd_wss_playback_close,
1683         .ioctl =        snd_pcm_lib_ioctl,
1684         .hw_params =    snd_wss_playback_hw_params,
1685         .hw_free =      snd_wss_playback_hw_free,
1686         .prepare =      snd_wss_playback_prepare,
1687         .trigger =      snd_wss_trigger,
1688         .pointer =      snd_wss_playback_pointer,
1689 };
1690
1691 static struct snd_pcm_ops snd_wss_capture_ops = {
1692         .open =         snd_wss_capture_open,
1693         .close =        snd_wss_capture_close,
1694         .ioctl =        snd_pcm_lib_ioctl,
1695         .hw_params =    snd_wss_capture_hw_params,
1696         .hw_free =      snd_wss_capture_hw_free,
1697         .prepare =      snd_wss_capture_prepare,
1698         .trigger =      snd_wss_trigger,
1699         .pointer =      snd_wss_capture_pointer,
1700 };
1701
1702 int snd_wss_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm)
1703 {
1704         struct snd_pcm *pcm;
1705         int err;
1706
1707         if ((err = snd_pcm_new(chip->card, "CS4231", device, 1, 1, &pcm)) < 0)
1708                 return err;
1709
1710         spin_lock_init(&chip->reg_lock);
1711         mutex_init(&chip->mce_mutex);
1712         mutex_init(&chip->open_mutex);
1713
1714         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_wss_playback_ops);
1715         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_wss_capture_ops);
1716
1717         /* global setup */
1718         pcm->private_data = chip;
1719         pcm->info_flags = 0;
1720         if (chip->single_dma)
1721                 pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX;
1722         if (chip->hardware != WSS_HW_INTERWAVE)
1723                 pcm->info_flags |= SNDRV_PCM_INFO_JOINT_DUPLEX;
1724         strcpy(pcm->name, snd_wss_chip_id(chip));
1725
1726         snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1727                                               snd_dma_isa_data(),
1728                                               64*1024, chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024);
1729
1730         chip->pcm = pcm;
1731         if (rpcm)
1732                 *rpcm = pcm;
1733         return 0;
1734 }
1735 EXPORT_SYMBOL(snd_wss_pcm);
1736
1737 static void snd_wss_timer_free(struct snd_timer *timer)
1738 {
1739         struct snd_wss *chip = timer->private_data;
1740         chip->timer = NULL;
1741 }
1742
1743 int snd_wss_timer(struct snd_wss *chip, int device, struct snd_timer **rtimer)
1744 {
1745         struct snd_timer *timer;
1746         struct snd_timer_id tid;
1747         int err;
1748
1749         /* Timer initialization */
1750         tid.dev_class = SNDRV_TIMER_CLASS_CARD;
1751         tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
1752         tid.card = chip->card->number;
1753         tid.device = device;
1754         tid.subdevice = 0;
1755         if ((err = snd_timer_new(chip->card, "CS4231", &tid, &timer)) < 0)
1756                 return err;
1757         strcpy(timer->name, snd_wss_chip_id(chip));
1758         timer->private_data = chip;
1759         timer->private_free = snd_wss_timer_free;
1760         timer->hw = snd_wss_timer_table;
1761         chip->timer = timer;
1762         if (rtimer)
1763                 *rtimer = timer;
1764         return 0;
1765 }
1766 EXPORT_SYMBOL(snd_wss_timer);
1767
1768 /*
1769  *  MIXER part
1770  */
1771
1772 static int snd_wss_info_mux(struct snd_kcontrol *kcontrol,
1773                             struct snd_ctl_elem_info *uinfo)
1774 {
1775         static char *texts[4] = {
1776                 "Line", "Aux", "Mic", "Mix"
1777         };
1778         static char *opl3sa_texts[4] = {
1779                 "Line", "CD", "Mic", "Mix"
1780         };
1781         static char *gusmax_texts[4] = {
1782                 "Line", "Synth", "Mic", "Mix"
1783         };
1784         char **ptexts = texts;
1785         struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
1786
1787         snd_assert(chip->card != NULL, return -EINVAL);
1788         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1789         uinfo->count = 2;
1790         uinfo->value.enumerated.items = 4;
1791         if (uinfo->value.enumerated.item > 3)
1792                 uinfo->value.enumerated.item = 3;
1793         if (!strcmp(chip->card->driver, "GUS MAX"))
1794                 ptexts = gusmax_texts;
1795         switch (chip->hardware) {
1796         case WSS_HW_INTERWAVE:
1797                 ptexts = gusmax_texts;
1798                 break;
1799         case WSS_HW_OPL3SA2:
1800                 ptexts = opl3sa_texts;
1801                 break;
1802         }
1803         strcpy(uinfo->value.enumerated.name, ptexts[uinfo->value.enumerated.item]);
1804         return 0;
1805 }
1806
1807 static int snd_wss_get_mux(struct snd_kcontrol *kcontrol,
1808                            struct snd_ctl_elem_value *ucontrol)
1809 {
1810         struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
1811         unsigned long flags;
1812
1813         spin_lock_irqsave(&chip->reg_lock, flags);
1814         ucontrol->value.enumerated.item[0] = (chip->image[CS4231_LEFT_INPUT] & CS4231_MIXS_ALL) >> 6;
1815         ucontrol->value.enumerated.item[1] = (chip->image[CS4231_RIGHT_INPUT] & CS4231_MIXS_ALL) >> 6;
1816         spin_unlock_irqrestore(&chip->reg_lock, flags);
1817         return 0;
1818 }
1819
1820 static int snd_wss_put_mux(struct snd_kcontrol *kcontrol,
1821                            struct snd_ctl_elem_value *ucontrol)
1822 {
1823         struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
1824         unsigned long flags;
1825         unsigned short left, right;
1826         int change;
1827
1828         if (ucontrol->value.enumerated.item[0] > 3 ||
1829             ucontrol->value.enumerated.item[1] > 3)
1830                 return -EINVAL;
1831         left = ucontrol->value.enumerated.item[0] << 6;
1832         right = ucontrol->value.enumerated.item[1] << 6;
1833         spin_lock_irqsave(&chip->reg_lock, flags);
1834         left = (chip->image[CS4231_LEFT_INPUT] & ~CS4231_MIXS_ALL) | left;
1835         right = (chip->image[CS4231_RIGHT_INPUT] & ~CS4231_MIXS_ALL) | right;
1836         change = left != chip->image[CS4231_LEFT_INPUT] ||
1837                  right != chip->image[CS4231_RIGHT_INPUT];
1838         snd_wss_out(chip, CS4231_LEFT_INPUT, left);
1839         snd_wss_out(chip, CS4231_RIGHT_INPUT, right);
1840         spin_unlock_irqrestore(&chip->reg_lock, flags);
1841         return change;
1842 }
1843
1844 int snd_wss_info_single(struct snd_kcontrol *kcontrol,
1845                         struct snd_ctl_elem_info *uinfo)
1846 {
1847         int mask = (kcontrol->private_value >> 16) & 0xff;
1848
1849         uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1850         uinfo->count = 1;
1851         uinfo->value.integer.min = 0;
1852         uinfo->value.integer.max = mask;
1853         return 0;
1854 }
1855 EXPORT_SYMBOL(snd_wss_info_single);
1856
1857 int snd_wss_get_single(struct snd_kcontrol *kcontrol,
1858                        struct snd_ctl_elem_value *ucontrol)
1859 {
1860         struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
1861         unsigned long flags;
1862         int reg = kcontrol->private_value & 0xff;
1863         int shift = (kcontrol->private_value >> 8) & 0xff;
1864         int mask = (kcontrol->private_value >> 16) & 0xff;
1865         int invert = (kcontrol->private_value >> 24) & 0xff;
1866
1867         spin_lock_irqsave(&chip->reg_lock, flags);
1868         ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask;
1869         spin_unlock_irqrestore(&chip->reg_lock, flags);
1870         if (invert)
1871                 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1872         return 0;
1873 }
1874 EXPORT_SYMBOL(snd_wss_get_single);
1875
1876 int snd_wss_put_single(struct snd_kcontrol *kcontrol,
1877                        struct snd_ctl_elem_value *ucontrol)
1878 {
1879         struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
1880         unsigned long flags;
1881         int reg = kcontrol->private_value & 0xff;
1882         int shift = (kcontrol->private_value >> 8) & 0xff;
1883         int mask = (kcontrol->private_value >> 16) & 0xff;
1884         int invert = (kcontrol->private_value >> 24) & 0xff;
1885         int change;
1886         unsigned short val;
1887
1888         val = (ucontrol->value.integer.value[0] & mask);
1889         if (invert)
1890                 val = mask - val;
1891         val <<= shift;
1892         spin_lock_irqsave(&chip->reg_lock, flags);
1893         val = (chip->image[reg] & ~(mask << shift)) | val;
1894         change = val != chip->image[reg];
1895         snd_wss_out(chip, reg, val);
1896         spin_unlock_irqrestore(&chip->reg_lock, flags);
1897         return change;
1898 }
1899 EXPORT_SYMBOL(snd_wss_put_single);
1900
1901 int snd_wss_info_double(struct snd_kcontrol *kcontrol,
1902                         struct snd_ctl_elem_info *uinfo)
1903 {
1904         int mask = (kcontrol->private_value >> 24) & 0xff;
1905
1906         uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1907         uinfo->count = 2;
1908         uinfo->value.integer.min = 0;
1909         uinfo->value.integer.max = mask;
1910         return 0;
1911 }
1912 EXPORT_SYMBOL(snd_wss_info_double);
1913
1914 int snd_wss_get_double(struct snd_kcontrol *kcontrol,
1915                        struct snd_ctl_elem_value *ucontrol)
1916 {
1917         struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
1918         unsigned long flags;
1919         int left_reg = kcontrol->private_value & 0xff;
1920         int right_reg = (kcontrol->private_value >> 8) & 0xff;
1921         int shift_left = (kcontrol->private_value >> 16) & 0x07;
1922         int shift_right = (kcontrol->private_value >> 19) & 0x07;
1923         int mask = (kcontrol->private_value >> 24) & 0xff;
1924         int invert = (kcontrol->private_value >> 22) & 1;
1925
1926         spin_lock_irqsave(&chip->reg_lock, flags);
1927         ucontrol->value.integer.value[0] = (chip->image[left_reg] >> shift_left) & mask;
1928         ucontrol->value.integer.value[1] = (chip->image[right_reg] >> shift_right) & mask;
1929         spin_unlock_irqrestore(&chip->reg_lock, flags);
1930         if (invert) {
1931                 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1932                 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
1933         }
1934         return 0;
1935 }
1936 EXPORT_SYMBOL(snd_wss_get_double);
1937
1938 int snd_wss_put_double(struct snd_kcontrol *kcontrol,
1939                        struct snd_ctl_elem_value *ucontrol)
1940 {
1941         struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
1942         unsigned long flags;
1943         int left_reg = kcontrol->private_value & 0xff;
1944         int right_reg = (kcontrol->private_value >> 8) & 0xff;
1945         int shift_left = (kcontrol->private_value >> 16) & 0x07;
1946         int shift_right = (kcontrol->private_value >> 19) & 0x07;
1947         int mask = (kcontrol->private_value >> 24) & 0xff;
1948         int invert = (kcontrol->private_value >> 22) & 1;
1949         int change;
1950         unsigned short val1, val2;
1951
1952         val1 = ucontrol->value.integer.value[0] & mask;
1953         val2 = ucontrol->value.integer.value[1] & mask;
1954         if (invert) {
1955                 val1 = mask - val1;
1956                 val2 = mask - val2;
1957         }
1958         val1 <<= shift_left;
1959         val2 <<= shift_right;
1960         spin_lock_irqsave(&chip->reg_lock, flags);
1961         if (left_reg != right_reg) {
1962                 val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1;
1963                 val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2;
1964                 change = val1 != chip->image[left_reg] ||
1965                          val2 != chip->image[right_reg];
1966                 snd_wss_out(chip, left_reg, val1);
1967                 snd_wss_out(chip, right_reg, val2);
1968         } else {
1969                 mask = (mask << shift_left) | (mask << shift_right);
1970                 val1 = (chip->image[left_reg] & ~mask) | val1 | val2;
1971                 change = val1 != chip->image[left_reg];
1972                 snd_wss_out(chip, left_reg, val1);
1973         }
1974         spin_unlock_irqrestore(&chip->reg_lock, flags);
1975         return change;
1976 }
1977 EXPORT_SYMBOL(snd_wss_put_double);
1978
1979 static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
1980 static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
1981 static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
1982
1983 static struct snd_kcontrol_new snd_ad1848_controls[] = {
1984 WSS_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT,
1985            7, 7, 1, 1),
1986 WSS_DOUBLE_TLV("PCM Playback Volume", 0,
1987                CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1,
1988                db_scale_6bit),
1989 WSS_DOUBLE("Aux Playback Switch", 0,
1990            CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
1991 WSS_DOUBLE_TLV("Aux Playback Volume", 0,
1992                CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
1993                db_scale_5bit_12db_max),
1994 WSS_DOUBLE("Aux Playback Switch", 1,
1995            CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
1996 WSS_DOUBLE_TLV("Aux Playback Volume", 1,
1997                CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
1998                db_scale_5bit_12db_max),
1999 WSS_DOUBLE_TLV("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT,
2000                 0, 0, 15, 0, db_scale_rec_gain),
2001 {
2002         .name = "Capture Source",
2003         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2004         .info = snd_wss_info_mux,
2005         .get = snd_wss_get_mux,
2006         .put = snd_wss_put_mux,
2007 },
2008 WSS_SINGLE("Loopback Capture Switch", 0, CS4231_LOOPBACK, 0, 1, 0),
2009 WSS_SINGLE_TLV("Loopback Capture Volume", 0, CS4231_LOOPBACK, 1, 63, 0,
2010                db_scale_6bit),
2011 };
2012
2013 static struct snd_kcontrol_new snd_wss_controls[] = {
2014 WSS_DOUBLE("PCM Playback Switch", 0,
2015                 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
2016 WSS_DOUBLE("PCM Playback Volume", 0,
2017                 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1),
2018 WSS_DOUBLE("Line Playback Switch", 0,
2019                 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
2020 WSS_DOUBLE("Line Playback Volume", 0,
2021                 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1),
2022 WSS_DOUBLE("Aux Playback Switch", 0,
2023                 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
2024 WSS_DOUBLE("Aux Playback Volume", 0,
2025                 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1),
2026 WSS_DOUBLE("Aux Playback Switch", 1,
2027                 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
2028 WSS_DOUBLE("Aux Playback Volume", 1,
2029                 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1),
2030 WSS_SINGLE("Mono Playback Switch", 0,
2031                 CS4231_MONO_CTRL, 7, 1, 1),
2032 WSS_SINGLE("Mono Playback Volume", 0,
2033                 CS4231_MONO_CTRL, 0, 15, 1),
2034 WSS_SINGLE("Mono Output Playback Switch", 0,
2035                 CS4231_MONO_CTRL, 6, 1, 1),
2036 WSS_SINGLE("Mono Output Playback Bypass", 0,
2037                 CS4231_MONO_CTRL, 5, 1, 0),
2038 WSS_DOUBLE("Capture Volume", 0,
2039                 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0),
2040 {
2041         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2042         .name = "Capture Source",
2043         .info = snd_wss_info_mux,
2044         .get = snd_wss_get_mux,
2045         .put = snd_wss_put_mux,
2046 },
2047 WSS_DOUBLE("Mic Boost", 0,
2048                 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
2049 WSS_SINGLE("Loopback Capture Switch", 0,
2050                 CS4231_LOOPBACK, 0, 1, 0),
2051 WSS_SINGLE("Loopback Capture Volume", 0,
2052                 CS4231_LOOPBACK, 2, 63, 1)
2053 };
2054
2055 static struct snd_kcontrol_new snd_opti93x_controls[] = {
2056 WSS_DOUBLE("Master Playback Switch", 0,
2057                 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
2058 WSS_DOUBLE("Master Playback Volume", 0,
2059                 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1),
2060 WSS_DOUBLE("PCM Playback Switch", 0,
2061                 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
2062 WSS_DOUBLE("PCM Playback Volume", 0,
2063                 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1),
2064 WSS_DOUBLE("FM Playback Switch", 0,
2065                 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
2066 WSS_DOUBLE("FM Playback Volume", 0,
2067                 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 1, 1, 15, 1),
2068 WSS_DOUBLE("Line Playback Switch", 0,
2069                 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
2070 WSS_DOUBLE("Line Playback Volume", 0,
2071                 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 15, 1),
2072 WSS_DOUBLE("Mic Playback Switch", 0,
2073                 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1),
2074 WSS_DOUBLE("Mic Playback Volume", 0,
2075                 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1),
2076 WSS_DOUBLE("Mic Boost", 0,
2077                 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
2078 WSS_DOUBLE("CD Playback Switch", 0,
2079                 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
2080 WSS_DOUBLE("CD Playback Volume", 0,
2081                 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 1, 1, 15, 1),
2082 WSS_DOUBLE("Aux Playback Switch", 0,
2083                 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1),
2084 WSS_DOUBLE("Aux Playback Volume", 0,
2085                 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1),
2086 WSS_DOUBLE("Capture Volume", 0,
2087                 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0),
2088 {
2089         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2090         .name = "Capture Source",
2091         .info = snd_wss_info_mux,
2092         .get = snd_wss_get_mux,
2093         .put = snd_wss_put_mux,
2094 }
2095 };
2096
2097 int snd_wss_mixer(struct snd_wss *chip)
2098 {
2099         struct snd_card *card;
2100         unsigned int idx;
2101         int err;
2102
2103         snd_assert(chip != NULL && chip->pcm != NULL, return -EINVAL);
2104
2105         card = chip->card;
2106
2107         strcpy(card->mixername, chip->pcm->name);
2108
2109         if (chip->hardware == WSS_HW_OPTI93X)
2110                 for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) {
2111                         err = snd_ctl_add(card,
2112                                         snd_ctl_new1(&snd_opti93x_controls[idx],
2113                                                      chip));
2114                         if (err < 0)
2115                                 return err;
2116                 }
2117         else if (chip->hardware & WSS_HW_AD1848_MASK)
2118                 for (idx = 0; idx < ARRAY_SIZE(snd_ad1848_controls); idx++) {
2119                         err = snd_ctl_add(card,
2120                                         snd_ctl_new1(&snd_ad1848_controls[idx],
2121                                                      chip));
2122                         if (err < 0)
2123                                 return err;
2124                 }
2125         else
2126                 for (idx = 0; idx < ARRAY_SIZE(snd_wss_controls); idx++) {
2127                         err = snd_ctl_add(card,
2128                                         snd_ctl_new1(&snd_wss_controls[idx],
2129                                                      chip));
2130                         if (err < 0)
2131                                 return err;
2132                 }
2133         return 0;
2134 }
2135 EXPORT_SYMBOL(snd_wss_mixer);
2136
2137 /*
2138  *  INIT part
2139  */
2140
2141 static int __init alsa_wss_init(void)
2142 {
2143         return 0;
2144 }
2145
2146 static void __exit alsa_wss_exit(void)
2147 {
2148 }
2149
2150 module_init(alsa_wss_init);
2151 module_exit(alsa_wss_exit);