1/*
2 *  Copyright (c) by Jaroslav Kysela <perex@suse.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 <sound/driver.h>
28#include <linux/delay.h>
29#include <linux/pm.h>
30#include <linux/init.h>
31#include <linux/interrupt.h>
32#include <linux/slab.h>
33#include <linux/ioport.h>
34#include <sound/core.h>
35#include <sound/cs4231.h>
36#include <sound/pcm_params.h>
37
38#include <asm/io.h>
39#include <asm/dma.h>
40#include <asm/irq.h>
41
42MODULE_AUTHOR("Jaroslav Kysela <perex@suse.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 = 14,
75	.list = rates,
76	.mask = 0,
77};
78
79static int snd_cs4231_xrate(struct snd_pcm_runtime *runtime)
80{
81	return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
82}
83
84static unsigned char snd_cs4231_original_image[32] =
85{
86	0x00,			/* 00/00 - lic */
87	0x00,			/* 01/01 - ric */
88	0x9f,			/* 02/02 - la1ic */
89	0x9f,			/* 03/03 - ra1ic */
90	0x9f,			/* 04/04 - la2ic */
91	0x9f,			/* 05/05 - ra2ic */
92	0xbf,			/* 06/06 - loc */
93	0xbf,			/* 07/07 - roc */
94	0x20,			/* 08/08 - pdfr */
95	CS4231_AUTOCALIB,	/* 09/09 - ic */
96	0x00,			/* 0a/10 - pc */
97	0x00,			/* 0b/11 - ti */
98	CS4231_MODE2,		/* 0c/12 - mi */
99	0xfc,			/* 0d/13 - lbc */
100	0x00,			/* 0e/14 - pbru */
101	0x00,			/* 0f/15 - pbrl */
102	0x80,			/* 10/16 - afei */
103	0x01,			/* 11/17 - afeii */
104	0x9f,			/* 12/18 - llic */
105	0x9f,			/* 13/19 - rlic */
106	0x00,			/* 14/20 - tlb */
107	0x00,			/* 15/21 - thb */
108	0x00,			/* 16/22 - la3mic/reserved */
109	0x00,			/* 17/23 - ra3mic/reserved */
110	0x00,			/* 18/24 - afs */
111	0x00,			/* 19/25 - lamoc/version */
112	0xcf,			/* 1a/26 - mioc */
113	0x00,			/* 1b/27 - ramoc/reserved */
114	0x20,			/* 1c/28 - cdfr */
115	0x00,			/* 1d/29 - res4 */
116	0x00,			/* 1e/30 - cbru */
117	0x00,			/* 1f/31 - cbrl */
118};
119
120/*
121 *  Basic I/O functions
122 */
123
124static inline void cs4231_outb(struct snd_cs4231 *chip, u8 offset, u8 val)
125{
126	outb(val, chip->port + offset);
127}
128
129static inline u8 cs4231_inb(struct snd_cs4231 *chip, u8 offset)
130{
131	return inb(chip->port + offset);
132}
133
134static void snd_cs4231_outm(struct snd_cs4231 *chip, unsigned char reg,
135			    unsigned char mask, unsigned char value)
136{
137	int timeout;
138	unsigned char tmp;
139
140	for (timeout = 250;
141	     timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
142	     timeout--)
143	     	udelay(100);
144#ifdef CONFIG_SND_DEBUG
145	if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
146		snd_printk("outm: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
147#endif
148	if (chip->calibrate_mute) {
149		chip->image[reg] &= mask;
150		chip->image[reg] |= value;
151	} else {
152		cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
153		mb();
154		tmp = (chip->image[reg] & mask) | value;
155		cs4231_outb(chip, CS4231P(REG), tmp);
156		chip->image[reg] = tmp;
157		mb();
158	}
159}
160
161static void snd_cs4231_dout(struct snd_cs4231 *chip, unsigned char reg, unsigned char value)
162{
163	int timeout;
164
165	for (timeout = 250;
166	     timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
167	     timeout--)
168	     	udelay(10);
169	cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
170	cs4231_outb(chip, CS4231P(REG), value);
171	mb();
172}
173
174void snd_cs4231_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char value)
175{
176	int timeout;
177
178	for (timeout = 250;
179	     timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
180	     timeout--)
181	     	udelay(100);
182#ifdef CONFIG_SND_DEBUG
183	if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
184		snd_printk("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
185#endif
186	cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
187	cs4231_outb(chip, CS4231P(REG), value);
188	chip->image[reg] = value;
189	mb();
190}
191
192unsigned char snd_cs4231_in(struct snd_cs4231 *chip, unsigned char reg)
193{
194	int timeout;
195
196	for (timeout = 250;
197	     timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
198	     timeout--)
199	     	udelay(100);
200#ifdef CONFIG_SND_DEBUG
201	if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
202		snd_printk("in: auto calibration time out - reg = 0x%x\n", reg);
203#endif
204	cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
205	mb();
206	return cs4231_inb(chip, CS4231P(REG));
207}
208
209void snd_cs4236_ext_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char val)
210{
211	cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17);
212	cs4231_outb(chip, CS4231P(REG), reg | (chip->image[CS4236_EXT_REG] & 0x01));
213	cs4231_outb(chip, CS4231P(REG), val);
214	chip->eimage[CS4236_REG(reg)] = val;
215}
216
217unsigned char snd_cs4236_ext_in(struct snd_cs4231 *chip, unsigned char reg)
218{
219	cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17);
220	cs4231_outb(chip, CS4231P(REG), reg | (chip->image[CS4236_EXT_REG] & 0x01));
221	return cs4231_inb(chip, CS4231P(REG));
222}
223
224
225/*
226 *  CS4231 detection / MCE routines
227 */
228
229static void snd_cs4231_busy_wait(struct snd_cs4231 *chip)
230{
231	int timeout;
232
233	/* huh.. looks like this sequence is proper for CS4231A chip (GUS MAX) */
234	for (timeout = 5; timeout > 0; timeout--)
235		cs4231_inb(chip, CS4231P(REGSEL));
236	/* end of cleanup sequence */
237	for (timeout = 250;
238	     timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
239	     timeout--)
240	     	udelay(10);
241}
242
243void snd_cs4231_mce_up(struct snd_cs4231 *chip)
244{
245	unsigned long flags;
246	int timeout;
247
248	for (timeout = 250; timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT); timeout--)
249		udelay(100);
250#ifdef CONFIG_SND_DEBUG
251	if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
252		snd_printk("mce_up - auto calibration time out (0)\n");
253#endif
254	spin_lock_irqsave(&chip->reg_lock, flags);
255	chip->mce_bit |= CS4231_MCE;
256	timeout = cs4231_inb(chip, CS4231P(REGSEL));
257	if (timeout == 0x80)
258		snd_printk("mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port);
259	if (!(timeout & CS4231_MCE))
260		cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
261	spin_unlock_irqrestore(&chip->reg_lock, flags);
262}
263
264void snd_cs4231_mce_down(struct snd_cs4231 *chip)
265{
266	unsigned long flags;
267	int timeout;
268
269	snd_cs4231_busy_wait(chip);
270#ifdef CONFIG_SND_DEBUG
271	if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
272		snd_printk("mce_down [0x%lx] - auto calibration time out (0)\n", (long)CS4231P(REGSEL));
273#endif
274	spin_lock_irqsave(&chip->reg_lock, flags);
275	chip->mce_bit &= ~CS4231_MCE;
276	timeout = cs4231_inb(chip, CS4231P(REGSEL));
277	cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
278	spin_unlock_irqrestore(&chip->reg_lock, flags);
279	if (timeout == 0x80)
280		snd_printk("mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port);
281	if ((timeout & CS4231_MCE) == 0 ||
282	    !(chip->hardware & (CS4231_HW_CS4231_MASK | CS4231_HW_CS4232_MASK))) {
283		return;
284	}
285	snd_cs4231_busy_wait(chip);
286
287	/* calibration process */
288
289	for (timeout = 500; timeout > 0 && (snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) == 0; timeout--)
290		udelay(10);
291	if ((snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) == 0) {
292		snd_printd("cs4231_mce_down - auto calibration time out (1)\n");
293		return;
294	}
295	/* in 10 ms increments, check condition, up to 250 ms */
296	timeout = 25;
297	while (snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) {
298		if (--timeout < 0) {
299			snd_printk("mce_down - auto calibration time out (2)\n");
300			return;
301		}
302		msleep(10);
303	}
304	/* in 10 ms increments, check condition, up to 100 ms */
305	timeout = 10;
306	while (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) {
307		if (--timeout < 0) {
308			snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n");
309			return;
310		}
311		msleep(10);
312	}
313}
314
315static unsigned int snd_cs4231_get_count(unsigned char format, unsigned int size)
316{
317	switch (format & 0xe0) {
318	case CS4231_LINEAR_16:
319	case CS4231_LINEAR_16_BIG:
320		size >>= 1;
321		break;
322	case CS4231_ADPCM_16:
323		return size >> 2;
324	}
325	if (format & CS4231_STEREO)
326		size >>= 1;
327	return size;
328}
329
330static int snd_cs4231_trigger(struct snd_pcm_substream *substream,
331			      int cmd)
332{
333	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
334	int result = 0;
335	unsigned int what;
336	struct snd_pcm_substream *s;
337	int do_start;
338
339
340	switch (cmd) {
341	case SNDRV_PCM_TRIGGER_START:
342	case SNDRV_PCM_TRIGGER_RESUME:
343		do_start = 1; break;
344	case SNDRV_PCM_TRIGGER_STOP:
345	case SNDRV_PCM_TRIGGER_SUSPEND:
346		do_start = 0; break;
347	default:
348		return -EINVAL;
349	}
350
351	what = 0;
352	snd_pcm_group_for_each_entry(s, substream) {
353		if (s == chip->playback_substream) {
354			what |= CS4231_PLAYBACK_ENABLE;
355			snd_pcm_trigger_done(s, substream);
356		} else if (s == chip->capture_substream) {
357			what |= CS4231_RECORD_ENABLE;
358			snd_pcm_trigger_done(s, substream);
359		}
360	}
361	spin_lock(&chip->reg_lock);
362	if (do_start) {
363		chip->image[CS4231_IFACE_CTRL] |= what;
364		if (chip->trigger)
365			chip->trigger(chip, what, 1);
366	} else {
367		chip->image[CS4231_IFACE_CTRL] &= ~what;
368		if (chip->trigger)
369			chip->trigger(chip, what, 0);
370	}
371	snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
372	spin_unlock(&chip->reg_lock);
373	return result;
374}
375
376/*
377 *  CODEC I/O
378 */
379
380static unsigned char snd_cs4231_get_rate(unsigned int rate)
381{
382	int i;
383
384	for (i = 0; i < 14; i++)
385		if (rate == rates[i])
386			return freq_bits[i];
387	// snd_BUG();
388	return freq_bits[13];
389}
390
391static unsigned char snd_cs4231_get_format(struct snd_cs4231 *chip,
392				           int format,
393                                           int channels)
394{
395	unsigned char rformat;
396
397	rformat = CS4231_LINEAR_8;
398	switch (format) {
399	case SNDRV_PCM_FORMAT_MU_LAW:	rformat = CS4231_ULAW_8; break;
400	case SNDRV_PCM_FORMAT_A_LAW:	rformat = CS4231_ALAW_8; break;
401	case SNDRV_PCM_FORMAT_S16_LE:	rformat = CS4231_LINEAR_16; break;
402	case SNDRV_PCM_FORMAT_S16_BE:	rformat = CS4231_LINEAR_16_BIG; break;
403	case SNDRV_PCM_FORMAT_IMA_ADPCM:	rformat = CS4231_ADPCM_16; break;
404	}
405	if (channels > 1)
406		rformat |= CS4231_STEREO;
407	return rformat;
408}
409
410static void snd_cs4231_calibrate_mute(struct snd_cs4231 *chip, int mute)
411{
412	unsigned long flags;
413
414	mute = mute ? 1 : 0;
415	spin_lock_irqsave(&chip->reg_lock, flags);
416	if (chip->calibrate_mute == mute) {
417		spin_unlock_irqrestore(&chip->reg_lock, flags);
418		return;
419	}
420	if (!mute) {
421		snd_cs4231_dout(chip, CS4231_LEFT_INPUT, chip->image[CS4231_LEFT_INPUT]);
422		snd_cs4231_dout(chip, CS4231_RIGHT_INPUT, chip->image[CS4231_RIGHT_INPUT]);
423		snd_cs4231_dout(chip, CS4231_LOOPBACK, chip->image[CS4231_LOOPBACK]);
424	}
425	snd_cs4231_dout(chip, CS4231_AUX1_LEFT_INPUT, mute ? 0x80 : chip->image[CS4231_AUX1_LEFT_INPUT]);
426	snd_cs4231_dout(chip, CS4231_AUX1_RIGHT_INPUT, mute ? 0x80 : chip->image[CS4231_AUX1_RIGHT_INPUT]);
427	snd_cs4231_dout(chip, CS4231_AUX2_LEFT_INPUT, mute ? 0x80 : chip->image[CS4231_AUX2_LEFT_INPUT]);
428	snd_cs4231_dout(chip, CS4231_AUX2_RIGHT_INPUT, mute ? 0x80 : chip->image[CS4231_AUX2_RIGHT_INPUT]);
429	snd_cs4231_dout(chip, CS4231_LEFT_OUTPUT, mute ? 0x80 : chip->image[CS4231_LEFT_OUTPUT]);
430	snd_cs4231_dout(chip, CS4231_RIGHT_OUTPUT, mute ? 0x80 : chip->image[CS4231_RIGHT_OUTPUT]);
431	snd_cs4231_dout(chip, CS4231_LEFT_LINE_IN, mute ? 0x80 : chip->image[CS4231_LEFT_LINE_IN]);
432	snd_cs4231_dout(chip, CS4231_RIGHT_LINE_IN, mute ? 0x80 : chip->image[CS4231_RIGHT_LINE_IN]);
433	snd_cs4231_dout(chip, CS4231_MONO_CTRL, mute ? 0xc0 : chip->image[CS4231_MONO_CTRL]);
434	if (chip->hardware == CS4231_HW_INTERWAVE) {
435		snd_cs4231_dout(chip, CS4231_LEFT_MIC_INPUT, mute ? 0x80 : chip->image[CS4231_LEFT_MIC_INPUT]);
436		snd_cs4231_dout(chip, CS4231_RIGHT_MIC_INPUT, mute ? 0x80 : chip->image[CS4231_RIGHT_MIC_INPUT]);
437		snd_cs4231_dout(chip, CS4231_LINE_LEFT_OUTPUT, mute ? 0x80 : chip->image[CS4231_LINE_LEFT_OUTPUT]);
438		snd_cs4231_dout(chip, CS4231_LINE_RIGHT_OUTPUT, mute ? 0x80 : chip->image[CS4231_LINE_RIGHT_OUTPUT]);
439	}
440	chip->calibrate_mute = mute;
441	spin_unlock_irqrestore(&chip->reg_lock, flags);
442}
443
444static void snd_cs4231_playback_format(struct snd_cs4231 *chip,
445				       struct snd_pcm_hw_params *params,
446				       unsigned char pdfr)
447{
448	unsigned long flags;
449	int full_calib = 1;
450
451	mutex_lock(&chip->mce_mutex);
452	snd_cs4231_calibrate_mute(chip, 1);
453	if (chip->hardware == CS4231_HW_CS4231A ||
454	    (chip->hardware & CS4231_HW_CS4232_MASK)) {
455		spin_lock_irqsave(&chip->reg_lock, flags);
456		if ((chip->image[CS4231_PLAYBK_FORMAT] & 0x0f) == (pdfr & 0x0f)) {	/* rate is same? */
457			snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] | 0x10);
458			snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, chip->image[CS4231_PLAYBK_FORMAT] = pdfr);
459			snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] &= ~0x10);
460			udelay(100); /* Fixes audible clicks at least on GUS MAX */
461			full_calib = 0;
462		}
463		spin_unlock_irqrestore(&chip->reg_lock, flags);
464	}
465	if (full_calib) {
466		snd_cs4231_mce_up(chip);
467		spin_lock_irqsave(&chip->reg_lock, flags);
468		if (chip->hardware != CS4231_HW_INTERWAVE && !chip->single_dma) {
469			snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT,
470					(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) ?
471					(pdfr & 0xf0) | (chip->image[CS4231_REC_FORMAT] & 0x0f) :
472				        pdfr);
473		} else {
474			snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, chip->image[CS4231_PLAYBK_FORMAT] = pdfr);
475		}
476		spin_unlock_irqrestore(&chip->reg_lock, flags);
477		snd_cs4231_mce_down(chip);
478	}
479	snd_cs4231_calibrate_mute(chip, 0);
480	mutex_unlock(&chip->mce_mutex);
481}
482
483static void snd_cs4231_capture_format(struct snd_cs4231 *chip,
484				      struct snd_pcm_hw_params *params,
485                                      unsigned char cdfr)
486{
487	unsigned long flags;
488	int full_calib = 1;
489
490	mutex_lock(&chip->mce_mutex);
491	snd_cs4231_calibrate_mute(chip, 1);
492	if (chip->hardware == CS4231_HW_CS4231A ||
493	    (chip->hardware & CS4231_HW_CS4232_MASK)) {
494		spin_lock_irqsave(&chip->reg_lock, flags);
495		if ((chip->image[CS4231_PLAYBK_FORMAT] & 0x0f) == (cdfr & 0x0f) ||	/* rate is same? */
496		    (chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) {
497			snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] | 0x20);
498			snd_cs4231_out(chip, CS4231_REC_FORMAT, chip->image[CS4231_REC_FORMAT] = cdfr);
499			snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] &= ~0x20);
500			full_calib = 0;
501		}
502		spin_unlock_irqrestore(&chip->reg_lock, flags);
503	}
504	if (full_calib) {
505		snd_cs4231_mce_up(chip);
506		spin_lock_irqsave(&chip->reg_lock, flags);
507		if (chip->hardware != CS4231_HW_INTERWAVE) {
508			if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) {
509				snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT,
510					       ((chip->single_dma ? cdfr : chip->image[CS4231_PLAYBK_FORMAT]) & 0xf0) |
511					       (cdfr & 0x0f));
512				spin_unlock_irqrestore(&chip->reg_lock, flags);
513				snd_cs4231_mce_down(chip);
514				snd_cs4231_mce_up(chip);
515				spin_lock_irqsave(&chip->reg_lock, flags);
516			}
517		}
518		snd_cs4231_out(chip, CS4231_REC_FORMAT, cdfr);
519		spin_unlock_irqrestore(&chip->reg_lock, flags);
520		snd_cs4231_mce_down(chip);
521	}
522	snd_cs4231_calibrate_mute(chip, 0);
523	mutex_unlock(&chip->mce_mutex);
524}
525
526/*
527 *  Timer interface
528 */
529
530static unsigned long snd_cs4231_timer_resolution(struct snd_timer * timer)
531{
532	struct snd_cs4231 *chip = snd_timer_chip(timer);
533	if (chip->hardware & CS4231_HW_CS4236B_MASK)
534		return 14467;
535	else
536		return chip->image[CS4231_PLAYBK_FORMAT] & 1 ? 9969 : 9920;
537}
538
539static int snd_cs4231_timer_start(struct snd_timer * timer)
540{
541	unsigned long flags;
542	unsigned int ticks;
543	struct snd_cs4231 *chip = snd_timer_chip(timer);
544	spin_lock_irqsave(&chip->reg_lock, flags);
545	ticks = timer->sticks;
546	if ((chip->image[CS4231_ALT_FEATURE_1] & CS4231_TIMER_ENABLE) == 0 ||
547	    (unsigned char)(ticks >> 8) != chip->image[CS4231_TIMER_HIGH] ||
548	    (unsigned char)ticks != chip->image[CS4231_TIMER_LOW]) {
549		snd_cs4231_out(chip, CS4231_TIMER_HIGH, chip->image[CS4231_TIMER_HIGH] = (unsigned char) (ticks >> 8));
550		snd_cs4231_out(chip, CS4231_TIMER_LOW, chip->image[CS4231_TIMER_LOW] = (unsigned char) ticks);
551		snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] | CS4231_TIMER_ENABLE);
552	}
553	spin_unlock_irqrestore(&chip->reg_lock, flags);
554	return 0;
555}
556
557static int snd_cs4231_timer_stop(struct snd_timer * timer)
558{
559	unsigned long flags;
560	struct snd_cs4231 *chip = snd_timer_chip(timer);
561	spin_lock_irqsave(&chip->reg_lock, flags);
562	snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] &= ~CS4231_TIMER_ENABLE);
563	spin_unlock_irqrestore(&chip->reg_lock, flags);
564	return 0;
565}
566
567static void snd_cs4231_init(struct snd_cs4231 *chip)
568{
569	unsigned long flags;
570
571	snd_cs4231_mce_down(chip);
572
573#ifdef SNDRV_DEBUG_MCE
574	snd_printk("init: (1)\n");
575#endif
576	snd_cs4231_mce_up(chip);
577	spin_lock_irqsave(&chip->reg_lock, flags);
578	chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO |
579			     CS4231_RECORD_ENABLE | CS4231_RECORD_PIO |
580			     CS4231_CALIB_MODE);
581	chip->image[CS4231_IFACE_CTRL] |= CS4231_AUTOCALIB;
582	snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
583	spin_unlock_irqrestore(&chip->reg_lock, flags);
584	snd_cs4231_mce_down(chip);
585
586#ifdef SNDRV_DEBUG_MCE
587	snd_printk("init: (2)\n");
588#endif
589
590	snd_cs4231_mce_up(chip);
591	spin_lock_irqsave(&chip->reg_lock, flags);
592	snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1]);
593	spin_unlock_irqrestore(&chip->reg_lock, flags);
594	snd_cs4231_mce_down(chip);
595
596#ifdef SNDRV_DEBUG_MCE
597	snd_printk("init: (3) - afei = 0x%x\n", chip->image[CS4231_ALT_FEATURE_1]);
598#endif
599
600	spin_lock_irqsave(&chip->reg_lock, flags);
601	snd_cs4231_out(chip, CS4231_ALT_FEATURE_2, chip->image[CS4231_ALT_FEATURE_2]);
602	spin_unlock_irqrestore(&chip->reg_lock, flags);
603
604	snd_cs4231_mce_up(chip);
605	spin_lock_irqsave(&chip->reg_lock, flags);
606	snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, chip->image[CS4231_PLAYBK_FORMAT]);
607	spin_unlock_irqrestore(&chip->reg_lock, flags);
608	snd_cs4231_mce_down(chip);
609
610#ifdef SNDRV_DEBUG_MCE
611	snd_printk("init: (4)\n");
612#endif
613
614	snd_cs4231_mce_up(chip);
615	spin_lock_irqsave(&chip->reg_lock, flags);
616	snd_cs4231_out(chip, CS4231_REC_FORMAT, chip->image[CS4231_REC_FORMAT]);
617	spin_unlock_irqrestore(&chip->reg_lock, flags);
618	snd_cs4231_mce_down(chip);
619
620#ifdef SNDRV_DEBUG_MCE
621	snd_printk("init: (5)\n");
622#endif
623}
624
625static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode)
626{
627	unsigned long flags;
628
629	mutex_lock(&chip->open_mutex);
630	if ((chip->mode & mode) ||
631	    ((chip->mode & CS4231_MODE_OPEN) && chip->single_dma)) {
632		mutex_unlock(&chip->open_mutex);
633		return -EAGAIN;
634	}
635	if (chip->mode & CS4231_MODE_OPEN) {
636		chip->mode |= mode;
637		mutex_unlock(&chip->open_mutex);
638		return 0;
639	}
640	/* ok. now enable and ack CODEC IRQ */
641	spin_lock_irqsave(&chip->reg_lock, flags);
642	snd_cs4231_out(chip, CS4231_IRQ_STATUS, CS4231_PLAYBACK_IRQ |
643		       CS4231_RECORD_IRQ |
644		       CS4231_TIMER_IRQ);
645	snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0);
646	cs4231_outb(chip, CS4231P(STATUS), 0);	/* clear IRQ */
647	cs4231_outb(chip, CS4231P(STATUS), 0);	/* clear IRQ */
648	chip->image[CS4231_PIN_CTRL] |= CS4231_IRQ_ENABLE;
649	snd_cs4231_out(chip, CS4231_PIN_CTRL, chip->image[CS4231_PIN_CTRL]);
650	snd_cs4231_out(chip, CS4231_IRQ_STATUS, CS4231_PLAYBACK_IRQ |
651		       CS4231_RECORD_IRQ |
652		       CS4231_TIMER_IRQ);
653	snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0);
654	spin_unlock_irqrestore(&chip->reg_lock, flags);
655
656	chip->mode = mode;
657	mutex_unlock(&chip->open_mutex);
658	return 0;
659}
660
661static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode)
662{
663	unsigned long flags;
664
665	mutex_lock(&chip->open_mutex);
666	chip->mode &= ~mode;
667	if (chip->mode & CS4231_MODE_OPEN) {
668		mutex_unlock(&chip->open_mutex);
669		return;
670	}
671	snd_cs4231_calibrate_mute(chip, 1);
672
673	/* disable IRQ */
674	spin_lock_irqsave(&chip->reg_lock, flags);
675	snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0);
676	cs4231_outb(chip, CS4231P(STATUS), 0);	/* clear IRQ */
677	cs4231_outb(chip, CS4231P(STATUS), 0);	/* clear IRQ */
678	chip->image[CS4231_PIN_CTRL] &= ~CS4231_IRQ_ENABLE;
679	snd_cs4231_out(chip, CS4231_PIN_CTRL, chip->image[CS4231_PIN_CTRL]);
680
681	/* now disable record & playback */
682
683	if (chip->image[CS4231_IFACE_CTRL] & (CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO |
684					       CS4231_RECORD_ENABLE | CS4231_RECORD_PIO)) {
685		spin_unlock_irqrestore(&chip->reg_lock, flags);
686		snd_cs4231_mce_up(chip);
687		spin_lock_irqsave(&chip->reg_lock, flags);
688		chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO |
689						     CS4231_RECORD_ENABLE | CS4231_RECORD_PIO);
690		snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
691		spin_unlock_irqrestore(&chip->reg_lock, flags);
692		snd_cs4231_mce_down(chip);
693		spin_lock_irqsave(&chip->reg_lock, flags);
694	}
695
696	/* clear IRQ again */
697	snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0);
698	cs4231_outb(chip, CS4231P(STATUS), 0);	/* clear IRQ */
699	cs4231_outb(chip, CS4231P(STATUS), 0);	/* clear IRQ */
700	spin_unlock_irqrestore(&chip->reg_lock, flags);
701
702	snd_cs4231_calibrate_mute(chip, 0);
703
704	chip->mode = 0;
705	mutex_unlock(&chip->open_mutex);
706}
707
708/*
709 *  timer open/close
710 */
711
712static int snd_cs4231_timer_open(struct snd_timer * timer)
713{
714	struct snd_cs4231 *chip = snd_timer_chip(timer);
715	snd_cs4231_open(chip, CS4231_MODE_TIMER);
716	return 0;
717}
718
719static int snd_cs4231_timer_close(struct snd_timer * timer)
720{
721	struct snd_cs4231 *chip = snd_timer_chip(timer);
722	snd_cs4231_close(chip, CS4231_MODE_TIMER);
723	return 0;
724}
725
726static struct snd_timer_hardware snd_cs4231_timer_table =
727{
728	.flags =	SNDRV_TIMER_HW_AUTO,
729	.resolution =	9945,
730	.ticks =	65535,
731	.open =		snd_cs4231_timer_open,
732	.close =	snd_cs4231_timer_close,
733	.c_resolution = snd_cs4231_timer_resolution,
734	.start =	snd_cs4231_timer_start,
735	.stop =		snd_cs4231_timer_stop,
736};
737
738/*
739 *  ok.. exported functions..
740 */
741
742static int snd_cs4231_playback_hw_params(struct snd_pcm_substream *substream,
743					 struct snd_pcm_hw_params *hw_params)
744{
745	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
746	unsigned char new_pdfr;
747	int err;
748
749	if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
750		return err;
751	new_pdfr = snd_cs4231_get_format(chip, params_format(hw_params), params_channels(hw_params)) |
752		   snd_cs4231_get_rate(params_rate(hw_params));
753	chip->set_playback_format(chip, hw_params, new_pdfr);
754	return 0;
755}
756
757static int snd_cs4231_playback_hw_free(struct snd_pcm_substream *substream)
758{
759	return snd_pcm_lib_free_pages(substream);
760}
761
762static int snd_cs4231_playback_prepare(struct snd_pcm_substream *substream)
763{
764	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
765	struct snd_pcm_runtime *runtime = substream->runtime;
766	unsigned long flags;
767	unsigned int size = snd_pcm_lib_buffer_bytes(substream);
768	unsigned int count = snd_pcm_lib_period_bytes(substream);
769
770	spin_lock_irqsave(&chip->reg_lock, flags);
771	chip->p_dma_size = size;
772	chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO);
773	snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
774	count = snd_cs4231_get_count(chip->image[CS4231_PLAYBK_FORMAT], count) - 1;
775	snd_cs4231_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count);
776	snd_cs4231_out(chip, CS4231_PLY_UPR_CNT, (unsigned char) (count >> 8));
777	spin_unlock_irqrestore(&chip->reg_lock, flags);
778	return 0;
779}
780
781static int snd_cs4231_capture_hw_params(struct snd_pcm_substream *substream,
782					struct snd_pcm_hw_params *hw_params)
783{
784	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
785	unsigned char new_cdfr;
786	int err;
787
788	if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
789		return err;
790	new_cdfr = snd_cs4231_get_format(chip, params_format(hw_params), params_channels(hw_params)) |
791		   snd_cs4231_get_rate(params_rate(hw_params));
792	chip->set_capture_format(chip, hw_params, new_cdfr);
793	return 0;
794}
795
796static int snd_cs4231_capture_hw_free(struct snd_pcm_substream *substream)
797{
798	return snd_pcm_lib_free_pages(substream);
799}
800
801static int snd_cs4231_capture_prepare(struct snd_pcm_substream *substream)
802{
803	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
804	struct snd_pcm_runtime *runtime = substream->runtime;
805	unsigned long flags;
806	unsigned int size = snd_pcm_lib_buffer_bytes(substream);
807	unsigned int count = snd_pcm_lib_period_bytes(substream);
808
809	spin_lock_irqsave(&chip->reg_lock, flags);
810	chip->c_dma_size = size;
811	chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE | CS4231_RECORD_PIO);
812	snd_dma_program(chip->dma2, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
813	count = snd_cs4231_get_count(chip->image[CS4231_REC_FORMAT], count) - 1;
814	if (chip->single_dma && chip->hardware != CS4231_HW_INTERWAVE) {
815		snd_cs4231_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count);
816		snd_cs4231_out(chip, CS4231_PLY_UPR_CNT, (unsigned char) (count >> 8));
817	} else {
818		snd_cs4231_out(chip, CS4231_REC_LWR_CNT, (unsigned char) count);
819		snd_cs4231_out(chip, CS4231_REC_UPR_CNT, (unsigned char) (count >> 8));
820	}
821	spin_unlock_irqrestore(&chip->reg_lock, flags);
822	return 0;
823}
824
825static void snd_cs4231_overrange(struct snd_cs4231 *chip)
826{
827	unsigned long flags;
828	unsigned char res;
829
830	spin_lock_irqsave(&chip->reg_lock, flags);
831	res = snd_cs4231_in(chip, CS4231_TEST_INIT);
832	spin_unlock_irqrestore(&chip->reg_lock, flags);
833	if (res & (0x08 | 0x02))	/* detect overrange only above 0dB; may be user selectable? */
834		chip->capture_substream->runtime->overrange++;
835}
836
837irqreturn_t snd_cs4231_interrupt(int irq, void *dev_id)
838{
839	struct snd_cs4231 *chip = dev_id;
840	unsigned char status;
841
842	status = snd_cs4231_in(chip, CS4231_IRQ_STATUS);
843	if (status & CS4231_TIMER_IRQ) {
844		if (chip->timer)
845			snd_timer_interrupt(chip->timer, chip->timer->sticks);
846	}
847	if (chip->single_dma && chip->hardware != CS4231_HW_INTERWAVE) {
848		if (status & CS4231_PLAYBACK_IRQ) {
849			if (chip->mode & CS4231_MODE_PLAY) {
850				if (chip->playback_substream)
851					snd_pcm_period_elapsed(chip->playback_substream);
852			}
853			if (chip->mode & CS4231_MODE_RECORD) {
854				if (chip->capture_substream) {
855					snd_cs4231_overrange(chip);
856					snd_pcm_period_elapsed(chip->capture_substream);
857				}
858			}
859		}
860	} else {
861		if (status & CS4231_PLAYBACK_IRQ) {
862			if (chip->playback_substream)
863				snd_pcm_period_elapsed(chip->playback_substream);
864		}
865		if (status & CS4231_RECORD_IRQ) {
866			if (chip->capture_substream) {
867				snd_cs4231_overrange(chip);
868				snd_pcm_period_elapsed(chip->capture_substream);
869			}
870		}
871	}
872
873	spin_lock(&chip->reg_lock);
874	snd_cs4231_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0);
875	spin_unlock(&chip->reg_lock);
876	return IRQ_HANDLED;
877}
878
879static snd_pcm_uframes_t snd_cs4231_playback_pointer(struct snd_pcm_substream *substream)
880{
881	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
882	size_t ptr;
883
884	if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE))
885		return 0;
886	ptr = snd_dma_pointer(chip->dma1, chip->p_dma_size);
887	return bytes_to_frames(substream->runtime, ptr);
888}
889
890static snd_pcm_uframes_t snd_cs4231_capture_pointer(struct snd_pcm_substream *substream)
891{
892	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
893	size_t ptr;
894
895	if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE))
896		return 0;
897	ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size);
898	return bytes_to_frames(substream->runtime, ptr);
899}
900
901/*
902
903 */
904
905static int snd_cs4231_probe(struct snd_cs4231 *chip)
906{
907	unsigned long flags;
908	int i, id, rev;
909	unsigned char *ptr;
910	unsigned int hw;
911
912	id = 0;
913	for (i = 0; i < 50; i++) {
914		mb();
915		if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
916			udelay(2000);
917		else {
918			spin_lock_irqsave(&chip->reg_lock, flags);
919			snd_cs4231_out(chip, CS4231_MISC_INFO, CS4231_MODE2);
920			id = snd_cs4231_in(chip, CS4231_MISC_INFO) & 0x0f;
921			spin_unlock_irqrestore(&chip->reg_lock, flags);
922			if (id == 0x0a)
923				break;	/* this is valid value */
924		}
925	}
926	snd_printdd("cs4231: port = 0x%lx, id = 0x%x\n", chip->port, id);
927	if (id != 0x0a)
928		return -ENODEV;	/* no valid device found */
929
930	if (((hw = chip->hardware) & CS4231_HW_TYPE_MASK) == CS4231_HW_DETECT) {
931		rev = snd_cs4231_in(chip, CS4231_VERSION) & 0xe7;
932		snd_printdd("CS4231: VERSION (I25) = 0x%x\n", rev);
933		if (rev == 0x80) {
934			unsigned char tmp = snd_cs4231_in(chip, 23);
935			snd_cs4231_out(chip, 23, ~tmp);
936			if (snd_cs4231_in(chip, 23) != tmp)
937				chip->hardware = CS4231_HW_AD1845;
938			else
939				chip->hardware = CS4231_HW_CS4231;
940		} else if (rev == 0xa0) {
941			chip->hardware = CS4231_HW_CS4231A;
942		} else if (rev == 0xa2) {
943			chip->hardware = CS4231_HW_CS4232;
944		} else if (rev == 0xb2) {
945			chip->hardware = CS4231_HW_CS4232A;
946		} else if (rev == 0x83) {
947			chip->hardware = CS4231_HW_CS4236;
948		} else if (rev == 0x03) {
949			chip->hardware = CS4231_HW_CS4236B;
950		} else {
951			snd_printk("unknown CS chip with version 0x%x\n", rev);
952			return -ENODEV;		/* unknown CS4231 chip? */
953		}
954	}
955	spin_lock_irqsave(&chip->reg_lock, flags);
956	cs4231_inb(chip, CS4231P(STATUS));	/* clear any pendings IRQ */
957	cs4231_outb(chip, CS4231P(STATUS), 0);
958	mb();
959	spin_unlock_irqrestore(&chip->reg_lock, flags);
960
961	chip->image[CS4231_MISC_INFO] = CS4231_MODE2;
962	switch (chip->hardware) {
963	case CS4231_HW_INTERWAVE:
964		chip->image[CS4231_MISC_INFO] = CS4231_IW_MODE3;
965		break;
966	case CS4231_HW_CS4235:
967	case CS4231_HW_CS4236B:
968	case CS4231_HW_CS4237B:
969	case CS4231_HW_CS4238B:
970	case CS4231_HW_CS4239:
971		if (hw == CS4231_HW_DETECT3)
972			chip->image[CS4231_MISC_INFO] = CS4231_4236_MODE3;
973		else
974			chip->hardware = CS4231_HW_CS4236;
975		break;
976	}
977
978	chip->image[CS4231_IFACE_CTRL] =
979	    (chip->image[CS4231_IFACE_CTRL] & ~CS4231_SINGLE_DMA) |
980	    (chip->single_dma ? CS4231_SINGLE_DMA : 0);
981	chip->image[CS4231_ALT_FEATURE_1] = 0x80;
982	chip->image[CS4231_ALT_FEATURE_2] = chip->hardware == CS4231_HW_INTERWAVE ? 0xc2 : 0x01;
983	ptr = (unsigned char *) &chip->image;
984	snd_cs4231_mce_down(chip);
985	spin_lock_irqsave(&chip->reg_lock, flags);
986	for (i = 0; i < 32; i++)	/* ok.. fill all CS4231 registers */
987		snd_cs4231_out(chip, i, *ptr++);
988	spin_unlock_irqrestore(&chip->reg_lock, flags);
989	snd_cs4231_mce_up(chip);
990	snd_cs4231_mce_down(chip);
991
992	mdelay(2);
993
994	/* ok.. try check hardware version for CS4236+ chips */
995	if ((hw & CS4231_HW_TYPE_MASK) == CS4231_HW_DETECT) {
996		if (chip->hardware == CS4231_HW_CS4236B) {
997			rev = snd_cs4236_ext_in(chip, CS4236_VERSION);
998			snd_cs4236_ext_out(chip, CS4236_VERSION, 0xff);
999			id = snd_cs4236_ext_in(chip, CS4236_VERSION);
1000			snd_cs4236_ext_out(chip, CS4236_VERSION, rev);
1001			snd_printdd("CS4231: ext version; rev = 0x%x, id = 0x%x\n", rev, id);
1002			if ((id & 0x1f) == 0x1d) {	/* CS4235 */
1003				chip->hardware = CS4231_HW_CS4235;
1004				switch (id >> 5) {
1005				case 4:
1006				case 5:
1007				case 6:
1008					break;
1009				default:
1010					snd_printk("unknown CS4235 chip (enhanced version = 0x%x)\n", id);
1011				}
1012			} else if ((id & 0x1f) == 0x0b) {	/* CS4236/B */
1013				switch (id >> 5) {
1014				case 4:
1015				case 5:
1016				case 6:
1017				case 7:
1018					chip->hardware = CS4231_HW_CS4236B;
1019					break;
1020				default:
1021					snd_printk("unknown CS4236 chip (enhanced version = 0x%x)\n", id);
1022				}
1023			} else if ((id & 0x1f) == 0x08) {	/* CS4237B */
1024				chip->hardware = CS4231_HW_CS4237B;
1025				switch (id >> 5) {
1026				case 4:
1027				case 5:
1028				case 6:
1029				case 7:
1030					break;
1031				default:
1032					snd_printk("unknown CS4237B chip (enhanced version = 0x%x)\n", id);
1033				}
1034			} else if ((id & 0x1f) == 0x09) {	/* CS4238B */
1035				chip->hardware = CS4231_HW_CS4238B;
1036				switch (id >> 5) {
1037				case 5:
1038				case 6:
1039				case 7:
1040					break;
1041				default:
1042					snd_printk("unknown CS4238B chip (enhanced version = 0x%x)\n", id);
1043				}
1044			} else if ((id & 0x1f) == 0x1e) {	/* CS4239 */
1045				chip->hardware = CS4231_HW_CS4239;
1046				switch (id >> 5) {
1047				case 4:
1048				case 5:
1049				case 6:
1050					break;
1051				default:
1052					snd_printk("unknown CS4239 chip (enhanced version = 0x%x)\n", id);
1053				}
1054			} else {
1055				snd_printk("unknown CS4236/CS423xB chip (enhanced version = 0x%x)\n", id);
1056			}
1057		}
1058	}
1059	return 0;		/* all things are ok.. */
1060}
1061
1062/*
1063
1064 */
1065
1066static struct snd_pcm_hardware snd_cs4231_playback =
1067{
1068	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1069				 SNDRV_PCM_INFO_MMAP_VALID |
1070				 SNDRV_PCM_INFO_RESUME |
1071				 SNDRV_PCM_INFO_SYNC_START),
1072	.formats =		(SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
1073				 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
1074	.rates =		SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
1075	.rate_min =		5510,
1076	.rate_max =		48000,
1077	.channels_min =		1,
1078	.channels_max =		2,
1079	.buffer_bytes_max =	(128*1024),
1080	.period_bytes_min =	64,
1081	.period_bytes_max =	(128*1024),
1082	.periods_min =		1,
1083	.periods_max =		1024,
1084	.fifo_size =		0,
1085};
1086
1087static struct snd_pcm_hardware snd_cs4231_capture =
1088{
1089	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1090				 SNDRV_PCM_INFO_MMAP_VALID |
1091				 SNDRV_PCM_INFO_RESUME |
1092				 SNDRV_PCM_INFO_SYNC_START),
1093	.formats =		(SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
1094				 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
1095	.rates =		SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
1096	.rate_min =		5510,
1097	.rate_max =		48000,
1098	.channels_min =		1,
1099	.channels_max =		2,
1100	.buffer_bytes_max =	(128*1024),
1101	.period_bytes_min =	64,
1102	.period_bytes_max =	(128*1024),
1103	.periods_min =		1,
1104	.periods_max =		1024,
1105	.fifo_size =		0,
1106};
1107
1108/*
1109
1110 */
1111
1112static int snd_cs4231_playback_open(struct snd_pcm_substream *substream)
1113{
1114	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
1115	struct snd_pcm_runtime *runtime = substream->runtime;
1116	int err;
1117
1118	runtime->hw = snd_cs4231_playback;
1119
1120	/* hardware bug in InterWave chipset */
1121	if (chip->hardware == CS4231_HW_INTERWAVE && chip->dma1 > 3)
1122	    	runtime->hw.formats &= ~SNDRV_PCM_FMTBIT_MU_LAW;
1123
1124	/* hardware limitation of cheap chips */
1125	if (chip->hardware == CS4231_HW_CS4235 ||
1126	    chip->hardware == CS4231_HW_CS4239)
1127		runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE;
1128
1129	snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max);
1130	snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.period_bytes_max);
1131
1132	if (chip->claim_dma) {
1133		if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma1)) < 0)
1134			return err;
1135	}
1136
1137	if ((err = snd_cs4231_open(chip, CS4231_MODE_PLAY)) < 0) {
1138		if (chip->release_dma)
1139			chip->release_dma(chip, chip->dma_private_data, chip->dma1);
1140		snd_free_pages(runtime->dma_area, runtime->dma_bytes);
1141		return err;
1142	}
1143	chip->playback_substream = substream;
1144	snd_pcm_set_sync(substream);
1145	chip->rate_constraint(runtime);
1146	return 0;
1147}
1148
1149static int snd_cs4231_capture_open(struct snd_pcm_substream *substream)
1150{
1151	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
1152	struct snd_pcm_runtime *runtime = substream->runtime;
1153	int err;
1154
1155	runtime->hw = snd_cs4231_capture;
1156
1157	/* hardware limitation of cheap chips */
1158	if (chip->hardware == CS4231_HW_CS4235 ||
1159	    chip->hardware == CS4231_HW_CS4239)
1160		runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE;
1161
1162	snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max);
1163	snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max);
1164
1165	if (chip->claim_dma) {
1166		if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma2)) < 0)
1167			return err;
1168	}
1169
1170	if ((err = snd_cs4231_open(chip, CS4231_MODE_RECORD)) < 0) {
1171		if (chip->release_dma)
1172			chip->release_dma(chip, chip->dma_private_data, chip->dma2);
1173		snd_free_pages(runtime->dma_area, runtime->dma_bytes);
1174		return err;
1175	}
1176	chip->capture_substream = substream;
1177	snd_pcm_set_sync(substream);
1178	chip->rate_constraint(runtime);
1179	return 0;
1180}
1181
1182static int snd_cs4231_playback_close(struct snd_pcm_substream *substream)
1183{
1184	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
1185
1186	chip->playback_substream = NULL;
1187	snd_cs4231_close(chip, CS4231_MODE_PLAY);
1188	return 0;
1189}
1190
1191static int snd_cs4231_capture_close(struct snd_pcm_substream *substream)
1192{
1193	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
1194
1195	chip->capture_substream = NULL;
1196	snd_cs4231_close(chip, CS4231_MODE_RECORD);
1197	return 0;
1198}
1199
1200#ifdef CONFIG_PM
1201
1202/* lowlevel suspend callback for CS4231 */
1203static void snd_cs4231_suspend(struct snd_cs4231 *chip)
1204{
1205	int reg;
1206	unsigned long flags;
1207
1208	snd_pcm_suspend_all(chip->pcm);
1209	spin_lock_irqsave(&chip->reg_lock, flags);
1210	for (reg = 0; reg < 32; reg++)
1211		chip->image[reg] = snd_cs4231_in(chip, reg);
1212	spin_unlock_irqrestore(&chip->reg_lock, flags);
1213}
1214
1215/* lowlevel resume callback for CS4231 */
1216static void snd_cs4231_resume(struct snd_cs4231 *chip)
1217{
1218	int reg;
1219	unsigned long flags;
1220	/* int timeout; */
1221
1222	snd_cs4231_mce_up(chip);
1223	spin_lock_irqsave(&chip->reg_lock, flags);
1224	for (reg = 0; reg < 32; reg++) {
1225		switch (reg) {
1226		case CS4231_VERSION:
1227			break;
1228		default:
1229			snd_cs4231_out(chip, reg, chip->image[reg]);
1230			break;
1231		}
1232	}
1233	spin_unlock_irqrestore(&chip->reg_lock, flags);
1234	snd_cs4231_mce_down(chip);
1235}
1236#endif /* CONFIG_PM */
1237
1238static int snd_cs4231_free(struct snd_cs4231 *chip)
1239{
1240	release_and_free_resource(chip->res_port);
1241	release_and_free_resource(chip->res_cport);
1242	if (chip->irq >= 0) {
1243		disable_irq(chip->irq);
1244		if (!(chip->hwshare & CS4231_HWSHARE_IRQ))
1245			free_irq(chip->irq, (void *) chip);
1246	}
1247	if (!(chip->hwshare & CS4231_HWSHARE_DMA1) && chip->dma1 >= 0) {
1248		snd_dma_disable(chip->dma1);
1249		free_dma(chip->dma1);
1250	}
1251	if (!(chip->hwshare & CS4231_HWSHARE_DMA2) && chip->dma2 >= 0 && chip->dma2 != chip->dma1) {
1252		snd_dma_disable(chip->dma2);
1253		free_dma(chip->dma2);
1254	}
1255	if (chip->timer)
1256		snd_device_free(chip->card, chip->timer);
1257	kfree(chip);
1258	return 0;
1259}
1260
1261static int snd_cs4231_dev_free(struct snd_device *device)
1262{
1263	struct snd_cs4231 *chip = device->device_data;
1264	return snd_cs4231_free(chip);
1265}
1266
1267const char *snd_cs4231_chip_id(struct snd_cs4231 *chip)
1268{
1269	switch (chip->hardware) {
1270	case CS4231_HW_CS4231:	return "CS4231";
1271	case CS4231_HW_CS4231A: return "CS4231A";
1272	case CS4231_HW_CS4232:	return "CS4232";
1273	case CS4231_HW_CS4232A:	return "CS4232A";
1274	case CS4231_HW_CS4235:	return "CS4235";
1275	case CS4231_HW_CS4236:  return "CS4236";
1276	case CS4231_HW_CS4236B: return "CS4236B";
1277	case CS4231_HW_CS4237B: return "CS4237B";
1278	case CS4231_HW_CS4238B: return "CS4238B";
1279	case CS4231_HW_CS4239:	return "CS4239";
1280	case CS4231_HW_INTERWAVE: return "AMD InterWave";
1281	case CS4231_HW_OPL3SA2: return chip->card->shortname;
1282	case CS4231_HW_AD1845: return "AD1845";
1283	default: return "???";
1284	}
1285}
1286
1287static int snd_cs4231_new(struct snd_card *card,
1288			  unsigned short hardware,
1289			  unsigned short hwshare,
1290			  struct snd_cs4231 ** rchip)
1291{
1292	struct snd_cs4231 *chip;
1293
1294	*rchip = NULL;
1295	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1296	if (chip == NULL)
1297		return -ENOMEM;
1298	chip->hardware = hardware;
1299	chip->hwshare = hwshare;
1300
1301	spin_lock_init(&chip->reg_lock);
1302	mutex_init(&chip->mce_mutex);
1303	mutex_init(&chip->open_mutex);
1304	chip->card = card;
1305	chip->rate_constraint = snd_cs4231_xrate;
1306	chip->set_playback_format = snd_cs4231_playback_format;
1307	chip->set_capture_format = snd_cs4231_capture_format;
1308        memcpy(&chip->image, &snd_cs4231_original_image, sizeof(snd_cs4231_original_image));
1309
1310        *rchip = chip;
1311        return 0;
1312}
1313
1314int snd_cs4231_create(struct snd_card *card,
1315	              unsigned long port,
1316	              unsigned long cport,
1317		      int irq, int dma1, int dma2,
1318		      unsigned short hardware,
1319		      unsigned short hwshare,
1320		      struct snd_cs4231 ** rchip)
1321{
1322	static struct snd_device_ops ops = {
1323		.dev_free =	snd_cs4231_dev_free,
1324	};
1325	struct snd_cs4231 *chip;
1326	int err;
1327
1328	err = snd_cs4231_new(card, hardware, hwshare, &chip);
1329	if (err < 0)
1330		return err;
1331
1332	chip->irq = -1;
1333	chip->dma1 = -1;
1334	chip->dma2 = -1;
1335
1336	if ((chip->res_port = request_region(port, 4, "CS4231")) == NULL) {
1337		snd_printk(KERN_ERR "cs4231: can't grab port 0x%lx\n", port);
1338		snd_cs4231_free(chip);
1339		return -EBUSY;
1340	}
1341	chip->port = port;
1342	if ((long)cport >= 0 && (chip->res_cport = request_region(cport, 8, "CS4232 Control")) == NULL) {
1343		snd_printk(KERN_ERR "cs4231: can't grab control port 0x%lx\n", cport);
1344		snd_cs4231_free(chip);
1345		return -ENODEV;
1346	}
1347	chip->cport = cport;
1348	if (!(hwshare & CS4231_HWSHARE_IRQ) && request_irq(irq, snd_cs4231_interrupt, IRQF_DISABLED, "CS4231", (void *) chip)) {
1349		snd_printk(KERN_ERR "cs4231: can't grab IRQ %d\n", irq);
1350		snd_cs4231_free(chip);
1351		return -EBUSY;
1352	}
1353	chip->irq = irq;
1354	if (!(hwshare & CS4231_HWSHARE_DMA1) && request_dma(dma1, "CS4231 - 1")) {
1355		snd_printk(KERN_ERR "cs4231: can't grab DMA1 %d\n", dma1);
1356		snd_cs4231_free(chip);
1357		return -EBUSY;
1358	}
1359	chip->dma1 = dma1;
1360	if (!(hwshare & CS4231_HWSHARE_DMA2) && dma1 != dma2 && dma2 >= 0 && request_dma(dma2, "CS4231 - 2")) {
1361		snd_printk(KERN_ERR "cs4231: can't grab DMA2 %d\n", dma2);
1362		snd_cs4231_free(chip);
1363		return -EBUSY;
1364	}
1365	if (dma1 == dma2 || dma2 < 0) {
1366		chip->single_dma = 1;
1367		chip->dma2 = chip->dma1;
1368	} else
1369		chip->dma2 = dma2;
1370
1371	/* global setup */
1372	if (snd_cs4231_probe(chip) < 0) {
1373		snd_cs4231_free(chip);
1374		return -ENODEV;
1375	}
1376	snd_cs4231_init(chip);
1377
1378
1379	/* Register device */
1380	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
1381		snd_cs4231_free(chip);
1382		return err;
1383	}
1384
1385#ifdef CONFIG_PM
1386	/* Power Management */
1387	chip->suspend = snd_cs4231_suspend;
1388	chip->resume = snd_cs4231_resume;
1389#endif
1390
1391	*rchip = chip;
1392	return 0;
1393}
1394
1395static struct snd_pcm_ops snd_cs4231_playback_ops = {
1396	.open =		snd_cs4231_playback_open,
1397	.close =	snd_cs4231_playback_close,
1398	.ioctl =	snd_pcm_lib_ioctl,
1399	.hw_params =	snd_cs4231_playback_hw_params,
1400	.hw_free =	snd_cs4231_playback_hw_free,
1401	.prepare =	snd_cs4231_playback_prepare,
1402	.trigger =	snd_cs4231_trigger,
1403	.pointer =	snd_cs4231_playback_pointer,
1404};
1405
1406static struct snd_pcm_ops snd_cs4231_capture_ops = {
1407	.open =		snd_cs4231_capture_open,
1408	.close =	snd_cs4231_capture_close,
1409	.ioctl =	snd_pcm_lib_ioctl,
1410	.hw_params =	snd_cs4231_capture_hw_params,
1411	.hw_free =	snd_cs4231_capture_hw_free,
1412	.prepare =	snd_cs4231_capture_prepare,
1413	.trigger =	snd_cs4231_trigger,
1414	.pointer =	snd_cs4231_capture_pointer,
1415};
1416
1417int snd_cs4231_pcm(struct snd_cs4231 *chip, int device, struct snd_pcm **rpcm)
1418{
1419	struct snd_pcm *pcm;
1420	int err;
1421
1422	if ((err = snd_pcm_new(chip->card, "CS4231", device, 1, 1, &pcm)) < 0)
1423		return err;
1424
1425	spin_lock_init(&chip->reg_lock);
1426	mutex_init(&chip->mce_mutex);
1427	mutex_init(&chip->open_mutex);
1428
1429	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs4231_playback_ops);
1430	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs4231_capture_ops);
1431
1432	/* global setup */
1433	pcm->private_data = chip;
1434	pcm->info_flags = 0;
1435	if (chip->single_dma)
1436		pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX;
1437	if (chip->hardware != CS4231_HW_INTERWAVE)
1438		pcm->info_flags |= SNDRV_PCM_INFO_JOINT_DUPLEX;
1439	strcpy(pcm->name, snd_cs4231_chip_id(chip));
1440
1441	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1442					      snd_dma_isa_data(),
1443					      64*1024, chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024);
1444
1445	chip->pcm = pcm;
1446	if (rpcm)
1447		*rpcm = pcm;
1448	return 0;
1449}
1450
1451static void snd_cs4231_timer_free(struct snd_timer *timer)
1452{
1453	struct snd_cs4231 *chip = timer->private_data;
1454	chip->timer = NULL;
1455}
1456
1457int snd_cs4231_timer(struct snd_cs4231 *chip, int device, struct snd_timer **rtimer)
1458{
1459	struct snd_timer *timer;
1460	struct snd_timer_id tid;
1461	int err;
1462
1463	/* Timer initialization */
1464	tid.dev_class = SNDRV_TIMER_CLASS_CARD;
1465	tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
1466	tid.card = chip->card->number;
1467	tid.device = device;
1468	tid.subdevice = 0;
1469	if ((err = snd_timer_new(chip->card, "CS4231", &tid, &timer)) < 0)
1470		return err;
1471	strcpy(timer->name, snd_cs4231_chip_id(chip));
1472	timer->private_data = chip;
1473	timer->private_free = snd_cs4231_timer_free;
1474	timer->hw = snd_cs4231_timer_table;
1475	chip->timer = timer;
1476	if (rtimer)
1477		*rtimer = timer;
1478	return 0;
1479}
1480
1481/*
1482 *  MIXER part
1483 */
1484
1485static int snd_cs4231_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1486{
1487	static char *texts[4] = {
1488		"Line", "Aux", "Mic", "Mix"
1489	};
1490	static char *opl3sa_texts[4] = {
1491		"Line", "CD", "Mic", "Mix"
1492	};
1493	static char *gusmax_texts[4] = {
1494		"Line", "Synth", "Mic", "Mix"
1495	};
1496	char **ptexts = texts;
1497	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
1498
1499	snd_assert(chip->card != NULL, return -EINVAL);
1500	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1501	uinfo->count = 2;
1502	uinfo->value.enumerated.items = 4;
1503	if (uinfo->value.enumerated.item > 3)
1504		uinfo->value.enumerated.item = 3;
1505	if (!strcmp(chip->card->driver, "GUS MAX"))
1506		ptexts = gusmax_texts;
1507	switch (chip->hardware) {
1508	case CS4231_HW_INTERWAVE: ptexts = gusmax_texts; break;
1509	case CS4231_HW_OPL3SA2: ptexts = opl3sa_texts; break;
1510	}
1511	strcpy(uinfo->value.enumerated.name, ptexts[uinfo->value.enumerated.item]);
1512	return 0;
1513}
1514
1515static int snd_cs4231_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1516{
1517	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
1518	unsigned long flags;
1519
1520	spin_lock_irqsave(&chip->reg_lock, flags);
1521	ucontrol->value.enumerated.item[0] = (chip->image[CS4231_LEFT_INPUT] & CS4231_MIXS_ALL) >> 6;
1522	ucontrol->value.enumerated.item[1] = (chip->image[CS4231_RIGHT_INPUT] & CS4231_MIXS_ALL) >> 6;
1523	spin_unlock_irqrestore(&chip->reg_lock, flags);
1524	return 0;
1525}
1526
1527static int snd_cs4231_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1528{
1529	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
1530	unsigned long flags;
1531	unsigned short left, right;
1532	int change;
1533
1534	if (ucontrol->value.enumerated.item[0] > 3 ||
1535	    ucontrol->value.enumerated.item[1] > 3)
1536		return -EINVAL;
1537	left = ucontrol->value.enumerated.item[0] << 6;
1538	right = ucontrol->value.enumerated.item[1] << 6;
1539	spin_lock_irqsave(&chip->reg_lock, flags);
1540	left = (chip->image[CS4231_LEFT_INPUT] & ~CS4231_MIXS_ALL) | left;
1541	right = (chip->image[CS4231_RIGHT_INPUT] & ~CS4231_MIXS_ALL) | right;
1542	change = left != chip->image[CS4231_LEFT_INPUT] ||
1543	         right != chip->image[CS4231_RIGHT_INPUT];
1544	snd_cs4231_out(chip, CS4231_LEFT_INPUT, left);
1545	snd_cs4231_out(chip, CS4231_RIGHT_INPUT, right);
1546	spin_unlock_irqrestore(&chip->reg_lock, flags);
1547	return change;
1548}
1549
1550int snd_cs4231_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1551{
1552	int mask = (kcontrol->private_value >> 16) & 0xff;
1553
1554	uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1555	uinfo->count = 1;
1556	uinfo->value.integer.min = 0;
1557	uinfo->value.integer.max = mask;
1558	return 0;
1559}
1560
1561int snd_cs4231_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1562{
1563	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
1564	unsigned long flags;
1565	int reg = kcontrol->private_value & 0xff;
1566	int shift = (kcontrol->private_value >> 8) & 0xff;
1567	int mask = (kcontrol->private_value >> 16) & 0xff;
1568	int invert = (kcontrol->private_value >> 24) & 0xff;
1569
1570	spin_lock_irqsave(&chip->reg_lock, flags);
1571	ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask;
1572	spin_unlock_irqrestore(&chip->reg_lock, flags);
1573	if (invert)
1574		ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1575	return 0;
1576}
1577
1578int snd_cs4231_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1579{
1580	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
1581	unsigned long flags;
1582	int reg = kcontrol->private_value & 0xff;
1583	int shift = (kcontrol->private_value >> 8) & 0xff;
1584	int mask = (kcontrol->private_value >> 16) & 0xff;
1585	int invert = (kcontrol->private_value >> 24) & 0xff;
1586	int change;
1587	unsigned short val;
1588
1589	val = (ucontrol->value.integer.value[0] & mask);
1590	if (invert)
1591		val = mask - val;
1592	val <<= shift;
1593	spin_lock_irqsave(&chip->reg_lock, flags);
1594	val = (chip->image[reg] & ~(mask << shift)) | val;
1595	change = val != chip->image[reg];
1596	snd_cs4231_out(chip, reg, val);
1597	spin_unlock_irqrestore(&chip->reg_lock, flags);
1598	return change;
1599}
1600
1601int snd_cs4231_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1602{
1603	int mask = (kcontrol->private_value >> 24) & 0xff;
1604
1605	uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1606	uinfo->count = 2;
1607	uinfo->value.integer.min = 0;
1608	uinfo->value.integer.max = mask;
1609	return 0;
1610}
1611
1612int snd_cs4231_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1613{
1614	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
1615	unsigned long flags;
1616	int left_reg = kcontrol->private_value & 0xff;
1617	int right_reg = (kcontrol->private_value >> 8) & 0xff;
1618	int shift_left = (kcontrol->private_value >> 16) & 0x07;
1619	int shift_right = (kcontrol->private_value >> 19) & 0x07;
1620	int mask = (kcontrol->private_value >> 24) & 0xff;
1621	int invert = (kcontrol->private_value >> 22) & 1;
1622
1623	spin_lock_irqsave(&chip->reg_lock, flags);
1624	ucontrol->value.integer.value[0] = (chip->image[left_reg] >> shift_left) & mask;
1625	ucontrol->value.integer.value[1] = (chip->image[right_reg] >> shift_right) & mask;
1626	spin_unlock_irqrestore(&chip->reg_lock, flags);
1627	if (invert) {
1628		ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1629		ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
1630	}
1631	return 0;
1632}
1633
1634int snd_cs4231_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1635{
1636	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
1637	unsigned long flags;
1638	int left_reg = kcontrol->private_value & 0xff;
1639	int right_reg = (kcontrol->private_value >> 8) & 0xff;
1640	int shift_left = (kcontrol->private_value >> 16) & 0x07;
1641	int shift_right = (kcontrol->private_value >> 19) & 0x07;
1642	int mask = (kcontrol->private_value >> 24) & 0xff;
1643	int invert = (kcontrol->private_value >> 22) & 1;
1644	int change;
1645	unsigned short val1, val2;
1646
1647	val1 = ucontrol->value.integer.value[0] & mask;
1648	val2 = ucontrol->value.integer.value[1] & mask;
1649	if (invert) {
1650		val1 = mask - val1;
1651		val2 = mask - val2;
1652	}
1653	val1 <<= shift_left;
1654	val2 <<= shift_right;
1655	spin_lock_irqsave(&chip->reg_lock, flags);
1656	val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1;
1657	val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2;
1658	change = val1 != chip->image[left_reg] || val2 != chip->image[right_reg];
1659	snd_cs4231_out(chip, left_reg, val1);
1660	snd_cs4231_out(chip, right_reg, val2);
1661	spin_unlock_irqrestore(&chip->reg_lock, flags);
1662	return change;
1663}
1664
1665static struct snd_kcontrol_new snd_cs4231_controls[] = {
1666CS4231_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
1667CS4231_DOUBLE("PCM Playback Volume", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1),
1668CS4231_DOUBLE("Line Playback Switch", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
1669CS4231_DOUBLE("Line Playback Volume", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1),
1670CS4231_DOUBLE("Aux Playback Switch", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
1671CS4231_DOUBLE("Aux Playback Volume", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1),
1672CS4231_DOUBLE("Aux Playback Switch", 1, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
1673CS4231_DOUBLE("Aux Playback Volume", 1, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1),
1674CS4231_SINGLE("Mono Playback Switch", 0, CS4231_MONO_CTRL, 7, 1, 1),
1675CS4231_SINGLE("Mono Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1),
1676CS4231_SINGLE("Mono Output Playback Switch", 0, CS4231_MONO_CTRL, 6, 1, 1),
1677CS4231_SINGLE("Mono Output Playback Bypass", 0, CS4231_MONO_CTRL, 5, 1, 0),
1678CS4231_DOUBLE("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0),
1679{
1680	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1681	.name = "Capture Source",
1682	.info = snd_cs4231_info_mux,
1683	.get = snd_cs4231_get_mux,
1684	.put = snd_cs4231_put_mux,
1685},
1686CS4231_DOUBLE("Mic Boost", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
1687CS4231_SINGLE("Loopback Capture Switch", 0, CS4231_LOOPBACK, 0, 1, 0),
1688CS4231_SINGLE("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1)
1689};
1690
1691int snd_cs4231_mixer(struct snd_cs4231 *chip)
1692{
1693	struct snd_card *card;
1694	unsigned int idx;
1695	int err;
1696
1697	snd_assert(chip != NULL && chip->pcm != NULL, return -EINVAL);
1698
1699	card = chip->card;
1700
1701	strcpy(card->mixername, chip->pcm->name);
1702
1703	for (idx = 0; idx < ARRAY_SIZE(snd_cs4231_controls); idx++) {
1704		if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4231_controls[idx], chip))) < 0)
1705			return err;
1706	}
1707	return 0;
1708}
1709
1710EXPORT_SYMBOL(snd_cs4231_out);
1711EXPORT_SYMBOL(snd_cs4231_in);
1712EXPORT_SYMBOL(snd_cs4236_ext_out);
1713EXPORT_SYMBOL(snd_cs4236_ext_in);
1714EXPORT_SYMBOL(snd_cs4231_mce_up);
1715EXPORT_SYMBOL(snd_cs4231_mce_down);
1716EXPORT_SYMBOL(snd_cs4231_interrupt);
1717EXPORT_SYMBOL(snd_cs4231_chip_id);
1718EXPORT_SYMBOL(snd_cs4231_create);
1719EXPORT_SYMBOL(snd_cs4231_pcm);
1720EXPORT_SYMBOL(snd_cs4231_mixer);
1721EXPORT_SYMBOL(snd_cs4231_timer);
1722EXPORT_SYMBOL(snd_cs4231_info_single);
1723EXPORT_SYMBOL(snd_cs4231_get_single);
1724EXPORT_SYMBOL(snd_cs4231_put_single);
1725EXPORT_SYMBOL(snd_cs4231_info_double);
1726EXPORT_SYMBOL(snd_cs4231_get_double);
1727EXPORT_SYMBOL(snd_cs4231_put_double);
1728
1729/*
1730 *  INIT part
1731 */
1732
1733static int __init alsa_cs4231_init(void)
1734{
1735	return 0;
1736}
1737
1738static void __exit alsa_cs4231_exit(void)
1739{
1740}
1741
1742module_init(alsa_cs4231_init)
1743module_exit(alsa_cs4231_exit)
1744