1/*
2 *  Copyright (c) 1999 by Uros Bizjak <uros@kss-loka.si>
3 *                        Takashi Iwai <tiwai@suse.de>
4 *
5 *  SB16ASP/AWE32 CSP control
6 *
7 *  CSP microcode loader:
8 *   alsa-tools/sb16_csp/
9 *
10 *   This program is free software; you can redistribute it and/or modify
11 *   it under the terms of the GNU General Public License as published by
12 *   the Free Software Foundation; either version 2 of the License, or
13 *   (at your option) any later version.
14 *
15 *   This program is distributed in the hope that it will be useful,
16 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
17 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 *   GNU General Public License for more details.
19 *
20 *   You should have received a copy of the GNU General Public License
21 *   along with this program; if not, write to the Free Software
22 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23 *
24 */
25
26#include <sound/driver.h>
27#include <linux/delay.h>
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <sound/core.h>
31#include <sound/control.h>
32#include <sound/info.h>
33#include <sound/sb16_csp.h>
34#include <sound/initval.h>
35
36MODULE_AUTHOR("Uros Bizjak <uros@kss-loka.si>");
37MODULE_DESCRIPTION("ALSA driver for SB16 Creative Signal Processor");
38MODULE_LICENSE("GPL");
39#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
40MODULE_FIRMWARE("sb16/mulaw_main.csp");
41MODULE_FIRMWARE("sb16/alaw_main.csp");
42MODULE_FIRMWARE("sb16/ima_adpcm_init.csp");
43MODULE_FIRMWARE("sb16/ima_adpcm_playback.csp");
44MODULE_FIRMWARE("sb16/ima_adpcm_capture.csp");
45#endif
46
47#ifdef SNDRV_LITTLE_ENDIAN
48#define CSP_HDR_VALUE(a,b,c,d)	((a) | ((b)<<8) | ((c)<<16) | ((d)<<24))
49#else
50#define CSP_HDR_VALUE(a,b,c,d)	((d) | ((c)<<8) | ((b)<<16) | ((a)<<24))
51#endif
52
53#define RIFF_HEADER	CSP_HDR_VALUE('R', 'I', 'F', 'F')
54#define CSP__HEADER	CSP_HDR_VALUE('C', 'S', 'P', ' ')
55#define LIST_HEADER	CSP_HDR_VALUE('L', 'I', 'S', 'T')
56#define FUNC_HEADER	CSP_HDR_VALUE('f', 'u', 'n', 'c')
57#define CODE_HEADER	CSP_HDR_VALUE('c', 'o', 'd', 'e')
58#define INIT_HEADER	CSP_HDR_VALUE('i', 'n', 'i', 't')
59#define MAIN_HEADER	CSP_HDR_VALUE('m', 'a', 'i', 'n')
60
61/*
62 * RIFF data format
63 */
64struct riff_header {
65	__u32 name;
66	__u32 len;
67};
68
69struct desc_header {
70	struct riff_header info;
71	__u16 func_nr;
72	__u16 VOC_type;
73	__u16 flags_play_rec;
74	__u16 flags_16bit_8bit;
75	__u16 flags_stereo_mono;
76	__u16 flags_rates;
77};
78
79/*
80 * prototypes
81 */
82static void snd_sb_csp_free(struct snd_hwdep *hw);
83static int snd_sb_csp_open(struct snd_hwdep * hw, struct file *file);
84static int snd_sb_csp_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg);
85static int snd_sb_csp_release(struct snd_hwdep * hw, struct file *file);
86
87static int csp_detect(struct snd_sb *chip, int *version);
88static int set_codec_parameter(struct snd_sb *chip, unsigned char par, unsigned char val);
89static int set_register(struct snd_sb *chip, unsigned char reg, unsigned char val);
90static int read_register(struct snd_sb *chip, unsigned char reg);
91static int set_mode_register(struct snd_sb *chip, unsigned char mode);
92static int get_version(struct snd_sb *chip);
93
94static int snd_sb_csp_riff_load(struct snd_sb_csp * p,
95				struct snd_sb_csp_microcode __user * code);
96static int snd_sb_csp_unload(struct snd_sb_csp * p);
97static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __user *buf, int size, int load_flags);
98static int snd_sb_csp_autoload(struct snd_sb_csp * p, int pcm_sfmt, int play_rec_mode);
99static int snd_sb_csp_check_version(struct snd_sb_csp * p);
100
101static int snd_sb_csp_use(struct snd_sb_csp * p);
102static int snd_sb_csp_unuse(struct snd_sb_csp * p);
103static int snd_sb_csp_start(struct snd_sb_csp * p, int sample_width, int channels);
104static int snd_sb_csp_stop(struct snd_sb_csp * p);
105static int snd_sb_csp_pause(struct snd_sb_csp * p);
106static int snd_sb_csp_restart(struct snd_sb_csp * p);
107
108static int snd_sb_qsound_build(struct snd_sb_csp * p);
109static void snd_sb_qsound_destroy(struct snd_sb_csp * p);
110static int snd_sb_csp_qsound_transfer(struct snd_sb_csp * p);
111
112static int init_proc_entry(struct snd_sb_csp * p, int device);
113static void info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer);
114
115/*
116 * Detect CSP chip and create a new instance
117 */
118int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep)
119{
120	struct snd_sb_csp *p;
121	int version, err;
122	struct snd_hwdep *hw;
123
124	if (rhwdep)
125		*rhwdep = NULL;
126
127	if (csp_detect(chip, &version))
128		return -ENODEV;
129
130	if ((err = snd_hwdep_new(chip->card, "SB16-CSP", device, &hw)) < 0)
131		return err;
132
133	if ((p = kzalloc(sizeof(*p), GFP_KERNEL)) == NULL) {
134		snd_device_free(chip->card, hw);
135		return -ENOMEM;
136	}
137	p->chip = chip;
138	p->version = version;
139
140	/* CSP operators */
141	p->ops.csp_use = snd_sb_csp_use;
142	p->ops.csp_unuse = snd_sb_csp_unuse;
143	p->ops.csp_autoload = snd_sb_csp_autoload;
144	p->ops.csp_start = snd_sb_csp_start;
145	p->ops.csp_stop = snd_sb_csp_stop;
146	p->ops.csp_qsound_transfer = snd_sb_csp_qsound_transfer;
147
148	mutex_init(&p->access_mutex);
149	sprintf(hw->name, "CSP v%d.%d", (version >> 4), (version & 0x0f));
150	hw->iface = SNDRV_HWDEP_IFACE_SB16CSP;
151	hw->private_data = p;
152	hw->private_free = snd_sb_csp_free;
153
154	/* operators - only write/ioctl */
155	hw->ops.open = snd_sb_csp_open;
156	hw->ops.ioctl = snd_sb_csp_ioctl;
157	hw->ops.release = snd_sb_csp_release;
158
159	/* create a proc entry */
160	init_proc_entry(p, device);
161	if (rhwdep)
162		*rhwdep = hw;
163	return 0;
164}
165
166/*
167 * free_private for hwdep instance
168 */
169static void snd_sb_csp_free(struct snd_hwdep *hwdep)
170{
171#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
172	int i;
173#endif
174	struct snd_sb_csp *p = hwdep->private_data;
175	if (p) {
176		if (p->running & SNDRV_SB_CSP_ST_RUNNING)
177			snd_sb_csp_stop(p);
178#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
179		for (i = 0; i < ARRAY_SIZE(p->csp_programs); ++i)
180			release_firmware(p->csp_programs[i]);
181#endif
182		kfree(p);
183	}
184}
185
186/* ------------------------------ */
187
188/*
189 * open the device exclusively
190 */
191static int snd_sb_csp_open(struct snd_hwdep * hw, struct file *file)
192{
193	struct snd_sb_csp *p = hw->private_data;
194	return (snd_sb_csp_use(p));
195}
196
197/*
198 * ioctl for hwdep device:
199 */
200static int snd_sb_csp_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg)
201{
202	struct snd_sb_csp *p = hw->private_data;
203	struct snd_sb_csp_info info;
204	struct snd_sb_csp_start start_info;
205	int err;
206
207	snd_assert(p != NULL, return -EINVAL);
208
209	if (snd_sb_csp_check_version(p))
210		return -ENODEV;
211
212	switch (cmd) {
213		/* get information */
214	case SNDRV_SB_CSP_IOCTL_INFO:
215		*info.codec_name = *p->codec_name;
216		info.func_nr = p->func_nr;
217		info.acc_format = p->acc_format;
218		info.acc_channels = p->acc_channels;
219		info.acc_width = p->acc_width;
220		info.acc_rates = p->acc_rates;
221		info.csp_mode = p->mode;
222		info.run_channels = p->run_channels;
223		info.run_width = p->run_width;
224		info.version = p->version;
225		info.state = p->running;
226		if (copy_to_user((void __user *)arg, &info, sizeof(info)))
227			err = -EFAULT;
228		else
229			err = 0;
230		break;
231
232		/* load CSP microcode */
233	case SNDRV_SB_CSP_IOCTL_LOAD_CODE:
234		err = (p->running & SNDRV_SB_CSP_ST_RUNNING ?
235		       -EBUSY : snd_sb_csp_riff_load(p, (struct snd_sb_csp_microcode __user *) arg));
236		break;
237	case SNDRV_SB_CSP_IOCTL_UNLOAD_CODE:
238		err = (p->running & SNDRV_SB_CSP_ST_RUNNING ?
239		       -EBUSY : snd_sb_csp_unload(p));
240		break;
241
242		/* change CSP running state */
243	case SNDRV_SB_CSP_IOCTL_START:
244		if (copy_from_user(&start_info, (void __user *) arg, sizeof(start_info)))
245			err = -EFAULT;
246		else
247			err = snd_sb_csp_start(p, start_info.sample_width, start_info.channels);
248		break;
249	case SNDRV_SB_CSP_IOCTL_STOP:
250		err = snd_sb_csp_stop(p);
251		break;
252	case SNDRV_SB_CSP_IOCTL_PAUSE:
253		err = snd_sb_csp_pause(p);
254		break;
255	case SNDRV_SB_CSP_IOCTL_RESTART:
256		err = snd_sb_csp_restart(p);
257		break;
258	default:
259		err = -ENOTTY;
260		break;
261	}
262
263	return err;
264}
265
266/*
267 * close the device
268 */
269static int snd_sb_csp_release(struct snd_hwdep * hw, struct file *file)
270{
271	struct snd_sb_csp *p = hw->private_data;
272	return (snd_sb_csp_unuse(p));
273}
274
275/* ------------------------------ */
276
277/*
278 * acquire device
279 */
280static int snd_sb_csp_use(struct snd_sb_csp * p)
281{
282	mutex_lock(&p->access_mutex);
283	if (p->used) {
284		mutex_unlock(&p->access_mutex);
285		return -EAGAIN;
286	}
287	p->used++;
288	mutex_unlock(&p->access_mutex);
289
290	return 0;
291
292}
293
294/*
295 * release device
296 */
297static int snd_sb_csp_unuse(struct snd_sb_csp * p)
298{
299	mutex_lock(&p->access_mutex);
300	p->used--;
301	mutex_unlock(&p->access_mutex);
302
303	return 0;
304}
305
306/*
307 * load microcode via ioctl:
308 * code is user-space pointer
309 */
310static int snd_sb_csp_riff_load(struct snd_sb_csp * p,
311				struct snd_sb_csp_microcode __user * mcode)
312{
313	struct snd_sb_csp_mc_header info;
314
315	unsigned char __user *data_ptr;
316	unsigned char __user *data_end;
317	unsigned short func_nr = 0;
318
319	struct riff_header file_h, item_h, code_h;
320	__u32 item_type;
321	struct desc_header funcdesc_h;
322
323	unsigned long flags;
324	int err;
325
326	if (copy_from_user(&info, mcode, sizeof(info)))
327		return -EFAULT;
328	data_ptr = mcode->data;
329
330	if (copy_from_user(&file_h, data_ptr, sizeof(file_h)))
331		return -EFAULT;
332	if ((file_h.name != RIFF_HEADER) ||
333	    (le32_to_cpu(file_h.len) >= SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE - sizeof(file_h))) {
334		snd_printd("%s: Invalid RIFF header\n", __FUNCTION__);
335		return -EINVAL;
336	}
337	data_ptr += sizeof(file_h);
338	data_end = data_ptr + le32_to_cpu(file_h.len);
339
340	if (copy_from_user(&item_type, data_ptr, sizeof(item_type)))
341		return -EFAULT;
342	if (item_type != CSP__HEADER) {
343		snd_printd("%s: Invalid RIFF file type\n", __FUNCTION__);
344		return -EINVAL;
345	}
346	data_ptr += sizeof (item_type);
347
348	for (; data_ptr < data_end; data_ptr += le32_to_cpu(item_h.len)) {
349		if (copy_from_user(&item_h, data_ptr, sizeof(item_h)))
350			return -EFAULT;
351		data_ptr += sizeof(item_h);
352		if (item_h.name != LIST_HEADER)
353			continue;
354
355		if (copy_from_user(&item_type, data_ptr, sizeof(item_type)))
356			 return -EFAULT;
357		switch (item_type) {
358		case FUNC_HEADER:
359			if (copy_from_user(&funcdesc_h, data_ptr + sizeof(item_type), sizeof(funcdesc_h)))
360				return -EFAULT;
361			func_nr = le16_to_cpu(funcdesc_h.func_nr);
362			break;
363		case CODE_HEADER:
364			if (func_nr != info.func_req)
365				break;	/* not required function, try next */
366			data_ptr += sizeof(item_type);
367
368			/* destroy QSound mixer element */
369			if (p->mode == SNDRV_SB_CSP_MODE_QSOUND) {
370				snd_sb_qsound_destroy(p);
371			}
372			/* Clear all flags */
373			p->running = 0;
374			p->mode = 0;
375
376			/* load microcode blocks */
377			for (;;) {
378				if (data_ptr >= data_end)
379					return -EINVAL;
380				if (copy_from_user(&code_h, data_ptr, sizeof(code_h)))
381					return -EFAULT;
382
383				/* init microcode blocks */
384				if (code_h.name != INIT_HEADER)
385					break;
386				data_ptr += sizeof(code_h);
387				err = snd_sb_csp_load_user(p, data_ptr, le32_to_cpu(code_h.len),
388						      SNDRV_SB_CSP_LOAD_INITBLOCK);
389				if (err)
390					return err;
391				data_ptr += le32_to_cpu(code_h.len);
392			}
393			/* main microcode block */
394			if (copy_from_user(&code_h, data_ptr, sizeof(code_h)))
395				return -EFAULT;
396
397			if (code_h.name != MAIN_HEADER) {
398				snd_printd("%s: Missing 'main' microcode\n", __FUNCTION__);
399				return -EINVAL;
400			}
401			data_ptr += sizeof(code_h);
402			err = snd_sb_csp_load_user(p, data_ptr,
403						   le32_to_cpu(code_h.len), 0);
404			if (err)
405				return err;
406
407			/* fill in codec header */
408			strlcpy(p->codec_name, info.codec_name, sizeof(p->codec_name));
409			p->func_nr = func_nr;
410			p->mode = le16_to_cpu(funcdesc_h.flags_play_rec);
411			switch (le16_to_cpu(funcdesc_h.VOC_type)) {
412			case 0x0001:	/* QSound decoder */
413				if (le16_to_cpu(funcdesc_h.flags_play_rec) == SNDRV_SB_CSP_MODE_DSP_WRITE) {
414					if (snd_sb_qsound_build(p) == 0)
415						/* set QSound flag and clear all other mode flags */
416						p->mode = SNDRV_SB_CSP_MODE_QSOUND;
417				}
418				p->acc_format = 0;
419				break;
420			case 0x0006:	/* A Law codec */
421				p->acc_format = SNDRV_PCM_FMTBIT_A_LAW;
422				break;
423			case 0x0007:	/* Mu Law codec */
424				p->acc_format = SNDRV_PCM_FMTBIT_MU_LAW;
425				break;
426			case 0x0011:	/* what Creative thinks is IMA ADPCM codec */
427			case 0x0200:	/* Creative ADPCM codec */
428				p->acc_format = SNDRV_PCM_FMTBIT_IMA_ADPCM;
429				break;
430			case    201:	/* Text 2 Speech decoder */
431				/* TODO: Text2Speech handling routines */
432				p->acc_format = 0;
433				break;
434			case 0x0202:	/* Fast Speech 8 codec */
435			case 0x0203:	/* Fast Speech 10 codec */
436				p->acc_format = SNDRV_PCM_FMTBIT_SPECIAL;
437				break;
438			default:	/* other codecs are unsupported */
439				p->acc_format = p->acc_width = p->acc_rates = 0;
440				p->mode = 0;
441				snd_printd("%s: Unsupported CSP codec type: 0x%04x\n",
442					   __FUNCTION__,
443					   le16_to_cpu(funcdesc_h.VOC_type));
444				return -EINVAL;
445			}
446			p->acc_channels = le16_to_cpu(funcdesc_h.flags_stereo_mono);
447			p->acc_width = le16_to_cpu(funcdesc_h.flags_16bit_8bit);
448			p->acc_rates = le16_to_cpu(funcdesc_h.flags_rates);
449
450			/* Decouple CSP from IRQ and DMAREQ lines */
451			spin_lock_irqsave(&p->chip->reg_lock, flags);
452			set_mode_register(p->chip, 0xfc);
453			set_mode_register(p->chip, 0x00);
454			spin_unlock_irqrestore(&p->chip->reg_lock, flags);
455
456			/* finished loading successfully */
457			p->running = SNDRV_SB_CSP_ST_LOADED;	/* set LOADED flag */
458			return 0;
459		}
460	}
461	snd_printd("%s: Function #%d not found\n", __FUNCTION__, info.func_req);
462	return -EINVAL;
463}
464
465/*
466 * unload CSP microcode
467 */
468static int snd_sb_csp_unload(struct snd_sb_csp * p)
469{
470	if (p->running & SNDRV_SB_CSP_ST_RUNNING)
471		return -EBUSY;
472	if (!(p->running & SNDRV_SB_CSP_ST_LOADED))
473		return -ENXIO;
474
475	/* clear supported formats */
476	p->acc_format = 0;
477	p->acc_channels = p->acc_width = p->acc_rates = 0;
478	/* destroy QSound mixer element */
479	if (p->mode == SNDRV_SB_CSP_MODE_QSOUND) {
480		snd_sb_qsound_destroy(p);
481	}
482	/* clear all flags */
483	p->running = 0;
484	p->mode = 0;
485	return 0;
486}
487
488/*
489 * send command sequence to DSP
490 */
491static inline int command_seq(struct snd_sb *chip, const unsigned char *seq, int size)
492{
493	int i;
494	for (i = 0; i < size; i++) {
495		if (!snd_sbdsp_command(chip, seq[i]))
496			return -EIO;
497	}
498	return 0;
499}
500
501/*
502 * set CSP codec parameter
503 */
504static int set_codec_parameter(struct snd_sb *chip, unsigned char par, unsigned char val)
505{
506	unsigned char dsp_cmd[3];
507
508	dsp_cmd[0] = 0x05;	/* CSP set codec parameter */
509	dsp_cmd[1] = val;	/* Parameter value */
510	dsp_cmd[2] = par;	/* Parameter */
511	command_seq(chip, dsp_cmd, 3);
512	snd_sbdsp_command(chip, 0x03);	/* DSP read? */
513	if (snd_sbdsp_get_byte(chip) != par)
514		return -EIO;
515	return 0;
516}
517
518/*
519 * set CSP register
520 */
521static int set_register(struct snd_sb *chip, unsigned char reg, unsigned char val)
522{
523	unsigned char dsp_cmd[3];
524
525	dsp_cmd[0] = 0x0e;	/* CSP set register */
526	dsp_cmd[1] = reg;	/* CSP Register */
527	dsp_cmd[2] = val;	/* value */
528	return command_seq(chip, dsp_cmd, 3);
529}
530
531/*
532 * read CSP register
533 * return < 0 -> error
534 */
535static int read_register(struct snd_sb *chip, unsigned char reg)
536{
537	unsigned char dsp_cmd[2];
538
539	dsp_cmd[0] = 0x0f;	/* CSP read register */
540	dsp_cmd[1] = reg;	/* CSP Register */
541	command_seq(chip, dsp_cmd, 2);
542	return snd_sbdsp_get_byte(chip);	/* Read DSP value */
543}
544
545/*
546 * set CSP mode register
547 */
548static int set_mode_register(struct snd_sb *chip, unsigned char mode)
549{
550	unsigned char dsp_cmd[2];
551
552	dsp_cmd[0] = 0x04;	/* CSP set mode register */
553	dsp_cmd[1] = mode;	/* mode */
554	return command_seq(chip, dsp_cmd, 2);
555}
556
557/*
558 * Detect CSP
559 * return 0 if CSP exists.
560 */
561static int csp_detect(struct snd_sb *chip, int *version)
562{
563	unsigned char csp_test1, csp_test2;
564	unsigned long flags;
565	int result = -ENODEV;
566
567	spin_lock_irqsave(&chip->reg_lock, flags);
568
569	set_codec_parameter(chip, 0x00, 0x00);
570	set_mode_register(chip, 0xfc);		/* 0xfc = ?? */
571
572	csp_test1 = read_register(chip, 0x83);
573	set_register(chip, 0x83, ~csp_test1);
574	csp_test2 = read_register(chip, 0x83);
575	if (csp_test2 != (csp_test1 ^ 0xff))
576		goto __fail;
577
578	set_register(chip, 0x83, csp_test1);
579	csp_test2 = read_register(chip, 0x83);
580	if (csp_test2 != csp_test1)
581		goto __fail;
582
583	set_mode_register(chip, 0x00);		/* 0x00 = ? */
584
585	*version = get_version(chip);
586	snd_sbdsp_reset(chip);	/* reset DSP after getversion! */
587	if (*version >= 0x10 && *version <= 0x1f)
588		result = 0;		/* valid version id */
589
590      __fail:
591	spin_unlock_irqrestore(&chip->reg_lock, flags);
592	return result;
593}
594
595/*
596 * get CSP version number
597 */
598static int get_version(struct snd_sb *chip)
599{
600	unsigned char dsp_cmd[2];
601
602	dsp_cmd[0] = 0x08;	/* SB_DSP_!something! */
603	dsp_cmd[1] = 0x03;	/* get chip version id? */
604	command_seq(chip, dsp_cmd, 2);
605
606	return (snd_sbdsp_get_byte(chip));
607}
608
609/*
610 * check if the CSP version is valid
611 */
612static int snd_sb_csp_check_version(struct snd_sb_csp * p)
613{
614	if (p->version < 0x10 || p->version > 0x1f) {
615		snd_printd("%s: Invalid CSP version: 0x%x\n", __FUNCTION__, p->version);
616		return 1;
617	}
618	return 0;
619}
620
621/*
622 * download microcode to CSP (microcode should have one "main" block).
623 */
624static int snd_sb_csp_load(struct snd_sb_csp * p, const unsigned char *buf, int size, int load_flags)
625{
626	int status, i;
627	int err;
628	int result = -EIO;
629	unsigned long flags;
630
631	spin_lock_irqsave(&p->chip->reg_lock, flags);
632	snd_sbdsp_command(p->chip, 0x01);	/* CSP download command */
633	if (snd_sbdsp_get_byte(p->chip)) {
634		snd_printd("%s: Download command failed\n", __FUNCTION__);
635		goto __fail;
636	}
637	/* Send CSP low byte (size - 1) */
638	snd_sbdsp_command(p->chip, (unsigned char)(size - 1));
639	/* Send high byte */
640	snd_sbdsp_command(p->chip, (unsigned char)((size - 1) >> 8));
641	/* send microcode sequence */
642	/* load from kernel space */
643	while (size--) {
644		if (!snd_sbdsp_command(p->chip, *buf++))
645			goto __fail;
646	}
647	if (snd_sbdsp_get_byte(p->chip))
648		goto __fail;
649
650	if (load_flags & SNDRV_SB_CSP_LOAD_INITBLOCK) {
651		i = 0;
652		/* some codecs (FastSpeech) take some time to initialize */
653		while (1) {
654			snd_sbdsp_command(p->chip, 0x03);
655			status = snd_sbdsp_get_byte(p->chip);
656			if (status == 0x55 || ++i >= 10)
657				break;
658			udelay (10);
659		}
660		if (status != 0x55) {
661			snd_printd("%s: Microcode initialization failed\n", __FUNCTION__);
662			goto __fail;
663		}
664	} else {
665		/*
666		 * Read mixer register SB_DSP4_DMASETUP after loading 'main' code.
667		 * Start CSP chip if no 16bit DMA channel is set - some kind
668		 * of autorun or perhaps a bugfix?
669		 */
670		spin_lock(&p->chip->mixer_lock);
671		status = snd_sbmixer_read(p->chip, SB_DSP4_DMASETUP);
672		spin_unlock(&p->chip->mixer_lock);
673		if (!(status & (SB_DMASETUP_DMA7 | SB_DMASETUP_DMA6 | SB_DMASETUP_DMA5))) {
674			err = (set_codec_parameter(p->chip, 0xaa, 0x00) ||
675			       set_codec_parameter(p->chip, 0xff, 0x00));
676			snd_sbdsp_reset(p->chip);		/* really! */
677			if (err)
678				goto __fail;
679			set_mode_register(p->chip, 0xc0);	/* c0 = STOP */
680			set_mode_register(p->chip, 0x70);	/* 70 = RUN */
681		}
682	}
683	result = 0;
684
685      __fail:
686	spin_unlock_irqrestore(&p->chip->reg_lock, flags);
687	return result;
688}
689
690static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __user *buf, int size, int load_flags)
691{
692	int err = -ENOMEM;
693	unsigned char *kbuf = kmalloc(size, GFP_KERNEL);
694	if (kbuf) {
695		if (copy_from_user(kbuf, buf, size))
696			err = -EFAULT;
697		else
698			err = snd_sb_csp_load(p, kbuf, size, load_flags);
699		kfree(kbuf);
700	}
701	return err;
702}
703
704#ifdef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
705#include "sb16_csp_codecs.h"
706
707static const struct firmware snd_sb_csp_static_programs[] = {
708	{ .data = mulaw_main, .size = sizeof mulaw_main },
709	{ .data = alaw_main, .size = sizeof alaw_main },
710	{ .data = ima_adpcm_init, .size = sizeof ima_adpcm_init },
711	{ .data = ima_adpcm_playback, .size = sizeof ima_adpcm_playback },
712	{ .data = ima_adpcm_capture, .size = sizeof ima_adpcm_capture },
713};
714#endif
715
716static int snd_sb_csp_firmware_load(struct snd_sb_csp *p, int index, int flags)
717{
718	static const char *const names[] = {
719		"sb16/mulaw_main.csp",
720		"sb16/alaw_main.csp",
721		"sb16/ima_adpcm_init.csp",
722		"sb16/ima_adpcm_playback.csp",
723		"sb16/ima_adpcm_capture.csp",
724	};
725	const struct firmware *program;
726
727	BUILD_BUG_ON(ARRAY_SIZE(names) != CSP_PROGRAM_COUNT);
728	program = p->csp_programs[index];
729	if (!program) {
730#ifdef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
731		program = &snd_sb_csp_static_programs[index];
732#else
733		int err = request_firmware(&program, names[index],
734				       p->chip->card->dev);
735		if (err < 0)
736			return err;
737#endif
738		p->csp_programs[index] = program;
739	}
740	return snd_sb_csp_load(p, program->data, program->size, flags);
741}
742
743/*
744 * autoload hardware codec if necessary
745 * return 0 if CSP is loaded and ready to run (p->running != 0)
746 */
747static int snd_sb_csp_autoload(struct snd_sb_csp * p, int pcm_sfmt, int play_rec_mode)
748{
749	unsigned long flags;
750	int err = 0;
751
752	/* if CSP is running or manually loaded then exit */
753	if (p->running & (SNDRV_SB_CSP_ST_RUNNING | SNDRV_SB_CSP_ST_LOADED))
754		return -EBUSY;
755
756	/* autoload microcode only if requested hardware codec is not already loaded */
757	if (((1 << pcm_sfmt) & p->acc_format) && (play_rec_mode & p->mode)) {
758		p->running = SNDRV_SB_CSP_ST_AUTO;
759	} else {
760		switch (pcm_sfmt) {
761		case SNDRV_PCM_FORMAT_MU_LAW:
762			err = snd_sb_csp_firmware_load(p, CSP_PROGRAM_MULAW, 0);
763			p->acc_format = SNDRV_PCM_FMTBIT_MU_LAW;
764			p->mode = SNDRV_SB_CSP_MODE_DSP_READ | SNDRV_SB_CSP_MODE_DSP_WRITE;
765			break;
766		case SNDRV_PCM_FORMAT_A_LAW:
767			err = snd_sb_csp_firmware_load(p, CSP_PROGRAM_ALAW, 0);
768			p->acc_format = SNDRV_PCM_FMTBIT_A_LAW;
769			p->mode = SNDRV_SB_CSP_MODE_DSP_READ | SNDRV_SB_CSP_MODE_DSP_WRITE;
770			break;
771		case SNDRV_PCM_FORMAT_IMA_ADPCM:
772			err = snd_sb_csp_firmware_load(p, CSP_PROGRAM_ADPCM_INIT,
773						       SNDRV_SB_CSP_LOAD_INITBLOCK);
774			if (err)
775				break;
776			if (play_rec_mode == SNDRV_SB_CSP_MODE_DSP_WRITE) {
777				err = snd_sb_csp_firmware_load
778					(p, CSP_PROGRAM_ADPCM_PLAYBACK, 0);
779				p->mode = SNDRV_SB_CSP_MODE_DSP_WRITE;
780			} else {
781				err = snd_sb_csp_firmware_load
782					(p, CSP_PROGRAM_ADPCM_CAPTURE, 0);
783				p->mode = SNDRV_SB_CSP_MODE_DSP_READ;
784			}
785			p->acc_format = SNDRV_PCM_FMTBIT_IMA_ADPCM;
786			break;
787		default:
788			/* Decouple CSP from IRQ and DMAREQ lines */
789			if (p->running & SNDRV_SB_CSP_ST_AUTO) {
790				spin_lock_irqsave(&p->chip->reg_lock, flags);
791				set_mode_register(p->chip, 0xfc);
792				set_mode_register(p->chip, 0x00);
793				spin_unlock_irqrestore(&p->chip->reg_lock, flags);
794				p->running = 0;			/* clear autoloaded flag */
795			}
796			return -EINVAL;
797		}
798		if (err) {
799			p->acc_format = 0;
800			p->acc_channels = p->acc_width = p->acc_rates = 0;
801
802			p->running = 0;				/* clear autoloaded flag */
803			p->mode = 0;
804			return (err);
805		} else {
806			p->running = SNDRV_SB_CSP_ST_AUTO;	/* set autoloaded flag */
807			p->acc_width = SNDRV_SB_CSP_SAMPLE_16BIT;	/* only 16 bit data */
808			p->acc_channels = SNDRV_SB_CSP_MONO | SNDRV_SB_CSP_STEREO;
809			p->acc_rates = SNDRV_SB_CSP_RATE_ALL;	/* HW codecs accept all rates */
810		}
811
812	}
813	return (p->running & SNDRV_SB_CSP_ST_AUTO) ? 0 : -ENXIO;
814}
815
816/*
817 * start CSP
818 */
819static int snd_sb_csp_start(struct snd_sb_csp * p, int sample_width, int channels)
820{
821	unsigned char s_type;	/* sample type */
822	unsigned char mixL, mixR;
823	int result = -EIO;
824	unsigned long flags;
825
826	if (!(p->running & (SNDRV_SB_CSP_ST_LOADED | SNDRV_SB_CSP_ST_AUTO))) {
827		snd_printd("%s: Microcode not loaded\n", __FUNCTION__);
828		return -ENXIO;
829	}
830	if (p->running & SNDRV_SB_CSP_ST_RUNNING) {
831		snd_printd("%s: CSP already running\n", __FUNCTION__);
832		return -EBUSY;
833	}
834	if (!(sample_width & p->acc_width)) {
835		snd_printd("%s: Unsupported PCM sample width\n", __FUNCTION__);
836		return -EINVAL;
837	}
838	if (!(channels & p->acc_channels)) {
839		snd_printd("%s: Invalid number of channels\n", __FUNCTION__);
840		return -EINVAL;
841	}
842
843	/* Mute PCM volume */
844	spin_lock_irqsave(&p->chip->mixer_lock, flags);
845	mixL = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV);
846	mixR = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV + 1);
847	snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL & 0x7);
848	snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR & 0x7);
849
850	spin_lock(&p->chip->reg_lock);
851	set_mode_register(p->chip, 0xc0);	/* c0 = STOP */
852	set_mode_register(p->chip, 0x70);	/* 70 = RUN */
853
854	s_type = 0x00;
855	if (channels == SNDRV_SB_CSP_MONO)
856		s_type = 0x11;	/* 000n 000n    (n = 1 if mono) */
857	if (sample_width == SNDRV_SB_CSP_SAMPLE_8BIT)
858		s_type |= 0x22;	/* 00dX 00dX    (d = 1 if 8 bit samples) */
859
860	if (set_codec_parameter(p->chip, 0x81, s_type)) {
861		snd_printd("%s: Set sample type command failed\n", __FUNCTION__);
862		goto __fail;
863	}
864	if (set_codec_parameter(p->chip, 0x80, 0x00)) {
865		snd_printd("%s: Codec start command failed\n", __FUNCTION__);
866		goto __fail;
867	}
868	p->run_width = sample_width;
869	p->run_channels = channels;
870
871	p->running |= SNDRV_SB_CSP_ST_RUNNING;
872
873	if (p->mode & SNDRV_SB_CSP_MODE_QSOUND) {
874		set_codec_parameter(p->chip, 0xe0, 0x01);
875		/* enable QSound decoder */
876		set_codec_parameter(p->chip, 0x00, 0xff);
877		set_codec_parameter(p->chip, 0x01, 0xff);
878		p->running |= SNDRV_SB_CSP_ST_QSOUND;
879		/* set QSound startup value */
880		snd_sb_csp_qsound_transfer(p);
881	}
882	result = 0;
883
884      __fail:
885	spin_unlock(&p->chip->reg_lock);
886
887	/* restore PCM volume */
888	snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL);
889	snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR);
890	spin_unlock_irqrestore(&p->chip->mixer_lock, flags);
891
892	return result;
893}
894
895/*
896 * stop CSP
897 */
898static int snd_sb_csp_stop(struct snd_sb_csp * p)
899{
900	int result;
901	unsigned char mixL, mixR;
902	unsigned long flags;
903
904	if (!(p->running & SNDRV_SB_CSP_ST_RUNNING))
905		return 0;
906
907	/* Mute PCM volume */
908	spin_lock_irqsave(&p->chip->mixer_lock, flags);
909	mixL = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV);
910	mixR = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV + 1);
911	snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL & 0x7);
912	snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR & 0x7);
913
914	spin_lock(&p->chip->reg_lock);
915	if (p->running & SNDRV_SB_CSP_ST_QSOUND) {
916		set_codec_parameter(p->chip, 0xe0, 0x01);
917		/* disable QSound decoder */
918		set_codec_parameter(p->chip, 0x00, 0x00);
919		set_codec_parameter(p->chip, 0x01, 0x00);
920
921		p->running &= ~SNDRV_SB_CSP_ST_QSOUND;
922	}
923	result = set_mode_register(p->chip, 0xc0);	/* c0 = STOP */
924	spin_unlock(&p->chip->reg_lock);
925
926	/* restore PCM volume */
927	snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL);
928	snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR);
929	spin_unlock_irqrestore(&p->chip->mixer_lock, flags);
930
931	if (!(result))
932		p->running &= ~(SNDRV_SB_CSP_ST_PAUSED | SNDRV_SB_CSP_ST_RUNNING);
933	return result;
934}
935
936/*
937 * pause CSP codec and hold DMA transfer
938 */
939static int snd_sb_csp_pause(struct snd_sb_csp * p)
940{
941	int result;
942	unsigned long flags;
943
944	if (!(p->running & SNDRV_SB_CSP_ST_RUNNING))
945		return -EBUSY;
946
947	spin_lock_irqsave(&p->chip->reg_lock, flags);
948	result = set_codec_parameter(p->chip, 0x80, 0xff);
949	spin_unlock_irqrestore(&p->chip->reg_lock, flags);
950	if (!(result))
951		p->running |= SNDRV_SB_CSP_ST_PAUSED;
952
953	return result;
954}
955
956/*
957 * restart CSP codec and resume DMA transfer
958 */
959static int snd_sb_csp_restart(struct snd_sb_csp * p)
960{
961	int result;
962	unsigned long flags;
963
964	if (!(p->running & SNDRV_SB_CSP_ST_PAUSED))
965		return -EBUSY;
966
967	spin_lock_irqsave(&p->chip->reg_lock, flags);
968	result = set_codec_parameter(p->chip, 0x80, 0x00);
969	spin_unlock_irqrestore(&p->chip->reg_lock, flags);
970	if (!(result))
971		p->running &= ~SNDRV_SB_CSP_ST_PAUSED;
972
973	return result;
974}
975
976/* ------------------------------ */
977
978/*
979 * QSound mixer control for PCM
980 */
981
982static int snd_sb_qsound_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
983{
984	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
985	uinfo->count = 1;
986	uinfo->value.integer.min = 0;
987	uinfo->value.integer.max = 1;
988	return 0;
989}
990
991static int snd_sb_qsound_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
992{
993	struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol);
994
995	ucontrol->value.integer.value[0] = p->q_enabled ? 1 : 0;
996	return 0;
997}
998
999static int snd_sb_qsound_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1000{
1001	struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol);
1002	unsigned long flags;
1003	int change;
1004	unsigned char nval;
1005
1006	nval = ucontrol->value.integer.value[0] & 0x01;
1007	spin_lock_irqsave(&p->q_lock, flags);
1008	change = p->q_enabled != nval;
1009	p->q_enabled = nval;
1010	spin_unlock_irqrestore(&p->q_lock, flags);
1011	return change;
1012}
1013
1014static int snd_sb_qsound_space_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1015{
1016	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1017	uinfo->count = 2;
1018	uinfo->value.integer.min = 0;
1019	uinfo->value.integer.max = SNDRV_SB_CSP_QSOUND_MAX_RIGHT;
1020	return 0;
1021}
1022
1023static int snd_sb_qsound_space_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1024{
1025	struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol);
1026	unsigned long flags;
1027
1028	spin_lock_irqsave(&p->q_lock, flags);
1029	ucontrol->value.integer.value[0] = p->qpos_left;
1030	ucontrol->value.integer.value[1] = p->qpos_right;
1031	spin_unlock_irqrestore(&p->q_lock, flags);
1032	return 0;
1033}
1034
1035static int snd_sb_qsound_space_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1036{
1037	struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol);
1038	unsigned long flags;
1039	int change;
1040	unsigned char nval1, nval2;
1041
1042	nval1 = ucontrol->value.integer.value[0];
1043	if (nval1 > SNDRV_SB_CSP_QSOUND_MAX_RIGHT)
1044		nval1 = SNDRV_SB_CSP_QSOUND_MAX_RIGHT;
1045	nval2 = ucontrol->value.integer.value[1];
1046	if (nval2 > SNDRV_SB_CSP_QSOUND_MAX_RIGHT)
1047		nval2 = SNDRV_SB_CSP_QSOUND_MAX_RIGHT;
1048	spin_lock_irqsave(&p->q_lock, flags);
1049	change = p->qpos_left != nval1 || p->qpos_right != nval2;
1050	p->qpos_left = nval1;
1051	p->qpos_right = nval2;
1052	p->qpos_changed = change;
1053	spin_unlock_irqrestore(&p->q_lock, flags);
1054	return change;
1055}
1056
1057static struct snd_kcontrol_new snd_sb_qsound_switch = {
1058	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1059	.name = "3D Control - Switch",
1060	.info = snd_sb_qsound_switch_info,
1061	.get = snd_sb_qsound_switch_get,
1062	.put = snd_sb_qsound_switch_put
1063};
1064
1065static struct snd_kcontrol_new snd_sb_qsound_space = {
1066	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1067	.name = "3D Control - Space",
1068	.info = snd_sb_qsound_space_info,
1069	.get = snd_sb_qsound_space_get,
1070	.put = snd_sb_qsound_space_put
1071};
1072
1073static int snd_sb_qsound_build(struct snd_sb_csp * p)
1074{
1075	struct snd_card *card;
1076	int err;
1077
1078	snd_assert(p != NULL, return -EINVAL);
1079
1080	card = p->chip->card;
1081	p->qpos_left = p->qpos_right = SNDRV_SB_CSP_QSOUND_MAX_RIGHT / 2;
1082	p->qpos_changed = 0;
1083
1084	spin_lock_init(&p->q_lock);
1085
1086	if ((err = snd_ctl_add(card, p->qsound_switch = snd_ctl_new1(&snd_sb_qsound_switch, p))) < 0)
1087		goto __error;
1088	if ((err = snd_ctl_add(card, p->qsound_space = snd_ctl_new1(&snd_sb_qsound_space, p))) < 0)
1089		goto __error;
1090
1091	return 0;
1092
1093     __error:
1094	snd_sb_qsound_destroy(p);
1095	return err;
1096}
1097
1098static void snd_sb_qsound_destroy(struct snd_sb_csp * p)
1099{
1100	struct snd_card *card;
1101	unsigned long flags;
1102
1103	snd_assert(p != NULL, return);
1104
1105	card = p->chip->card;
1106
1107	down_write(&card->controls_rwsem);
1108	if (p->qsound_switch)
1109		snd_ctl_remove(card, p->qsound_switch);
1110	if (p->qsound_space)
1111		snd_ctl_remove(card, p->qsound_space);
1112	up_write(&card->controls_rwsem);
1113
1114	/* cancel pending transfer of QSound parameters */
1115	spin_lock_irqsave (&p->q_lock, flags);
1116	p->qpos_changed = 0;
1117	spin_unlock_irqrestore (&p->q_lock, flags);
1118}
1119
1120/*
1121 * Transfer qsound parameters to CSP,
1122 * function should be called from interrupt routine
1123 */
1124static int snd_sb_csp_qsound_transfer(struct snd_sb_csp * p)
1125{
1126	int err = -ENXIO;
1127
1128	spin_lock(&p->q_lock);
1129	if (p->running & SNDRV_SB_CSP_ST_QSOUND) {
1130		set_codec_parameter(p->chip, 0xe0, 0x01);
1131		/* left channel */
1132		set_codec_parameter(p->chip, 0x00, p->qpos_left);
1133		set_codec_parameter(p->chip, 0x02, 0x00);
1134		/* right channel */
1135		set_codec_parameter(p->chip, 0x00, p->qpos_right);
1136		set_codec_parameter(p->chip, 0x03, 0x00);
1137		err = 0;
1138	}
1139	p->qpos_changed = 0;
1140	spin_unlock(&p->q_lock);
1141	return err;
1142}
1143
1144/* ------------------------------ */
1145
1146/*
1147 * proc interface
1148 */
1149static int init_proc_entry(struct snd_sb_csp * p, int device)
1150{
1151	char name[16];
1152	struct snd_info_entry *entry;
1153	sprintf(name, "cspD%d", device);
1154	if (! snd_card_proc_new(p->chip->card, name, &entry))
1155		snd_info_set_text_ops(entry, p, info_read);
1156	return 0;
1157}
1158
1159static void info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
1160{
1161	struct snd_sb_csp *p = entry->private_data;
1162
1163	snd_iprintf(buffer, "Creative Signal Processor [v%d.%d]\n", (p->version >> 4), (p->version & 0x0f));
1164	snd_iprintf(buffer, "State: %cx%c%c%c\n", ((p->running & SNDRV_SB_CSP_ST_QSOUND) ? 'Q' : '-'),
1165		    ((p->running & SNDRV_SB_CSP_ST_PAUSED) ? 'P' : '-'),
1166		    ((p->running & SNDRV_SB_CSP_ST_RUNNING) ? 'R' : '-'),
1167		    ((p->running & SNDRV_SB_CSP_ST_LOADED) ? 'L' : '-'));
1168	if (p->running & SNDRV_SB_CSP_ST_LOADED) {
1169		snd_iprintf(buffer, "Codec: %s [func #%d]\n", p->codec_name, p->func_nr);
1170		snd_iprintf(buffer, "Sample rates: ");
1171		if (p->acc_rates == SNDRV_SB_CSP_RATE_ALL) {
1172			snd_iprintf(buffer, "All\n");
1173		} else {
1174			snd_iprintf(buffer, "%s%s%s%s\n",
1175				    ((p->acc_rates & SNDRV_SB_CSP_RATE_8000) ? "8000Hz " : ""),
1176				    ((p->acc_rates & SNDRV_SB_CSP_RATE_11025) ? "11025Hz " : ""),
1177				    ((p->acc_rates & SNDRV_SB_CSP_RATE_22050) ? "22050Hz " : ""),
1178				    ((p->acc_rates & SNDRV_SB_CSP_RATE_44100) ? "44100Hz" : ""));
1179		}
1180		if (p->mode == SNDRV_SB_CSP_MODE_QSOUND) {
1181			snd_iprintf(buffer, "QSound decoder %sabled\n",
1182				    p->q_enabled ? "en" : "dis");
1183		} else {
1184			snd_iprintf(buffer, "PCM format ID: 0x%x (%s/%s) [%s/%s] [%s/%s]\n",
1185				    p->acc_format,
1186				    ((p->acc_width & SNDRV_SB_CSP_SAMPLE_16BIT) ? "16bit" : "-"),
1187				    ((p->acc_width & SNDRV_SB_CSP_SAMPLE_8BIT) ? "8bit" : "-"),
1188				    ((p->acc_channels & SNDRV_SB_CSP_MONO) ? "mono" : "-"),
1189				    ((p->acc_channels & SNDRV_SB_CSP_STEREO) ? "stereo" : "-"),
1190				    ((p->mode & SNDRV_SB_CSP_MODE_DSP_WRITE) ? "playback" : "-"),
1191				    ((p->mode & SNDRV_SB_CSP_MODE_DSP_READ) ? "capture" : "-"));
1192		}
1193	}
1194	if (p->running & SNDRV_SB_CSP_ST_AUTO) {
1195		snd_iprintf(buffer, "Autoloaded Mu-Law, A-Law or Ima-ADPCM hardware codec\n");
1196	}
1197	if (p->running & SNDRV_SB_CSP_ST_RUNNING) {
1198		snd_iprintf(buffer, "Processing %dbit %s PCM samples\n",
1199			    ((p->run_width & SNDRV_SB_CSP_SAMPLE_16BIT) ? 16 : 8),
1200			    ((p->run_channels & SNDRV_SB_CSP_MONO) ? "mono" : "stereo"));
1201	}
1202	if (p->running & SNDRV_SB_CSP_ST_QSOUND) {
1203		snd_iprintf(buffer, "Qsound position: left = 0x%x, right = 0x%x\n",
1204			    p->qpos_left, p->qpos_right);
1205	}
1206}
1207
1208/* */
1209
1210EXPORT_SYMBOL(snd_sb_csp_new);
1211
1212/*
1213 * INIT part
1214 */
1215
1216static int __init alsa_sb_csp_init(void)
1217{
1218	return 0;
1219}
1220
1221static void __exit alsa_sb_csp_exit(void)
1222{
1223}
1224
1225module_init(alsa_sb_csp_init)
1226module_exit(alsa_sb_csp_exit)
1227