linux-old/drivers/sound/sscape.c
<<
>>
Prefs
   1/*
   2 * sound/sscape.c
   3 *
   4 * Low level driver for Ensoniq SoundScape
   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 * Sergey Smitienko     : ensoniq p'n'p support
  16 * Christoph Hellwig    : adapted to module_init/module_exit
  17 * Bartlomiej Zolnierkiewicz : added __init to attach_sscape()
  18 * Chris Rankin         : Specify that this module owns the coprocessor
  19 * Arnaldo C. de Melo   : added missing restore_flags in sscape_pnp_upload_file
  20 */
  21
  22#include <linux/init.h>
  23#include <linux/module.h>
  24
  25#include "sound_config.h"
  26#include "sound_firmware.h"
  27
  28#include <linux/types.h>
  29#include <linux/errno.h>
  30#include <linux/signal.h>
  31#include <linux/fcntl.h>
  32#include <linux/ctype.h>
  33#include <linux/stddef.h>
  34#include <linux/kmod.h>
  35#include <asm/dma.h>
  36#include <asm/io.h>
  37#include <asm/segment.h>
  38#include <linux/wait.h>
  39#include <linux/slab.h>
  40#include <linux/ioport.h>
  41#include <linux/delay.h>
  42#include <linux/proc_fs.h>
  43#include <linux/wrapper.h>
  44
  45#include "coproc.h"
  46
  47#include "ad1848.h"
  48#include "mpu401.h"
  49
  50/*
  51 *    I/O ports
  52 */
  53#define MIDI_DATA       0
  54#define MIDI_CTRL       1
  55#define HOST_CTRL       2
  56#define TX_READY        0x02
  57#define RX_READY        0x01
  58#define HOST_DATA       3
  59#define ODIE_ADDR       4
  60#define ODIE_DATA       5
  61
  62/*
  63 *    Indirect registers
  64 */
  65
  66#define GA_INTSTAT_REG  0
  67#define GA_INTENA_REG   1
  68#define GA_DMAA_REG     2
  69#define GA_DMAB_REG     3
  70#define GA_INTCFG_REG   4
  71#define GA_DMACFG_REG   5
  72#define GA_CDCFG_REG    6
  73#define GA_SMCFGA_REG   7
  74#define GA_SMCFGB_REG   8
  75#define GA_HMCTL_REG    9
  76
  77/*
  78 * DMA channel identifiers (A and B)
  79 */
  80
  81#define SSCAPE_DMA_A    0
  82#define SSCAPE_DMA_B    1
  83
  84#define PORT(name)      (devc->base+name)
  85
  86/*
  87 * Host commands recognized by the OBP microcode
  88 */
  89 
  90#define CMD_GEN_HOST_ACK        0x80
  91#define CMD_GEN_MPU_ACK         0x81
  92#define CMD_GET_BOARD_TYPE      0x82
  93#define CMD_SET_CONTROL         0x88    /* Old firmware only */
  94#define CMD_GET_CONTROL         0x89    /* Old firmware only */
  95#define CTL_MASTER_VOL          0
  96#define CTL_MIC_MODE            2
  97#define CTL_SYNTH_VOL           4
  98#define CTL_WAVE_VOL            7
  99#define CMD_SET_EXTMIDI         0x8a
 100#define CMD_GET_EXTMIDI         0x8b
 101#define CMD_SET_MT32            0x8c
 102#define CMD_GET_MT32            0x8d
 103
 104#define CMD_ACK                 0x80
 105
 106#define IC_ODIE                 1
 107#define IC_OPUS                 2
 108
 109typedef struct sscape_info
 110{
 111        int     base, irq, dma;
 112        
 113        int     codec, codec_irq;       /* required to setup pnp cards*/
 114        int     codec_type;
 115        int     ic_type;
 116        char*   raw_buf;
 117        unsigned long   raw_buf_phys;
 118        int     buffsize;               /* -------------------------- */
 119        
 120        int     ok;     /* Properly detected */
 121        int     failed;
 122        int     dma_allocated;
 123        int     codec_audiodev;
 124        int     opened;
 125        int     *osp;
 126        int     my_audiodev;
 127} sscape_info;
 128
 129static struct sscape_info adev_info = {
 130        0
 131};
 132
 133static struct sscape_info *devc = &adev_info;
 134static int sscape_mididev = -1;
 135
 136/* Some older cards have assigned interrupt bits differently than new ones */
 137static char valid_interrupts_old[] = {
 138        9, 7, 5, 15
 139};
 140
 141static char valid_interrupts_new[] = {
 142        9, 5, 7, 10
 143};
 144
 145static char *valid_interrupts = valid_interrupts_new;
 146
 147/*
 148 *      See the bottom of the driver. This can be set by spea =0/1.
 149 */
 150 
 151#ifdef REVEAL_SPEA
 152static char old_hardware = 1;
 153#else
 154static char old_hardware = 0;
 155#endif
 156
 157static void sleep(unsigned howlong)
 158{
 159        current->state = TASK_INTERRUPTIBLE;
 160        schedule_timeout(howlong);
 161}
 162
 163static unsigned char sscape_read(struct sscape_info *devc, int reg)
 164{
 165        unsigned long flags;
 166        unsigned char val;
 167
 168        save_flags(flags);
 169        cli();
 170        outb(reg, PORT(ODIE_ADDR));
 171        val = inb(PORT(ODIE_DATA));
 172        restore_flags(flags);
 173        return val;
 174}
 175
 176static void sscape_write(struct sscape_info *devc, int reg, int data)
 177{
 178        unsigned long flags;
 179
 180        save_flags(flags);
 181        cli();
 182        outb(reg, PORT(ODIE_ADDR));
 183        outb(data, PORT(ODIE_DATA));
 184        restore_flags(flags);
 185}
 186
 187static unsigned char sscape_pnp_read_codec(sscape_info* devc, unsigned char reg)
 188{
 189        unsigned char res;
 190        unsigned long flags;
 191
 192        save_flags(flags);
 193        cli();  
 194        outb( reg, devc -> codec);
 195        res = inb (devc -> codec + 1);
 196        restore_flags(flags);
 197        return res;
 198
 199}
 200
 201static void sscape_pnp_write_codec(sscape_info* devc, unsigned char reg, unsigned char data)
 202{
 203        unsigned long flags;
 204        
 205        save_flags(flags);
 206        cli();
 207        outb( reg, devc -> codec);
 208        outb( data, devc -> codec + 1);
 209        restore_flags(flags);
 210}
 211
 212static void host_open(struct sscape_info *devc)
 213{
 214        outb((0x00), PORT(HOST_CTRL));  /* Put the board to the host mode */
 215}
 216
 217static void host_close(struct sscape_info *devc)
 218{
 219        outb((0x03), PORT(HOST_CTRL));  /* Put the board to the MIDI mode */
 220}
 221
 222static int host_write(struct sscape_info *devc, unsigned char *data, int count)
 223{
 224        unsigned long flags;
 225        int i, timeout_val;
 226
 227        save_flags(flags);
 228        cli();
 229
 230        /*
 231         * Send the command and data bytes
 232         */
 233
 234        for (i = 0; i < count; i++)
 235        {
 236                for (timeout_val = 10000; timeout_val > 0; timeout_val--)
 237                        if (inb(PORT(HOST_CTRL)) & TX_READY)
 238                                break;
 239
 240                if (timeout_val <= 0)
 241                {
 242                            restore_flags(flags);
 243                            return 0;
 244                }
 245                outb(data[i], PORT(HOST_DATA));
 246        }
 247        restore_flags(flags);
 248        return 1;
 249}
 250
 251static int host_read(struct sscape_info *devc)
 252{
 253        unsigned long flags;
 254        int timeout_val;
 255        unsigned char data;
 256
 257        save_flags(flags);
 258        cli();
 259
 260        /*
 261         * Read a byte
 262         */
 263
 264        for (timeout_val = 10000; timeout_val > 0; timeout_val--)
 265                if (inb(PORT(HOST_CTRL)) & RX_READY)
 266                        break;
 267
 268        if (timeout_val <= 0)
 269        {
 270                restore_flags(flags);
 271                return -1;
 272        }
 273        data = inb(PORT(HOST_DATA));
 274        restore_flags(flags);
 275        return data;
 276}
 277
 278#if 0 /* unused */
 279static int host_command1(struct sscape_info *devc, int cmd)
 280{
 281        unsigned char buf[10];
 282        buf[0] = (unsigned char) (cmd & 0xff);
 283        return host_write(devc, buf, 1);
 284}
 285#endif /* unused */
 286
 287
 288static int host_command2(struct sscape_info *devc, int cmd, int parm1)
 289{
 290        unsigned char buf[10];
 291
 292        buf[0] = (unsigned char) (cmd & 0xff);
 293        buf[1] = (unsigned char) (parm1 & 0xff);
 294
 295        return host_write(devc, buf, 2);
 296}
 297
 298static int host_command3(struct sscape_info *devc, int cmd, int parm1, int parm2)
 299{
 300        unsigned char buf[10];
 301
 302        buf[0] = (unsigned char) (cmd & 0xff);
 303        buf[1] = (unsigned char) (parm1 & 0xff);
 304        buf[2] = (unsigned char) (parm2 & 0xff);
 305        return host_write(devc, buf, 3);
 306}
 307
 308static void set_mt32(struct sscape_info *devc, int value)
 309{
 310        host_open(devc);
 311        host_command2(devc, CMD_SET_MT32, value ? 1 : 0);
 312        if (host_read(devc) != CMD_ACK)
 313        {
 314                /* printk( "SNDSCAPE: Setting MT32 mode failed\n"); */
 315        }
 316        host_close(devc);
 317}
 318
 319static void set_control(struct sscape_info *devc, int ctrl, int value)
 320{
 321        host_open(devc);
 322        host_command3(devc, CMD_SET_CONTROL, ctrl, value);
 323        if (host_read(devc) != CMD_ACK)
 324        {
 325                /* printk( "SNDSCAPE: Setting control (%d) failed\n",  ctrl); */
 326        }
 327        host_close(devc);
 328}
 329
 330static void do_dma(struct sscape_info *devc, int dma_chan, unsigned long buf, int blk_size, int mode)
 331{
 332        unsigned char temp;
 333
 334        if (dma_chan != SSCAPE_DMA_A)
 335        {
 336                printk(KERN_WARNING "soundscape: Tried to use DMA channel  != A. Why?\n");
 337                return;
 338        }
 339        audio_devs[devc->codec_audiodev]->flags &= ~DMA_AUTOMODE;
 340        DMAbuf_start_dma(devc->codec_audiodev, buf, blk_size, mode);
 341        audio_devs[devc->codec_audiodev]->flags |= DMA_AUTOMODE;
 342
 343        temp = devc->dma << 4;  /* Setup DMA channel select bits */
 344        if (devc->dma <= 3)
 345                temp |= 0x80;   /* 8 bit DMA channel */
 346
 347        temp |= 1;              /* Trigger DMA */
 348        sscape_write(devc, GA_DMAA_REG, temp);
 349        temp &= 0xfe;           /* Clear DMA trigger */
 350        sscape_write(devc, GA_DMAA_REG, temp);
 351}
 352
 353static int verify_mpu(struct sscape_info *devc)
 354{
 355        /*
 356         * The SoundScape board could be in three modes (MPU, 8250 and host).
 357         * If the card is not in the MPU mode, enabling the MPU driver will
 358         * cause infinite loop (the driver believes that there is always some
 359         * received data in the buffer.
 360         *
 361         * Detect this by looking if there are more than 10 received MIDI bytes
 362         * (0x00) in the buffer.
 363         */
 364
 365        int i;
 366
 367        for (i = 0; i < 10; i++)
 368        {
 369                if (inb(devc->base + HOST_CTRL) & 0x80)
 370                        return 1;
 371
 372                if (inb(devc->base) != 0x00)
 373                        return 1;
 374        }
 375        printk(KERN_WARNING "SoundScape: The device is not in the MPU-401 mode\n");
 376        return 0;
 377}
 378
 379static int sscape_coproc_open(void *dev_info, int sub_device)
 380{
 381        if (sub_device == COPR_MIDI)
 382        {
 383                set_mt32(devc, 0);
 384                if (!verify_mpu(devc))
 385                        return -EIO;
 386        }
 387        return 0;
 388}
 389
 390static void sscape_coproc_close(void *dev_info, int sub_device)
 391{
 392        struct sscape_info *devc = dev_info;
 393        unsigned long   flags;
 394
 395        save_flags(flags);
 396        cli();
 397        if (devc->dma_allocated)
 398        {
 399                sscape_write(devc, GA_DMAA_REG, 0x20);  /* DMA channel disabled */
 400                devc->dma_allocated = 0;
 401        }
 402        restore_flags(flags);
 403        return;
 404}
 405
 406static void sscape_coproc_reset(void *dev_info)
 407{
 408}
 409
 410static int sscape_download_boot(struct sscape_info *devc, unsigned char *block, int size, int flag)
 411{
 412        unsigned long flags;
 413        unsigned char temp;
 414        volatile int done, timeout_val;
 415        static unsigned char codec_dma_bits = 0;
 416
 417        if (flag & CPF_FIRST)
 418        {
 419                /*
 420                 * First block. Have to allocate DMA and to reset the board
 421                 * before continuing.
 422                 */
 423
 424                save_flags(flags);
 425                cli();
 426                codec_dma_bits = sscape_read(devc, GA_CDCFG_REG);
 427
 428                if (devc->dma_allocated == 0)
 429                        devc->dma_allocated = 1;
 430
 431                restore_flags(flags);
 432
 433                sscape_write(devc, GA_HMCTL_REG, 
 434                        (temp = sscape_read(devc, GA_HMCTL_REG)) & 0x3f);       /*Reset */
 435
 436                for (timeout_val = 10000; timeout_val > 0; timeout_val--)
 437                        sscape_read(devc, GA_HMCTL_REG);        /* Delay */
 438
 439                /* Take board out of reset */
 440                sscape_write(devc, GA_HMCTL_REG,
 441                        (temp = sscape_read(devc, GA_HMCTL_REG)) | 0x80);
 442        }
 443        /*
 444         * Transfer one code block using DMA
 445         */
 446        if (audio_devs[devc->codec_audiodev]->dmap_out->raw_buf == NULL)
 447        {
 448                printk(KERN_WARNING "soundscape: DMA buffer not available\n");
 449                return 0;
 450        }
 451        memcpy(audio_devs[devc->codec_audiodev]->dmap_out->raw_buf, block, size);
 452
 453        save_flags(flags);
 454        cli();
 455        
 456        /******** INTERRUPTS DISABLED NOW ********/
 457        
 458        do_dma(devc, SSCAPE_DMA_A,
 459               audio_devs[devc->codec_audiodev]->dmap_out->raw_buf_phys,
 460               size, DMA_MODE_WRITE);
 461
 462        /*
 463         * Wait until transfer completes.
 464         */
 465        
 466        done = 0;
 467        timeout_val = 30;
 468        while (!done && timeout_val-- > 0)
 469        {
 470                int resid;
 471
 472                if (HZ / 50)
 473                        sleep(HZ / 50);
 474                clear_dma_ff(devc->dma);
 475                if ((resid = get_dma_residue(devc->dma)) == 0)
 476                        done = 1;
 477        }
 478
 479        restore_flags(flags);
 480        if (!done)
 481                return 0;
 482
 483        if (flag & CPF_LAST)
 484        {
 485                /*
 486                 * Take the board out of reset
 487                 */
 488                outb((0x00), PORT(HOST_CTRL));
 489                outb((0x00), PORT(MIDI_CTRL));
 490
 491                temp = sscape_read(devc, GA_HMCTL_REG);
 492                temp |= 0x40;
 493                sscape_write(devc, GA_HMCTL_REG, temp); /* Kickstart the board */
 494
 495                /*
 496                 * Wait until the ODB wakes up
 497                 */
 498
 499                save_flags(flags);
 500                cli();
 501                done = 0;
 502                timeout_val = 5 * HZ;
 503                while (!done && timeout_val-- > 0)
 504                {
 505                        unsigned char x;
 506                        
 507                        sleep(1);
 508                        x = inb(PORT(HOST_DATA));
 509                        if (x == 0xff || x == 0xfe)             /* OBP startup acknowledge */
 510                        {
 511                                DDB(printk("Soundscape: Acknowledge = %x\n", x));
 512                                done = 1;
 513                        }
 514                }
 515                sscape_write(devc, GA_CDCFG_REG, codec_dma_bits);
 516
 517                restore_flags(flags);
 518                if (!done)
 519                {
 520                        printk(KERN_ERR "soundscape: The OBP didn't respond after code download\n");
 521                        return 0;
 522                }
 523                save_flags(flags);
 524                cli();
 525                done = 0;
 526                timeout_val = 5 * HZ;
 527                while (!done && timeout_val-- > 0)
 528                {
 529                        sleep(1);
 530                        if (inb(PORT(HOST_DATA)) == 0xfe)       /* Host startup acknowledge */
 531                                done = 1;
 532                }
 533                restore_flags(flags);
 534                if (!done)
 535                {
 536                        printk(KERN_ERR "soundscape: OBP Initialization failed.\n");
 537                        return 0;
 538                }
 539                printk(KERN_INFO "SoundScape board initialized OK\n");
 540                set_control(devc, CTL_MASTER_VOL, 100);
 541                set_control(devc, CTL_SYNTH_VOL, 100);
 542
 543#ifdef SSCAPE_DEBUG3
 544                /*
 545                 * Temporary debugging aid. Print contents of the registers after
 546                 * downloading the code.
 547                 */
 548                {
 549                        int i;
 550
 551                        for (i = 0; i < 13; i++)
 552                                printk("I%d = %02x (new value)\n", i, sscape_read(devc, i));
 553                }
 554#endif
 555
 556        }
 557        return 1;
 558}
 559
 560static int download_boot_block(void *dev_info, copr_buffer * buf)
 561{
 562        if (buf->len <= 0 || buf->len > sizeof(buf->data))
 563                return -EINVAL;
 564
 565        if (!sscape_download_boot(devc, buf->data, buf->len, buf->flags))
 566        {
 567                printk(KERN_ERR "soundscape: Unable to load microcode block to the OBP.\n");
 568                return -EIO;
 569        }
 570        return 0;
 571}
 572
 573static int sscape_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int local)
 574{
 575        copr_buffer *buf;
 576        int err;
 577
 578        switch (cmd) 
 579        {
 580                case SNDCTL_COPR_RESET:
 581                        sscape_coproc_reset(dev_info);
 582                        return 0;
 583
 584                case SNDCTL_COPR_LOAD:
 585                        buf = (copr_buffer *) vmalloc(sizeof(copr_buffer));
 586                        if (buf == NULL)
 587                                return -ENOSPC;
 588                        if (copy_from_user(buf, arg, sizeof(copr_buffer))) 
 589                        {
 590                                vfree(buf);
 591                                return -EFAULT;
 592                        }
 593                        err = download_boot_block(dev_info, buf);
 594                        vfree(buf);
 595                        return err;
 596                
 597                default:
 598                        return -EINVAL;
 599        }
 600}
 601
 602static coproc_operations sscape_coproc_operations =
 603{
 604        "SoundScape M68K",
 605        THIS_MODULE,
 606        sscape_coproc_open,
 607        sscape_coproc_close,
 608        sscape_coproc_ioctl,
 609        sscape_coproc_reset,
 610        &adev_info
 611};
 612
 613static int sscape_detected = 0;
 614static int sscape_is_pnp   = 0;
 615
 616void __init attach_sscape(struct address_info *hw_config)
 617{
 618#ifndef SSCAPE_REGS
 619        /*
 620         * Config register values for Spea/V7 Media FX and Ensoniq S-2000.
 621         * These values are card
 622         * dependent. If you have another SoundScape based card, you have to
 623         * find the correct values. Do the following:
 624         *  - Compile this driver with SSCAPE_DEBUG1 defined.
 625         *  - Shut down and power off your machine.
 626         *  - Boot with DOS so that the SSINIT.EXE program is run.
 627         *  - Warm boot to {Linux|SYSV|BSD} and write down the lines displayed
 628         *    when detecting the SoundScape.
 629         *  - Modify the following list to use the values printed during boot.
 630         *    Undefine the SSCAPE_DEBUG1
 631         */
 632#define SSCAPE_REGS { \
 633/* I0 */        0x00, \
 634/* I1 */        0xf0, /* Note! Ignored. Set always to 0xf0 */ \
 635/* I2 */        0x20, /* Note! Ignored. Set always to 0x20 */ \
 636/* I3 */        0x20, /* Note! Ignored. Set always to 0x20 */ \
 637/* I4 */        0xf5, /* Ignored */ \
 638/* I5 */        0x10, \
 639/* I6 */        0x00, \
 640/* I7 */        0x2e, /* I7 MEM config A. Likely to vary between models */ \
 641/* I8 */        0x00, /* I8 MEM config B. Likely to vary between models */ \
 642/* I9 */        0x40 /* Ignored */ \
 643        }
 644#endif
 645
 646        unsigned long   flags;
 647        static unsigned char regs[10] = SSCAPE_REGS;
 648
 649        int i, irq_bits = 0xff;
 650
 651        if (sscape_detected != hw_config->io_base)
 652                return;
 653
 654        request_region(devc->base + 2, 6, "SoundScape");
 655        if (old_hardware)
 656        {
 657                valid_interrupts = valid_interrupts_old;
 658                conf_printf("Ensoniq SoundScape (old)", hw_config);
 659        }
 660        else
 661                conf_printf("Ensoniq SoundScape", hw_config);
 662
 663        for (i = 0; i < sizeof(valid_interrupts); i++)
 664        {
 665                if (hw_config->irq == valid_interrupts[i])
 666                {
 667                        irq_bits = i;
 668                        break;
 669                }
 670        }
 671        if (hw_config->irq > 15 || ((regs[4] = irq_bits) == 0xff))
 672        {
 673                printk(KERN_ERR "Invalid IRQ%d\n", hw_config->irq);
 674                return;
 675        }
 676        
 677        if (!sscape_is_pnp) {
 678        
 679            save_flags(flags);
 680            cli();
 681            for (i = 1; i < 10; i++)
 682            {
 683                switch (i)
 684                {
 685                        case 1: /* Host interrupt enable */
 686                                sscape_write(devc, i, 0xf0);    /* All interrupts enabled */
 687                                break;
 688
 689                        case 2: /* DMA A status/trigger register */
 690                        case 3: /* DMA B status/trigger register */
 691                                sscape_write(devc, i, 0x20);    /* DMA channel disabled */
 692                                break;
 693
 694                        case 4: /* Host interrupt config reg */
 695                                sscape_write(devc, i, 0xf0 | (irq_bits << 2) | irq_bits);
 696                                break;
 697
 698                        case 5: /* Don't destroy CD-ROM DMA config bits (0xc0) */
 699                                sscape_write(devc, i, (regs[i] & 0x3f) | (sscape_read(devc, i) & 0xc0));
 700                                break;
 701
 702                        case 6: /* CD-ROM config (WSS codec actually) */
 703                                sscape_write(devc, i, regs[i]);
 704                                break;
 705
 706                        case 9: /* Master control reg. Don't modify CR-ROM bits. Disable SB emul */
 707                                sscape_write(devc, i, (sscape_read(devc, i) & 0xf0) | 0x08);
 708                                break;
 709
 710                        default:
 711                                sscape_write(devc, i, regs[i]);
 712                }
 713            }
 714            restore_flags(flags);
 715        }
 716#ifdef SSCAPE_DEBUG2
 717        /*
 718         * Temporary debugging aid. Print contents of the registers after
 719         * changing them.
 720         */
 721        {
 722                int i;
 723
 724                for (i = 0; i < 13; i++)
 725                        printk("I%d = %02x (new value)\n", i, sscape_read(devc, i));
 726        }
 727#endif
 728
 729        if (probe_mpu401(hw_config))
 730                hw_config->always_detect = 1;
 731        hw_config->name = "SoundScape";
 732
 733        hw_config->irq *= -1;   /* Negative value signals IRQ sharing */
 734        attach_mpu401(hw_config, THIS_MODULE);
 735        hw_config->irq *= -1;   /* Restore it */
 736
 737        if (hw_config->slots[1] != -1)  /* The MPU driver installed itself */
 738        {
 739                sscape_mididev = hw_config->slots[1];
 740                midi_devs[hw_config->slots[1]]->coproc = &sscape_coproc_operations;
 741        }
 742        sscape_write(devc, GA_INTENA_REG, 0x80);        /* Master IRQ enable */
 743        devc->ok = 1;
 744        devc->failed = 0;
 745}
 746
 747static int detect_ga(sscape_info * devc)
 748{
 749        unsigned char save;
 750
 751        DDB(printk("Entered Soundscape detect_ga(%x)\n", devc->base));
 752
 753        if (check_region(devc->base, 8))
 754                return 0;
 755
 756        /*
 757         * First check that the address register of "ODIE" is
 758         * there and that it has exactly 4 writable bits.
 759         * First 4 bits
 760         */
 761        
 762        if ((save = inb(PORT(ODIE_ADDR))) & 0xf0)
 763        {
 764                DDB(printk("soundscape: Detect error A\n"));
 765                return 0;
 766        }
 767        outb((0x00), PORT(ODIE_ADDR));
 768        if (inb(PORT(ODIE_ADDR)) != 0x00)
 769        {
 770                DDB(printk("soundscape: Detect error B\n"));
 771                return 0;
 772        }
 773        outb((0xff), PORT(ODIE_ADDR));
 774        if (inb(PORT(ODIE_ADDR)) != 0x0f)
 775        {
 776                DDB(printk("soundscape: Detect error C\n"));
 777                return 0;
 778        }
 779        outb((save), PORT(ODIE_ADDR));
 780
 781        /*
 782         * Now verify that some indirect registers return zero on some bits.
 783         * This may break the driver with some future revisions of "ODIE" but...
 784         */
 785
 786        if (sscape_read(devc, 0) & 0x0c)
 787        {
 788                DDB(printk("soundscape: Detect error D (%x)\n", sscape_read(devc, 0)));
 789                return 0;
 790        }
 791        if (sscape_read(devc, 1) & 0x0f)
 792        {
 793                DDB(printk("soundscape: Detect error E\n"));
 794                return 0;
 795        }
 796        if (sscape_read(devc, 5) & 0x0f)
 797        {
 798                DDB(printk("soundscape: Detect error F\n"));
 799                return 0;
 800        }
 801        return 1;
 802}
 803
 804static  int sscape_read_host_ctrl(sscape_info* devc)
 805{
 806        return host_read(devc);
 807}
 808
 809static  void sscape_write_host_ctrl2(sscape_info *devc, int a, int b)
 810{
 811        host_command2(devc, a, b);
 812}
 813
 814static int sscape_alloc_dma(sscape_info *devc)
 815{
 816        char *start_addr, *end_addr;
 817        int dma_pagesize;
 818        int sz, size;
 819        struct page *page;
 820
 821        if (devc->raw_buf != NULL) return 0;    /* Already done */
 822        dma_pagesize = (devc->dma < 4) ? (64 * 1024) : (128 * 1024);
 823        devc->raw_buf = NULL;
 824        devc->buffsize = 8192*4;
 825        if (devc->buffsize > dma_pagesize) devc->buffsize = dma_pagesize;
 826        start_addr = NULL;
 827        /*
 828         * Now loop until we get a free buffer. Try to get smaller buffer if
 829         * it fails. Don't accept smaller than 8k buffer for performance
 830         * reasons.
 831         */
 832        while (start_addr == NULL && devc->buffsize > PAGE_SIZE) {
 833                for (sz = 0, size = PAGE_SIZE; size < devc->buffsize; sz++, size <<= 1);
 834                devc->buffsize = PAGE_SIZE * (1 << sz);
 835                start_addr = (char *) __get_free_pages(GFP_ATOMIC|GFP_DMA, sz);
 836                if (start_addr == NULL) devc->buffsize /= 2;
 837        }
 838
 839        if (start_addr == NULL) {
 840                printk(KERN_ERR "sscape pnp init error: Couldn't allocate DMA buffer\n");
 841                return 0;
 842        } else {
 843                /* make some checks */
 844                end_addr = start_addr + devc->buffsize - 1;             
 845                /* now check if it fits into the same dma-pagesize */
 846
 847                if (((long) start_addr & ~(dma_pagesize - 1)) != ((long) end_addr & ~(dma_pagesize - 1))
 848                    || end_addr >= (char *) (MAX_DMA_ADDRESS)) {
 849                        printk(KERN_ERR "sscape pnp: Got invalid address 0x%lx for %db DMA-buffer\n", (long) start_addr, devc->buffsize);
 850                        return 0;
 851                }
 852        }
 853        devc->raw_buf = start_addr;
 854        devc->raw_buf_phys = virt_to_bus(start_addr);
 855
 856        for (page = virt_to_page(start_addr); page <= virt_to_page(end_addr); page++)
 857                mem_map_reserve(page);
 858        return 1;
 859}
 860
 861static void sscape_free_dma(sscape_info *devc)
 862{
 863        int sz, size;
 864        unsigned long start_addr, end_addr;
 865        struct page *page;
 866
 867        if (devc->raw_buf == NULL) return;
 868        for (sz = 0, size = PAGE_SIZE; size < devc->buffsize; sz++, size <<= 1);
 869        start_addr = (unsigned long) devc->raw_buf;
 870        end_addr = start_addr + devc->buffsize;
 871
 872        for (page = virt_to_page(start_addr); page <= virt_to_page(end_addr); page++)
 873                mem_map_unreserve(page);
 874
 875        free_pages((unsigned long) devc->raw_buf, sz);
 876        devc->raw_buf = NULL;
 877}
 878
 879/* Intel version !!!!!!!!! */
 880
 881static int sscape_start_dma(int chan, unsigned long physaddr, int count, int dma_mode)
 882{
 883        unsigned long flags;
 884
 885        flags = claim_dma_lock();
 886        disable_dma(chan);
 887        clear_dma_ff(chan);
 888        set_dma_mode(chan, dma_mode);
 889        set_dma_addr(chan, physaddr);
 890        set_dma_count(chan, count);
 891        enable_dma(chan);
 892        release_dma_lock(flags);
 893        return 0;
 894}
 895
 896static void sscape_pnp_start_dma(sscape_info* devc, int arg )
 897{
 898        int reg;
 899        if (arg == 0) reg = 2;
 900        else reg = 3;
 901
 902        sscape_write(devc, reg, sscape_read( devc, reg) | 0x01);
 903        sscape_write(devc, reg, sscape_read( devc, reg) & 0xFE);
 904}
 905
 906static int sscape_pnp_wait_dma (sscape_info* devc, int arg )
 907{
 908        int             reg;
 909        unsigned long   i;
 910        unsigned char   d;
 911
 912        if (arg == 0) reg = 2;
 913        else reg = 3;
 914
 915        sleep ( 1 );
 916        i = 0;
 917        do {
 918                d = sscape_read(devc, reg) & 1;
 919                if ( d == 1)  break;
 920                i++;
 921        } while (i < 500000);
 922        d = sscape_read(devc, reg) & 1; 
 923        return d;
 924}
 925
 926static  int     sscape_pnp_alloc_dma(sscape_info* devc)
 927{
 928        /* printk(KERN_INFO "sscape: requesting dma\n"); */
 929        if (request_dma(devc -> dma, "sscape")) return 0;
 930        /* printk(KERN_INFO "sscape: dma channel allocated\n"); */
 931        if (!sscape_alloc_dma(devc)) {
 932                free_dma(devc -> dma);
 933                return 0;
 934        };
 935        return 1;
 936}
 937
 938static  void    sscape_pnp_free_dma(sscape_info* devc)
 939{
 940        sscape_free_dma( devc);
 941        free_dma(devc -> dma ); 
 942        /* printk(KERN_INFO "sscape: dma released\n"); */
 943}
 944
 945static  int     sscape_pnp_upload_file(sscape_info* devc, char* fn)
 946{       
 947        int             done = 0;
 948        int             timeout_val;
 949        char*           data,*dt;
 950        int             len,l;
 951        unsigned long   flags;
 952
 953        sscape_write( devc, 9, sscape_read(devc, 9 )  & 0x3F );
 954        sscape_write( devc, 2, (devc -> dma << 4) | 0x80 );
 955        sscape_write( devc, 3, 0x20 );
 956        sscape_write( devc, 9, sscape_read( devc, 9 )  | 0x80 );
 957        
 958        len = mod_firmware_load(fn, &data);
 959        if (len == 0) {
 960                    printk(KERN_ERR "sscape: file not found: %s\n", fn);
 961                    return 0;
 962        }
 963        dt = data;
 964        save_flags(flags);
 965        cli();
 966        while ( len > 0 ) {
 967                if (len > devc -> buffsize) l = devc->buffsize;
 968                else l = len;
 969                len -= l;               
 970                memcpy(devc->raw_buf, dt, l); dt += l;
 971                sscape_start_dma(devc->dma, devc->raw_buf_phys, l, 0x48);
 972                sscape_pnp_start_dma ( devc, 0 );
 973                if (sscape_pnp_wait_dma ( devc, 0 ) == 0) {
 974                        restore_flags(flags);       
 975                        return 0;
 976                }
 977        }
 978        
 979        restore_flags(flags);       
 980        vfree(data);
 981        
 982        outb(0, devc -> base + 2);
 983        outb(0, devc -> base);
 984
 985        sscape_write ( devc, 9, sscape_read( devc, 9 ) | 0x40);
 986
 987        timeout_val = 5 * HZ; 
 988        while (!done && timeout_val-- > 0)
 989        {
 990                unsigned char x;
 991                sleep(1);
 992                x = inb( devc -> base + 3);
 993                if (x == 0xff || x == 0xfe)             /* OBP startup acknowledge */
 994                {
 995                        //printk(KERN_ERR "Soundscape: Acknowledge = %x\n", x);
 996                        done = 1;
 997                }
 998        }
 999        timeout_val = 5 * HZ;
1000        done = 0;
1001        while (!done && timeout_val-- > 0)
1002        {
1003                unsigned char x;
1004                sleep(1);
1005                x = inb( devc -> base + 3);
1006                if (x == 0xfe)          /* OBP startup acknowledge */
1007                {
1008                        //printk(KERN_ERR "Soundscape: Acknowledge = %x\n", x);
1009                        done = 1;
1010                }
1011        }
1012
1013        if ( !done ) printk(KERN_ERR "soundscape: OBP Initialization failed.\n");
1014
1015        sscape_write( devc, 2, devc->ic_type == IC_ODIE ? 0x70 : 0x40);
1016        sscape_write( devc, 3, (devc -> dma << 4) + 0x80);
1017        return 1;
1018}
1019
1020static void __init sscape_pnp_init_hw(sscape_info* devc)
1021{       
1022        unsigned char midi_irq = 0, sb_irq = 0;
1023        unsigned i;
1024        static  char code_file_name[23] = "/sndscape/sndscape.cox";
1025        
1026        int sscape_sb_enable            = 0;
1027        int sscape_joystic_enable       = 0x7f;
1028        int sscape_mic_enable           = 0;
1029        int sscape_ext_midi             = 0;            
1030
1031        if ( !sscape_pnp_alloc_dma(devc) ) {
1032                printk(KERN_ERR "sscape: faild to allocate dma\n");
1033                return;
1034        }
1035
1036        for (i = 0; i < 4; i++) {
1037                if ( devc -> irq   == valid_interrupts[i] ) 
1038                        midi_irq = i;
1039                if ( devc -> codec_irq == valid_interrupts[i] ) 
1040                        sb_irq = i;
1041        }
1042
1043        sscape_write( devc, 5, 0x50);
1044        sscape_write( devc, 7, 0x2e);
1045        sscape_write( devc, 8, 0x00);
1046
1047        sscape_write( devc, 2, devc->ic_type == IC_ODIE ? 0x70 : 0x40);
1048        sscape_write( devc, 3, ( devc -> dma << 4) | 0x80);
1049
1050        if ( sscape_sb_enable )
1051                sscape_write (devc, 4, 0xF0 | (sb_irq << 2) | midi_irq);
1052        else    
1053                sscape_write (devc, 4, 0xF0 | (midi_irq<<2) | midi_irq);
1054
1055        i = 0x10; //sscape_read(devc, 9) & (devc->ic_type == IC_ODIE ? 0xf0 : 0xc0);
1056        if ( sscape_sb_enable )
1057                i |= devc->ic_type == IC_ODIE ? 0x05 : 0x07;        
1058        if (sscape_joystic_enable) i |= 8;
1059        
1060        sscape_write (devc, 9, i);
1061        sscape_write (devc, 6, 0x80);
1062        sscape_write (devc, 1, 0x80);
1063
1064        if (devc -> codec_type == 2) {
1065                sscape_pnp_write_codec( devc, 0x0C, 0x50);
1066                sscape_pnp_write_codec( devc, 0x10, sscape_pnp_read_codec( devc, 0x10) & 0x3F);
1067                sscape_pnp_write_codec( devc, 0x11, sscape_pnp_read_codec( devc, 0x11) | 0xC0);
1068                sscape_pnp_write_codec( devc, 29, 0x20);
1069        }
1070
1071        if (sscape_pnp_upload_file(devc, "/sndscape/scope.cod") == 0 ) {
1072                printk(KERN_ERR "sscape: faild to upload file /sndscape/scope.cod\n");
1073                sscape_pnp_free_dma(devc);
1074                return;
1075        }
1076
1077        i = sscape_read_host_ctrl( devc );
1078        
1079        if ( (i & 0x0F) >  7 ) {
1080                printk(KERN_ERR "sscape: scope.cod faild\n");
1081                sscape_pnp_free_dma(devc);
1082                return;
1083        }
1084        if ( i & 0x10 ) sscape_write( devc, 7, 0x2F);
1085        code_file_name[21] = (char) ( i & 0x0F) + 0x30;
1086        if (sscape_pnp_upload_file( devc, code_file_name) == 0) {
1087                printk(KERN_ERR "sscape: faild to upload file %s\n", code_file_name);
1088                sscape_pnp_free_dma(devc);
1089                return;
1090        }
1091        
1092        if (devc->ic_type != IC_ODIE) {
1093                sscape_pnp_write_codec( devc, 10, (sscape_pnp_read_codec(devc, 10) & 0x7f) |
1094                 ( sscape_mic_enable == 0 ? 0x00 : 0x80) );
1095        }
1096        sscape_write_host_ctrl2( devc, 0x84, 0x64 );  /* MIDI volume */
1097        sscape_write_host_ctrl2( devc, 0x86, 0x64 );  /* MIDI volume?? */
1098        sscape_write_host_ctrl2( devc, 0x8A, sscape_ext_midi);
1099
1100        sscape_pnp_write_codec ( devc, 6, 0x3f ); //WAV_VOL
1101        sscape_pnp_write_codec ( devc, 7, 0x3f ); //WAV_VOL
1102        sscape_pnp_write_codec ( devc, 2, 0x1F ); //WD_CDXVOLL
1103        sscape_pnp_write_codec ( devc, 3, 0x1F ); //WD_CDXVOLR
1104
1105        if (devc -> codec_type == 1) {
1106                sscape_pnp_write_codec ( devc, 4, 0x1F );
1107                sscape_pnp_write_codec ( devc, 5, 0x1F );
1108                sscape_write_host_ctrl2( devc, 0x88, sscape_mic_enable);
1109        } else {
1110                int t;
1111                sscape_pnp_write_codec ( devc, 0x10, 0x1F << 1);
1112                sscape_pnp_write_codec ( devc, 0x11, 0xC0 | (0x1F << 1));
1113
1114                t = sscape_pnp_read_codec( devc, 0x00) & 0xDF;
1115                if ( (sscape_mic_enable == 0)) t |= 0;
1116                else t |= 0x20;
1117                sscape_pnp_write_codec ( devc, 0x00, t);
1118                t = sscape_pnp_read_codec( devc, 0x01) & 0xDF;
1119                if ( (sscape_mic_enable == 0) ) t |= 0;
1120                else t |= 0x20;
1121                sscape_pnp_write_codec ( devc, 0x01, t);
1122                sscape_pnp_write_codec ( devc, 0x40 | 29 , 0x20);
1123                outb(0, devc -> codec);
1124        }
1125        if (devc -> ic_type == IC_OPUS ) {
1126                int i = sscape_read( devc, 9 );
1127                sscape_write( devc, 9, i | 3 );
1128                sscape_write( devc, 3, 0x40);
1129
1130                if (check_region(0x228, 1)) {
1131                            outb(0, 0x228);
1132                            release_region(0x228,1);
1133                }
1134                sscape_write( devc, 3, (devc -> dma << 4) | 0x80);
1135                sscape_write( devc, 9, i );
1136        }
1137        
1138        host_close ( devc );
1139        sscape_pnp_free_dma(devc);
1140}
1141
1142static int __init detect_sscape_pnp(sscape_info* devc)
1143{
1144        long     i, irq_bits = 0xff;
1145        unsigned int d;
1146
1147        DDB(printk("Entered detect_sscape_pnp(%x)\n", devc->base));
1148
1149        if (check_region(devc->base, 8)) {
1150                printk(KERN_ERR "detect_sscape_pnp: port %x is not free\n", devc->base);        
1151                return 0;
1152        }
1153                
1154        if (check_region(devc->codec, 2)) {
1155                printk(KERN_ERR "detect_sscape_pnp: port %x is not free\n", devc->codec);       
1156                return 0;
1157        }
1158
1159        if ( (inb( devc -> base + 2) & 0x78) != 0) return 0;
1160
1161        d = inb ( devc -> base + 4) & 0xF0;
1162        if (  (d & 0x80) != 0)  return 0;
1163        
1164        if (d == 0) {
1165                        devc->codec_type = 1;
1166                        devc->ic_type = IC_ODIE;
1167        }
1168        else if ( (d & 0x60) != 0) {
1169                        devc->codec_type = 2;
1170                        devc->ic_type = IC_OPUS;
1171        }
1172        else if ( (d & 0x40) != 0) {
1173                        devc->codec_type = 2;
1174                        devc->ic_type = IC_ODIE;
1175        } 
1176        else return 0;
1177        
1178        sscape_is_pnp = 1;
1179                
1180        outb(0xFA, devc -> base+4);
1181        if  ((inb( devc -> base+4) & 0x9F) != 0x0A)
1182                return 0;
1183        outb(0xFE, devc -> base+4);
1184        if  ( (inb(devc -> base+4) & 0x9F) != 0x0E)
1185                return 0;
1186        if  ( (inb(devc -> base+5) & 0x9F) != 0x0E)
1187                return 0;
1188
1189        if (devc->codec_type == 2) {
1190                if (devc -> codec != devc -> base + 8)
1191                        printk("soundscape warning: incorrect codec port specified\n");
1192                devc -> codec = devc -> base + 8;
1193                d = 0x10 | (sscape_read(devc, 9)  & 0xCF);
1194                sscape_write(devc, 9, d);
1195                sscape_write(devc, 6, 0x80);
1196        } else {
1197                //todo: check codec is not base + 8
1198        }
1199
1200        d  = (sscape_read(devc, 9) & 0x3F) | 0xC0;
1201        sscape_write(devc, 9, d);
1202
1203        for (i = 0; i < 550000; i++)
1204                if ( !(inb(devc -> codec) & 0x80) ) break;
1205
1206        d = inb(devc -> codec);
1207        if (d & 0x80)
1208                return 0;
1209        if ( inb(devc -> codec + 2) == 0xFF)
1210                return 0;
1211
1212        sscape_write(devc, 9, sscape_read(devc, 9)  & 0x3F );
1213
1214        d  = inb(devc -> codec) & 0x80;
1215        if ( d == 0) {
1216                printk(KERN_INFO "soundscape: hardware detected\n");
1217                valid_interrupts = valid_interrupts_new;
1218        } else  {
1219                printk(KERN_INFO "soundscape: board looks like media fx\n");
1220                valid_interrupts = valid_interrupts_old;
1221                old_hardware = 1;
1222        }
1223
1224        sscape_write( devc, 9, 0xC0 | (sscape_read(devc, 9)  & 0x3F) );
1225
1226        for (i = 0; i < 550000; i++)
1227                if ( !(inb(devc -> codec) & 0x80)) 
1228                        break;
1229                
1230        sscape_pnp_init_hw(devc);
1231
1232        for (i = 0; i < sizeof(valid_interrupts); i++)
1233        {
1234                if (devc->codec_irq == valid_interrupts[i]) {
1235                        irq_bits = i;
1236                        break;
1237                }
1238        }       
1239        sscape_write(devc, GA_INTENA_REG, 0x00);
1240        sscape_write(devc, GA_DMACFG_REG, 0x50);
1241        sscape_write(devc, GA_DMAA_REG, 0x70);
1242        sscape_write(devc, GA_DMAB_REG, 0x20);
1243        sscape_write(devc, GA_INTCFG_REG, 0xf0);
1244        sscape_write(devc, GA_CDCFG_REG, 0x89 | (devc->dma << 4) | (irq_bits << 1));
1245
1246        sscape_pnp_write_codec( devc, 0, sscape_pnp_read_codec( devc, 0) | 0x20);
1247        sscape_pnp_write_codec( devc, 0, sscape_pnp_read_codec( devc, 1) | 0x20);
1248
1249        return 1;       
1250}
1251
1252static int __init probe_sscape(struct address_info *hw_config)
1253{
1254
1255        if (sscape_detected != 0 && sscape_detected != hw_config->io_base)
1256                return 0;
1257
1258        devc->base = hw_config->io_base;
1259        devc->irq = hw_config->irq;
1260        devc->dma = hw_config->dma;
1261        devc->osp = hw_config->osp;
1262
1263#ifdef SSCAPE_DEBUG1
1264        /*
1265         * Temporary debugging aid. Print contents of the registers before
1266         * changing them.
1267         */
1268        {
1269                int i;
1270
1271                for (i = 0; i < 13; i++)
1272                        printk("I%d = %02x (old value)\n", i, sscape_read(devc, i));
1273        }
1274#endif
1275        devc->failed = 1;
1276
1277        if (!detect_ga(devc)) {
1278                if (detect_sscape_pnp(devc)) {                  
1279                        sscape_detected = hw_config->io_base;
1280                        return 1;
1281                } 
1282                else return 0;
1283        }
1284
1285        if (old_hardware)       /* Check that it's really an old Spea/Reveal card. */
1286        {
1287                unsigned char   tmp;
1288                int             cc;
1289
1290                if (!((tmp = sscape_read(devc, GA_HMCTL_REG)) & 0xc0))
1291                {
1292                        sscape_write(devc, GA_HMCTL_REG, tmp | 0x80);
1293                        for (cc = 0; cc < 200000; ++cc)
1294                                inb(devc->base + ODIE_ADDR);
1295                }
1296        }
1297        sscape_detected = hw_config->io_base;
1298        return 1;
1299}
1300
1301static int __init probe_ss_ms_sound(struct address_info *hw_config)
1302{
1303        int i, irq_bits = 0xff;
1304        int ad_flags = 0;
1305        
1306        if (devc->failed)
1307        {
1308                printk(KERN_ERR "soundscape: Card not detected\n");
1309                return 0;
1310        }
1311        if (devc->ok == 0)
1312        {
1313                printk(KERN_ERR "soundscape: Invalid initialization order.\n");
1314                return 0;
1315        }
1316        for (i = 0; i < sizeof(valid_interrupts); i++)
1317        {
1318                if (hw_config->irq == valid_interrupts[i])
1319                {
1320                        irq_bits = i;
1321                        break;
1322                }
1323        }
1324        if (hw_config->irq > 15 || irq_bits == 0xff)
1325        {
1326                printk(KERN_ERR "soundscape: Invalid MSS IRQ%d\n", hw_config->irq);
1327                return 0;
1328        }
1329        
1330        if (!sscape_is_pnp) {
1331                if (old_hardware)
1332                        ad_flags = 0x12345677;  /* Tell that we may have a CS4248 chip (Spea-V7 Media FX) */
1333                return ad1848_detect(hw_config->io_base, &ad_flags, hw_config->osp);
1334        } 
1335        else {
1336                if (old_hardware)
1337                        ad_flags = 0x12345677;  /* Tell that we may have a CS4248 chip (Spea-V7 Media FX) */
1338                else
1339                        ad_flags = 0x87654321;  /* Tell that we have a soundscape pnp with 1845 chip */
1340                return ad1848_detect(hw_config->io_base, &ad_flags, hw_config->osp);
1341        }
1342}
1343
1344static void __init attach_ss_ms_sound(struct address_info *hw_config)
1345{
1346        /*
1347         * This routine configures the SoundScape card for use with the
1348         * Win Sound System driver. The AD1848 codec interface uses the CD-ROM
1349         * config registers of the "ODIE".
1350         */
1351
1352        int i, irq_bits = 0xff;
1353
1354                
1355        if (!sscape_is_pnp)  /*pnp is already setup*/
1356        {
1357                /*
1358                 * Setup the DMA polarity.
1359                 */
1360                sscape_write(devc, GA_DMACFG_REG, 0x50);
1361        
1362                /*
1363                 * Take the gate-array off of the DMA channel.
1364                 */
1365                sscape_write(devc, GA_DMAB_REG, 0x20);
1366        
1367                /*
1368                 * Init the AD1848 (CD-ROM) config reg.
1369                 */
1370                for (i = 0; i < sizeof(valid_interrupts); i++)
1371                {
1372                        if (hw_config->irq == valid_interrupts[i])
1373                        {
1374                                irq_bits = i;
1375                                break;
1376                        }
1377                }       
1378                sscape_write(devc, GA_CDCFG_REG, 0x89 | (hw_config->dma << 4) | (irq_bits << 1));
1379        }
1380        
1381        if (hw_config->irq == devc->irq)
1382                printk(KERN_WARNING "soundscape: Warning! The WSS mode can't share IRQ with MIDI\n");
1383                                
1384        hw_config->slots[0] = ad1848_init(
1385                        sscape_is_pnp ? "SoundScape" : "SoundScape PNP",
1386                        hw_config->io_base,
1387                        hw_config->irq,
1388                        hw_config->dma,
1389                        hw_config->dma,
1390                        0,
1391                        devc->osp,
1392                        THIS_MODULE);
1393
1394                                          
1395        if (hw_config->slots[0] != -1)  /* The AD1848 driver installed itself */
1396        {
1397                audio_devs[hw_config->slots[0]]->coproc = &sscape_coproc_operations;
1398                devc->codec_audiodev = hw_config->slots[0];
1399                devc->my_audiodev = hw_config->slots[0];
1400
1401                /* Set proper routings here (what are they) */
1402                AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_LINE);
1403        }
1404                
1405#ifdef SSCAPE_DEBUG5
1406        /*
1407         * Temporary debugging aid. Print contents of the registers
1408         * after the AD1848 device has been initialized.
1409         */
1410        {
1411                int i;
1412
1413                for (i = 0; i < 13; i++)
1414                        printk("I%d = %02x\n", i, sscape_read(devc, i));
1415        }
1416#endif
1417
1418}
1419
1420static void __exit unload_sscape(struct address_info *hw_config)
1421{
1422        release_region(devc->base + 2, 6);
1423        unload_mpu401(hw_config);
1424}
1425
1426static void __exit unload_ss_ms_sound(struct address_info *hw_config)
1427{
1428        ad1848_unload(hw_config->io_base,
1429                      hw_config->irq,
1430                      devc->dma,
1431                      devc->dma,
1432                      0);
1433        sound_unload_audiodev(hw_config->slots[0]);
1434}
1435
1436static struct address_info cfg;
1437static struct address_info cfg_mpu;
1438
1439static int __initdata spea = -1;
1440static int __initdata mss = 0;
1441static int __initdata dma = -1;
1442static int __initdata irq = -1;
1443static int __initdata io = -1;
1444static int __initdata mpu_irq = -1;
1445static int __initdata mpu_io = -1;
1446
1447MODULE_PARM(dma, "i");
1448MODULE_PARM(irq, "i");
1449MODULE_PARM(io, "i");
1450MODULE_PARM(spea, "i");         /* spea=0/1 set the old_hardware */
1451MODULE_PARM(mpu_irq, "i");
1452MODULE_PARM(mpu_io, "i");
1453MODULE_PARM(mss, "i");
1454
1455static int __init init_sscape(void)
1456{
1457        printk(KERN_INFO "Soundscape driver Copyright (C) by Hannu Savolainen 1993-1996\n");
1458        
1459        cfg.irq = irq;
1460        cfg.dma = dma;
1461        cfg.io_base = io;
1462
1463        cfg_mpu.irq = mpu_irq;
1464        cfg_mpu.io_base = mpu_io;
1465        /* WEH - Try to get right dma channel */
1466        cfg_mpu.dma = dma;
1467        
1468        devc->codec = cfg.io_base;
1469        devc->codec_irq = cfg.irq;
1470        devc->codec_type = 0;
1471        devc->ic_type = 0;
1472        devc->raw_buf = NULL;
1473
1474        if (cfg.dma == -1 || cfg.irq == -1 || cfg.io_base == -1) {
1475                printk(KERN_ERR "DMA, IRQ, and IO port must be specified.\n");
1476                return -EINVAL;
1477        }
1478        
1479        if (cfg_mpu.irq == -1 && cfg_mpu.io_base != -1) {
1480                printk(KERN_ERR "MPU_IRQ must be specified if MPU_IO is set.\n");
1481                return -EINVAL;
1482        }
1483        
1484        if(spea != -1) {
1485                old_hardware = spea;
1486                printk(KERN_INFO "Forcing %s hardware support.\n",
1487                        spea?"new":"old");
1488        }       
1489        if (probe_sscape(&cfg_mpu) == 0)
1490                return -ENODEV;
1491
1492        attach_sscape(&cfg_mpu);
1493        
1494        mss = probe_ss_ms_sound(&cfg);
1495
1496        if (mss)
1497                attach_ss_ms_sound(&cfg);
1498
1499        return 0;
1500}
1501
1502static void __exit cleanup_sscape(void)
1503{
1504        if (mss)
1505                unload_ss_ms_sound(&cfg);
1506        unload_sscape(&cfg_mpu);
1507}
1508
1509module_init(init_sscape);
1510module_exit(cleanup_sscape);
1511
1512#ifndef MODULE
1513static int __init setup_sscape(char *str)
1514{
1515        /* io, irq, dma, mpu_io, mpu_irq */
1516        int ints[6];
1517        
1518        str = get_options(str, ARRAY_SIZE(ints), ints);
1519        
1520        io      = ints[1];
1521        irq     = ints[2];
1522        dma     = ints[3];
1523        mpu_io  = ints[4];
1524        mpu_irq = ints[5];
1525
1526        return 1;
1527}
1528
1529__setup("sscape=", setup_sscape);
1530#endif
1531MODULE_LICENSE("GPL");
1532
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.