• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 		if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma1)) < 0)
1497 			return err;
1498 	}
1499 
1500 	err = snd_wss_open(chip, WSS_MODE_PLAY);
1501 	if (err < 0) {
1502 		if (chip->release_dma)
1503 			chip->release_dma(chip, chip->dma_private_data, chip->dma1);
1504 		return err;
1505 	}
1506 	chip->playback_substream = substream;
1507 	snd_pcm_set_sync(substream);
1508 	chip->rate_constraint(runtime);
1509 	return 0;
1510 }
1511 
snd_wss_capture_open(struct snd_pcm_substream * substream)1512 static int snd_wss_capture_open(struct snd_pcm_substream *substream)
1513 {
1514 	struct snd_wss *chip = snd_pcm_substream_chip(substream);
1515 	struct snd_pcm_runtime *runtime = substream->runtime;
1516 	int err;
1517 
1518 	runtime->hw = snd_wss_capture;
1519 
1520 	/* hardware limitation of older chipsets */
1521 	if (chip->hardware & WSS_HW_AD1848_MASK)
1522 		runtime->hw.formats &= ~(SNDRV_PCM_FMTBIT_IMA_ADPCM |
1523 					 SNDRV_PCM_FMTBIT_S16_BE);
1524 
1525 	/* hardware limitation of cheap chips */
1526 	if (chip->hardware == WSS_HW_CS4235 ||
1527 	    chip->hardware == WSS_HW_CS4239 ||
1528 	    chip->hardware == WSS_HW_OPTI93X)
1529 		runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 |
1530 				      SNDRV_PCM_FMTBIT_S16_LE;
1531 
1532 	snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max);
1533 	snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max);
1534 
1535 	if (chip->claim_dma) {
1536 		if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma2)) < 0)
1537 			return err;
1538 	}
1539 
1540 	err = snd_wss_open(chip, WSS_MODE_RECORD);
1541 	if (err < 0) {
1542 		if (chip->release_dma)
1543 			chip->release_dma(chip, chip->dma_private_data, chip->dma2);
1544 		return err;
1545 	}
1546 	chip->capture_substream = substream;
1547 	snd_pcm_set_sync(substream);
1548 	chip->rate_constraint(runtime);
1549 	return 0;
1550 }
1551 
snd_wss_playback_close(struct snd_pcm_substream * substream)1552 static int snd_wss_playback_close(struct snd_pcm_substream *substream)
1553 {
1554 	struct snd_wss *chip = snd_pcm_substream_chip(substream);
1555 
1556 	chip->playback_substream = NULL;
1557 	snd_wss_close(chip, WSS_MODE_PLAY);
1558 	return 0;
1559 }
1560 
snd_wss_capture_close(struct snd_pcm_substream * substream)1561 static int snd_wss_capture_close(struct snd_pcm_substream *substream)
1562 {
1563 	struct snd_wss *chip = snd_pcm_substream_chip(substream);
1564 
1565 	chip->capture_substream = NULL;
1566 	snd_wss_close(chip, WSS_MODE_RECORD);
1567 	return 0;
1568 }
1569 
snd_wss_thinkpad_twiddle(struct snd_wss * chip,int on)1570 static void snd_wss_thinkpad_twiddle(struct snd_wss *chip, int on)
1571 {
1572 	int tmp;
1573 
1574 	if (!chip->thinkpad_flag)
1575 		return;
1576 
1577 	outb(0x1c, AD1848_THINKPAD_CTL_PORT1);
1578 	tmp = inb(AD1848_THINKPAD_CTL_PORT2);
1579 
1580 	if (on)
1581 		/* turn it on */
1582 		tmp |= AD1848_THINKPAD_CS4248_ENABLE_BIT;
1583 	else
1584 		/* turn it off */
1585 		tmp &= ~AD1848_THINKPAD_CS4248_ENABLE_BIT;
1586 
1587 	outb(tmp, AD1848_THINKPAD_CTL_PORT2);
1588 }
1589 
1590 #ifdef CONFIG_PM
1591 
1592 /* lowlevel suspend callback for CS4231 */
snd_wss_suspend(struct snd_wss * chip)1593 static void snd_wss_suspend(struct snd_wss *chip)
1594 {
1595 	int reg;
1596 	unsigned long flags;
1597 
1598 	spin_lock_irqsave(&chip->reg_lock, flags);
1599 	for (reg = 0; reg < 32; reg++)
1600 		chip->image[reg] = snd_wss_in(chip, reg);
1601 	spin_unlock_irqrestore(&chip->reg_lock, flags);
1602 	if (chip->thinkpad_flag)
1603 		snd_wss_thinkpad_twiddle(chip, 0);
1604 }
1605 
1606 /* lowlevel resume callback for CS4231 */
snd_wss_resume(struct snd_wss * chip)1607 static void snd_wss_resume(struct snd_wss *chip)
1608 {
1609 	int reg;
1610 	unsigned long flags;
1611 	/* int timeout; */
1612 
1613 	if (chip->thinkpad_flag)
1614 		snd_wss_thinkpad_twiddle(chip, 1);
1615 	snd_wss_mce_up(chip);
1616 	spin_lock_irqsave(&chip->reg_lock, flags);
1617 	for (reg = 0; reg < 32; reg++) {
1618 		switch (reg) {
1619 		case CS4231_VERSION:
1620 			break;
1621 		default:
1622 			snd_wss_out(chip, reg, chip->image[reg]);
1623 			break;
1624 		}
1625 	}
1626 	/* Yamaha needs this to resume properly */
1627 	if (chip->hardware == WSS_HW_OPL3SA2)
1628 		snd_wss_out(chip, CS4231_PLAYBK_FORMAT,
1629 			    chip->image[CS4231_PLAYBK_FORMAT]);
1630 	spin_unlock_irqrestore(&chip->reg_lock, flags);
1631 #if 1
1632 	snd_wss_mce_down(chip);
1633 #else
1634 	/* The following is a workaround to avoid freeze after resume on TP600E.
1635 	   This is the first half of copy of snd_wss_mce_down(), but doesn't
1636 	   include rescheduling.  -- iwai
1637 	   */
1638 	snd_wss_busy_wait(chip);
1639 	spin_lock_irqsave(&chip->reg_lock, flags);
1640 	chip->mce_bit &= ~CS4231_MCE;
1641 	timeout = wss_inb(chip, CS4231P(REGSEL));
1642 	wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
1643 	spin_unlock_irqrestore(&chip->reg_lock, flags);
1644 	if (timeout == 0x80)
1645 		snd_printk(KERN_ERR "down [0x%lx]: serious init problem "
1646 			   "- codec still busy\n", chip->port);
1647 	if ((timeout & CS4231_MCE) == 0 ||
1648 	    !(chip->hardware & (WSS_HW_CS4231_MASK | WSS_HW_CS4232_MASK))) {
1649 		return;
1650 	}
1651 	snd_wss_busy_wait(chip);
1652 #endif
1653 }
1654 #endif /* CONFIG_PM */
1655 
snd_wss_free(struct snd_wss * chip)1656 static int snd_wss_free(struct snd_wss *chip)
1657 {
1658 	release_and_free_resource(chip->res_port);
1659 	release_and_free_resource(chip->res_cport);
1660 	if (chip->irq >= 0) {
1661 		disable_irq(chip->irq);
1662 		if (!(chip->hwshare & WSS_HWSHARE_IRQ))
1663 			free_irq(chip->irq, (void *) chip);
1664 	}
1665 	if (!(chip->hwshare & WSS_HWSHARE_DMA1) && chip->dma1 >= 0) {
1666 		snd_dma_disable(chip->dma1);
1667 		free_dma(chip->dma1);
1668 	}
1669 	if (!(chip->hwshare & WSS_HWSHARE_DMA2) &&
1670 	    chip->dma2 >= 0 && chip->dma2 != chip->dma1) {
1671 		snd_dma_disable(chip->dma2);
1672 		free_dma(chip->dma2);
1673 	}
1674 	if (chip->timer)
1675 		snd_device_free(chip->card, chip->timer);
1676 	kfree(chip);
1677 	return 0;
1678 }
1679 
snd_wss_dev_free(struct snd_device * device)1680 static int snd_wss_dev_free(struct snd_device *device)
1681 {
1682 	struct snd_wss *chip = device->device_data;
1683 	return snd_wss_free(chip);
1684 }
1685 
snd_wss_chip_id(struct snd_wss * chip)1686 const char *snd_wss_chip_id(struct snd_wss *chip)
1687 {
1688 	switch (chip->hardware) {
1689 	case WSS_HW_CS4231:
1690 		return "CS4231";
1691 	case WSS_HW_CS4231A:
1692 		return "CS4231A";
1693 	case WSS_HW_CS4232:
1694 		return "CS4232";
1695 	case WSS_HW_CS4232A:
1696 		return "CS4232A";
1697 	case WSS_HW_CS4235:
1698 		return "CS4235";
1699 	case WSS_HW_CS4236:
1700 		return "CS4236";
1701 	case WSS_HW_CS4236B:
1702 		return "CS4236B";
1703 	case WSS_HW_CS4237B:
1704 		return "CS4237B";
1705 	case WSS_HW_CS4238B:
1706 		return "CS4238B";
1707 	case WSS_HW_CS4239:
1708 		return "CS4239";
1709 	case WSS_HW_INTERWAVE:
1710 		return "AMD InterWave";
1711 	case WSS_HW_OPL3SA2:
1712 		return chip->card->shortname;
1713 	case WSS_HW_AD1845:
1714 		return "AD1845";
1715 	case WSS_HW_OPTI93X:
1716 		return "OPTi 93x";
1717 	case WSS_HW_AD1847:
1718 		return "AD1847";
1719 	case WSS_HW_AD1848:
1720 		return "AD1848";
1721 	case WSS_HW_CS4248:
1722 		return "CS4248";
1723 	case WSS_HW_CMI8330:
1724 		return "CMI8330/C3D";
1725 	default:
1726 		return "???";
1727 	}
1728 }
1729 EXPORT_SYMBOL(snd_wss_chip_id);
1730 
snd_wss_new(struct snd_card * card,unsigned short hardware,unsigned short hwshare,struct snd_wss ** rchip)1731 static int snd_wss_new(struct snd_card *card,
1732 			  unsigned short hardware,
1733 			  unsigned short hwshare,
1734 			  struct snd_wss **rchip)
1735 {
1736 	struct snd_wss *chip;
1737 
1738 	*rchip = NULL;
1739 	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1740 	if (chip == NULL)
1741 		return -ENOMEM;
1742 	chip->hardware = hardware;
1743 	chip->hwshare = hwshare;
1744 
1745 	spin_lock_init(&chip->reg_lock);
1746 	mutex_init(&chip->mce_mutex);
1747 	mutex_init(&chip->open_mutex);
1748 	chip->card = card;
1749 	chip->rate_constraint = snd_wss_xrate;
1750 	chip->set_playback_format = snd_wss_playback_format;
1751 	chip->set_capture_format = snd_wss_capture_format;
1752 	if (chip->hardware == WSS_HW_OPTI93X)
1753 		memcpy(&chip->image, &snd_opti93x_original_image,
1754 		       sizeof(snd_opti93x_original_image));
1755 	else
1756 		memcpy(&chip->image, &snd_wss_original_image,
1757 		       sizeof(snd_wss_original_image));
1758 	if (chip->hardware & WSS_HW_AD1848_MASK) {
1759 		chip->image[CS4231_PIN_CTRL] = 0;
1760 		chip->image[CS4231_TEST_INIT] = 0;
1761 	}
1762 
1763 	*rchip = chip;
1764 	return 0;
1765 }
1766 
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)1767 int snd_wss_create(struct snd_card *card,
1768 		      unsigned long port,
1769 		      unsigned long cport,
1770 		      int irq, int dma1, int dma2,
1771 		      unsigned short hardware,
1772 		      unsigned short hwshare,
1773 		      struct snd_wss **rchip)
1774 {
1775 	static const struct snd_device_ops ops = {
1776 		.dev_free =	snd_wss_dev_free,
1777 	};
1778 	struct snd_wss *chip;
1779 	int err;
1780 
1781 	err = snd_wss_new(card, hardware, hwshare, &chip);
1782 	if (err < 0)
1783 		return err;
1784 
1785 	chip->irq = -1;
1786 	chip->dma1 = -1;
1787 	chip->dma2 = -1;
1788 
1789 	chip->res_port = request_region(port, 4, "WSS");
1790 	if (!chip->res_port) {
1791 		snd_printk(KERN_ERR "wss: can't grab port 0x%lx\n", port);
1792 		snd_wss_free(chip);
1793 		return -EBUSY;
1794 	}
1795 	chip->port = port;
1796 	if ((long)cport >= 0) {
1797 		chip->res_cport = request_region(cport, 8, "CS4232 Control");
1798 		if (!chip->res_cport) {
1799 			snd_printk(KERN_ERR
1800 				"wss: can't grab control port 0x%lx\n", cport);
1801 			snd_wss_free(chip);
1802 			return -ENODEV;
1803 		}
1804 	}
1805 	chip->cport = cport;
1806 	if (!(hwshare & WSS_HWSHARE_IRQ))
1807 		if (request_irq(irq, snd_wss_interrupt, 0,
1808 				"WSS", (void *) chip)) {
1809 			snd_printk(KERN_ERR "wss: can't grab IRQ %d\n", irq);
1810 			snd_wss_free(chip);
1811 			return -EBUSY;
1812 		}
1813 	chip->irq = irq;
1814 	card->sync_irq = chip->irq;
1815 	if (!(hwshare & WSS_HWSHARE_DMA1) && request_dma(dma1, "WSS - 1")) {
1816 		snd_printk(KERN_ERR "wss: can't grab DMA1 %d\n", dma1);
1817 		snd_wss_free(chip);
1818 		return -EBUSY;
1819 	}
1820 	chip->dma1 = dma1;
1821 	if (!(hwshare & WSS_HWSHARE_DMA2) && dma1 != dma2 &&
1822 	      dma2 >= 0 && request_dma(dma2, "WSS - 2")) {
1823 		snd_printk(KERN_ERR "wss: can't grab DMA2 %d\n", dma2);
1824 		snd_wss_free(chip);
1825 		return -EBUSY;
1826 	}
1827 	if (dma1 == dma2 || dma2 < 0) {
1828 		chip->single_dma = 1;
1829 		chip->dma2 = chip->dma1;
1830 	} else
1831 		chip->dma2 = dma2;
1832 
1833 	if (hardware == WSS_HW_THINKPAD) {
1834 		chip->thinkpad_flag = 1;
1835 		chip->hardware = WSS_HW_DETECT; /* reset */
1836 		snd_wss_thinkpad_twiddle(chip, 1);
1837 	}
1838 
1839 	/* global setup */
1840 	if (snd_wss_probe(chip) < 0) {
1841 		snd_wss_free(chip);
1842 		return -ENODEV;
1843 	}
1844 	snd_wss_init(chip);
1845 
1846 #if 0
1847 	if (chip->hardware & WSS_HW_CS4232_MASK) {
1848 		if (chip->res_cport == NULL)
1849 			snd_printk(KERN_ERR "CS4232 control port features are "
1850 				   "not accessible\n");
1851 	}
1852 #endif
1853 
1854 	/* Register device */
1855 	err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
1856 	if (err < 0) {
1857 		snd_wss_free(chip);
1858 		return err;
1859 	}
1860 
1861 #ifdef CONFIG_PM
1862 	/* Power Management */
1863 	chip->suspend = snd_wss_suspend;
1864 	chip->resume = snd_wss_resume;
1865 #endif
1866 
1867 	*rchip = chip;
1868 	return 0;
1869 }
1870 EXPORT_SYMBOL(snd_wss_create);
1871 
1872 static const struct snd_pcm_ops snd_wss_playback_ops = {
1873 	.open =		snd_wss_playback_open,
1874 	.close =	snd_wss_playback_close,
1875 	.hw_params =	snd_wss_playback_hw_params,
1876 	.prepare =	snd_wss_playback_prepare,
1877 	.trigger =	snd_wss_trigger,
1878 	.pointer =	snd_wss_playback_pointer,
1879 };
1880 
1881 static const struct snd_pcm_ops snd_wss_capture_ops = {
1882 	.open =		snd_wss_capture_open,
1883 	.close =	snd_wss_capture_close,
1884 	.hw_params =	snd_wss_capture_hw_params,
1885 	.prepare =	snd_wss_capture_prepare,
1886 	.trigger =	snd_wss_trigger,
1887 	.pointer =	snd_wss_capture_pointer,
1888 };
1889 
snd_wss_pcm(struct snd_wss * chip,int device)1890 int snd_wss_pcm(struct snd_wss *chip, int device)
1891 {
1892 	struct snd_pcm *pcm;
1893 	int err;
1894 
1895 	err = snd_pcm_new(chip->card, "WSS", device, 1, 1, &pcm);
1896 	if (err < 0)
1897 		return err;
1898 
1899 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_wss_playback_ops);
1900 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_wss_capture_ops);
1901 
1902 	/* global setup */
1903 	pcm->private_data = chip;
1904 	pcm->info_flags = 0;
1905 	if (chip->single_dma)
1906 		pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX;
1907 	if (chip->hardware != WSS_HW_INTERWAVE)
1908 		pcm->info_flags |= SNDRV_PCM_INFO_JOINT_DUPLEX;
1909 	strcpy(pcm->name, snd_wss_chip_id(chip));
1910 
1911 	snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, chip->card->dev,
1912 				       64*1024, chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024);
1913 
1914 	chip->pcm = pcm;
1915 	return 0;
1916 }
1917 EXPORT_SYMBOL(snd_wss_pcm);
1918 
snd_wss_timer_free(struct snd_timer * timer)1919 static void snd_wss_timer_free(struct snd_timer *timer)
1920 {
1921 	struct snd_wss *chip = timer->private_data;
1922 	chip->timer = NULL;
1923 }
1924 
snd_wss_timer(struct snd_wss * chip,int device)1925 int snd_wss_timer(struct snd_wss *chip, int device)
1926 {
1927 	struct snd_timer *timer;
1928 	struct snd_timer_id tid;
1929 	int err;
1930 
1931 	/* Timer initialization */
1932 	tid.dev_class = SNDRV_TIMER_CLASS_CARD;
1933 	tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
1934 	tid.card = chip->card->number;
1935 	tid.device = device;
1936 	tid.subdevice = 0;
1937 	if ((err = snd_timer_new(chip->card, "CS4231", &tid, &timer)) < 0)
1938 		return err;
1939 	strcpy(timer->name, snd_wss_chip_id(chip));
1940 	timer->private_data = chip;
1941 	timer->private_free = snd_wss_timer_free;
1942 	timer->hw = snd_wss_timer_table;
1943 	chip->timer = timer;
1944 	return 0;
1945 }
1946 EXPORT_SYMBOL(snd_wss_timer);
1947 
1948 /*
1949  *  MIXER part
1950  */
1951 
snd_wss_info_mux(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)1952 static int snd_wss_info_mux(struct snd_kcontrol *kcontrol,
1953 			    struct snd_ctl_elem_info *uinfo)
1954 {
1955 	static const char * const texts[4] = {
1956 		"Line", "Aux", "Mic", "Mix"
1957 	};
1958 	static const char * const opl3sa_texts[4] = {
1959 		"Line", "CD", "Mic", "Mix"
1960 	};
1961 	static const char * const gusmax_texts[4] = {
1962 		"Line", "Synth", "Mic", "Mix"
1963 	};
1964 	const char * const *ptexts = texts;
1965 	struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
1966 
1967 	if (snd_BUG_ON(!chip->card))
1968 		return -EINVAL;
1969 	if (!strcmp(chip->card->driver, "GUS MAX"))
1970 		ptexts = gusmax_texts;
1971 	switch (chip->hardware) {
1972 	case WSS_HW_INTERWAVE:
1973 		ptexts = gusmax_texts;
1974 		break;
1975 	case WSS_HW_OPTI93X:
1976 	case WSS_HW_OPL3SA2:
1977 		ptexts = opl3sa_texts;
1978 		break;
1979 	}
1980 	return snd_ctl_enum_info(uinfo, 2, 4, ptexts);
1981 }
1982 
snd_wss_get_mux(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1983 static int snd_wss_get_mux(struct snd_kcontrol *kcontrol,
1984 			   struct snd_ctl_elem_value *ucontrol)
1985 {
1986 	struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
1987 	unsigned long flags;
1988 
1989 	spin_lock_irqsave(&chip->reg_lock, flags);
1990 	ucontrol->value.enumerated.item[0] = (chip->image[CS4231_LEFT_INPUT] & CS4231_MIXS_ALL) >> 6;
1991 	ucontrol->value.enumerated.item[1] = (chip->image[CS4231_RIGHT_INPUT] & CS4231_MIXS_ALL) >> 6;
1992 	spin_unlock_irqrestore(&chip->reg_lock, flags);
1993 	return 0;
1994 }
1995 
snd_wss_put_mux(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1996 static int snd_wss_put_mux(struct snd_kcontrol *kcontrol,
1997 			   struct snd_ctl_elem_value *ucontrol)
1998 {
1999 	struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2000 	unsigned long flags;
2001 	unsigned short left, right;
2002 	int change;
2003 
2004 	if (ucontrol->value.enumerated.item[0] > 3 ||
2005 	    ucontrol->value.enumerated.item[1] > 3)
2006 		return -EINVAL;
2007 	left = ucontrol->value.enumerated.item[0] << 6;
2008 	right = ucontrol->value.enumerated.item[1] << 6;
2009 	spin_lock_irqsave(&chip->reg_lock, flags);
2010 	left = (chip->image[CS4231_LEFT_INPUT] & ~CS4231_MIXS_ALL) | left;
2011 	right = (chip->image[CS4231_RIGHT_INPUT] & ~CS4231_MIXS_ALL) | right;
2012 	change = left != chip->image[CS4231_LEFT_INPUT] ||
2013 		 right != chip->image[CS4231_RIGHT_INPUT];
2014 	snd_wss_out(chip, CS4231_LEFT_INPUT, left);
2015 	snd_wss_out(chip, CS4231_RIGHT_INPUT, right);
2016 	spin_unlock_irqrestore(&chip->reg_lock, flags);
2017 	return change;
2018 }
2019 
snd_wss_info_single(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)2020 int snd_wss_info_single(struct snd_kcontrol *kcontrol,
2021 			struct snd_ctl_elem_info *uinfo)
2022 {
2023 	int mask = (kcontrol->private_value >> 16) & 0xff;
2024 
2025 	uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
2026 	uinfo->count = 1;
2027 	uinfo->value.integer.min = 0;
2028 	uinfo->value.integer.max = mask;
2029 	return 0;
2030 }
2031 EXPORT_SYMBOL(snd_wss_info_single);
2032 
snd_wss_get_single(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2033 int snd_wss_get_single(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 	int reg = kcontrol->private_value & 0xff;
2039 	int shift = (kcontrol->private_value >> 8) & 0xff;
2040 	int mask = (kcontrol->private_value >> 16) & 0xff;
2041 	int invert = (kcontrol->private_value >> 24) & 0xff;
2042 
2043 	spin_lock_irqsave(&chip->reg_lock, flags);
2044 	ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask;
2045 	spin_unlock_irqrestore(&chip->reg_lock, flags);
2046 	if (invert)
2047 		ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
2048 	return 0;
2049 }
2050 EXPORT_SYMBOL(snd_wss_get_single);
2051 
snd_wss_put_single(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2052 int snd_wss_put_single(struct snd_kcontrol *kcontrol,
2053 		       struct snd_ctl_elem_value *ucontrol)
2054 {
2055 	struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2056 	unsigned long flags;
2057 	int reg = kcontrol->private_value & 0xff;
2058 	int shift = (kcontrol->private_value >> 8) & 0xff;
2059 	int mask = (kcontrol->private_value >> 16) & 0xff;
2060 	int invert = (kcontrol->private_value >> 24) & 0xff;
2061 	int change;
2062 	unsigned short val;
2063 
2064 	val = (ucontrol->value.integer.value[0] & mask);
2065 	if (invert)
2066 		val = mask - val;
2067 	val <<= shift;
2068 	spin_lock_irqsave(&chip->reg_lock, flags);
2069 	val = (chip->image[reg] & ~(mask << shift)) | val;
2070 	change = val != chip->image[reg];
2071 	snd_wss_out(chip, reg, val);
2072 	spin_unlock_irqrestore(&chip->reg_lock, flags);
2073 	return change;
2074 }
2075 EXPORT_SYMBOL(snd_wss_put_single);
2076 
snd_wss_info_double(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)2077 int snd_wss_info_double(struct snd_kcontrol *kcontrol,
2078 			struct snd_ctl_elem_info *uinfo)
2079 {
2080 	int mask = (kcontrol->private_value >> 24) & 0xff;
2081 
2082 	uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
2083 	uinfo->count = 2;
2084 	uinfo->value.integer.min = 0;
2085 	uinfo->value.integer.max = mask;
2086 	return 0;
2087 }
2088 EXPORT_SYMBOL(snd_wss_info_double);
2089 
snd_wss_get_double(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2090 int snd_wss_get_double(struct snd_kcontrol *kcontrol,
2091 		       struct snd_ctl_elem_value *ucontrol)
2092 {
2093 	struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2094 	unsigned long flags;
2095 	int left_reg = kcontrol->private_value & 0xff;
2096 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
2097 	int shift_left = (kcontrol->private_value >> 16) & 0x07;
2098 	int shift_right = (kcontrol->private_value >> 19) & 0x07;
2099 	int mask = (kcontrol->private_value >> 24) & 0xff;
2100 	int invert = (kcontrol->private_value >> 22) & 1;
2101 
2102 	spin_lock_irqsave(&chip->reg_lock, flags);
2103 	ucontrol->value.integer.value[0] = (chip->image[left_reg] >> shift_left) & mask;
2104 	ucontrol->value.integer.value[1] = (chip->image[right_reg] >> shift_right) & mask;
2105 	spin_unlock_irqrestore(&chip->reg_lock, flags);
2106 	if (invert) {
2107 		ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
2108 		ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
2109 	}
2110 	return 0;
2111 }
2112 EXPORT_SYMBOL(snd_wss_get_double);
2113 
snd_wss_put_double(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2114 int snd_wss_put_double(struct snd_kcontrol *kcontrol,
2115 		       struct snd_ctl_elem_value *ucontrol)
2116 {
2117 	struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2118 	unsigned long flags;
2119 	int left_reg = kcontrol->private_value & 0xff;
2120 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
2121 	int shift_left = (kcontrol->private_value >> 16) & 0x07;
2122 	int shift_right = (kcontrol->private_value >> 19) & 0x07;
2123 	int mask = (kcontrol->private_value >> 24) & 0xff;
2124 	int invert = (kcontrol->private_value >> 22) & 1;
2125 	int change;
2126 	unsigned short val1, val2;
2127 
2128 	val1 = ucontrol->value.integer.value[0] & mask;
2129 	val2 = ucontrol->value.integer.value[1] & mask;
2130 	if (invert) {
2131 		val1 = mask - val1;
2132 		val2 = mask - val2;
2133 	}
2134 	val1 <<= shift_left;
2135 	val2 <<= shift_right;
2136 	spin_lock_irqsave(&chip->reg_lock, flags);
2137 	if (left_reg != right_reg) {
2138 		val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1;
2139 		val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2;
2140 		change = val1 != chip->image[left_reg] ||
2141 			 val2 != chip->image[right_reg];
2142 		snd_wss_out(chip, left_reg, val1);
2143 		snd_wss_out(chip, right_reg, val2);
2144 	} else {
2145 		mask = (mask << shift_left) | (mask << shift_right);
2146 		val1 = (chip->image[left_reg] & ~mask) | val1 | val2;
2147 		change = val1 != chip->image[left_reg];
2148 		snd_wss_out(chip, left_reg, val1);
2149 	}
2150 	spin_unlock_irqrestore(&chip->reg_lock, flags);
2151 	return change;
2152 }
2153 EXPORT_SYMBOL(snd_wss_put_double);
2154 
2155 static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
2156 static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
2157 static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
2158 static const DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0);
2159 
2160 static const struct snd_kcontrol_new snd_wss_controls[] = {
2161 WSS_DOUBLE("PCM Playback Switch", 0,
2162 		CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
2163 WSS_DOUBLE_TLV("PCM Playback Volume", 0,
2164 		CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1,
2165 		db_scale_6bit),
2166 WSS_DOUBLE("Aux Playback Switch", 0,
2167 		CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
2168 WSS_DOUBLE_TLV("Aux Playback Volume", 0,
2169 		CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
2170 		db_scale_5bit_12db_max),
2171 WSS_DOUBLE("Aux Playback Switch", 1,
2172 		CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
2173 WSS_DOUBLE_TLV("Aux Playback Volume", 1,
2174 		CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
2175 		db_scale_5bit_12db_max),
2176 WSS_DOUBLE_TLV("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT,
2177 		0, 0, 15, 0, db_scale_rec_gain),
2178 {
2179 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2180 	.name = "Capture Source",
2181 	.info = snd_wss_info_mux,
2182 	.get = snd_wss_get_mux,
2183 	.put = snd_wss_put_mux,
2184 },
2185 WSS_DOUBLE("Mic Boost (+20dB)", 0,
2186 		CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
2187 WSS_SINGLE("Loopback Capture Switch", 0,
2188 		CS4231_LOOPBACK, 0, 1, 0),
2189 WSS_SINGLE_TLV("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1,
2190 		db_scale_6bit),
2191 WSS_DOUBLE("Line Playback Switch", 0,
2192 		CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
2193 WSS_DOUBLE_TLV("Line Playback Volume", 0,
2194 		CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1,
2195 		db_scale_5bit_12db_max),
2196 WSS_SINGLE("Beep Playback Switch", 0,
2197 		CS4231_MONO_CTRL, 7, 1, 1),
2198 WSS_SINGLE_TLV("Beep Playback Volume", 0,
2199 		CS4231_MONO_CTRL, 0, 15, 1,
2200 		db_scale_4bit),
2201 WSS_SINGLE("Mono Output Playback Switch", 0,
2202 		CS4231_MONO_CTRL, 6, 1, 1),
2203 WSS_SINGLE("Beep Bypass Playback Switch", 0,
2204 		CS4231_MONO_CTRL, 5, 1, 0),
2205 };
2206 
snd_wss_mixer(struct snd_wss * chip)2207 int snd_wss_mixer(struct snd_wss *chip)
2208 {
2209 	struct snd_card *card;
2210 	unsigned int idx;
2211 	int err;
2212 	int count = ARRAY_SIZE(snd_wss_controls);
2213 
2214 	if (snd_BUG_ON(!chip || !chip->pcm))
2215 		return -EINVAL;
2216 
2217 	card = chip->card;
2218 
2219 	strcpy(card->mixername, chip->pcm->name);
2220 
2221 	/* Use only the first 11 entries on AD1848 */
2222 	if (chip->hardware & WSS_HW_AD1848_MASK)
2223 		count = 11;
2224 	/* There is no loopback on OPTI93X */
2225 	else if (chip->hardware == WSS_HW_OPTI93X)
2226 		count = 9;
2227 
2228 	for (idx = 0; idx < count; idx++) {
2229 		err = snd_ctl_add(card,
2230 				snd_ctl_new1(&snd_wss_controls[idx],
2231 					     chip));
2232 		if (err < 0)
2233 			return err;
2234 	}
2235 	return 0;
2236 }
2237 EXPORT_SYMBOL(snd_wss_mixer);
2238 
snd_wss_get_pcm_ops(int direction)2239 const struct snd_pcm_ops *snd_wss_get_pcm_ops(int direction)
2240 {
2241 	return direction == SNDRV_PCM_STREAM_PLAYBACK ?
2242 		&snd_wss_playback_ops : &snd_wss_capture_ops;
2243 }
2244 EXPORT_SYMBOL(snd_wss_get_pcm_ops);
2245