blob: 81314f9e2ccb9c8bffccdc699cca698820081625 [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
Rusty Russella67ff6a2011-12-15 13:49:36 +1030120static bool pss_mixer = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121#else
Rusty Russella67ff6a2011-12-15 13:49:36 +1030122static bool pss_mixer;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123#endif
124
125
Himangi Saraogi81cb6b62014-08-05 18:56:47 +0530126struct pss_mixerdata {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127 unsigned int volume_l;
128 unsigned int volume_r;
129 unsigned int bass;
130 unsigned int treble;
131 unsigned int synth;
Himangi Saraogi81cb6b62014-08-05 18:56:47 +0530132};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133
Himangi Saraogi81cb6b62014-08-05 18:56:47 +0530134struct pss_confdata {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135 int base;
136 int irq;
137 int dma;
138 int *osp;
Himangi Saraogi81cb6b62014-08-05 18:56:47 +0530139 struct pss_mixerdata mixer;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140 int ad_mixer_dev;
Himangi Saraogi81cb6b62014-08-05 18:56:47 +0530141};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142
Himangi Saraogi81cb6b62014-08-05 18:56:47 +0530143static struct pss_confdata pss_data;
144static struct pss_confdata *devc = &pss_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145static DEFINE_SPINLOCK(lock);
146
147static int pss_initialized;
148static int nonstandard_microcode;
149static int pss_cdrom_port = -1; /* Parameter for the PSS cdrom port */
Rusty Russella67ff6a2011-12-15 13:49:36 +1030150static bool pss_enable_joystick; /* Parameter for enabling the joystick */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151static coproc_operations pss_coproc_operations;
152
Himangi Saraogi81cb6b62014-08-05 18:56:47 +0530153static void pss_write(struct pss_confdata *devc, int data)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154{
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
Himangi Saraogi81cb6b62014-08-05 18:56:47 +0530209static int set_irq(struct pss_confdata *devc, int dev, int irq)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210{
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
Himangi Saraogi81cb6b62014-08-05 18:56:47 +0530235static void set_io_base(struct 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
Himangi Saraogi81cb6b62014-08-05 18:56:47 +0530243static int set_dma(struct pss_confdata *devc, int dev, int dma)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244{
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
Himangi Saraogi81cb6b62014-08-05 18:56:47 +0530267static int pss_reset_dsp(struct pss_confdata *devc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268{
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
Himangi Saraogi81cb6b62014-08-05 18:56:47 +0530278static int pss_put_dspword(struct pss_confdata *devc, unsigned short word)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279{
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
Himangi Saraogi81cb6b62014-08-05 18:56:47 +0530294static int pss_get_dspword(struct pss_confdata *devc, unsigned short *word)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295{
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
Himangi Saraogi81cb6b62014-08-05 18:56:47 +0530310static int pss_download_boot(struct pss_confdata *devc, unsigned char *block,
311 int size, int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312{
313 int i, val, count;
314 unsigned long limit;
315
316 if (flags & CPF_FIRST)
317 {
318/*_____ Warn DSP software that a boot is coming */
319 outw(0x00fe, REG(PSS_DATA));
320
321 limit = jiffies + HZ/10;
322 for (i = 0; i < 32768 && time_before(jiffies, limit); i++)
323 if (inw(REG(PSS_DATA)) == 0x5500)
324 break;
325
326 outw(*block++, REG(PSS_DATA));
327 pss_reset_dsp(devc);
328 }
329 count = 1;
330 while ((flags&CPF_LAST) || count<size )
331 {
332 int j;
333
334 for (j = 0; j < 327670; j++)
335 {
336/*_____ Wait for BG to appear */
337 if (inw(REG(PSS_STATUS)) & PSS_FLAG3)
338 break;
339 }
340
341 if (j == 327670)
342 {
343 /* It's ok we timed out when the file was empty */
344 if (count >= size && flags & CPF_LAST)
345 break;
346 else
347 {
348 printk("\n");
349 printk(KERN_ERR "PSS: Download timeout problems, byte %d=%d\n", count, size);
350 return 0;
351 }
352 }
353/*_____ Send the next byte */
354 if (count >= size)
355 {
356 /* If not data in block send 0xffff */
357 outw (0xffff, REG (PSS_DATA));
358 }
359 else
360 {
361 /*_____ Send the next byte */
362 outw (*block++, REG (PSS_DATA));
Peter Senna Tschudin395d9dd2012-09-28 11:24:57 +0200363 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364 count++;
365 }
366
367 if (flags & CPF_LAST)
368 {
369/*_____ Why */
370 outw(0, REG(PSS_DATA));
371
372 limit = jiffies + HZ/10;
Roel Kluin2fbe74b2009-12-16 16:54:43 +0100373 for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 val = inw(REG(PSS_STATUS));
375
376 limit = jiffies + HZ/10;
Roel Kluin2fbe74b2009-12-16 16:54:43 +0100377 for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378 {
379 val = inw(REG(PSS_STATUS));
380 if (val & 0x4000)
381 break;
382 }
383
384 /* now read the version */
385 for (i = 0; i < 32000; i++)
386 {
387 val = inw(REG(PSS_STATUS));
388 if (val & PSS_READ_FULL)
389 break;
390 }
391 if (i == 32000)
392 return 0;
393
394 val = inw(REG(PSS_DATA));
395 /* printk( "<PSS: microcode version %d.%d loaded>", val/16, val % 16); */
396 }
397 return 1;
398}
399
400/* Mixer */
Himangi Saraogi81cb6b62014-08-05 18:56:47 +0530401static void set_master_volume(struct pss_confdata *devc, int left, int right)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402{
403 static unsigned char log_scale[101] = {
404 0xdb, 0xe0, 0xe3, 0xe5, 0xe7, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xed, 0xee,
405 0xef, 0xef, 0xf0, 0xf0, 0xf1, 0xf1, 0xf2, 0xf2, 0xf2, 0xf3, 0xf3, 0xf3,
406 0xf4, 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6, 0xf7,
407 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9,
408 0xf9, 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb,
409 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc,
410 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd,
411 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
412 0xfe, 0xfe, 0xff, 0xff, 0xff
413 };
414 pss_write(devc, 0x0010);
415 pss_write(devc, log_scale[left] | 0x0000);
416 pss_write(devc, 0x0010);
417 pss_write(devc, log_scale[right] | 0x0100);
418}
419
Himangi Saraogi81cb6b62014-08-05 18:56:47 +0530420static void set_synth_volume(struct pss_confdata *devc, int volume)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421{
422 int vol = ((0x8000*volume)/100L);
423 pss_write(devc, 0x0080);
424 pss_write(devc, vol);
425 pss_write(devc, 0x0081);
426 pss_write(devc, vol);
427}
428
Himangi Saraogi81cb6b62014-08-05 18:56:47 +0530429static void set_bass(struct pss_confdata *devc, int level)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430{
431 int vol = (int)(((0xfd - 0xf0) * level)/100L) + 0xf0;
432 pss_write(devc, 0x0010);
433 pss_write(devc, vol | 0x0200);
434};
435
Himangi Saraogi81cb6b62014-08-05 18:56:47 +0530436static void set_treble(struct pss_confdata *devc, int level)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437{
438 int vol = (((0xfd - 0xf0) * level)/100L) + 0xf0;
439 pss_write(devc, 0x0010);
440 pss_write(devc, vol | 0x0300);
441};
442
Himangi Saraogi81cb6b62014-08-05 18:56:47 +0530443static void pss_mixer_reset(struct pss_confdata *devc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444{
445 set_master_volume(devc, 33, 33);
446 set_bass(devc, 50);
447 set_treble(devc, 50);
448 set_synth_volume(devc, 30);
449 pss_write (devc, 0x0010);
450 pss_write (devc, 0x0800 | 0xce); /* Stereo */
451
452 if(pss_mixer)
453 {
454 devc->mixer.volume_l = devc->mixer.volume_r = 33;
455 devc->mixer.bass = 50;
456 devc->mixer.treble = 50;
457 devc->mixer.synth = 30;
458 }
459}
460
Hannes Eder5d44aa42009-02-25 22:29:29 +0100461static int set_volume_mono(unsigned __user *p, unsigned int *aleft)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462{
Hannes Eder5d44aa42009-02-25 22:29:29 +0100463 unsigned int left, volume;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464 if (get_user(volume, p))
465 return -EFAULT;
466
467 left = volume & 0xff;
468 if (left > 100)
469 left = 100;
470 *aleft = left;
471 return 0;
472}
473
Hannes Eder5d44aa42009-02-25 22:29:29 +0100474static int set_volume_stereo(unsigned __user *p,
475 unsigned int *aleft,
476 unsigned int *aright)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477{
Hannes Eder5d44aa42009-02-25 22:29:29 +0100478 unsigned int left, right, volume;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479 if (get_user(volume, p))
480 return -EFAULT;
481
482 left = volume & 0xff;
483 if (left > 100)
484 left = 100;
485 right = (volume >> 8) & 0xff;
486 if (right > 100)
487 right = 100;
488 *aleft = left;
489 *aright = right;
490 return 0;
491}
492
493static int ret_vol_mono(int left)
494{
495 return ((left << 8) | left);
496}
497
498static int ret_vol_stereo(int left, int right)
499{
500 return ((right << 8) | left);
501}
502
Himangi Saraogi81cb6b62014-08-05 18:56:47 +0530503static int call_ad_mixer(struct pss_confdata *devc, unsigned int cmd,
504 void __user *arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505{
506 if (devc->ad_mixer_dev != NO_WSS_MIXER)
507 return mixer_devs[devc->ad_mixer_dev]->ioctl(devc->ad_mixer_dev, cmd, arg);
508 else
509 return -EINVAL;
510}
511
512static int pss_mixer_ioctl (int dev, unsigned int cmd, void __user *arg)
513{
Himangi Saraogi81cb6b62014-08-05 18:56:47 +0530514 struct pss_confdata *devc = mixer_devs[dev]->devc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515 int cmdf = cmd & 0xff;
516
517 if ((cmdf != SOUND_MIXER_VOLUME) && (cmdf != SOUND_MIXER_BASS) &&
518 (cmdf != SOUND_MIXER_TREBLE) && (cmdf != SOUND_MIXER_SYNTH) &&
519 (cmdf != SOUND_MIXER_DEVMASK) && (cmdf != SOUND_MIXER_STEREODEVS) &&
520 (cmdf != SOUND_MIXER_RECMASK) && (cmdf != SOUND_MIXER_CAPS) &&
521 (cmdf != SOUND_MIXER_RECSRC))
522 {
523 return call_ad_mixer(devc, cmd, arg);
524 }
525
526 if (((cmd >> 8) & 0xff) != 'M')
527 return -EINVAL;
528
529 if (_SIOC_DIR (cmd) & _SIOC_WRITE)
530 {
531 switch (cmdf)
532 {
533 case SOUND_MIXER_RECSRC:
534 if (devc->ad_mixer_dev != NO_WSS_MIXER)
535 return call_ad_mixer(devc, cmd, arg);
536 else
537 {
538 int v;
539 if (get_user(v, (int __user *)arg))
540 return -EFAULT;
541 if (v != 0)
542 return -EINVAL;
543 return 0;
544 }
545 case SOUND_MIXER_VOLUME:
546 if (set_volume_stereo(arg,
547 &devc->mixer.volume_l,
548 &devc->mixer.volume_r))
549 return -EFAULT;
550 set_master_volume(devc, devc->mixer.volume_l,
551 devc->mixer.volume_r);
552 return ret_vol_stereo(devc->mixer.volume_l,
553 devc->mixer.volume_r);
554
555 case SOUND_MIXER_BASS:
556 if (set_volume_mono(arg, &devc->mixer.bass))
557 return -EFAULT;
558 set_bass(devc, devc->mixer.bass);
559 return ret_vol_mono(devc->mixer.bass);
560
561 case SOUND_MIXER_TREBLE:
562 if (set_volume_mono(arg, &devc->mixer.treble))
563 return -EFAULT;
564 set_treble(devc, devc->mixer.treble);
565 return ret_vol_mono(devc->mixer.treble);
566
567 case SOUND_MIXER_SYNTH:
568 if (set_volume_mono(arg, &devc->mixer.synth))
569 return -EFAULT;
570 set_synth_volume(devc, devc->mixer.synth);
571 return ret_vol_mono(devc->mixer.synth);
572
573 default:
574 return -EINVAL;
575 }
576 }
577 else
578 {
579 int val, and_mask = 0, or_mask = 0;
580 /*
581 * Return parameters
582 */
583 switch (cmdf)
584 {
585 case SOUND_MIXER_DEVMASK:
586 if (call_ad_mixer(devc, cmd, arg) == -EINVAL)
587 break;
588 and_mask = ~0;
589 or_mask = SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_SYNTH;
590 break;
591
592 case SOUND_MIXER_STEREODEVS:
593 if (call_ad_mixer(devc, cmd, arg) == -EINVAL)
594 break;
595 and_mask = ~0;
596 or_mask = SOUND_MASK_VOLUME;
597 break;
598
599 case SOUND_MIXER_RECMASK:
600 if (devc->ad_mixer_dev != NO_WSS_MIXER)
601 return call_ad_mixer(devc, cmd, arg);
602 break;
603
604 case SOUND_MIXER_CAPS:
605 if (devc->ad_mixer_dev != NO_WSS_MIXER)
606 return call_ad_mixer(devc, cmd, arg);
607 or_mask = SOUND_CAP_EXCL_INPUT;
608 break;
609
610 case SOUND_MIXER_RECSRC:
611 if (devc->ad_mixer_dev != NO_WSS_MIXER)
612 return call_ad_mixer(devc, cmd, arg);
613 break;
614
615 case SOUND_MIXER_VOLUME:
616 or_mask = ret_vol_stereo(devc->mixer.volume_l, devc->mixer.volume_r);
617 break;
618
619 case SOUND_MIXER_BASS:
620 or_mask = ret_vol_mono(devc->mixer.bass);
621 break;
622
623 case SOUND_MIXER_TREBLE:
624 or_mask = ret_vol_mono(devc->mixer.treble);
625 break;
626
627 case SOUND_MIXER_SYNTH:
628 or_mask = ret_vol_mono(devc->mixer.synth);
629 break;
630 default:
631 return -EINVAL;
632 }
633 if (get_user(val, (int __user *)arg))
634 return -EFAULT;
635 val &= and_mask;
636 val |= or_mask;
637 if (put_user(val, (int __user *)arg))
638 return -EFAULT;
639 return val;
640 }
641}
642
643static struct mixer_operations pss_mixer_operations =
644{
645 .owner = THIS_MODULE,
646 .id = "SOUNDPORT",
647 .name = "PSS-AD1848",
648 .ioctl = pss_mixer_ioctl
649};
650
651static void disable_all_emulations(void)
652{
653 outw(0x0000, REG(CONF_PSS)); /* 0x0400 enables joystick */
654 outw(0x0000, REG(CONF_WSS));
655 outw(0x0000, REG(CONF_SB));
656 outw(0x0000, REG(CONF_MIDI));
657 outw(0x0000, REG(CONF_CDROM));
658}
659
660static void configure_nonsound_components(void)
661{
662 /* Configure Joystick port */
663
664 if(pss_enable_joystick)
665 {
666 outw(0x0400, REG(CONF_PSS)); /* 0x0400 enables joystick */
667 printk(KERN_INFO "PSS: joystick enabled.\n");
668 }
669 else
670 {
671 printk(KERN_INFO "PSS: joystick port not enabled.\n");
672 }
673
674 /* Configure CDROM port */
675
Jeff Garzikffce7a82008-02-06 01:36:15 -0800676 if (pss_cdrom_port == -1) { /* If cdrom port enablation wasn't requested */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677 printk(KERN_INFO "PSS: CDROM port not enabled.\n");
Wang Shaoyan80392902011-08-08 19:10:26 +0800678 } else if (!request_region(pss_cdrom_port, 2, "PSS CDROM")) {
679 pss_cdrom_port = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680 printk(KERN_ERR "PSS: CDROM I/O port conflict.\n");
Jeff Garzikffce7a82008-02-06 01:36:15 -0800681 } else {
682 set_io_base(devc, CONF_CDROM, pss_cdrom_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700683 printk(KERN_INFO "PSS: CDROM I/O port set to 0x%x.\n", pss_cdrom_port);
684 }
685}
686
687static int __init attach_pss(struct address_info *hw_config)
688{
689 unsigned short id;
690 char tmp[100];
691
692 devc->base = hw_config->io_base;
693 devc->irq = hw_config->irq;
694 devc->dma = hw_config->dma;
695 devc->osp = hw_config->osp;
696 devc->ad_mixer_dev = NO_WSS_MIXER;
697
698 if (!probe_pss(hw_config))
699 return 0;
700
701 id = inw(REG(PSS_ID)) & 0x00ff;
702
703 /*
704 * Disable all emulations. Will be enabled later (if required).
705 */
706
707 disable_all_emulations();
708
Olaf Hering44456d32005-07-27 11:45:17 -0700709#ifdef YOU_REALLY_WANT_TO_ALLOCATE_THESE_RESOURCES
Linus Torvalds1da177e2005-04-16 15:20:36 -0700710 if (sound_alloc_dma(hw_config->dma, "PSS"))
711 {
712 printk("pss.c: Can't allocate DMA channel.\n");
713 release_region(hw_config->io_base, 0x10);
714 release_region(hw_config->io_base+0x10, 0x9);
715 return 0;
716 }
717 if (!set_irq(devc, CONF_PSS, devc->irq))
718 {
719 printk("PSS: IRQ allocation error.\n");
720 release_region(hw_config->io_base, 0x10);
721 release_region(hw_config->io_base+0x10, 0x9);
722 return 0;
723 }
724 if (!set_dma(devc, CONF_PSS, devc->dma))
725 {
726 printk(KERN_ERR "PSS: DMA allocation error\n");
727 release_region(hw_config->io_base, 0x10);
728 release_region(hw_config->io_base+0x10, 0x9);
729 return 0;
730 }
731#endif
732
733 configure_nonsound_components();
734 pss_initialized = 1;
735 sprintf(tmp, "ECHO-PSS Rev. %d", id);
736 conf_printf(tmp, hw_config);
737 return 1;
738}
739
740static int __init probe_pss_mpu(struct address_info *hw_config)
741{
742 struct resource *ports;
743 int timeout;
744
745 if (!pss_initialized)
746 return 0;
747
748 ports = request_region(hw_config->io_base, 2, "mpu401");
749
750 if (!ports) {
751 printk(KERN_ERR "PSS: MPU I/O port conflict\n");
752 return 0;
753 }
Jeff Garzikffce7a82008-02-06 01:36:15 -0800754 set_io_base(devc, CONF_MIDI, hw_config->io_base);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755 if (!set_irq(devc, CONF_MIDI, hw_config->irq)) {
756 printk(KERN_ERR "PSS: MIDI IRQ allocation error.\n");
757 goto fail;
758 }
759 if (!pss_synthLen) {
760 printk(KERN_ERR "PSS: Can't enable MPU. MIDI synth microcode not available.\n");
761 goto fail;
762 }
763 if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST)) {
764 printk(KERN_ERR "PSS: Unable to load MIDI synth microcode to DSP.\n");
765 goto fail;
766 }
767
768 /*
769 * Finally wait until the DSP algorithm has initialized itself and
770 * deactivates receive interrupt.
771 */
772
773 for (timeout = 900000; timeout > 0; timeout--)
774 {
775 if ((inb(hw_config->io_base + 1) & 0x80) == 0) /* Input data avail */
776 inb(hw_config->io_base); /* Discard it */
777 else
778 break; /* No more input */
779 }
780
781 if (!probe_mpu401(hw_config, ports))
782 goto fail;
783
784 attach_mpu401(hw_config, THIS_MODULE); /* Slot 1 */
785 if (hw_config->slots[1] != -1) /* The MPU driver installed itself */
786 midi_devs[hw_config->slots[1]]->coproc = &pss_coproc_operations;
787 return 1;
788fail:
789 release_region(hw_config->io_base, 2);
790 return 0;
791}
792
793static int pss_coproc_open(void *dev_info, int sub_device)
794{
795 switch (sub_device)
796 {
797 case COPR_MIDI:
798 if (pss_synthLen == 0)
799 {
800 printk(KERN_ERR "PSS: MIDI synth microcode not available.\n");
801 return -EIO;
802 }
803 if (nonstandard_microcode)
804 if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
805 {
806 printk(KERN_ERR "PSS: Unable to load MIDI synth microcode to DSP.\n");
807 return -EIO;
808 }
809 nonstandard_microcode = 0;
810 break;
811
812 default:
813 break;
814 }
815 return 0;
816}
817
818static void pss_coproc_close(void *dev_info, int sub_device)
819{
820 return;
821}
822
823static void pss_coproc_reset(void *dev_info)
824{
825 if (pss_synthLen)
826 if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
827 {
828 printk(KERN_ERR "PSS: Unable to load MIDI synth microcode to DSP.\n");
829 }
830 nonstandard_microcode = 0;
831}
832
833static int download_boot_block(void *dev_info, copr_buffer * buf)
834{
835 if (buf->len <= 0 || buf->len > sizeof(buf->data))
836 return -EINVAL;
837
838 if (!pss_download_boot(devc, buf->data, buf->len, buf->flags))
839 {
840 printk(KERN_ERR "PSS: Unable to load microcode block to DSP.\n");
841 return -EIO;
842 }
843 nonstandard_microcode = 1; /* The MIDI microcode has been overwritten */
844 return 0;
845}
846
847static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, void __user *arg, int local)
848{
849 copr_buffer *buf;
850 copr_msg *mbuf;
851 copr_debug_buf dbuf;
852 unsigned short tmp;
853 unsigned long flags;
854 unsigned short *data;
855 int i, err;
856 /* printk( "PSS coproc ioctl %x %x %d\n", cmd, arg, local); */
857
858 switch (cmd)
859 {
860 case SNDCTL_COPR_RESET:
861 pss_coproc_reset(dev_info);
862 return 0;
863
864 case SNDCTL_COPR_LOAD:
Jesper Juhlea7dd252010-11-09 00:11:03 +0100865 buf = vmalloc(sizeof(copr_buffer));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866 if (buf == NULL)
867 return -ENOSPC;
868 if (copy_from_user(buf, arg, sizeof(copr_buffer))) {
869 vfree(buf);
870 return -EFAULT;
871 }
872 err = download_boot_block(dev_info, buf);
873 vfree(buf);
874 return err;
875
876 case SNDCTL_COPR_SENDMSG:
Jesper Juhlea7dd252010-11-09 00:11:03 +0100877 mbuf = vmalloc(sizeof(copr_msg));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878 if (mbuf == NULL)
879 return -ENOSPC;
880 if (copy_from_user(mbuf, arg, sizeof(copr_msg))) {
881 vfree(mbuf);
882 return -EFAULT;
883 }
884 data = (unsigned short *)(mbuf->data);
885 spin_lock_irqsave(&lock, flags);
886 for (i = 0; i < mbuf->len; i++) {
887 if (!pss_put_dspword(devc, *data++)) {
888 spin_unlock_irqrestore(&lock,flags);
889 mbuf->len = i; /* feed back number of WORDs sent */
890 err = copy_to_user(arg, mbuf, sizeof(copr_msg));
891 vfree(mbuf);
892 return err ? -EFAULT : -EIO;
893 }
894 }
895 spin_unlock_irqrestore(&lock,flags);
896 vfree(mbuf);
897 return 0;
898
899 case SNDCTL_COPR_RCVMSG:
900 err = 0;
Jesper Juhlea7dd252010-11-09 00:11:03 +0100901 mbuf = vmalloc(sizeof(copr_msg));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902 if (mbuf == NULL)
903 return -ENOSPC;
904 data = (unsigned short *)mbuf->data;
905 spin_lock_irqsave(&lock, flags);
906 for (i = 0; i < sizeof(mbuf->data)/sizeof(unsigned short); i++) {
907 mbuf->len = i; /* feed back number of WORDs read */
908 if (!pss_get_dspword(devc, data++)) {
909 if (i == 0)
910 err = -EIO;
911 break;
912 }
913 }
914 spin_unlock_irqrestore(&lock,flags);
915 if (copy_to_user(arg, mbuf, sizeof(copr_msg)))
916 err = -EFAULT;
917 vfree(mbuf);
918 return err;
919
920 case SNDCTL_COPR_RDATA:
921 if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
922 return -EFAULT;
923 spin_lock_irqsave(&lock, flags);
924 if (!pss_put_dspword(devc, 0x00d0)) {
925 spin_unlock_irqrestore(&lock,flags);
926 return -EIO;
927 }
928 if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
929 spin_unlock_irqrestore(&lock,flags);
930 return -EIO;
931 }
932 if (!pss_get_dspword(devc, &tmp)) {
933 spin_unlock_irqrestore(&lock,flags);
934 return -EIO;
935 }
936 dbuf.parm1 = tmp;
937 spin_unlock_irqrestore(&lock,flags);
938 if (copy_to_user(arg, &dbuf, sizeof(dbuf)))
939 return -EFAULT;
940 return 0;
941
942 case SNDCTL_COPR_WDATA:
943 if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
944 return -EFAULT;
945 spin_lock_irqsave(&lock, flags);
946 if (!pss_put_dspword(devc, 0x00d1)) {
947 spin_unlock_irqrestore(&lock,flags);
948 return -EIO;
949 }
950 if (!pss_put_dspword(devc, (unsigned short) (dbuf.parm1 & 0xffff))) {
951 spin_unlock_irqrestore(&lock,flags);
952 return -EIO;
953 }
954 tmp = (unsigned int)dbuf.parm2 & 0xffff;
955 if (!pss_put_dspword(devc, tmp)) {
956 spin_unlock_irqrestore(&lock,flags);
957 return -EIO;
958 }
959 spin_unlock_irqrestore(&lock,flags);
960 return 0;
961
962 case SNDCTL_COPR_WCODE:
963 if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
964 return -EFAULT;
965 spin_lock_irqsave(&lock, flags);
966 if (!pss_put_dspword(devc, 0x00d3)) {
967 spin_unlock_irqrestore(&lock,flags);
968 return -EIO;
969 }
970 if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
971 spin_unlock_irqrestore(&lock,flags);
972 return -EIO;
973 }
974 tmp = (unsigned int)dbuf.parm2 & 0x00ff;
975 if (!pss_put_dspword(devc, tmp)) {
976 spin_unlock_irqrestore(&lock,flags);
977 return -EIO;
978 }
979 tmp = ((unsigned int)dbuf.parm2 >> 8) & 0xffff;
980 if (!pss_put_dspword(devc, tmp)) {
981 spin_unlock_irqrestore(&lock,flags);
982 return -EIO;
983 }
984 spin_unlock_irqrestore(&lock,flags);
985 return 0;
986
987 case SNDCTL_COPR_RCODE:
988 if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
989 return -EFAULT;
990 spin_lock_irqsave(&lock, flags);
991 if (!pss_put_dspword(devc, 0x00d2)) {
992 spin_unlock_irqrestore(&lock,flags);
993 return -EIO;
994 }
995 if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
996 spin_unlock_irqrestore(&lock,flags);
997 return -EIO;
998 }
999 if (!pss_get_dspword(devc, &tmp)) { /* Read MSB */
1000 spin_unlock_irqrestore(&lock,flags);
1001 return -EIO;
1002 }
1003 dbuf.parm1 = tmp << 8;
1004 if (!pss_get_dspword(devc, &tmp)) { /* Read LSB */
1005 spin_unlock_irqrestore(&lock,flags);
1006 return -EIO;
1007 }
1008 dbuf.parm1 |= tmp & 0x00ff;
1009 spin_unlock_irqrestore(&lock,flags);
1010 if (copy_to_user(arg, &dbuf, sizeof(dbuf)))
1011 return -EFAULT;
1012 return 0;
1013
1014 default:
1015 return -EINVAL;
1016 }
1017 return -EINVAL;
1018}
1019
1020static coproc_operations pss_coproc_operations =
1021{
1022 "ADSP-2115",
1023 THIS_MODULE,
1024 pss_coproc_open,
1025 pss_coproc_close,
1026 pss_coproc_ioctl,
1027 pss_coproc_reset,
1028 &pss_data
1029};
1030
1031static int __init probe_pss_mss(struct address_info *hw_config)
1032{
1033 volatile int timeout;
1034 struct resource *ports;
1035 int my_mix = -999; /* gcc shut up */
1036
1037 if (!pss_initialized)
1038 return 0;
1039
1040 if (!request_region(hw_config->io_base, 4, "WSS config")) {
1041 printk(KERN_ERR "PSS: WSS I/O port conflicts.\n");
1042 return 0;
1043 }
1044 ports = request_region(hw_config->io_base + 4, 4, "ad1848");
1045 if (!ports) {
1046 printk(KERN_ERR "PSS: WSS I/O port conflicts.\n");
1047 release_region(hw_config->io_base, 4);
1048 return 0;
1049 }
Jeff Garzikffce7a82008-02-06 01:36:15 -08001050 set_io_base(devc, CONF_WSS, hw_config->io_base);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051 if (!set_irq(devc, CONF_WSS, hw_config->irq)) {
1052 printk("PSS: WSS IRQ allocation error.\n");
1053 goto fail;
1054 }
1055 if (!set_dma(devc, CONF_WSS, hw_config->dma)) {
1056 printk(KERN_ERR "PSS: WSS DMA allocation error\n");
1057 goto fail;
1058 }
1059 /*
1060 * For some reason the card returns 0xff in the WSS status register
1061 * immediately after boot. Probably MIDI+SB emulation algorithm
1062 * downloaded to the ADSP2115 spends some time initializing the card.
1063 * Let's try to wait until it finishes this task.
1064 */
1065 for (timeout = 0; timeout < 100000 && (inb(hw_config->io_base + WSS_INDEX) &
1066 WSS_INITIALIZING); timeout++)
1067 ;
1068
1069 outb((0x0b), hw_config->io_base + WSS_INDEX); /* Required by some cards */
1070
1071 for (timeout = 0; (inb(hw_config->io_base + WSS_DATA) & WSS_AUTOCALIBRATION) &&
1072 (timeout < 100000); timeout++)
1073 ;
1074
1075 if (!probe_ms_sound(hw_config, ports))
1076 goto fail;
1077
1078 devc->ad_mixer_dev = NO_WSS_MIXER;
1079 if (pss_mixer)
1080 {
1081 if ((my_mix = sound_install_mixer (MIXER_DRIVER_VERSION,
1082 "PSS-SPEAKERS and AD1848 (through MSS audio codec)",
1083 &pss_mixer_operations,
1084 sizeof (struct mixer_operations),
1085 devc)) < 0)
1086 {
1087 printk(KERN_ERR "Could not install PSS mixer\n");
1088 goto fail;
1089 }
1090 }
1091 pss_mixer_reset(devc);
1092 attach_ms_sound(hw_config, ports, THIS_MODULE); /* Slot 0 */
1093
1094 if (hw_config->slots[0] != -1)
1095 {
1096 /* The MSS driver installed itself */
1097 audio_devs[hw_config->slots[0]]->coproc = &pss_coproc_operations;
1098 if (pss_mixer && (num_mixers == (my_mix + 2)))
1099 {
1100 /* The MSS mixer installed */
1101 devc->ad_mixer_dev = audio_devs[hw_config->slots[0]]->mixer_dev;
1102 }
1103 }
1104 return 1;
1105fail:
1106 release_region(hw_config->io_base + 4, 4);
1107 release_region(hw_config->io_base, 4);
1108 return 0;
1109}
1110
1111static inline void __exit unload_pss(struct address_info *hw_config)
1112{
1113 release_region(hw_config->io_base, 0x10);
1114 release_region(hw_config->io_base+0x10, 0x9);
1115}
1116
1117static inline void __exit unload_pss_mpu(struct address_info *hw_config)
1118{
1119 unload_mpu401(hw_config);
1120}
1121
1122static inline void __exit unload_pss_mss(struct address_info *hw_config)
1123{
1124 unload_ms_sound(hw_config);
1125}
1126
1127
1128static struct address_info cfg;
1129static struct address_info cfg2;
1130static struct address_info cfg_mpu;
1131
1132static int pss_io __initdata = -1;
1133static int mss_io __initdata = -1;
1134static int mss_irq __initdata = -1;
1135static int mss_dma __initdata = -1;
1136static int mpu_io __initdata = -1;
1137static int mpu_irq __initdata = -1;
Rusty Russella67ff6a2011-12-15 13:49:36 +10301138static bool pss_no_sound = 0; /* Just configure non-sound components */
1139static bool pss_keep_settings = 1; /* Keep hardware settings at module exit */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140static char *pss_firmware = "/etc/sound/pss_synth";
1141
1142module_param(pss_io, int, 0);
1143MODULE_PARM_DESC(pss_io, "Set i/o base of PSS card (probably 0x220 or 0x240)");
1144module_param(mss_io, int, 0);
1145MODULE_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)");
1146module_param(mss_irq, int, 0);
1147MODULE_PARM_DESC(mss_irq, "Set WSS (audio) IRQ (3, 5, 7, 9, 10, 11, 12)");
1148module_param(mss_dma, int, 0);
1149MODULE_PARM_DESC(mss_dma, "Set WSS (audio) DMA (0, 1, 3)");
1150module_param(mpu_io, int, 0);
1151MODULE_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)");
1152module_param(mpu_irq, int, 0);
1153MODULE_PARM_DESC(mpu_irq, "Set MIDI IRQ (3, 5, 7, 9, 10, 11, 12)");
1154module_param(pss_cdrom_port, int, 0);
1155MODULE_PARM_DESC(pss_cdrom_port, "Set the PSS CDROM port i/o base (0x340 or other)");
1156module_param(pss_enable_joystick, bool, 0);
1157MODULE_PARM_DESC(pss_enable_joystick, "Enables the PSS joystick port (1 to enable, 0 to disable)");
1158module_param(pss_no_sound, bool, 0);
1159MODULE_PARM_DESC(pss_no_sound, "Configure sound compoents (0 - no, 1 - yes)");
1160module_param(pss_keep_settings, bool, 0);
1161MODULE_PARM_DESC(pss_keep_settings, "Keep hardware setting at driver unloading (0 - no, 1 - yes)");
1162module_param(pss_firmware, charp, 0);
1163MODULE_PARM_DESC(pss_firmware, "Location of the firmware file (default - /etc/sound/pss_synth)");
1164module_param(pss_mixer, bool, 0);
1165MODULE_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.");
1166MODULE_AUTHOR("Hannu Savolainen, Vladimir Michl");
1167MODULE_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).");
1168MODULE_LICENSE("GPL");
1169
1170
1171static int fw_load = 0;
1172static int pssmpu = 0, pssmss = 0;
1173
1174/*
1175 * Load a PSS sound card module
1176 */
1177
1178static int __init init_pss(void)
1179{
1180
1181 if(pss_no_sound) /* If configuring only nonsound components */
1182 {
1183 cfg.io_base = pss_io;
1184 if(!probe_pss(&cfg))
1185 return -ENODEV;
1186 printk(KERN_INFO "ECHO-PSS Rev. %d\n", inw(REG(PSS_ID)) & 0x00ff);
1187 printk(KERN_INFO "PSS: loading in no sound mode.\n");
1188 disable_all_emulations();
1189 configure_nonsound_components();
1190 release_region(pss_io, 0x10);
1191 release_region(pss_io + 0x10, 0x9);
1192 return 0;
1193 }
1194
1195 cfg.io_base = pss_io;
1196
1197 cfg2.io_base = mss_io;
1198 cfg2.irq = mss_irq;
1199 cfg2.dma = mss_dma;
1200
1201 cfg_mpu.io_base = mpu_io;
1202 cfg_mpu.irq = mpu_irq;
1203
1204 if (cfg.io_base == -1 || cfg2.io_base == -1 || cfg2.irq == -1 || cfg.dma == -1) {
1205 printk(KERN_INFO "pss: mss_io, mss_dma, mss_irq and pss_io must be set.\n");
1206 return -EINVAL;
1207 }
1208
1209 if (!pss_synth) {
1210 fw_load = 1;
1211 pss_synthLen = mod_firmware_load(pss_firmware, (void *) &pss_synth);
1212 }
1213 if (!attach_pss(&cfg))
1214 return -ENODEV;
1215 /*
1216 * Attach stuff
1217 */
1218 if (probe_pss_mpu(&cfg_mpu))
1219 pssmpu = 1;
1220
1221 if (probe_pss_mss(&cfg2))
1222 pssmss = 1;
1223
1224 return 0;
1225}
1226
1227static void __exit cleanup_pss(void)
1228{
1229 if(!pss_no_sound)
1230 {
Markus Elfringd1f45e62015-01-03 15:10:52 +01001231 if (fw_load)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232 vfree(pss_synth);
1233 if(pssmss)
1234 unload_pss_mss(&cfg2);
1235 if(pssmpu)
1236 unload_pss_mpu(&cfg_mpu);
1237 unload_pss(&cfg);
Wang Shaoyan80392902011-08-08 19:10:26 +08001238 } else if (pss_cdrom_port != -1)
1239 release_region(pss_cdrom_port, 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240
1241 if(!pss_keep_settings) /* Keep hardware settings if asked */
1242 {
1243 disable_all_emulations();
1244 printk(KERN_INFO "Resetting PSS sound card configurations.\n");
1245 }
1246}
1247
1248module_init(init_pss);
1249module_exit(cleanup_pss);
1250
1251#ifndef MODULE
1252static int __init setup_pss(char *str)
1253{
1254 /* io, mss_io, mss_irq, mss_dma, mpu_io, mpu_irq */
1255 int ints[7];
1256
1257 str = get_options(str, ARRAY_SIZE(ints), ints);
1258
1259 pss_io = ints[1];
1260 mss_io = ints[2];
1261 mss_irq = ints[3];
1262 mss_dma = ints[4];
1263 mpu_io = ints[5];
1264 mpu_irq = ints[6];
1265
1266 return 1;
1267}
1268
1269__setup("pss=", setup_pss);
1270#endif