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