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