blob: 9b800ce5100ef286864234b308fb646c7d5dc9a1 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Uwe Zeisbergerf30c2262006-10-03 23:01:26 +02002 * sound/oss/pss.c
Linus Torvalds1da177e2005-04-16 15:20:36 -07003 *
4 * The low level driver for the Personal Sound System (ECHO ESC614).
5 *
6 *
7 * Copyright (C) by Hannu Savolainen 1993-1997
8 *
9 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
10 * Version 2 (June 1991). See the "COPYING" file distributed with this software
11 * for more info.
12 *
13 *
14 * Thomas Sailer ioctl code reworked (vmalloc/vfree removed)
15 * Alan Cox modularisation, clean up.
16 *
17 * 98-02-21: Vladimir Michl <vladimir.michl@upol.cz>
18 * Added mixer device for Beethoven ADSP-16 (master volume,
19 * bass, treble, synth), only for speakers.
20 * Fixed bug in pss_write (exchange parameters)
21 * Fixed config port of SB
22 * Requested two regions for PSS (PSS mixer, PSS config)
23 * Modified pss_download_boot
24 * To probe_pss_mss added test for initialize AD1848
25 * 98-05-28: Vladimir Michl <vladimir.michl@upol.cz>
26 * Fixed computation of mixer volumes
27 * 04-05-1999: Anthony Barbachan <barbcode@xmen.cis.fordham.edu>
28 * Added code that allows the user to enable his cdrom and/or
29 * joystick through the module parameters pss_cdrom_port and
30 * pss_enable_joystick. pss_cdrom_port takes a port address as its
31 * argument. pss_enable_joystick takes either a 0 or a non-0 as its
32 * argument.
33 * 04-06-1999: Anthony Barbachan <barbcode@xmen.cis.fordham.edu>
34 * Separated some code into new functions for easier reuse.
35 * Cleaned up and streamlined new code. Added code to allow a user
36 * to only use this driver for enabling non-sound components
37 * through the new module parameter pss_no_sound (flag). Added
38 * code that would allow a user to decide whether the driver should
39 * reset the configured hardware settings for the PSS board through
40 * the module parameter pss_keep_settings (flag). This flag will
41 * allow a user to free up resources in use by this card if needbe,
42 * furthermore it allows him to use this driver to just enable the
43 * emulations and then be unloaded as it is no longer needed. Both
44 * new settings are only available to this driver if compiled as a
45 * module. The default settings of all new parameters are set to
46 * load the driver as it did in previous versions.
47 * 04-07-1999: Anthony Barbachan <barbcode@xmen.cis.fordham.edu>
48 * Added module parameter pss_firmware to allow the user to tell
Nick Andrew877d0312009-01-26 11:06:57 +010049 * the driver where the firmware file is located. The default
Linus Torvalds1da177e2005-04-16 15:20:36 -070050 * setting is the previous hardcoded setting "/etc/sound/pss_synth".
51 * 00-03-03: Christoph Hellwig <chhellwig@infradead.org>
52 * Adapted to module_init/module_exit
53 * 11-10-2000: Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
54 * Added __init to probe_pss(), attach_pss() and probe_pss_mpu()
55 * 02-Jan-2001: Chris Rankin
56 * Specify that this module owns the coprocessor
57 */
58
59
Linus Torvalds1da177e2005-04-16 15:20:36 -070060#include <linux/init.h>
61#include <linux/module.h>
62#include <linux/spinlock.h>
63
64#include "sound_config.h"
65#include "sound_firmware.h"
66
67#include "ad1848.h"
68#include "mpu401.h"
69
70/*
71 * PSS registers.
72 */
73#define REG(x) (devc->base+x)
74#define PSS_DATA 0
75#define PSS_STATUS 2
76#define PSS_CONTROL 2
77#define PSS_ID 4
78#define PSS_IRQACK 4
79#define PSS_PIO 0x1a
80
81/*
82 * Config registers
83 */
84#define CONF_PSS 0x10
85#define CONF_WSS 0x12
86#define CONF_SB 0x14
87#define CONF_CDROM 0x16
88#define CONF_MIDI 0x18
89
90/*
91 * Status bits.
92 */
93#define PSS_FLAG3 0x0800
94#define PSS_FLAG2 0x0400
95#define PSS_FLAG1 0x1000
96#define PSS_FLAG0 0x0800
97#define PSS_WRITE_EMPTY 0x8000
98#define PSS_READ_FULL 0x4000
99
100/*
101 * WSS registers
102 */
103#define WSS_INDEX 4
104#define WSS_DATA 5
105
106/*
107 * WSS status bits
108 */
109#define WSS_INITIALIZING 0x80
110#define WSS_AUTOCALIBRATION 0x20
111
112#define NO_WSS_MIXER -1
113
114#include "coproc.h"
115
116#include "pss_boot.h"
117
118/* If compiled into kernel, it enable or disable pss mixer */
119#ifdef CONFIG_PSS_MIXER
120static int pss_mixer = 1;
121#else
122static int pss_mixer;
123#endif
124
125
126typedef struct pss_mixerdata {
127 unsigned int volume_l;
128 unsigned int volume_r;
129 unsigned int bass;
130 unsigned int treble;
131 unsigned int synth;
132} pss_mixerdata;
133
134typedef struct pss_confdata {
135 int base;
136 int irq;
137 int dma;
138 int *osp;
139 pss_mixerdata mixer;
140 int ad_mixer_dev;
141} pss_confdata;
142
143static pss_confdata pss_data;
144static pss_confdata *devc = &pss_data;
145static DEFINE_SPINLOCK(lock);
146
147static int pss_initialized;
148static int nonstandard_microcode;
149static int pss_cdrom_port = -1; /* Parameter for the PSS cdrom port */
150static int pss_enable_joystick; /* Parameter for enabling the joystick */
151static coproc_operations pss_coproc_operations;
152
153static void pss_write(pss_confdata *devc, int data)
154{
155 unsigned long i, limit;
156
157 limit = jiffies + HZ/10; /* The timeout is 0.1 seconds */
158 /*
159 * Note! the i<5000000 is an emergency exit. The dsp_command() is sometimes
160 * called while interrupts are disabled. This means that the timer is
161 * disabled also. However the timeout situation is a abnormal condition.
162 * Normally the DSP should be ready to accept commands after just couple of
163 * loops.
164 */
165
166 for (i = 0; i < 5000000 && time_before(jiffies, limit); i++)
167 {
168 if (inw(REG(PSS_STATUS)) & PSS_WRITE_EMPTY)
169 {
170 outw(data, REG(PSS_DATA));
171 return;
172 }
173 }
174 printk(KERN_WARNING "PSS: DSP Command (%04x) Timeout.\n", data);
175}
176
177static int __init probe_pss(struct address_info *hw_config)
178{
179 unsigned short id;
180 int irq, dma;
181
182 devc->base = hw_config->io_base;
183 irq = devc->irq = hw_config->irq;
184 dma = devc->dma = hw_config->dma;
185 devc->osp = hw_config->osp;
186
187 if (devc->base != 0x220 && devc->base != 0x240)
188 if (devc->base != 0x230 && devc->base != 0x250) /* Some cards use these */
189 return 0;
190
191 if (!request_region(devc->base, 0x10, "PSS mixer, SB emulation")) {
192 printk(KERN_ERR "PSS: I/O port conflict\n");
193 return 0;
194 }
195 id = inw(REG(PSS_ID));
196 if ((id >> 8) != 'E') {
197 printk(KERN_ERR "No PSS signature detected at 0x%x (0x%x)\n", devc->base, id);
198 release_region(devc->base, 0x10);
199 return 0;
200 }
201 if (!request_region(devc->base + 0x10, 0x9, "PSS config")) {
202 printk(KERN_ERR "PSS: I/O port conflict\n");
203 release_region(devc->base, 0x10);
204 return 0;
205 }
206 return 1;
207}
208
209static int set_irq(pss_confdata * devc, int dev, int irq)
210{
211 static unsigned short irq_bits[16] =
212 {
213 0x0000, 0x0000, 0x0000, 0x0008,
214 0x0000, 0x0010, 0x0000, 0x0018,
215 0x0000, 0x0020, 0x0028, 0x0030,
216 0x0038, 0x0000, 0x0000, 0x0000
217 };
218
219 unsigned short tmp, bits;
220
221 if (irq < 0 || irq > 15)
222 return 0;
223
224 tmp = inw(REG(dev)) & ~0x38; /* Load confreg, mask IRQ bits out */
225
226 if ((bits = irq_bits[irq]) == 0 && irq != 0)
227 {
228 printk(KERN_ERR "PSS: Invalid IRQ %d\n", irq);
229 return 0;
230 }
231 outw(tmp | bits, REG(dev));
232 return 1;
233}
234
Jeff Garzikffce7a82008-02-06 01:36:15 -0800235static void set_io_base(pss_confdata * devc, int dev, int base)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236{
237 unsigned short tmp = inw(REG(dev)) & 0x003f;
238 unsigned short bits = (base & 0x0ffc) << 4;
239
240 outw(bits | tmp, REG(dev));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241}
242
243static int set_dma(pss_confdata * devc, int dev, int dma)
244{
245 static unsigned short dma_bits[8] =
246 {
247 0x0001, 0x0002, 0x0000, 0x0003,
248 0x0000, 0x0005, 0x0006, 0x0007
249 };
250
251 unsigned short tmp, bits;
252
253 if (dma < 0 || dma > 7)
254 return 0;
255
256 tmp = inw(REG(dev)) & ~0x07; /* Load confreg, mask DMA bits out */
257
258 if ((bits = dma_bits[dma]) == 0 && dma != 4)
259 {
260 printk(KERN_ERR "PSS: Invalid DMA %d\n", dma);
261 return 0;
262 }
263 outw(tmp | bits, REG(dev));
264 return 1;
265}
266
267static int pss_reset_dsp(pss_confdata * devc)
268{
269 unsigned long i, limit = jiffies + HZ/10;
270
271 outw(0x2000, REG(PSS_CONTROL));
Roel Kluin2fbe74b2009-12-16 16:54:43 +0100272 for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273 inw(REG(PSS_CONTROL));
274 outw(0x0000, REG(PSS_CONTROL));
275 return 1;
276}
277
278static int pss_put_dspword(pss_confdata * devc, unsigned short word)
279{
280 int i, val;
281
282 for (i = 0; i < 327680; i++)
283 {
284 val = inw(REG(PSS_STATUS));
285 if (val & PSS_WRITE_EMPTY)
286 {
287 outw(word, REG(PSS_DATA));
288 return 1;
289 }
290 }
291 return 0;
292}
293
294static int pss_get_dspword(pss_confdata * devc, unsigned short *word)
295{
296 int i, val;
297
298 for (i = 0; i < 327680; i++)
299 {
300 val = inw(REG(PSS_STATUS));
301 if (val & PSS_READ_FULL)
302 {
303 *word = inw(REG(PSS_DATA));
304 return 1;
305 }
306 }
307 return 0;
308}
309
310static int pss_download_boot(pss_confdata * devc, unsigned char *block, int size, int flags)
311{
312 int i, val, count;
313 unsigned long limit;
314
315 if (flags & CPF_FIRST)
316 {
317/*_____ Warn DSP software that a boot is coming */
318 outw(0x00fe, REG(PSS_DATA));
319
320 limit = jiffies + HZ/10;
321 for (i = 0; i < 32768 && time_before(jiffies, limit); i++)
322 if (inw(REG(PSS_DATA)) == 0x5500)
323 break;
324
325 outw(*block++, REG(PSS_DATA));
326 pss_reset_dsp(devc);
327 }
328 count = 1;
329 while ((flags&CPF_LAST) || count<size )
330 {
331 int j;
332
333 for (j = 0; j < 327670; j++)
334 {
335/*_____ Wait for BG to appear */
336 if (inw(REG(PSS_STATUS)) & PSS_FLAG3)
337 break;
338 }
339
340 if (j == 327670)
341 {
342 /* It's ok we timed out when the file was empty */
343 if (count >= size && flags & CPF_LAST)
344 break;
345 else
346 {
347 printk("\n");
348 printk(KERN_ERR "PSS: Download timeout problems, byte %d=%d\n", count, size);
349 return 0;
350 }
351 }
352/*_____ Send the next byte */
353 if (count >= size)
354 {
355 /* If not data in block send 0xffff */
356 outw (0xffff, REG (PSS_DATA));
357 }
358 else
359 {
360 /*_____ Send the next byte */
361 outw (*block++, REG (PSS_DATA));
362 };
363 count++;
364 }
365
366 if (flags & CPF_LAST)
367 {
368/*_____ Why */
369 outw(0, REG(PSS_DATA));
370
371 limit = jiffies + HZ/10;
Roel Kluin2fbe74b2009-12-16 16:54:43 +0100372 for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 val = inw(REG(PSS_STATUS));
374
375 limit = jiffies + HZ/10;
Roel Kluin2fbe74b2009-12-16 16:54:43 +0100376 for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 {
378 val = inw(REG(PSS_STATUS));
379 if (val & 0x4000)
380 break;
381 }
382
383 /* now read the version */
384 for (i = 0; i < 32000; i++)
385 {
386 val = inw(REG(PSS_STATUS));
387 if (val & PSS_READ_FULL)
388 break;
389 }
390 if (i == 32000)
391 return 0;
392
393 val = inw(REG(PSS_DATA));
394 /* printk( "<PSS: microcode version %d.%d loaded>", val/16, val % 16); */
395 }
396 return 1;
397}
398
399/* Mixer */
400static void set_master_volume(pss_confdata *devc, int left, int right)
401{
402 static unsigned char log_scale[101] = {
403 0xdb, 0xe0, 0xe3, 0xe5, 0xe7, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xed, 0xee,
404 0xef, 0xef, 0xf0, 0xf0, 0xf1, 0xf1, 0xf2, 0xf2, 0xf2, 0xf3, 0xf3, 0xf3,
405 0xf4, 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6, 0xf7,
406 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9,
407 0xf9, 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb,
408 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc,
409 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd,
410 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
411 0xfe, 0xfe, 0xff, 0xff, 0xff
412 };
413 pss_write(devc, 0x0010);
414 pss_write(devc, log_scale[left] | 0x0000);
415 pss_write(devc, 0x0010);
416 pss_write(devc, log_scale[right] | 0x0100);
417}
418
419static void set_synth_volume(pss_confdata *devc, int volume)
420{
421 int vol = ((0x8000*volume)/100L);
422 pss_write(devc, 0x0080);
423 pss_write(devc, vol);
424 pss_write(devc, 0x0081);
425 pss_write(devc, vol);
426}
427
428static void set_bass(pss_confdata *devc, int level)
429{
430 int vol = (int)(((0xfd - 0xf0) * level)/100L) + 0xf0;
431 pss_write(devc, 0x0010);
432 pss_write(devc, vol | 0x0200);
433};
434
435static void set_treble(pss_confdata *devc, int level)
436{
437 int vol = (((0xfd - 0xf0) * level)/100L) + 0xf0;
438 pss_write(devc, 0x0010);
439 pss_write(devc, vol | 0x0300);
440};
441
442static void pss_mixer_reset(pss_confdata *devc)
443{
444 set_master_volume(devc, 33, 33);
445 set_bass(devc, 50);
446 set_treble(devc, 50);
447 set_synth_volume(devc, 30);
448 pss_write (devc, 0x0010);
449 pss_write (devc, 0x0800 | 0xce); /* Stereo */
450
451 if(pss_mixer)
452 {
453 devc->mixer.volume_l = devc->mixer.volume_r = 33;
454 devc->mixer.bass = 50;
455 devc->mixer.treble = 50;
456 devc->mixer.synth = 30;
457 }
458}
459
Hannes Eder5d44aa42009-02-25 22:29:29 +0100460static int set_volume_mono(unsigned __user *p, unsigned int *aleft)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461{
Hannes Eder5d44aa42009-02-25 22:29:29 +0100462 unsigned int left, volume;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463 if (get_user(volume, p))
464 return -EFAULT;
465
466 left = volume & 0xff;
467 if (left > 100)
468 left = 100;
469 *aleft = left;
470 return 0;
471}
472
Hannes Eder5d44aa42009-02-25 22:29:29 +0100473static int set_volume_stereo(unsigned __user *p,
474 unsigned int *aleft,
475 unsigned int *aright)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476{
Hannes Eder5d44aa42009-02-25 22:29:29 +0100477 unsigned int left, right, volume;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478 if (get_user(volume, p))
479 return -EFAULT;
480
481 left = volume & 0xff;
482 if (left > 100)
483 left = 100;
484 right = (volume >> 8) & 0xff;
485 if (right > 100)
486 right = 100;
487 *aleft = left;
488 *aright = right;
489 return 0;
490}
491
492static int ret_vol_mono(int left)
493{
494 return ((left << 8) | left);
495}
496
497static int ret_vol_stereo(int left, int right)
498{
499 return ((right << 8) | left);
500}
501
502static int call_ad_mixer(pss_confdata *devc,unsigned int cmd, void __user *arg)
503{
504 if (devc->ad_mixer_dev != NO_WSS_MIXER)
505 return mixer_devs[devc->ad_mixer_dev]->ioctl(devc->ad_mixer_dev, cmd, arg);
506 else
507 return -EINVAL;
508}
509
510static int pss_mixer_ioctl (int dev, unsigned int cmd, void __user *arg)
511{
512 pss_confdata *devc = mixer_devs[dev]->devc;
513 int cmdf = cmd & 0xff;
514
515 if ((cmdf != SOUND_MIXER_VOLUME) && (cmdf != SOUND_MIXER_BASS) &&
516 (cmdf != SOUND_MIXER_TREBLE) && (cmdf != SOUND_MIXER_SYNTH) &&
517 (cmdf != SOUND_MIXER_DEVMASK) && (cmdf != SOUND_MIXER_STEREODEVS) &&
518 (cmdf != SOUND_MIXER_RECMASK) && (cmdf != SOUND_MIXER_CAPS) &&
519 (cmdf != SOUND_MIXER_RECSRC))
520 {
521 return call_ad_mixer(devc, cmd, arg);
522 }
523
524 if (((cmd >> 8) & 0xff) != 'M')
525 return -EINVAL;
526
527 if (_SIOC_DIR (cmd) & _SIOC_WRITE)
528 {
529 switch (cmdf)
530 {
531 case SOUND_MIXER_RECSRC:
532 if (devc->ad_mixer_dev != NO_WSS_MIXER)
533 return call_ad_mixer(devc, cmd, arg);
534 else
535 {
536 int v;
537 if (get_user(v, (int __user *)arg))
538 return -EFAULT;
539 if (v != 0)
540 return -EINVAL;
541 return 0;
542 }
543 case SOUND_MIXER_VOLUME:
544 if (set_volume_stereo(arg,
545 &devc->mixer.volume_l,
546 &devc->mixer.volume_r))
547 return -EFAULT;
548 set_master_volume(devc, devc->mixer.volume_l,
549 devc->mixer.volume_r);
550 return ret_vol_stereo(devc->mixer.volume_l,
551 devc->mixer.volume_r);
552
553 case SOUND_MIXER_BASS:
554 if (set_volume_mono(arg, &devc->mixer.bass))
555 return -EFAULT;
556 set_bass(devc, devc->mixer.bass);
557 return ret_vol_mono(devc->mixer.bass);
558
559 case SOUND_MIXER_TREBLE:
560 if (set_volume_mono(arg, &devc->mixer.treble))
561 return -EFAULT;
562 set_treble(devc, devc->mixer.treble);
563 return ret_vol_mono(devc->mixer.treble);
564
565 case SOUND_MIXER_SYNTH:
566 if (set_volume_mono(arg, &devc->mixer.synth))
567 return -EFAULT;
568 set_synth_volume(devc, devc->mixer.synth);
569 return ret_vol_mono(devc->mixer.synth);
570
571 default:
572 return -EINVAL;
573 }
574 }
575 else
576 {
577 int val, and_mask = 0, or_mask = 0;
578 /*
579 * Return parameters
580 */
581 switch (cmdf)
582 {
583 case SOUND_MIXER_DEVMASK:
584 if (call_ad_mixer(devc, cmd, arg) == -EINVAL)
585 break;
586 and_mask = ~0;
587 or_mask = SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_SYNTH;
588 break;
589
590 case SOUND_MIXER_STEREODEVS:
591 if (call_ad_mixer(devc, cmd, arg) == -EINVAL)
592 break;
593 and_mask = ~0;
594 or_mask = SOUND_MASK_VOLUME;
595 break;
596
597 case SOUND_MIXER_RECMASK:
598 if (devc->ad_mixer_dev != NO_WSS_MIXER)
599 return call_ad_mixer(devc, cmd, arg);
600 break;
601
602 case SOUND_MIXER_CAPS:
603 if (devc->ad_mixer_dev != NO_WSS_MIXER)
604 return call_ad_mixer(devc, cmd, arg);
605 or_mask = SOUND_CAP_EXCL_INPUT;
606 break;
607
608 case SOUND_MIXER_RECSRC:
609 if (devc->ad_mixer_dev != NO_WSS_MIXER)
610 return call_ad_mixer(devc, cmd, arg);
611 break;
612
613 case SOUND_MIXER_VOLUME:
614 or_mask = ret_vol_stereo(devc->mixer.volume_l, devc->mixer.volume_r);
615 break;
616
617 case SOUND_MIXER_BASS:
618 or_mask = ret_vol_mono(devc->mixer.bass);
619 break;
620
621 case SOUND_MIXER_TREBLE:
622 or_mask = ret_vol_mono(devc->mixer.treble);
623 break;
624
625 case SOUND_MIXER_SYNTH:
626 or_mask = ret_vol_mono(devc->mixer.synth);
627 break;
628 default:
629 return -EINVAL;
630 }
631 if (get_user(val, (int __user *)arg))
632 return -EFAULT;
633 val &= and_mask;
634 val |= or_mask;
635 if (put_user(val, (int __user *)arg))
636 return -EFAULT;
637 return val;
638 }
639}
640
641static struct mixer_operations pss_mixer_operations =
642{
643 .owner = THIS_MODULE,
644 .id = "SOUNDPORT",
645 .name = "PSS-AD1848",
646 .ioctl = pss_mixer_ioctl
647};
648
649static void disable_all_emulations(void)
650{
651 outw(0x0000, REG(CONF_PSS)); /* 0x0400 enables joystick */
652 outw(0x0000, REG(CONF_WSS));
653 outw(0x0000, REG(CONF_SB));
654 outw(0x0000, REG(CONF_MIDI));
655 outw(0x0000, REG(CONF_CDROM));
656}
657
658static void configure_nonsound_components(void)
659{
660 /* Configure Joystick port */
661
662 if(pss_enable_joystick)
663 {
664 outw(0x0400, REG(CONF_PSS)); /* 0x0400 enables joystick */
665 printk(KERN_INFO "PSS: joystick enabled.\n");
666 }
667 else
668 {
669 printk(KERN_INFO "PSS: joystick port not enabled.\n");
670 }
671
672 /* Configure CDROM port */
673
Jeff Garzikffce7a82008-02-06 01:36:15 -0800674 if (pss_cdrom_port == -1) { /* If cdrom port enablation wasn't requested */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675 printk(KERN_INFO "PSS: CDROM port not enabled.\n");
Jeff Garzikffce7a82008-02-06 01:36:15 -0800676 } else if (check_region(pss_cdrom_port, 2)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677 printk(KERN_ERR "PSS: CDROM I/O port conflict.\n");
Jeff Garzikffce7a82008-02-06 01:36:15 -0800678 } else {
679 set_io_base(devc, CONF_CDROM, pss_cdrom_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680 printk(KERN_INFO "PSS: CDROM I/O port set to 0x%x.\n", pss_cdrom_port);
681 }
682}
683
684static int __init attach_pss(struct address_info *hw_config)
685{
686 unsigned short id;
687 char tmp[100];
688
689 devc->base = hw_config->io_base;
690 devc->irq = hw_config->irq;
691 devc->dma = hw_config->dma;
692 devc->osp = hw_config->osp;
693 devc->ad_mixer_dev = NO_WSS_MIXER;
694
695 if (!probe_pss(hw_config))
696 return 0;
697
698 id = inw(REG(PSS_ID)) & 0x00ff;
699
700 /*
701 * Disable all emulations. Will be enabled later (if required).
702 */
703
704 disable_all_emulations();
705
Olaf Hering44456d32005-07-27 11:45:17 -0700706#ifdef YOU_REALLY_WANT_TO_ALLOCATE_THESE_RESOURCES
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707 if (sound_alloc_dma(hw_config->dma, "PSS"))
708 {
709 printk("pss.c: Can't allocate DMA channel.\n");
710 release_region(hw_config->io_base, 0x10);
711 release_region(hw_config->io_base+0x10, 0x9);
712 return 0;
713 }
714 if (!set_irq(devc, CONF_PSS, devc->irq))
715 {
716 printk("PSS: IRQ allocation error.\n");
717 release_region(hw_config->io_base, 0x10);
718 release_region(hw_config->io_base+0x10, 0x9);
719 return 0;
720 }
721 if (!set_dma(devc, CONF_PSS, devc->dma))
722 {
723 printk(KERN_ERR "PSS: DMA allocation error\n");
724 release_region(hw_config->io_base, 0x10);
725 release_region(hw_config->io_base+0x10, 0x9);
726 return 0;
727 }
728#endif
729
730 configure_nonsound_components();
731 pss_initialized = 1;
732 sprintf(tmp, "ECHO-PSS Rev. %d", id);
733 conf_printf(tmp, hw_config);
734 return 1;
735}
736
737static int __init probe_pss_mpu(struct address_info *hw_config)
738{
739 struct resource *ports;
740 int timeout;
741
742 if (!pss_initialized)
743 return 0;
744
745 ports = request_region(hw_config->io_base, 2, "mpu401");
746
747 if (!ports) {
748 printk(KERN_ERR "PSS: MPU I/O port conflict\n");
749 return 0;
750 }
Jeff Garzikffce7a82008-02-06 01:36:15 -0800751 set_io_base(devc, CONF_MIDI, hw_config->io_base);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752 if (!set_irq(devc, CONF_MIDI, hw_config->irq)) {
753 printk(KERN_ERR "PSS: MIDI IRQ allocation error.\n");
754 goto fail;
755 }
756 if (!pss_synthLen) {
757 printk(KERN_ERR "PSS: Can't enable MPU. MIDI synth microcode not available.\n");
758 goto fail;
759 }
760 if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST)) {
761 printk(KERN_ERR "PSS: Unable to load MIDI synth microcode to DSP.\n");
762 goto fail;
763 }
764
765 /*
766 * Finally wait until the DSP algorithm has initialized itself and
767 * deactivates receive interrupt.
768 */
769
770 for (timeout = 900000; timeout > 0; timeout--)
771 {
772 if ((inb(hw_config->io_base + 1) & 0x80) == 0) /* Input data avail */
773 inb(hw_config->io_base); /* Discard it */
774 else
775 break; /* No more input */
776 }
777
778 if (!probe_mpu401(hw_config, ports))
779 goto fail;
780
781 attach_mpu401(hw_config, THIS_MODULE); /* Slot 1 */
782 if (hw_config->slots[1] != -1) /* The MPU driver installed itself */
783 midi_devs[hw_config->slots[1]]->coproc = &pss_coproc_operations;
784 return 1;
785fail:
786 release_region(hw_config->io_base, 2);
787 return 0;
788}
789
790static int pss_coproc_open(void *dev_info, int sub_device)
791{
792 switch (sub_device)
793 {
794 case COPR_MIDI:
795 if (pss_synthLen == 0)
796 {
797 printk(KERN_ERR "PSS: MIDI synth microcode not available.\n");
798 return -EIO;
799 }
800 if (nonstandard_microcode)
801 if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
802 {
803 printk(KERN_ERR "PSS: Unable to load MIDI synth microcode to DSP.\n");
804 return -EIO;
805 }
806 nonstandard_microcode = 0;
807 break;
808
809 default:
810 break;
811 }
812 return 0;
813}
814
815static void pss_coproc_close(void *dev_info, int sub_device)
816{
817 return;
818}
819
820static void pss_coproc_reset(void *dev_info)
821{
822 if (pss_synthLen)
823 if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
824 {
825 printk(KERN_ERR "PSS: Unable to load MIDI synth microcode to DSP.\n");
826 }
827 nonstandard_microcode = 0;
828}
829
830static int download_boot_block(void *dev_info, copr_buffer * buf)
831{
832 if (buf->len <= 0 || buf->len > sizeof(buf->data))
833 return -EINVAL;
834
835 if (!pss_download_boot(devc, buf->data, buf->len, buf->flags))
836 {
837 printk(KERN_ERR "PSS: Unable to load microcode block to DSP.\n");
838 return -EIO;
839 }
840 nonstandard_microcode = 1; /* The MIDI microcode has been overwritten */
841 return 0;
842}
843
844static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, void __user *arg, int local)
845{
846 copr_buffer *buf;
847 copr_msg *mbuf;
848 copr_debug_buf dbuf;
849 unsigned short tmp;
850 unsigned long flags;
851 unsigned short *data;
852 int i, err;
853 /* printk( "PSS coproc ioctl %x %x %d\n", cmd, arg, local); */
854
855 switch (cmd)
856 {
857 case SNDCTL_COPR_RESET:
858 pss_coproc_reset(dev_info);
859 return 0;
860
861 case SNDCTL_COPR_LOAD:
Jesper Juhlea7dd252010-11-09 00:11:03 +0100862 buf = vmalloc(sizeof(copr_buffer));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700863 if (buf == NULL)
864 return -ENOSPC;
865 if (copy_from_user(buf, arg, sizeof(copr_buffer))) {
866 vfree(buf);
867 return -EFAULT;
868 }
869 err = download_boot_block(dev_info, buf);
870 vfree(buf);
871 return err;
872
873 case SNDCTL_COPR_SENDMSG:
Jesper Juhlea7dd252010-11-09 00:11:03 +0100874 mbuf = vmalloc(sizeof(copr_msg));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875 if (mbuf == NULL)
876 return -ENOSPC;
877 if (copy_from_user(mbuf, arg, sizeof(copr_msg))) {
878 vfree(mbuf);
879 return -EFAULT;
880 }
881 data = (unsigned short *)(mbuf->data);
882 spin_lock_irqsave(&lock, flags);
883 for (i = 0; i < mbuf->len; i++) {
884 if (!pss_put_dspword(devc, *data++)) {
885 spin_unlock_irqrestore(&lock,flags);
886 mbuf->len = i; /* feed back number of WORDs sent */
887 err = copy_to_user(arg, mbuf, sizeof(copr_msg));
888 vfree(mbuf);
889 return err ? -EFAULT : -EIO;
890 }
891 }
892 spin_unlock_irqrestore(&lock,flags);
893 vfree(mbuf);
894 return 0;
895
896 case SNDCTL_COPR_RCVMSG:
897 err = 0;
Jesper Juhlea7dd252010-11-09 00:11:03 +0100898 mbuf = vmalloc(sizeof(copr_msg));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700899 if (mbuf == NULL)
900 return -ENOSPC;
901 data = (unsigned short *)mbuf->data;
902 spin_lock_irqsave(&lock, flags);
903 for (i = 0; i < sizeof(mbuf->data)/sizeof(unsigned short); i++) {
904 mbuf->len = i; /* feed back number of WORDs read */
905 if (!pss_get_dspword(devc, data++)) {
906 if (i == 0)
907 err = -EIO;
908 break;
909 }
910 }
911 spin_unlock_irqrestore(&lock,flags);
912 if (copy_to_user(arg, mbuf, sizeof(copr_msg)))
913 err = -EFAULT;
914 vfree(mbuf);
915 return err;
916
917 case SNDCTL_COPR_RDATA:
918 if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
919 return -EFAULT;
920 spin_lock_irqsave(&lock, flags);
921 if (!pss_put_dspword(devc, 0x00d0)) {
922 spin_unlock_irqrestore(&lock,flags);
923 return -EIO;
924 }
925 if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
926 spin_unlock_irqrestore(&lock,flags);
927 return -EIO;
928 }
929 if (!pss_get_dspword(devc, &tmp)) {
930 spin_unlock_irqrestore(&lock,flags);
931 return -EIO;
932 }
933 dbuf.parm1 = tmp;
934 spin_unlock_irqrestore(&lock,flags);
935 if (copy_to_user(arg, &dbuf, sizeof(dbuf)))
936 return -EFAULT;
937 return 0;
938
939 case SNDCTL_COPR_WDATA:
940 if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
941 return -EFAULT;
942 spin_lock_irqsave(&lock, flags);
943 if (!pss_put_dspword(devc, 0x00d1)) {
944 spin_unlock_irqrestore(&lock,flags);
945 return -EIO;
946 }
947 if (!pss_put_dspword(devc, (unsigned short) (dbuf.parm1 & 0xffff))) {
948 spin_unlock_irqrestore(&lock,flags);
949 return -EIO;
950 }
951 tmp = (unsigned int)dbuf.parm2 & 0xffff;
952 if (!pss_put_dspword(devc, tmp)) {
953 spin_unlock_irqrestore(&lock,flags);
954 return -EIO;
955 }
956 spin_unlock_irqrestore(&lock,flags);
957 return 0;
958
959 case SNDCTL_COPR_WCODE:
960 if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
961 return -EFAULT;
962 spin_lock_irqsave(&lock, flags);
963 if (!pss_put_dspword(devc, 0x00d3)) {
964 spin_unlock_irqrestore(&lock,flags);
965 return -EIO;
966 }
967 if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
968 spin_unlock_irqrestore(&lock,flags);
969 return -EIO;
970 }
971 tmp = (unsigned int)dbuf.parm2 & 0x00ff;
972 if (!pss_put_dspword(devc, tmp)) {
973 spin_unlock_irqrestore(&lock,flags);
974 return -EIO;
975 }
976 tmp = ((unsigned int)dbuf.parm2 >> 8) & 0xffff;
977 if (!pss_put_dspword(devc, tmp)) {
978 spin_unlock_irqrestore(&lock,flags);
979 return -EIO;
980 }
981 spin_unlock_irqrestore(&lock,flags);
982 return 0;
983
984 case SNDCTL_COPR_RCODE:
985 if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
986 return -EFAULT;
987 spin_lock_irqsave(&lock, flags);
988 if (!pss_put_dspword(devc, 0x00d2)) {
989 spin_unlock_irqrestore(&lock,flags);
990 return -EIO;
991 }
992 if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
993 spin_unlock_irqrestore(&lock,flags);
994 return -EIO;
995 }
996 if (!pss_get_dspword(devc, &tmp)) { /* Read MSB */
997 spin_unlock_irqrestore(&lock,flags);
998 return -EIO;
999 }
1000 dbuf.parm1 = tmp << 8;
1001 if (!pss_get_dspword(devc, &tmp)) { /* Read LSB */
1002 spin_unlock_irqrestore(&lock,flags);
1003 return -EIO;
1004 }
1005 dbuf.parm1 |= tmp & 0x00ff;
1006 spin_unlock_irqrestore(&lock,flags);
1007 if (copy_to_user(arg, &dbuf, sizeof(dbuf)))
1008 return -EFAULT;
1009 return 0;
1010
1011 default:
1012 return -EINVAL;
1013 }
1014 return -EINVAL;
1015}
1016
1017static coproc_operations pss_coproc_operations =
1018{
1019 "ADSP-2115",
1020 THIS_MODULE,
1021 pss_coproc_open,
1022 pss_coproc_close,
1023 pss_coproc_ioctl,
1024 pss_coproc_reset,
1025 &pss_data
1026};
1027
1028static int __init probe_pss_mss(struct address_info *hw_config)
1029{
1030 volatile int timeout;
1031 struct resource *ports;
1032 int my_mix = -999; /* gcc shut up */
1033
1034 if (!pss_initialized)
1035 return 0;
1036
1037 if (!request_region(hw_config->io_base, 4, "WSS config")) {
1038 printk(KERN_ERR "PSS: WSS I/O port conflicts.\n");
1039 return 0;
1040 }
1041 ports = request_region(hw_config->io_base + 4, 4, "ad1848");
1042 if (!ports) {
1043 printk(KERN_ERR "PSS: WSS I/O port conflicts.\n");
1044 release_region(hw_config->io_base, 4);
1045 return 0;
1046 }
Jeff Garzikffce7a82008-02-06 01:36:15 -08001047 set_io_base(devc, CONF_WSS, hw_config->io_base);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048 if (!set_irq(devc, CONF_WSS, hw_config->irq)) {
1049 printk("PSS: WSS IRQ allocation error.\n");
1050 goto fail;
1051 }
1052 if (!set_dma(devc, CONF_WSS, hw_config->dma)) {
1053 printk(KERN_ERR "PSS: WSS DMA allocation error\n");
1054 goto fail;
1055 }
1056 /*
1057 * For some reason the card returns 0xff in the WSS status register
1058 * immediately after boot. Probably MIDI+SB emulation algorithm
1059 * downloaded to the ADSP2115 spends some time initializing the card.
1060 * Let's try to wait until it finishes this task.
1061 */
1062 for (timeout = 0; timeout < 100000 && (inb(hw_config->io_base + WSS_INDEX) &
1063 WSS_INITIALIZING); timeout++)
1064 ;
1065
1066 outb((0x0b), hw_config->io_base + WSS_INDEX); /* Required by some cards */
1067
1068 for (timeout = 0; (inb(hw_config->io_base + WSS_DATA) & WSS_AUTOCALIBRATION) &&
1069 (timeout < 100000); timeout++)
1070 ;
1071
1072 if (!probe_ms_sound(hw_config, ports))
1073 goto fail;
1074
1075 devc->ad_mixer_dev = NO_WSS_MIXER;
1076 if (pss_mixer)
1077 {
1078 if ((my_mix = sound_install_mixer (MIXER_DRIVER_VERSION,
1079 "PSS-SPEAKERS and AD1848 (through MSS audio codec)",
1080 &pss_mixer_operations,
1081 sizeof (struct mixer_operations),
1082 devc)) < 0)
1083 {
1084 printk(KERN_ERR "Could not install PSS mixer\n");
1085 goto fail;
1086 }
1087 }
1088 pss_mixer_reset(devc);
1089 attach_ms_sound(hw_config, ports, THIS_MODULE); /* Slot 0 */
1090
1091 if (hw_config->slots[0] != -1)
1092 {
1093 /* The MSS driver installed itself */
1094 audio_devs[hw_config->slots[0]]->coproc = &pss_coproc_operations;
1095 if (pss_mixer && (num_mixers == (my_mix + 2)))
1096 {
1097 /* The MSS mixer installed */
1098 devc->ad_mixer_dev = audio_devs[hw_config->slots[0]]->mixer_dev;
1099 }
1100 }
1101 return 1;
1102fail:
1103 release_region(hw_config->io_base + 4, 4);
1104 release_region(hw_config->io_base, 4);
1105 return 0;
1106}
1107
1108static inline void __exit unload_pss(struct address_info *hw_config)
1109{
1110 release_region(hw_config->io_base, 0x10);
1111 release_region(hw_config->io_base+0x10, 0x9);
1112}
1113
1114static inline void __exit unload_pss_mpu(struct address_info *hw_config)
1115{
1116 unload_mpu401(hw_config);
1117}
1118
1119static inline void __exit unload_pss_mss(struct address_info *hw_config)
1120{
1121 unload_ms_sound(hw_config);
1122}
1123
1124
1125static struct address_info cfg;
1126static struct address_info cfg2;
1127static struct address_info cfg_mpu;
1128
1129static int pss_io __initdata = -1;
1130static int mss_io __initdata = -1;
1131static int mss_irq __initdata = -1;
1132static int mss_dma __initdata = -1;
1133static int mpu_io __initdata = -1;
1134static int mpu_irq __initdata = -1;
1135static int pss_no_sound = 0; /* Just configure non-sound components */
1136static int pss_keep_settings = 1; /* Keep hardware settings at module exit */
1137static char *pss_firmware = "/etc/sound/pss_synth";
1138
1139module_param(pss_io, int, 0);
1140MODULE_PARM_DESC(pss_io, "Set i/o base of PSS card (probably 0x220 or 0x240)");
1141module_param(mss_io, int, 0);
1142MODULE_PARM_DESC(mss_io, "Set WSS (audio) i/o base (0x530, 0x604, 0xE80, 0xF40, or other. Address must end in 0 or 4 and must be from 0x100 to 0xFF4)");
1143module_param(mss_irq, int, 0);
1144MODULE_PARM_DESC(mss_irq, "Set WSS (audio) IRQ (3, 5, 7, 9, 10, 11, 12)");
1145module_param(mss_dma, int, 0);
1146MODULE_PARM_DESC(mss_dma, "Set WSS (audio) DMA (0, 1, 3)");
1147module_param(mpu_io, int, 0);
1148MODULE_PARM_DESC(mpu_io, "Set MIDI i/o base (0x330 or other. Address must be on 4 location boundaries and must be from 0x100 to 0xFFC)");
1149module_param(mpu_irq, int, 0);
1150MODULE_PARM_DESC(mpu_irq, "Set MIDI IRQ (3, 5, 7, 9, 10, 11, 12)");
1151module_param(pss_cdrom_port, int, 0);
1152MODULE_PARM_DESC(pss_cdrom_port, "Set the PSS CDROM port i/o base (0x340 or other)");
1153module_param(pss_enable_joystick, bool, 0);
1154MODULE_PARM_DESC(pss_enable_joystick, "Enables the PSS joystick port (1 to enable, 0 to disable)");
1155module_param(pss_no_sound, bool, 0);
1156MODULE_PARM_DESC(pss_no_sound, "Configure sound compoents (0 - no, 1 - yes)");
1157module_param(pss_keep_settings, bool, 0);
1158MODULE_PARM_DESC(pss_keep_settings, "Keep hardware setting at driver unloading (0 - no, 1 - yes)");
1159module_param(pss_firmware, charp, 0);
1160MODULE_PARM_DESC(pss_firmware, "Location of the firmware file (default - /etc/sound/pss_synth)");
1161module_param(pss_mixer, bool, 0);
1162MODULE_PARM_DESC(pss_mixer, "Enable (1) or disable (0) PSS mixer (controlling of output volume, bass, treble, synth volume). The mixer is not available on all PSS cards.");
1163MODULE_AUTHOR("Hannu Savolainen, Vladimir Michl");
1164MODULE_DESCRIPTION("Module for PSS sound cards (based on AD1848, ADSP-2115 and ESC614). This module includes control of output amplifier and synth volume of the Beethoven ADSP-16 card (this may work with other PSS cards).");
1165MODULE_LICENSE("GPL");
1166
1167
1168static int fw_load = 0;
1169static int pssmpu = 0, pssmss = 0;
1170
1171/*
1172 * Load a PSS sound card module
1173 */
1174
1175static int __init init_pss(void)
1176{
1177
1178 if(pss_no_sound) /* If configuring only nonsound components */
1179 {
1180 cfg.io_base = pss_io;
1181 if(!probe_pss(&cfg))
1182 return -ENODEV;
1183 printk(KERN_INFO "ECHO-PSS Rev. %d\n", inw(REG(PSS_ID)) & 0x00ff);
1184 printk(KERN_INFO "PSS: loading in no sound mode.\n");
1185 disable_all_emulations();
1186 configure_nonsound_components();
1187 release_region(pss_io, 0x10);
1188 release_region(pss_io + 0x10, 0x9);
1189 return 0;
1190 }
1191
1192 cfg.io_base = pss_io;
1193
1194 cfg2.io_base = mss_io;
1195 cfg2.irq = mss_irq;
1196 cfg2.dma = mss_dma;
1197
1198 cfg_mpu.io_base = mpu_io;
1199 cfg_mpu.irq = mpu_irq;
1200
1201 if (cfg.io_base == -1 || cfg2.io_base == -1 || cfg2.irq == -1 || cfg.dma == -1) {
1202 printk(KERN_INFO "pss: mss_io, mss_dma, mss_irq and pss_io must be set.\n");
1203 return -EINVAL;
1204 }
1205
1206 if (!pss_synth) {
1207 fw_load = 1;
1208 pss_synthLen = mod_firmware_load(pss_firmware, (void *) &pss_synth);
1209 }
1210 if (!attach_pss(&cfg))
1211 return -ENODEV;
1212 /*
1213 * Attach stuff
1214 */
1215 if (probe_pss_mpu(&cfg_mpu))
1216 pssmpu = 1;
1217
1218 if (probe_pss_mss(&cfg2))
1219 pssmss = 1;
1220
1221 return 0;
1222}
1223
1224static void __exit cleanup_pss(void)
1225{
1226 if(!pss_no_sound)
1227 {
1228 if(fw_load && pss_synth)
1229 vfree(pss_synth);
1230 if(pssmss)
1231 unload_pss_mss(&cfg2);
1232 if(pssmpu)
1233 unload_pss_mpu(&cfg_mpu);
1234 unload_pss(&cfg);
1235 }
1236
1237 if(!pss_keep_settings) /* Keep hardware settings if asked */
1238 {
1239 disable_all_emulations();
1240 printk(KERN_INFO "Resetting PSS sound card configurations.\n");
1241 }
1242}
1243
1244module_init(init_pss);
1245module_exit(cleanup_pss);
1246
1247#ifndef MODULE
1248static int __init setup_pss(char *str)
1249{
1250 /* io, mss_io, mss_irq, mss_dma, mpu_io, mpu_irq */
1251 int ints[7];
1252
1253 str = get_options(str, ARRAY_SIZE(ints), ints);
1254
1255 pss_io = ints[1];
1256 mss_io = ints[2];
1257 mss_irq = ints[3];
1258 mss_dma = ints[4];
1259 mpu_io = ints[5];
1260 mpu_irq = ints[6];
1261
1262 return 1;
1263}
1264
1265__setup("pss=", setup_pss);
1266#endif