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