Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.9.
   1/*
   2 * sound/oss/pss.c
   3 *
   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 
  49 *          the driver where the firmware file is located.  The default 
  50 *          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
  60#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
 235static void set_io_base(pss_confdata * devc, int dev, int base)
 236{
 237	unsigned short  tmp = inw(REG(dev)) & 0x003f;
 238	unsigned short  bits = (base & 0x0ffc) << 4;
 239
 240	outw(bits | tmp, REG(dev));
 241}
 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));
 272	for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
 273		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;
 372		for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
 373			val = inw(REG(PSS_STATUS));
 374
 375		limit = jiffies + HZ/10;
 376		for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
 377		{
 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
 460static int set_volume_mono(unsigned __user *p, unsigned int *aleft)
 461{
 462	unsigned int left, volume;
 463	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
 473static int set_volume_stereo(unsigned __user *p,
 474			     unsigned int *aleft,
 475			     unsigned int *aright)
 476{
 477	unsigned int left, right, volume;
 478	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
 674	if (pss_cdrom_port == -1) {	/* If cdrom port enablation wasn't requested */
 675		printk(KERN_INFO "PSS: CDROM port not enabled.\n");
 676	} else if (!request_region(pss_cdrom_port, 2, "PSS CDROM")) {
 677		pss_cdrom_port = -1;
 678		printk(KERN_ERR "PSS: CDROM I/O port conflict.\n");
 679	} else {
 680		set_io_base(devc, CONF_CDROM, pss_cdrom_port);
 681		printk(KERN_INFO "PSS: CDROM I/O port set to 0x%x.\n", pss_cdrom_port);
 682	}
 683}
 684
 685static int __init attach_pss(struct address_info *hw_config)
 686{
 687	unsigned short  id;
 688	char tmp[100];
 689
 690	devc->base = hw_config->io_base;
 691	devc->irq = hw_config->irq;
 692	devc->dma = hw_config->dma;
 693	devc->osp = hw_config->osp;
 694	devc->ad_mixer_dev = NO_WSS_MIXER;
 695
 696	if (!probe_pss(hw_config))
 697		return 0;
 698
 699	id = inw(REG(PSS_ID)) & 0x00ff;
 700
 701	/*
 702	 * Disable all emulations. Will be enabled later (if required).
 703	 */
 704	 
 705	disable_all_emulations();
 706
 707#ifdef YOU_REALLY_WANT_TO_ALLOCATE_THESE_RESOURCES
 708	if (sound_alloc_dma(hw_config->dma, "PSS"))
 709	{
 710		printk("pss.c: Can't allocate DMA channel.\n");
 711		release_region(hw_config->io_base, 0x10);
 712		release_region(hw_config->io_base+0x10, 0x9);
 713		return 0;
 714	}
 715	if (!set_irq(devc, CONF_PSS, devc->irq))
 716	{
 717		printk("PSS: IRQ allocation error.\n");
 718		release_region(hw_config->io_base, 0x10);
 719		release_region(hw_config->io_base+0x10, 0x9);
 720		return 0;
 721	}
 722	if (!set_dma(devc, CONF_PSS, devc->dma))
 723	{
 724		printk(KERN_ERR "PSS: DMA allocation error\n");
 725		release_region(hw_config->io_base, 0x10);
 726		release_region(hw_config->io_base+0x10, 0x9);
 727		return 0;
 728	}
 729#endif
 730
 731	configure_nonsound_components();
 732	pss_initialized = 1;
 733	sprintf(tmp, "ECHO-PSS  Rev. %d", id);
 734	conf_printf(tmp, hw_config);
 735	return 1;
 736}
 737
 738static int __init probe_pss_mpu(struct address_info *hw_config)
 739{
 740	struct resource *ports;
 741	int timeout;
 742
 743	if (!pss_initialized)
 744		return 0;
 745
 746	ports = request_region(hw_config->io_base, 2, "mpu401");
 747
 748	if (!ports) {
 749		printk(KERN_ERR "PSS: MPU I/O port conflict\n");
 750		return 0;
 751	}
 752	set_io_base(devc, CONF_MIDI, hw_config->io_base);
 753	if (!set_irq(devc, CONF_MIDI, hw_config->irq)) {
 754		printk(KERN_ERR "PSS: MIDI IRQ allocation error.\n");
 755		goto fail;
 756	}
 757	if (!pss_synthLen) {
 758		printk(KERN_ERR "PSS: Can't enable MPU. MIDI synth microcode not available.\n");
 759		goto fail;
 760	}
 761	if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST)) {
 762		printk(KERN_ERR "PSS: Unable to load MIDI synth microcode to DSP.\n");
 763		goto fail;
 764	}
 765
 766	/*
 767	 * Finally wait until the DSP algorithm has initialized itself and
 768	 * deactivates receive interrupt.
 769	 */
 770
 771	for (timeout = 900000; timeout > 0; timeout--)
 772	{
 773		if ((inb(hw_config->io_base + 1) & 0x80) == 0)	/* Input data avail */
 774			inb(hw_config->io_base);	/* Discard it */
 775		else
 776			break;	/* No more input */
 777	}
 778
 779	if (!probe_mpu401(hw_config, ports))
 780		goto fail;
 781
 782	attach_mpu401(hw_config, THIS_MODULE);	/* Slot 1 */
 783	if (hw_config->slots[1] != -1)	/* The MPU driver installed itself */
 784		midi_devs[hw_config->slots[1]]->coproc = &pss_coproc_operations;
 785	return 1;
 786fail:
 787	release_region(hw_config->io_base, 2);
 788	return 0;
 789}
 790
 791static int pss_coproc_open(void *dev_info, int sub_device)
 792{
 793	switch (sub_device)
 794	{
 795		case COPR_MIDI:
 796			if (pss_synthLen == 0)
 797			{
 798				printk(KERN_ERR "PSS: MIDI synth microcode not available.\n");
 799				return -EIO;
 800			}
 801			if (nonstandard_microcode)
 802				if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
 803			{
 804				printk(KERN_ERR "PSS: Unable to load MIDI synth microcode to DSP.\n");
 805				return -EIO;
 806			}
 807			nonstandard_microcode = 0;
 808			break;
 809
 810		default:
 811			break;
 812	}
 813	return 0;
 814}
 815
 816static void pss_coproc_close(void *dev_info, int sub_device)
 817{
 818	return;
 819}
 820
 821static void pss_coproc_reset(void *dev_info)
 822{
 823	if (pss_synthLen)
 824		if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
 825		{
 826			printk(KERN_ERR "PSS: Unable to load MIDI synth microcode to DSP.\n");
 827		}
 828	nonstandard_microcode = 0;
 829}
 830
 831static int download_boot_block(void *dev_info, copr_buffer * buf)
 832{
 833	if (buf->len <= 0 || buf->len > sizeof(buf->data))
 834		return -EINVAL;
 835
 836	if (!pss_download_boot(devc, buf->data, buf->len, buf->flags))
 837	{
 838		printk(KERN_ERR "PSS: Unable to load microcode block to DSP.\n");
 839		return -EIO;
 840	}
 841	nonstandard_microcode = 1;	/* The MIDI microcode has been overwritten */
 842	return 0;
 843}
 844
 845static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, void __user *arg, int local)
 846{
 847	copr_buffer *buf;
 848	copr_msg *mbuf;
 849	copr_debug_buf dbuf;
 850	unsigned short tmp;
 851	unsigned long flags;
 852	unsigned short *data;
 853	int i, err;
 854	/* printk( "PSS coproc ioctl %x %x %d\n",  cmd,  arg,  local); */
 855	
 856	switch (cmd) 
 857	{
 858		case SNDCTL_COPR_RESET:
 859			pss_coproc_reset(dev_info);
 860			return 0;
 861
 862		case SNDCTL_COPR_LOAD:
 863			buf = vmalloc(sizeof(copr_buffer));
 864			if (buf == NULL)
 865				return -ENOSPC;
 866			if (copy_from_user(buf, arg, sizeof(copr_buffer))) {
 867				vfree(buf);
 868				return -EFAULT;
 869			}
 870			err = download_boot_block(dev_info, buf);
 871			vfree(buf);
 872			return err;
 873		
 874		case SNDCTL_COPR_SENDMSG:
 875			mbuf = vmalloc(sizeof(copr_msg));
 876			if (mbuf == NULL)
 877				return -ENOSPC;
 878			if (copy_from_user(mbuf, arg, sizeof(copr_msg))) {
 879				vfree(mbuf);
 880				return -EFAULT;
 881			}
 882			data = (unsigned short *)(mbuf->data);
 883			spin_lock_irqsave(&lock, flags);
 884			for (i = 0; i < mbuf->len; i++) {
 885				if (!pss_put_dspword(devc, *data++)) {
 886					spin_unlock_irqrestore(&lock,flags);
 887					mbuf->len = i;	/* feed back number of WORDs sent */
 888					err = copy_to_user(arg, mbuf, sizeof(copr_msg));
 889					vfree(mbuf);
 890					return err ? -EFAULT : -EIO;
 891				}
 892			}
 893			spin_unlock_irqrestore(&lock,flags);
 894			vfree(mbuf);
 895			return 0;
 896
 897		case SNDCTL_COPR_RCVMSG:
 898			err = 0;
 899			mbuf = vmalloc(sizeof(copr_msg));
 900			if (mbuf == NULL)
 901				return -ENOSPC;
 902			data = (unsigned short *)mbuf->data;
 903			spin_lock_irqsave(&lock, flags);
 904			for (i = 0; i < sizeof(mbuf->data)/sizeof(unsigned short); i++) {
 905				mbuf->len = i;	/* feed back number of WORDs read */
 906				if (!pss_get_dspword(devc, data++)) {
 907					if (i == 0)
 908						err = -EIO;
 909					break;
 910				}
 911			}
 912			spin_unlock_irqrestore(&lock,flags);
 913			if (copy_to_user(arg, mbuf, sizeof(copr_msg)))
 914				err = -EFAULT;
 915			vfree(mbuf);
 916			return err;
 917		
 918		case SNDCTL_COPR_RDATA:
 919			if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
 920				return -EFAULT;
 921			spin_lock_irqsave(&lock, flags);
 922			if (!pss_put_dspword(devc, 0x00d0)) {
 923				spin_unlock_irqrestore(&lock,flags);
 924				return -EIO;
 925			}
 926			if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
 927				spin_unlock_irqrestore(&lock,flags);
 928				return -EIO;
 929			}
 930			if (!pss_get_dspword(devc, &tmp)) {
 931				spin_unlock_irqrestore(&lock,flags);
 932				return -EIO;
 933			}
 934			dbuf.parm1 = tmp;
 935			spin_unlock_irqrestore(&lock,flags);
 936			if (copy_to_user(arg, &dbuf, sizeof(dbuf)))
 937				return -EFAULT;
 938			return 0;
 939		
 940		case SNDCTL_COPR_WDATA:
 941			if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
 942				return -EFAULT;
 943			spin_lock_irqsave(&lock, flags);
 944			if (!pss_put_dspword(devc, 0x00d1)) {
 945				spin_unlock_irqrestore(&lock,flags);
 946				return -EIO;
 947			}
 948			if (!pss_put_dspword(devc, (unsigned short) (dbuf.parm1 & 0xffff))) {
 949				spin_unlock_irqrestore(&lock,flags);
 950				return -EIO;
 951			}
 952			tmp = (unsigned int)dbuf.parm2 & 0xffff;
 953			if (!pss_put_dspword(devc, tmp)) {
 954				spin_unlock_irqrestore(&lock,flags);
 955				return -EIO;
 956			}
 957			spin_unlock_irqrestore(&lock,flags);
 958			return 0;
 959		
 960		case SNDCTL_COPR_WCODE:
 961			if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
 962				return -EFAULT;
 963			spin_lock_irqsave(&lock, flags);
 964			if (!pss_put_dspword(devc, 0x00d3)) {
 965				spin_unlock_irqrestore(&lock,flags);
 966				return -EIO;
 967			}
 968			if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
 969				spin_unlock_irqrestore(&lock,flags);
 970				return -EIO;
 971			}
 972			tmp = (unsigned int)dbuf.parm2 & 0x00ff;
 973			if (!pss_put_dspword(devc, tmp)) {
 974				spin_unlock_irqrestore(&lock,flags);
 975				return -EIO;
 976			}
 977			tmp = ((unsigned int)dbuf.parm2 >> 8) & 0xffff;
 978			if (!pss_put_dspword(devc, tmp)) {
 979				spin_unlock_irqrestore(&lock,flags);
 980				return -EIO;
 981			}
 982			spin_unlock_irqrestore(&lock,flags);
 983			return 0;
 984		
 985		case SNDCTL_COPR_RCODE:
 986			if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
 987				return -EFAULT;
 988			spin_lock_irqsave(&lock, flags);
 989			if (!pss_put_dspword(devc, 0x00d2)) {
 990				spin_unlock_irqrestore(&lock,flags);
 991				return -EIO;
 992			}
 993			if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
 994				spin_unlock_irqrestore(&lock,flags);
 995				return -EIO;
 996			}
 997			if (!pss_get_dspword(devc, &tmp)) { /* Read MSB */
 998				spin_unlock_irqrestore(&lock,flags);
 999				return -EIO;
1000			}
1001			dbuf.parm1 = tmp << 8;
1002			if (!pss_get_dspword(devc, &tmp)) { /* Read LSB */
1003				spin_unlock_irqrestore(&lock,flags);
1004				return -EIO;
1005			}
1006			dbuf.parm1 |= tmp & 0x00ff;
1007			spin_unlock_irqrestore(&lock,flags);
1008			if (copy_to_user(arg, &dbuf, sizeof(dbuf)))
1009				return -EFAULT;
1010			return 0;
1011
1012		default:
1013			return -EINVAL;
1014	}
1015	return -EINVAL;
1016}
1017
1018static coproc_operations pss_coproc_operations =
1019{
1020	"ADSP-2115",
1021	THIS_MODULE,
1022	pss_coproc_open,
1023	pss_coproc_close,
1024	pss_coproc_ioctl,
1025	pss_coproc_reset,
1026	&pss_data
1027};
1028
1029static int __init probe_pss_mss(struct address_info *hw_config)
1030{
1031	volatile int timeout;
1032	struct resource *ports;
1033	int        my_mix = -999;	/* gcc shut up */
1034
1035	if (!pss_initialized)
1036		return 0;
1037
1038	if (!request_region(hw_config->io_base, 4, "WSS config")) {
1039		printk(KERN_ERR "PSS: WSS I/O port conflicts.\n");
1040		return 0;
1041	}
1042	ports = request_region(hw_config->io_base + 4, 4, "ad1848");
1043	if (!ports) {
1044		printk(KERN_ERR "PSS: WSS I/O port conflicts.\n");
1045		release_region(hw_config->io_base, 4);
1046		return 0;
1047	}
1048	set_io_base(devc, CONF_WSS, hw_config->io_base);
1049	if (!set_irq(devc, CONF_WSS, hw_config->irq)) {
1050		printk("PSS: WSS IRQ allocation error.\n");
1051		goto fail;
1052	}
1053	if (!set_dma(devc, CONF_WSS, hw_config->dma)) {
1054		printk(KERN_ERR "PSS: WSS DMA allocation error\n");
1055		goto fail;
1056	}
1057	/*
1058	 * For some reason the card returns 0xff in the WSS status register
1059	 * immediately after boot. Probably MIDI+SB emulation algorithm
1060	 * downloaded to the ADSP2115 spends some time initializing the card.
1061	 * Let's try to wait until it finishes this task.
1062	 */
1063	for (timeout = 0; timeout < 100000 && (inb(hw_config->io_base + WSS_INDEX) &
1064	  WSS_INITIALIZING); timeout++)
1065		;
1066
1067	outb((0x0b), hw_config->io_base + WSS_INDEX);	/* Required by some cards */
1068
1069	for (timeout = 0; (inb(hw_config->io_base + WSS_DATA) & WSS_AUTOCALIBRATION) &&
1070	  (timeout < 100000); timeout++)
1071		;
1072
1073	if (!probe_ms_sound(hw_config, ports))
1074		goto fail;
1075
1076	devc->ad_mixer_dev = NO_WSS_MIXER;
1077	if (pss_mixer) 
1078	{
1079		if ((my_mix = sound_install_mixer (MIXER_DRIVER_VERSION,
1080			"PSS-SPEAKERS and AD1848 (through MSS audio codec)",
1081			&pss_mixer_operations,
1082			sizeof (struct mixer_operations),
1083			devc)) < 0) 
1084		{
1085			printk(KERN_ERR "Could not install PSS mixer\n");
1086			goto fail;
1087		}
1088	}
1089	pss_mixer_reset(devc);
1090	attach_ms_sound(hw_config, ports, THIS_MODULE);	/* Slot 0 */
1091
1092	if (hw_config->slots[0] != -1)
1093	{
1094		/* The MSS driver installed itself */
1095		audio_devs[hw_config->slots[0]]->coproc = &pss_coproc_operations;
1096		if (pss_mixer && (num_mixers == (my_mix + 2)))
1097		{
1098			/* The MSS mixer installed */
1099			devc->ad_mixer_dev = audio_devs[hw_config->slots[0]]->mixer_dev;
1100		}
1101	}
1102	return 1;
1103fail:
1104	release_region(hw_config->io_base + 4, 4);
1105	release_region(hw_config->io_base, 4);
1106	return 0;
1107}
1108
1109static inline void __exit unload_pss(struct address_info *hw_config)
1110{
1111	release_region(hw_config->io_base, 0x10);
1112	release_region(hw_config->io_base+0x10, 0x9);
1113}
1114
1115static inline void __exit unload_pss_mpu(struct address_info *hw_config)
1116{
1117	unload_mpu401(hw_config);
1118}
1119
1120static inline void __exit unload_pss_mss(struct address_info *hw_config)
1121{
1122	unload_ms_sound(hw_config);
1123}
1124
1125
1126static struct address_info cfg;
1127static struct address_info cfg2;
1128static struct address_info cfg_mpu;
1129
1130static int pss_io __initdata	= -1;
1131static int mss_io __initdata	= -1;
1132static int mss_irq __initdata	= -1;
1133static int mss_dma __initdata	= -1;
1134static int mpu_io __initdata	= -1;
1135static int mpu_irq __initdata	= -1;
1136static int pss_no_sound = 0;	/* Just configure non-sound components */
1137static int pss_keep_settings  = 1;	/* Keep hardware settings at module exit */
1138static char *pss_firmware = "/etc/sound/pss_synth";
1139
1140module_param(pss_io, int, 0);
1141MODULE_PARM_DESC(pss_io, "Set i/o base of PSS card (probably 0x220 or 0x240)");
1142module_param(mss_io, int, 0);
1143MODULE_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)");
1144module_param(mss_irq, int, 0);
1145MODULE_PARM_DESC(mss_irq, "Set WSS (audio) IRQ (3, 5, 7, 9, 10, 11, 12)");
1146module_param(mss_dma, int, 0);
1147MODULE_PARM_DESC(mss_dma, "Set WSS (audio) DMA (0, 1, 3)");
1148module_param(mpu_io, int, 0);
1149MODULE_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)");
1150module_param(mpu_irq, int, 0);
1151MODULE_PARM_DESC(mpu_irq, "Set MIDI IRQ (3, 5, 7, 9, 10, 11, 12)");
1152module_param(pss_cdrom_port, int, 0);
1153MODULE_PARM_DESC(pss_cdrom_port, "Set the PSS CDROM port i/o base (0x340 or other)");
1154module_param(pss_enable_joystick, bool, 0);
1155MODULE_PARM_DESC(pss_enable_joystick, "Enables the PSS joystick port (1 to enable, 0 to disable)");
1156module_param(pss_no_sound, bool, 0);
1157MODULE_PARM_DESC(pss_no_sound, "Configure sound compoents (0 - no, 1 - yes)");
1158module_param(pss_keep_settings, bool, 0);
1159MODULE_PARM_DESC(pss_keep_settings, "Keep hardware setting at driver unloading (0 - no, 1 - yes)");
1160module_param(pss_firmware, charp, 0);
1161MODULE_PARM_DESC(pss_firmware, "Location of the firmware file (default - /etc/sound/pss_synth)");
1162module_param(pss_mixer, bool, 0);
1163MODULE_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.");
1164MODULE_AUTHOR("Hannu Savolainen, Vladimir Michl");
1165MODULE_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).");
1166MODULE_LICENSE("GPL");
1167
1168
1169static int fw_load = 0;
1170static int pssmpu = 0, pssmss = 0;
1171
1172/*
1173 *    Load a PSS sound card module
1174 */
1175
1176static int __init init_pss(void)
1177{
1178
1179	if(pss_no_sound)		/* If configuring only nonsound components */
1180	{
1181		cfg.io_base = pss_io;
1182		if(!probe_pss(&cfg))
1183			return -ENODEV;
1184		printk(KERN_INFO "ECHO-PSS  Rev. %d\n", inw(REG(PSS_ID)) & 0x00ff);
1185		printk(KERN_INFO "PSS: loading in no sound mode.\n");
1186		disable_all_emulations();
1187		configure_nonsound_components();
1188		release_region(pss_io, 0x10);
1189		release_region(pss_io + 0x10, 0x9);
1190		return 0;
1191	}
1192
1193	cfg.io_base = pss_io;
1194
1195	cfg2.io_base = mss_io;
1196	cfg2.irq = mss_irq;
1197	cfg2.dma = mss_dma;
1198
1199	cfg_mpu.io_base = mpu_io;
1200	cfg_mpu.irq = mpu_irq;
1201
1202	if (cfg.io_base == -1 || cfg2.io_base == -1 || cfg2.irq == -1 || cfg.dma == -1) {
1203		printk(KERN_INFO "pss: mss_io, mss_dma, mss_irq and pss_io must be set.\n");
1204		return -EINVAL;
1205	}
1206
1207	if (!pss_synth) {
1208		fw_load = 1;
1209		pss_synthLen = mod_firmware_load(pss_firmware, (void *) &pss_synth);
1210	}
1211	if (!attach_pss(&cfg))
1212		return -ENODEV;
1213	/*
1214	 *    Attach stuff
1215	 */
1216	if (probe_pss_mpu(&cfg_mpu))
1217		pssmpu = 1;
1218
1219	if (probe_pss_mss(&cfg2))
1220		pssmss = 1;
1221
1222	return 0;
1223}
1224
1225static void __exit cleanup_pss(void)
1226{
1227	if(!pss_no_sound)
1228	{
1229		if(fw_load && pss_synth)
1230			vfree(pss_synth);
1231		if(pssmss)
1232			unload_pss_mss(&cfg2);
1233		if(pssmpu)
1234			unload_pss_mpu(&cfg_mpu);
1235		unload_pss(&cfg);
1236	} else if (pss_cdrom_port != -1)
1237		release_region(pss_cdrom_port, 2);
1238
1239	if(!pss_keep_settings)	/* Keep hardware settings if asked */
1240	{
1241		disable_all_emulations();
1242		printk(KERN_INFO "Resetting PSS sound card configurations.\n");
1243	}
1244}
1245
1246module_init(init_pss);
1247module_exit(cleanup_pss);
1248
1249#ifndef MODULE
1250static int __init setup_pss(char *str)
1251{
1252	/* io, mss_io, mss_irq, mss_dma, mpu_io, mpu_irq */
1253	int ints[7];
1254	
1255	str = get_options(str, ARRAY_SIZE(ints), ints);
1256
1257	pss_io	= ints[1];
1258	mss_io	= ints[2];
1259	mss_irq	= ints[3];
1260	mss_dma	= ints[4];
1261	mpu_io	= ints[5];
1262	mpu_irq	= ints[6];
1263
1264	return 1;
1265}
1266
1267__setup("pss=", setup_pss);
1268#endif