!C99Shell v. 1.0 pre-release build #13!

Software: Apache/2.0.54 (Unix) mod_perl/1.99_09 Perl/v5.8.0 mod_ssl/2.0.54 OpenSSL/0.9.7l DAV/2 FrontPage/5.0.2.2635 PHP/4.4.0 mod_gzip/2.0.26.1a 

uname -a: Linux snow.he.net 4.4.276-v2-mono-1 #1 SMP Wed Jul 21 11:21:17 PDT 2021 i686 

uid=99(nobody) gid=98(nobody) groups=98(nobody) 

Safe-mode: OFF (not secure)

/usr/src/linux-2.4.18-xfs-1.1/drivers/sound/   drwxr-xr-x
Free 318.37 GB of 458.09 GB (69.5%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     mad16.c (22.47 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
 * Copyright (C) by Hannu Savolainen 1993-1997
 *
 * mad16.c
 *
 * Initialization code for OPTi MAD16 compatible audio chips. Including
 *
 *      OPTi 82C928     MAD16           (replaced by C929)
 *      OAK OTI-601D    Mozart
 *      OAK OTI-605    Mozart        (later version with MPU401 Midi)
 *      OPTi 82C929     MAD16 Pro
 *      OPTi 82C930
 *      OPTi 82C924
 *
 * These audio interface chips don't produce sound themselves. They just
 * connect some other components (OPL-[234] and a WSS compatible codec)
 * to the PC bus and perform I/O, DMA and IRQ address decoding. There is
 * also a UART for the MPU-401 mode (not 82C928/Mozart).
 * The Mozart chip appears to be compatible with the 82C928, although later
 * issues of the card, using the OTI-605 chip, have an MPU-401 compatable Midi
 * port. This port is configured differently to that of the OPTi audio chips.
 *
 *    Changes
 *    
 *    Alan Cox        Clean up, added module selections.
 *
 *    A. Wik            Added support for Opti924 PnP.
 *                Improved debugging support.    16-May-1998
 *                Fixed bug.            16-Jun-1998
 *
 *      Torsten Duwe            Made Opti924 PnP support non-destructive
 *                                                                 23-Dec-1998
 *
 *    Paul Grayson        Added support for Midi on later Mozart cards.
 *                                25-Nov-1999
 *    Christoph Hellwig    Adapted to module_init/module_exit.
 *    Arnaldo C. de Melo    got rid of attach_uart401       21-Sep-2000
 *
 *    Pavel Rabel        Clean up                           Nov-2000
 */

#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>

#include "sound_config.h"

#include "ad1848.h"
#include "sb.h"
#include "mpu401.h"

static int      mad16_conf;
static int      mad16_cdsel;

static int      already_initialized = 0;

#define C928    1
#define MOZART    2
#define C929    3
#define C930    4
#define C924    5

/*
 *    Registers
 *
 *      The MAD16 occupies I/O ports 0xf8d to 0xf93 (fixed locations).
 *      All ports are inactive by default. They can be activated by
 *      writing 0xE2 or 0xE3 to the password register. The password is valid
 *      only until the next I/O read or write.
 *
 *      82C930 uses 0xE4 as the password and indirect addressing to access
 *      the config registers.
 */

#define MC0_PORT    0xf8c    /* Dummy port */
#define MC1_PORT    0xf8d    /* SB address, CD-ROM interface type, joystick */
#define MC2_PORT    0xf8e    /* CD-ROM address, IRQ, DMA, plus OPL4 bit */
#define MC3_PORT    0xf8f
#define PASSWD_REG    0xf8f
#define MC4_PORT    0xf90
#define MC5_PORT    0xf91
#define MC6_PORT    0xf92
#define MC7_PORT    0xf93
#define MC8_PORT    0xf94
#define MC9_PORT    0xf95
#define MC10_PORT    0xf96
#define MC11_PORT    0xf97
#define MC12_PORT    0xf98

static int      board_type = C928;

static int     *mad16_osp;
static int    c931_detected;    /* minor differences from C930 */
static char    c924pnp = 0;    /* "     "           "    C924 */
static int    debug = 0;    /* debugging output */

#ifdef DDB
#undef DDB
#endif
#define DDB(x) {if (debug) x;}

static unsigned char mad_read(int port)
{
    unsigned long flags;
    unsigned char tmp;

    save_flags(flags);
    cli();

    switch (board_type)    /* Output password */
    {
        case C928:
        case MOZART:
            outb((0xE2), PASSWD_REG);
            break;

        case C929:
            outb((0xE3), PASSWD_REG);
            break;

        case C930:
            /* outb(( 0xE4),  PASSWD_REG); */
            break;

        case C924:
            /* the c924 has its ports relocated by -128 if
               PnP is enabled  -aw */
            if (!c924pnp)
                outb((0xE5), PASSWD_REG); else
                outb((0xE5), PASSWD_REG - 0x80);
            break;
    }

    if (board_type == C930)
    {
        outb((port - MC0_PORT), 0xe0e);    /* Write to index reg */
        tmp = inb(0xe0f);    /* Read from data reg */
    }
    else
        if (!c924pnp)
            tmp = inb(port); else
            tmp = inb(port-0x80);
    restore_flags(flags);

    return tmp;
}

static void mad_write(int port, int value)
{
    unsigned long   flags;

    save_flags(flags);
    cli();

    switch (board_type)    /* Output password */
    {
        case C928:
        case MOZART:
            outb((0xE2), PASSWD_REG);
            break;

        case C929:
            outb((0xE3), PASSWD_REG);
            break;

        case C930:
            /* outb(( 0xE4),  PASSWD_REG); */
            break;

        case C924:
            if (!c924pnp)
                outb((0xE5), PASSWD_REG); else
                outb((0xE5), PASSWD_REG - 0x80);
            break;
    }

    if (board_type == C930)
    {
        outb((port - MC0_PORT), 0xe0e);    /* Write to index reg */
        outb(((unsigned char) (value & 0xff)), 0xe0f);
    }
    else
        if (!c924pnp)
            outb(((unsigned char) (value & 0xff)), port); else
            outb(((unsigned char) (value & 0xff)), port-0x80);
    restore_flags(flags);
}

static int __init detect_c930(void)
{
    unsigned char   tmp = mad_read(MC1_PORT);

    if ((tmp & 0x06) != 0x06)
    {
        DDB(printk("Wrong C930 signature (%x)\n", tmp));
        /* return 0; */
    }
    mad_write(MC1_PORT, 0);

    if (mad_read(MC1_PORT) != 0x06)
    {
        DDB(printk("Wrong C930 signature2 (%x)\n", tmp));
        /* return 0; */
    }
    mad_write(MC1_PORT, tmp);    /* Restore bits */

    mad_write(MC7_PORT, 0);
    if ((tmp = mad_read(MC7_PORT)) != 0)
    {
        DDB(printk("MC7 not writable (%x)\n", tmp));
        return 0;
    }
    mad_write(MC7_PORT, 0xcb);
    if ((tmp = mad_read(MC7_PORT)) != 0xcb)
    {
        DDB(printk("MC7 not writable2 (%x)\n", tmp));
        return 0;
    }

    tmp = mad_read(MC0_PORT+18);
    if (tmp == 0xff || tmp == 0x00)
        return 1;
    /* We probably have a C931 */
    DDB(printk("Detected C931 config=0x%02x\n", tmp));
    c931_detected = 1;

    /*
         * We cannot configure the chip if it is in PnP mode.
         * If we have a CSN assigned (bit 8 in MC13) we first try
         * a software reset, then a software power off, finally
         * Clearing PnP mode. The last option is not
     * Bit 8 in MC13 
         */
    if ((mad_read(MC0_PORT+13) & 0x80) == 0)
        return 1;

    /* Software reset */
    mad_write(MC9_PORT, 0x02);
    mad_write(MC9_PORT, 0x00);

    if ((mad_read(MC0_PORT+13) & 0x80) == 0)
        return 1;
    
    /* Power off, and on again */
    mad_write(MC9_PORT, 0xc2);
    mad_write(MC9_PORT, 0xc0);

    if ((mad_read(MC0_PORT+13) & 0x80) == 0)
        return 1;
    
#if 0    
    /* Force off PnP mode. This is not recommended because
     * the PnP bios will not recognize the chip on the next
     * warm boot and may assignd different resources to other
     * PnP/PCI cards.
     */
    mad_write(MC0_PORT+17, 0x04);
#endif
    return 1;
}

static int __init detect_mad16(void)
{
    unsigned char tmp, tmp2, bit;
    int i, port;

    /*
     * Check that reading a register doesn't return bus float (0xff)
     * when the card is accessed using password. This may fail in case
     * the card is in low power mode. Normally at least the power saving
     * mode bit should be 0.
     */

    if ((tmp = mad_read(MC1_PORT)) == 0xff)
    {
        DDB(printk("MC1_PORT returned 0xff\n"));
        return 0;
    }
    for (i = 0xf8d; i <= 0xf98; i++)
        if (!c924pnp)
            DDB(printk("Port %0x (init value) = %0x\n", i, mad_read(i))) else
            DDB(printk("Port %0x (init value) = %0x\n", i-0x80, mad_read(i)));

    if (board_type == C930)
        return detect_c930();

    /*
     * Now check that the gate is closed on first I/O after writing
     * the password. (This is how a MAD16 compatible card works).
     */

    if ((tmp2 = inb(MC1_PORT)) == tmp)    /* It didn't close */
    {
        DDB(printk("MC1_PORT didn't close after read (0x%02x)\n", tmp2));
        return 0;
    }

    bit  = (c924pnp) ?     0x20 : 0x80;
    port = (c924pnp) ? MC2_PORT : MC1_PORT;

    tmp = mad_read(port);
    mad_write(port, tmp ^ bit);    /* Toggle a bit */
    if ((tmp2 = mad_read(port)) != (tmp ^ bit))    /* Compare the bit */
    {
        mad_write(port, tmp);    /* Restore */
        DDB(printk("Bit revert test failed (0x%02x, 0x%02x)\n", tmp, tmp2));
        return 0;
    }
    mad_write(port, tmp);    /* Restore */
    return 1;        /* Bingo */
}

static int __init wss_init(struct address_info *hw_config)
{
    int ad_flags = 0;

    /*
     *    Verify the WSS parameters
     */

    if (check_region(hw_config->io_base, 8))
    {
        printk(KERN_ERR "MSS: I/O port conflict\n");
        return 0;
    }
    if (!ad1848_detect(hw_config->io_base + 4, &ad_flags, mad16_osp))
        return 0;
    /*
     * Check if the IO port returns valid signature. The original MS Sound
     * system returns 0x04 while some cards (AudioTrix Pro for example)
     * return 0x00.
     */

    if ((inb(hw_config->io_base + 3) & 0x3f) != 0x04 &&
        (inb(hw_config->io_base + 3) & 0x3f) != 0x00)
    {
        DDB(printk("No MSS signature detected on port 0x%x (0x%x)\n", hw_config->io_base, inb(hw_config->io_base + 3)));
        return 0;
    }
    if (hw_config->irq > 11)
    {
        printk(KERN_ERR "MSS: Bad IRQ %d\n", hw_config->irq);
        return 0;
    }
    if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3)
    {
        printk(KERN_ERR "MSS: Bad DMA %d\n", hw_config->dma);
        return 0;
    }
    /*
     * Check that DMA0 is not in use with a 8 bit board.
     */

    if (hw_config->dma == 0 && inb(hw_config->io_base + 3) & 0x80)
    {
        printk("MSS: Can't use DMA0 with a 8 bit card/slot\n");
        return 0;
    }
    if (hw_config->irq > 7 && hw_config->irq != 9 && inb(hw_config->io_base + 3) & 0x80)
        printk(KERN_ERR "MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
    return 1;
}

static int __init init_c930(struct address_info *hw_config)
{
    unsigned char cfg = 0;

    if(c931_detected)
    {
        /* Bit 0 has reversd meaning. Bits 1 and 2 sese
           reversed on write.
           Support only IDE cdrom. IDE port programmed
           somewhere else. */
        cfg =  (cfg & 0x09) ^ 0x07;
    }

    switch (hw_config->io_base)
    {
        case 0x530:
            cfg |= 0x00;
            break;
        case 0xe80:
            cfg |= 0x10;
            break;
        case 0xf40:
            cfg |= 0x20;
            break;
        case 0x604:
            cfg |= 0x30;
            break;
        default:
            printk(KERN_ERR "MAD16: Invalid codec port %x\n", hw_config->io_base);
            return 0;
    }
    mad_write(MC1_PORT, cfg);

    /* MC2 is CD configuration. Don't touch it. */

    mad_write(MC3_PORT, 0);    /* Disable SB mode IRQ and DMA */

    /* bit 2 of MC4 reverses it's meaning between the C930
       and the C931. */
    cfg = c931_detected ? 0x04 : 0x00;

    mad_write(MC4_PORT, 0x52|cfg);

    mad_write(MC5_PORT, 0x3C);    /* Init it into mode2 */
    mad_write(MC6_PORT, 0x02);    /* Enable WSS, Disable MPU and SB */
    mad_write(MC7_PORT, 0xCB);
    mad_write(MC10_PORT, 0x11);

    return wss_init(hw_config);
}

static int __init chip_detect(void)
{
    int i;

    /*
     *    Then try to detect with the old password
     */
    board_type = C924;

    DDB(printk("Detect using password = 0xE5\n"));
    
    if (detect_mad16()) {
        return 1;
    }
    
    board_type = C928;

    DDB(printk("Detect using password = 0xE2\n"));

    if (detect_mad16())
    {
        unsigned char model;

        if (((model = mad_read(MC3_PORT)) & 0x03) == 0x03) {
            DDB(printk("mad16.c: Mozart detected\n"));
            board_type = MOZART;
        } else {
            DDB(printk("mad16.c: 82C928 detected???\n"));
            board_type = C928;
        }
        return 1;
    }

    board_type = C929;

    DDB(printk("Detect using password = 0xE3\n"));

    if (detect_mad16())
    {
        DDB(printk("mad16.c: 82C929 detected\n"));
        return 1;
    }

    if (inb(PASSWD_REG) != 0xff)
        return 0;

    /*
     * First relocate MC# registers to 0xe0e/0xe0f, disable password 
     */

    outb((0xE4), PASSWD_REG);
    outb((0x80), PASSWD_REG);

    board_type = C930;

    DDB(printk("Detect using password = 0xE4\n"));

    for (i = 0xf8d; i <= 0xf93; i++)
        DDB(printk("port %03x = %02x\n", i, mad_read(i)));

        if(detect_mad16()) {
        DDB(printk("mad16.c: 82C930 detected\n"));
        return 1;
    }

    /* The C931 has the password reg at F8D */
    outb((0xE4), 0xF8D);
    outb((0x80), 0xF8D);
    DDB(printk("Detect using password = 0xE4 for C931\n"));

    if (detect_mad16()) {
        return 1;
    }

    board_type = C924;
    c924pnp++;
    DDB(printk("Detect using password = 0xE5 (again), port offset -0x80\n"));
    if (detect_mad16()) {
        DDB(printk("mad16.c: 82C924 PnP detected\n"));
        return 1;
    }
    
    c924pnp=0;

    return 0;
}

static int __init probe_mad16(struct address_info *hw_config)
{
    int i;
    static int valid_ports[] = 
    {
        0x530, 0xe80, 0xf40, 0x604
    };
    unsigned char tmp;
    unsigned char cs4231_mode = 0;

    int ad_flags = 0;

    if (already_initialized)
        return 0;

    mad16_osp = hw_config->osp;

    /*
     *    Check that all ports return 0xff (bus float) when no password
     *      is written to the password register.
     */

    DDB(printk("--- Detecting MAD16 / Mozart ---\n"));
    if (!chip_detect())
        return 0;

    if (board_type == C930)
        return init_c930(hw_config);


    for (i = 0xf8d; i <= 0xf93; i++)
        if (!c924pnp)
            DDB(printk("port %03x = %02x\n", i, mad_read(i))) else
            DDB(printk("port %03x = %02x\n", i-0x80, mad_read(i)));

/*
 * Set the WSS address
 */

    tmp = (mad_read(MC1_PORT) & 0x0f) | 0x80;    /* Enable WSS, Disable SB */

    for (i = 0; i < 5; i++)
    {
        if (i > 3)    /* Not a valid port */
        {
            printk(KERN_ERR "MAD16/Mozart: Bad WSS base address 0x%x\n", hw_config->io_base);
            return 0;
        }
        if (valid_ports[i] == hw_config->io_base)
        {
            tmp |= i << 4;    /* WSS port select bits */
            break;
        }
    }

    /*
     * Set optional CD-ROM and joystick settings.
     */

    tmp &= ~0x0f;
    mad_write(MC1_PORT, tmp);

    tmp = mad_read(MC2_PORT);

    mad_write(MC2_PORT, tmp);
    mad_write(MC3_PORT, 0xf0);    /* Disable SB */

    if (board_type == C924)    /* Specific C924 init values */
    {
        mad_write(MC4_PORT, 0xA0);
        mad_write(MC5_PORT, 0x05);
        mad_write(MC6_PORT, 0x03);
    }
    if (!ad1848_detect(hw_config->io_base + 4, &ad_flags, mad16_osp))
        return 0;

    if (ad_flags & (AD_F_CS4231 | AD_F_CS4248))
        cs4231_mode = 0x02;    /* CS4248/CS4231 sync delay switch */

    if (board_type == C929)
    {
        mad_write(MC4_PORT, 0xa2);
        mad_write(MC5_PORT, 0xA5 | cs4231_mode);
        mad_write(MC6_PORT, 0x03);    /* Disable MPU401 */
    }
    else
    {
        mad_write(MC4_PORT, 0x02);
        mad_write(MC5_PORT, 0x30 | cs4231_mode);
    }

    for (i = 0xf8d; i <= 0xf93; i++) if (!c924pnp)
        DDB(printk("port %03x after init = %02x\n", i, mad_read(i))) else
        DDB(printk("port %03x after init = %02x\n", i-0x80, mad_read(i)));
    wss_init(hw_config);

    return 1;
}

static void __init attach_mad16(struct address_info *hw_config)
{

    static signed char     interrupt_bits[12] = {
        -1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20
    };
    signed char bits;

    static char     dma_bits[4] = {
        1, 2, 0, 3
    };

    int config_port = hw_config->io_base + 0, version_port = hw_config->io_base + 3;
    int ad_flags = 0, dma = hw_config->dma, dma2 = hw_config->dma2;
    unsigned char dma2_bit = 0;

    already_initialized = 1;

    if (!ad1848_detect(hw_config->io_base + 4, &ad_flags, mad16_osp))
        return;

    /*
     * Set the IRQ and DMA addresses.
     */
    
    if (board_type == C930 || c924pnp)
        interrupt_bits[5] = 0x28;    /* Also IRQ5 is possible on C930 */

    bits = interrupt_bits[hw_config->irq];
    if (bits == -1)
        return;

    outb((bits | 0x40), config_port);
    if ((inb(version_port) & 0x40) == 0)
        printk(KERN_ERR "[IRQ Conflict?]\n");

    /*
     * Handle the capture DMA channel
     */

    if (ad_flags & AD_F_CS4231 && dma2 != -1 && dma2 != dma)
    {
        if (!((dma == 0 && dma2 == 1) ||
            (dma == 1 && dma2 == 0) ||
            (dma == 3 && dma2 == 0)))
        {        /* Unsupported combination. Try to swap channels */
            int tmp = dma;

            dma = dma2;
            dma2 = tmp;
        }
        if ((dma == 0 && dma2 == 1) || (dma == 1 && dma2 == 0) ||
            (dma == 3 && dma2 == 0))
        {
            dma2_bit = 0x04;    /* Enable capture DMA */
        }
        else
        {
            printk("MAD16: Invalid capture DMA\n");
            dma2 = dma;
        }
    }
    else dma2 = dma;

    outb((bits | dma_bits[dma] | dma2_bit), config_port);    /* Write IRQ+DMA setup */

    hw_config->slots[0] = ad1848_init("MAD16 WSS", hw_config->io_base + 4,
                      hw_config->irq,
                      dma,
                      dma2, 0,
                      hw_config->osp,
                      THIS_MODULE);
    request_region(hw_config->io_base, 4, "MAD16 WSS config");
}

static int __init probe_mad16_mpu(struct address_info *hw_config)
{
    static int mpu_attached = 0;
    unsigned char tmp;

    if (!already_initialized)    /* The MSS port must be initialized first */
        return 0;

    if (mpu_attached)        /* Don't let them call this twice */
        return 0;
    mpu_attached = 1;

    if (board_type < C929)    /* Early chip. No MPU support. Just SB MIDI */
    {

#ifdef CONFIG_MAD16_OLDCARD

        tmp = mad_read(MC3_PORT);

        /* 
         * MAD16 SB base is defined by the WSS base. It cannot be changed 
         * alone.
         * Ignore configured I/O base. Use the active setting. 
         */

        if (mad_read(MC1_PORT) & 0x20)
            hw_config->io_base = 0x240;
        else
            hw_config->io_base = 0x220;

        switch (hw_config->irq)
        {
            case 5:
                tmp = (tmp & 0x3f) | 0x80;
                break;
            case 7:
                tmp = (tmp & 0x3f);
                break;
            case 11:
                tmp = (tmp & 0x3f) | 0x40;
                break;
            default:
                printk(KERN_ERR "mad16/Mozart: Invalid MIDI IRQ\n");
                return 0;
        }

        mad_write(MC3_PORT, tmp | 0x04);
        hw_config->driver_use_1 = SB_MIDI_ONLY;
        if (!sb_dsp_detect(hw_config, 0, 0, NULL))
            return 0;

        if (mad_read(MC1_PORT) & 0x20)
            hw_config->io_base = 0x240;
        else
            hw_config->io_base = 0x220;

        hw_config->name = "Mad16/Mozart";
        sb_dsp_init(hw_config, THIS_MODULE);
        return 1;
#else
        /* assuming all later Mozart cards are identified as
         * either 82C928 or Mozart. If so, following code attempts
         * to set MPU register. TODO - add probing
         */

        tmp = mad_read(MC8_PORT);

        switch (hw_config->irq)
        {
            case 5:
                tmp |= 0x08;
                break;
            case 7:
                tmp |= 0x10;
                break;
            case 9:
                tmp |= 0x18;
                break;
            case 10:
                tmp |= 0x20;
                break;
            case 11:
                tmp |= 0x28;
                break;
            default:
                printk(KERN_ERR "mad16/MOZART: invalid mpu_irq\n");
                return 0;
        }

        switch (hw_config->io_base)
        {
            case 0x300:
                tmp |= 0x01;
                break;
            case 0x310:
                tmp |= 0x03;
                break;
            case 0x320:
                tmp |= 0x05;
                break;
            case 0x330:
                tmp |= 0x07;
                break;
            default:
                printk(KERN_ERR "mad16/MOZART: invalid mpu_io\n");
                return 0;
        }

        mad_write(MC8_PORT, tmp);    /* write MPU port parameters */
        goto probe_401;
#endif
    }
    tmp = mad_read(MC6_PORT) & 0x83;
    tmp |= 0x80;        /* MPU-401 enable */

    /* Set the MPU base bits */

    switch (hw_config->io_base)
    {
        case 0x300:
            tmp |= 0x60;
            break;
        case 0x310:
            tmp |= 0x40;
            break;
        case 0x320:
            tmp |= 0x20;
            break;
        case 0x330:
            tmp |= 0x00;
            break;
        default:
            printk(KERN_ERR "MAD16: Invalid MIDI port 0x%x\n", hw_config->io_base);
            return 0;
    }

    /* Set the MPU IRQ bits */

    switch (hw_config->irq)
    {
        case 5:
            tmp |= 0x10;
            break;
        case 7:
            tmp |= 0x18;
            break;
        case 9:
            tmp |= 0x00;
            break;
        case 10:
            tmp |= 0x08;
            break;
        default:
            printk(KERN_ERR "MAD16: Invalid MIDI IRQ %d\n", hw_config->irq);
            break;
    }
            
    mad_write(MC6_PORT, tmp);    /* Write MPU401 config */

#ifndef CONFIG_MAD16_OLDCARD
probe_401:
#endif
    hw_config->driver_use_1 = SB_MIDI_ONLY;
    hw_config->name = "Mad16/Mozart";
    return probe_uart401(hw_config, THIS_MODULE);
}

static void __exit unload_mad16(struct address_info *hw_config)
{
    ad1848_unload(hw_config->io_base + 4,
            hw_config->irq,
            hw_config->dma,
            hw_config->dma2, 0);
    release_region(hw_config->io_base, 4);
    sound_unload_audiodev(hw_config->slots[0]);
}

static void __exit unload_mad16_mpu(struct address_info *hw_config)
{
#ifdef CONFIG_MAD16_OLDCARD
    if (board_type < C929)    /* Early chip. No MPU support. Just SB MIDI */
    {
        sb_dsp_unload(hw_config, 0);
        return;
    }
#endif

    unload_uart401(hw_config);
}

static struct address_info cfg;
static struct address_info cfg_mpu;

static int found_mpu;

static int __initdata mpu_io = 0;
static int __initdata mpu_irq = 0;
static int __initdata io = -1;
static int __initdata dma = -1;
static int __initdata dma16 = -1; /* Set this for modules that need it */
static int __initdata irq = -1;
static int __initdata cdtype = 0;
static int __initdata cdirq = 0;
static int __initdata cdport = 0x340;
static int __initdata cddma = -1;
static int __initdata opl4 = 0;
static int __initdata joystick = 0;

MODULE_PARM(mpu_io, "i");
MODULE_PARM(mpu_irq, "i");
MODULE_PARM(io,"i");
MODULE_PARM(dma,"i");
MODULE_PARM(dma16,"i");
MODULE_PARM(irq,"i");
MODULE_PARM(cdtype,"i");
MODULE_PARM(cdirq,"i");
MODULE_PARM(cdport,"i");
MODULE_PARM(cddma,"i");
MODULE_PARM(opl4,"i");
MODULE_PARM(joystick,"i");
MODULE_PARM(debug,"i");

static int __initdata dma_map[2][8] =
{
    {0x03, -1, -1, -1, -1, 0x00, 0x01, 0x02},
    {0x03, -1, 0x01, 0x00, -1, -1, -1, -1}
};

static int __initdata irq_map[16] =
{
    0x00, -1, -1, 0x0A,
    -1, 0x04, -1, 0x08,
    -1, 0x10, 0x14, 0x18,
    -1, -1, -1, -1
};

static int __init init_mad16(void)
{
    int dmatype = 0;

    printk(KERN_INFO "MAD16 audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");

    printk(KERN_INFO "CDROM ");
    switch (cdtype)
    {
        case 0x00:
            printk("Disabled");
            cdirq = 0;
            break;
        case 0x02:
            printk("Sony CDU31A");
            dmatype = 1;
            if(cddma == -1) cddma = 3;
            break;
        case 0x04:
            printk("Mitsumi");
            dmatype = 0;
            if(cddma == -1) cddma = 5;
            break;
        case 0x06:
            printk("Panasonic Lasermate");
            dmatype = 1;
            if(cddma == -1) cddma = 3;
            break;
        case 0x08:
            printk("Secondary IDE");
            dmatype = 0;
            if(cddma == -1) cddma = 5;
            break;
        case 0x0A:
            printk("Primary IDE");
            dmatype = 0;
            if(cddma == -1) cddma = 5;
            break;
        default:
            printk("\n");
            printk(KERN_ERR "Invalid CDROM type\n");
            return -EINVAL;
    }

     /*
         *    Build the config words
         */

        mad16_conf = (joystick ^ 1) | cdtype;
    mad16_cdsel = 0;
        if (opl4)
                mad16_cdsel |= 0x20;

    if(cdtype){
        if (cddma > 7 || cddma < 0 || dma_map[dmatype][cddma] == -1)
        {
            printk("\n");
            printk(KERN_ERR "Invalid CDROM DMA\n");
            return -EINVAL;
        }
        if (cddma)
            printk(", DMA %d", cddma);
        else
            printk(", no DMA");

        if (!cdirq)
            printk(", no IRQ");
        else if (cdirq < 0 || cdirq > 15 || irq_map[cdirq] == -1)
        {
              printk(", invalid IRQ (disabling)");
              cdirq = 0;
        }
        else printk(", IRQ %d", cdirq);

        mad16_cdsel |= dma_map[dmatype][cddma];

        if (cdtype < 0x08)
        {
            switch (cdport)
            {
                case 0x340:
                    mad16_cdsel |= 0x00;
                    break;
                case 0x330:
                    mad16_cdsel |= 0x40;
                    break;
                case 0x360:
                    mad16_cdsel |= 0x80;
                    break;
                case 0x320:
                    mad16_cdsel |= 0xC0;
                    break;
                default:
                    printk(KERN_ERR "Unknown CDROM I/O base %d\n", cdport);
                    return -EINVAL;
            }
        }
        mad16_cdsel |= irq_map[cdirq];
    }

    printk(".\n");
        printk(KERN_INFO "Joystick port ");
        if (joystick == 1)
                printk("enabled.\n");
        else
        {
                joystick = 0;
                printk("disabled.\n");
        }

    cfg.io_base = io;
    cfg.irq = irq;
    cfg.dma = dma;
    cfg.dma2 = dma16;

    if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) {
        printk(KERN_ERR "I/O, DMA and irq are mandatory\n");
        return -EINVAL;
    }
    
    if (!probe_mad16(&cfg))
        return -ENODEV;

    cfg_mpu.io_base = mpu_io;
    cfg_mpu.irq = mpu_irq;

    attach_mad16(&cfg);

    found_mpu = probe_mad16_mpu(&cfg_mpu);
    return 0;
}

static void __exit cleanup_mad16(void)
{
    if (found_mpu)
        unload_mad16_mpu(&cfg_mpu);
    unload_mad16(&cfg);
}

module_init(init_mad16);
module_exit(cleanup_mad16);

#ifndef MODULE
static int __init setup_mad16(char *str)
{
        /* io, irq */
    int ints[7];
    
    str = get_options(str, ARRAY_SIZE(ints), ints);

    io    = ints[1];
    irq    = ints[2];
    dma    = ints[3];
    dma16    = ints[4];
    mpu_io    = ints[5];
    mpu_irq = ints[6];

    return 1;
}

__setup("mad16=", setup_mad16);
#endif
MODULE_LICENSE("GPL");

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0264 ]--