linux/sound/oss/waveartist.c
<<
>>
Prefs
   1/*
   2 * linux/sound/oss/waveartist.c
   3 *
   4 * The low level driver for the RWA010 Rockwell Wave Artist
   5 * codec chip used in the Rebel.com NetWinder.
   6 *
   7 * Cleaned up and integrated into 2.1 by Russell King (rmk@arm.linux.org.uk)
   8 * and Pat Beirne (patb@corel.ca)
   9 *
  10 *
  11 * Copyright (C) by Rebel.com 1998-1999
  12 *
  13 * RWA010 specs received under NDA from Rockwell
  14 *
  15 * Copyright (C) by Hannu Savolainen 1993-1997
  16 *
  17 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
  18 * Version 2 (June 1991). See the "COPYING" file distributed with this software
  19 * for more info.
  20 *
  21 * Changes:
  22 * 11-10-2000   Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
  23 *              Added __init to waveartist_init()
  24 */
  25
  26/* Debugging */
  27#define DEBUG_CMD       1
  28#define DEBUG_OUT       2
  29#define DEBUG_IN        4
  30#define DEBUG_INTR      8
  31#define DEBUG_MIXER     16
  32#define DEBUG_TRIGGER   32
  33
  34#define debug_flg (0)
  35
  36#include <linux/module.h>
  37#include <linux/init.h>
  38#include <linux/slab.h>
  39#include <linux/sched.h>
  40#include <linux/interrupt.h>
  41#include <linux/delay.h>
  42#include <linux/spinlock.h>
  43#include <linux/bitops.h>
  44
  45#include <asm/system.h>
  46
  47#include "sound_config.h"
  48#include "waveartist.h"
  49
  50#ifdef CONFIG_ARM
  51#include <mach/hardware.h>
  52#include <asm/mach-types.h>
  53#endif
  54
  55#ifndef NO_DMA
  56#define NO_DMA  255
  57#endif
  58
  59#define SUPPORTED_MIXER_DEVICES         (SOUND_MASK_SYNTH      |\
  60                                         SOUND_MASK_PCM        |\
  61                                         SOUND_MASK_LINE       |\
  62                                         SOUND_MASK_MIC        |\
  63                                         SOUND_MASK_LINE1      |\
  64                                         SOUND_MASK_RECLEV     |\
  65                                         SOUND_MASK_VOLUME     |\
  66                                         SOUND_MASK_IMIX)
  67
  68static unsigned short levels[SOUND_MIXER_NRDEVICES] = {
  69        0x5555,         /* Master Volume         */
  70        0x0000,         /* Bass                  */
  71        0x0000,         /* Treble                */
  72        0x2323,         /* Synth (FM)            */
  73        0x4b4b,         /* PCM                   */
  74        0x6464,         /* PC Speaker            */
  75        0x0000,         /* Ext Line              */
  76        0x0000,         /* Mic                   */
  77        0x0000,         /* CD                    */
  78        0x6464,         /* Recording monitor     */
  79        0x0000,         /* SB PCM (ALT PCM)      */
  80        0x0000,         /* Recording level       */
  81        0x6464,         /* Input gain            */
  82        0x6464,         /* Output gain           */
  83        0x0000,         /* Line1 (Aux1)          */
  84        0x0000,         /* Line2 (Aux2)          */
  85        0x0000,         /* Line3 (Aux3)          */
  86        0x0000,         /* Digital1              */
  87        0x0000,         /* Digital2              */
  88        0x0000,         /* Digital3              */
  89        0x0000,         /* Phone In              */
  90        0x6464,         /* Phone Out             */
  91        0x0000,         /* Video                 */
  92        0x0000,         /* Radio                 */
  93        0x0000          /* Monitor               */
  94};
  95
  96typedef struct {
  97        struct address_info  hw;        /* hardware */
  98        char            *chip_name;
  99
 100        int             xfer_count;
 101        int             audio_mode;
 102        int             open_mode;
 103        int             audio_flags;
 104        int             record_dev;
 105        int             playback_dev;
 106        int             dev_no;
 107
 108        /* Mixer parameters */
 109        const struct waveartist_mixer_info *mix;
 110
 111        unsigned short  *levels;           /* cache of volume settings   */
 112        int             recmask;           /* currently enabled recording device! */
 113
 114#ifdef CONFIG_ARCH_NETWINDER
 115        signed int      slider_vol;        /* hardware slider volume     */
 116        unsigned int    handset_detect  :1;
 117        unsigned int    telephone_detect:1;
 118        unsigned int    no_autoselect   :1;/* handset/telephone autoselects a path */
 119        unsigned int    spkr_mute_state :1;/* set by ioctl or autoselect */
 120        unsigned int    line_mute_state :1;/* set by ioctl or autoselect */
 121        unsigned int    use_slider      :1;/* use slider setting for o/p vol */
 122#endif
 123} wavnc_info;
 124
 125/*
 126 * This is the implementation specific mixer information.
 127 */
 128struct waveartist_mixer_info {
 129        unsigned int    supported_devs;    /* Supported devices */
 130        unsigned int    recording_devs;    /* Recordable devies */
 131        unsigned int    stereo_devs;       /* Stereo devices    */
 132
 133        unsigned int    (*select_input)(wavnc_info *, unsigned int,
 134                                        unsigned char *, unsigned char *);
 135        int             (*decode_mixer)(wavnc_info *, int,
 136                                        unsigned char, unsigned char);
 137        int             (*get_mixer)(wavnc_info *, int);
 138};
 139
 140typedef struct wavnc_port_info {
 141        int             open_mode;
 142        int             speed;
 143        int             channels;
 144        int             audio_format;
 145} wavnc_port_info;
 146
 147static int              nr_waveartist_devs;
 148static wavnc_info       adev_info[MAX_AUDIO_DEV];
 149static DEFINE_SPINLOCK(waveartist_lock);
 150
 151#ifndef CONFIG_ARCH_NETWINDER
 152#define machine_is_netwinder() 0
 153#else
 154static struct timer_list vnc_timer;
 155static void vnc_configure_mixer(wavnc_info *devc, unsigned int input_mask);
 156static int vnc_private_ioctl(int dev, unsigned int cmd, int __user *arg);
 157static void vnc_slider_tick(unsigned long data);
 158#endif
 159
 160static inline void
 161waveartist_set_ctlr(struct address_info *hw, unsigned char clear, unsigned char set)
 162{
 163        unsigned int ctlr_port = hw->io_base + CTLR;
 164
 165        clear = ~clear & inb(ctlr_port);
 166
 167        outb(clear | set, ctlr_port);
 168}
 169
 170/* Toggle IRQ acknowledge line
 171 */
 172static inline void
 173waveartist_iack(wavnc_info *devc)
 174{
 175        unsigned int ctlr_port = devc->hw.io_base + CTLR;
 176        int old_ctlr;
 177
 178        old_ctlr = inb(ctlr_port) & ~IRQ_ACK;
 179
 180        outb(old_ctlr | IRQ_ACK, ctlr_port);
 181        outb(old_ctlr, ctlr_port);
 182}
 183
 184static inline int
 185waveartist_sleep(int timeout_ms)
 186{
 187        unsigned int timeout = timeout_ms * 10 * HZ / 100;
 188
 189        do {
 190                set_current_state(TASK_INTERRUPTIBLE);
 191                timeout = schedule_timeout(timeout);
 192        } while (timeout);
 193
 194        return 0;
 195}
 196
 197static int
 198waveartist_reset(wavnc_info *devc)
 199{
 200        struct address_info *hw = &devc->hw;
 201        unsigned int timeout, res = -1;
 202
 203        waveartist_set_ctlr(hw, -1, RESET);
 204        waveartist_sleep(2);
 205        waveartist_set_ctlr(hw, RESET, 0);
 206
 207        timeout = 500;
 208        do {
 209                mdelay(2);
 210
 211                if (inb(hw->io_base + STATR) & CMD_RF) {
 212                        res = inw(hw->io_base + CMDR);
 213                        if (res == 0x55aa)
 214                                break;
 215                }
 216        } while (--timeout);
 217
 218        if (timeout == 0) {
 219                printk(KERN_WARNING "WaveArtist: reset timeout ");
 220                if (res != (unsigned int)-1)
 221                        printk("(res=%04X)", res);
 222                printk("\n");
 223                return 1;
 224        }
 225        return 0;
 226}
 227
 228/* Helper function to send and receive words
 229 * from WaveArtist.  It handles all the handshaking
 230 * and can send or receive multiple words.
 231 */
 232static int
 233waveartist_cmd(wavnc_info *devc,
 234                int nr_cmd, unsigned int *cmd,
 235                int nr_resp, unsigned int *resp)
 236{
 237        unsigned int io_base = devc->hw.io_base;
 238        unsigned int timed_out = 0;
 239        unsigned int i;
 240
 241        if (debug_flg & DEBUG_CMD) {
 242                printk("waveartist_cmd: cmd=");
 243
 244                for (i = 0; i < nr_cmd; i++)
 245                        printk("%04X ", cmd[i]);
 246
 247                printk("\n");
 248        }
 249
 250        if (inb(io_base + STATR) & CMD_RF) {
 251                int old_data;
 252
 253                /* flush the port
 254                 */
 255
 256                old_data = inw(io_base + CMDR);
 257
 258                if (debug_flg & DEBUG_CMD)
 259                        printk("flushed %04X...", old_data);
 260
 261                udelay(10);
 262        }
 263
 264        for (i = 0; !timed_out && i < nr_cmd; i++) {
 265                int count;
 266
 267                for (count = 5000; count; count--)
 268                        if (inb(io_base + STATR) & CMD_WE)
 269                                break;
 270
 271                if (!count)
 272                        timed_out = 1;
 273                else
 274                        outw(cmd[i], io_base + CMDR);
 275        }
 276
 277        for (i = 0; !timed_out && i < nr_resp; i++) {
 278                int count;
 279
 280                for (count = 5000; count; count--)
 281                        if (inb(io_base + STATR) & CMD_RF)
 282                                break;
 283
 284                if (!count)
 285                        timed_out = 1;
 286                else
 287                        resp[i] = inw(io_base + CMDR);
 288        }
 289
 290        if (debug_flg & DEBUG_CMD) {
 291                if (!timed_out) {
 292                        printk("waveartist_cmd: resp=");
 293
 294                        for (i = 0; i < nr_resp; i++)
 295                                printk("%04X ", resp[i]);
 296
 297                        printk("\n");
 298                } else
 299                        printk("waveartist_cmd: timed out\n");
 300        }
 301
 302        return timed_out ? 1 : 0;
 303}
 304
 305/*
 306 * Send one command word
 307 */
 308static inline int
 309waveartist_cmd1(wavnc_info *devc, unsigned int cmd)
 310{
 311        return waveartist_cmd(devc, 1, &cmd, 0, NULL);
 312}
 313
 314/*
 315 * Send one command, receive one word
 316 */
 317static inline unsigned int
 318waveartist_cmd1_r(wavnc_info *devc, unsigned int cmd)
 319{
 320        unsigned int ret;
 321
 322        waveartist_cmd(devc, 1, &cmd, 1, &ret);
 323
 324        return ret;
 325}
 326
 327/*
 328 * Send a double command, receive one
 329 * word (and throw it away)
 330 */
 331static inline int
 332waveartist_cmd2(wavnc_info *devc, unsigned int cmd, unsigned int arg)
 333{
 334        unsigned int vals[2];
 335
 336        vals[0] = cmd;
 337        vals[1] = arg;
 338
 339        return waveartist_cmd(devc, 2, vals, 1, vals);
 340}
 341
 342/*
 343 * Send a triple command
 344 */
 345static inline int
 346waveartist_cmd3(wavnc_info *devc, unsigned int cmd,
 347                unsigned int arg1, unsigned int arg2)
 348{
 349        unsigned int vals[3];
 350
 351        vals[0] = cmd;
 352        vals[1] = arg1;
 353        vals[2] = arg2;
 354
 355        return waveartist_cmd(devc, 3, vals, 0, NULL);
 356}
 357
 358static int
 359waveartist_getrev(wavnc_info *devc, char *rev)
 360{
 361        unsigned int temp[2];
 362        unsigned int cmd = WACMD_GETREV;
 363
 364        waveartist_cmd(devc, 1, &cmd, 2, temp);
 365
 366        rev[0] = temp[0] >> 8;
 367        rev[1] = temp[0] & 255;
 368        rev[2] = '\0';
 369
 370        return temp[0];
 371}
 372
 373static void waveartist_halt_output(int dev);
 374static void waveartist_halt_input(int dev);
 375static void waveartist_halt(int dev);
 376static void waveartist_trigger(int dev, int state);
 377
 378static int
 379waveartist_open(int dev, int mode)
 380{
 381        wavnc_info      *devc;
 382        wavnc_port_info *portc;
 383        unsigned long   flags;
 384
 385        if (dev < 0 || dev >= num_audiodevs)
 386                return -ENXIO;
 387
 388        devc  = (wavnc_info *) audio_devs[dev]->devc;
 389        portc = (wavnc_port_info *) audio_devs[dev]->portc;
 390
 391        spin_lock_irqsave(&waveartist_lock, flags);
 392        if (portc->open_mode || (devc->open_mode & mode)) {
 393                spin_unlock_irqrestore(&waveartist_lock, flags);
 394                return -EBUSY;
 395        }
 396
 397        devc->audio_mode  = 0;
 398        devc->open_mode  |= mode;
 399        portc->open_mode  = mode;
 400        waveartist_trigger(dev, 0);
 401
 402        if (mode & OPEN_READ)
 403                devc->record_dev = dev;
 404        if (mode & OPEN_WRITE)
 405                devc->playback_dev = dev;
 406        spin_unlock_irqrestore(&waveartist_lock, flags);
 407
 408        return 0;
 409}
 410
 411static void
 412waveartist_close(int dev)
 413{
 414        wavnc_info      *devc = (wavnc_info *) audio_devs[dev]->devc;
 415        wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
 416        unsigned long   flags;
 417
 418        spin_lock_irqsave(&waveartist_lock, flags);
 419
 420        waveartist_halt(dev);
 421
 422        devc->audio_mode = 0;
 423        devc->open_mode &= ~portc->open_mode;
 424        portc->open_mode = 0;
 425
 426        spin_unlock_irqrestore(&waveartist_lock, flags);
 427}
 428
 429static void
 430waveartist_output_block(int dev, unsigned long buf, int __count, int intrflag)
 431{
 432        wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
 433        wavnc_info      *devc = (wavnc_info *) audio_devs[dev]->devc;
 434        unsigned long   flags;
 435        unsigned int    count = __count; 
 436
 437        if (debug_flg & DEBUG_OUT)
 438                printk("waveartist: output block, buf=0x%lx, count=0x%x...\n",
 439                        buf, count);
 440        /*
 441         * 16 bit data
 442         */
 443        if (portc->audio_format & (AFMT_S16_LE | AFMT_S16_BE))
 444                count >>= 1;
 445
 446        if (portc->channels > 1)
 447                count >>= 1;
 448
 449        count -= 1;
 450
 451        if (devc->audio_mode & PCM_ENABLE_OUTPUT &&
 452            audio_devs[dev]->flags & DMA_AUTOMODE &&
 453            intrflag &&
 454            count == devc->xfer_count) {
 455                devc->audio_mode |= PCM_ENABLE_OUTPUT;
 456                return; /*
 457                         * Auto DMA mode on. No need to react
 458                         */
 459        }
 460
 461        spin_lock_irqsave(&waveartist_lock, flags);
 462
 463        /*
 464         * set sample count
 465         */
 466        waveartist_cmd2(devc, WACMD_OUTPUTSIZE, count);
 467
 468        devc->xfer_count = count;
 469        devc->audio_mode |= PCM_ENABLE_OUTPUT;
 470
 471        spin_unlock_irqrestore(&waveartist_lock, flags);
 472}
 473
 474static void
 475waveartist_start_input(int dev, unsigned long buf, int __count, int intrflag)
 476{
 477        wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
 478        wavnc_info      *devc = (wavnc_info *) audio_devs[dev]->devc;
 479        unsigned long   flags;
 480        unsigned int    count = __count;
 481
 482        if (debug_flg & DEBUG_IN)
 483                printk("waveartist: start input, buf=0x%lx, count=0x%x...\n",
 484                        buf, count);
 485
 486        if (portc->audio_format & (AFMT_S16_LE | AFMT_S16_BE))  /* 16 bit data */
 487                count >>= 1;
 488
 489        if (portc->channels > 1)
 490                count >>= 1;
 491
 492        count -= 1;
 493
 494        if (devc->audio_mode & PCM_ENABLE_INPUT &&
 495            audio_devs[dev]->flags & DMA_AUTOMODE &&
 496            intrflag &&
 497            count == devc->xfer_count) {
 498                devc->audio_mode |= PCM_ENABLE_INPUT;
 499                return; /*
 500                         * Auto DMA mode on. No need to react
 501                         */
 502        }
 503
 504        spin_lock_irqsave(&waveartist_lock, flags);
 505
 506        /*
 507         * set sample count
 508         */
 509        waveartist_cmd2(devc, WACMD_INPUTSIZE, count);
 510
 511        devc->xfer_count = count;
 512        devc->audio_mode |= PCM_ENABLE_INPUT;
 513
 514        spin_unlock_irqrestore(&waveartist_lock, flags);
 515}
 516
 517static int
 518waveartist_ioctl(int dev, unsigned int cmd, void __user * arg)
 519{
 520        return -EINVAL;
 521}
 522
 523static unsigned int
 524waveartist_get_speed(wavnc_port_info *portc)
 525{
 526        unsigned int speed;
 527
 528        /*
 529         * program the speed, channels, bits
 530         */
 531        if (portc->speed == 8000)
 532                speed = 0x2E71;
 533        else if (portc->speed == 11025)
 534                speed = 0x4000;
 535        else if (portc->speed == 22050)
 536                speed = 0x8000;
 537        else if (portc->speed == 44100)
 538                speed = 0x0;
 539        else {
 540                /*
 541                 * non-standard - just calculate
 542                 */
 543                speed = portc->speed << 16;
 544
 545                speed = (speed / 44100) & 65535;
 546        }
 547
 548        return speed;
 549}
 550
 551static unsigned int
 552waveartist_get_bits(wavnc_port_info *portc)
 553{
 554        unsigned int bits;
 555
 556        if (portc->audio_format == AFMT_S16_LE)
 557                bits = 1;
 558        else if (portc->audio_format == AFMT_S8)
 559                bits = 0;
 560        else
 561                bits = 2;       //default AFMT_U8
 562
 563        return bits;
 564}
 565
 566static int
 567waveartist_prepare_for_input(int dev, int bsize, int bcount)
 568{
 569        unsigned long   flags;
 570        wavnc_info      *devc = (wavnc_info *) audio_devs[dev]->devc;
 571        wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
 572        unsigned int    speed, bits;
 573
 574        if (devc->audio_mode)
 575                return 0;
 576
 577        speed = waveartist_get_speed(portc);
 578        bits  = waveartist_get_bits(portc);
 579
 580        spin_lock_irqsave(&waveartist_lock, flags);
 581
 582        if (waveartist_cmd2(devc, WACMD_INPUTFORMAT, bits))
 583                printk(KERN_WARNING "waveartist: error setting the "
 584                       "record format to %d\n", portc->audio_format);
 585
 586        if (waveartist_cmd2(devc, WACMD_INPUTCHANNELS, portc->channels))
 587                printk(KERN_WARNING "waveartist: error setting record "
 588                       "to %d channels\n", portc->channels);
 589
 590        /*
 591         * write cmd SetSampleSpeedTimeConstant
 592         */
 593        if (waveartist_cmd2(devc, WACMD_INPUTSPEED, speed))
 594                printk(KERN_WARNING "waveartist: error setting the record "
 595                       "speed to %dHz.\n", portc->speed);
 596
 597        if (waveartist_cmd2(devc, WACMD_INPUTDMA, 1))
 598                printk(KERN_WARNING "waveartist: error setting the record "
 599                       "data path to 0x%X\n", 1);
 600
 601        if (waveartist_cmd2(devc, WACMD_INPUTFORMAT, bits))
 602                printk(KERN_WARNING "waveartist: error setting the record "
 603                       "format to %d\n", portc->audio_format);
 604
 605        devc->xfer_count = 0;
 606        spin_unlock_irqrestore(&waveartist_lock, flags);
 607        waveartist_halt_input(dev);
 608
 609        if (debug_flg & DEBUG_INTR) {
 610                printk("WA CTLR reg: 0x%02X.\n",
 611                       inb(devc->hw.io_base + CTLR));
 612                printk("WA STAT reg: 0x%02X.\n",
 613                       inb(devc->hw.io_base + STATR));
 614                printk("WA IRQS reg: 0x%02X.\n",
 615                       inb(devc->hw.io_base + IRQSTAT));
 616        }
 617
 618        return 0;
 619}
 620
 621static int
 622waveartist_prepare_for_output(int dev, int bsize, int bcount)
 623{
 624        unsigned long   flags;
 625        wavnc_info      *devc = (wavnc_info *) audio_devs[dev]->devc;
 626        wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
 627        unsigned int    speed, bits;
 628
 629        /*
 630         * program the speed, channels, bits
 631         */
 632        speed = waveartist_get_speed(portc);
 633        bits  = waveartist_get_bits(portc);
 634
 635        spin_lock_irqsave(&waveartist_lock, flags);
 636
 637        if (waveartist_cmd2(devc, WACMD_OUTPUTSPEED, speed) &&
 638            waveartist_cmd2(devc, WACMD_OUTPUTSPEED, speed))
 639                printk(KERN_WARNING "waveartist: error setting the playback "
 640                       "speed to %dHz.\n", portc->speed);
 641
 642        if (waveartist_cmd2(devc, WACMD_OUTPUTCHANNELS, portc->channels))
 643                printk(KERN_WARNING "waveartist: error setting the playback "
 644                       "to %d channels\n", portc->channels);
 645
 646        if (waveartist_cmd2(devc, WACMD_OUTPUTDMA, 0))
 647                printk(KERN_WARNING "waveartist: error setting the playback "
 648                       "data path to 0x%X\n", 0);
 649
 650        if (waveartist_cmd2(devc, WACMD_OUTPUTFORMAT, bits))
 651                printk(KERN_WARNING "waveartist: error setting the playback "
 652                       "format to %d\n", portc->audio_format);
 653
 654        devc->xfer_count = 0;
 655        spin_unlock_irqrestore(&waveartist_lock, flags);
 656        waveartist_halt_output(dev);
 657
 658        if (debug_flg & DEBUG_INTR) {
 659                printk("WA CTLR reg: 0x%02X.\n",inb(devc->hw.io_base + CTLR));
 660                printk("WA STAT reg: 0x%02X.\n",inb(devc->hw.io_base + STATR));
 661                printk("WA IRQS reg: 0x%02X.\n",inb(devc->hw.io_base + IRQSTAT));
 662        }
 663
 664        return 0;
 665}
 666
 667static void
 668waveartist_halt(int dev)
 669{
 670        wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
 671        wavnc_info      *devc;
 672
 673        if (portc->open_mode & OPEN_WRITE)
 674                waveartist_halt_output(dev);
 675
 676        if (portc->open_mode & OPEN_READ)
 677                waveartist_halt_input(dev);
 678
 679        devc = (wavnc_info *) audio_devs[dev]->devc;
 680        devc->audio_mode = 0;
 681}
 682
 683static void
 684waveartist_halt_input(int dev)
 685{
 686        wavnc_info      *devc = (wavnc_info *) audio_devs[dev]->devc;
 687        unsigned long   flags;
 688
 689        spin_lock_irqsave(&waveartist_lock, flags);
 690
 691        /*
 692         * Stop capture
 693         */
 694        waveartist_cmd1(devc, WACMD_INPUTSTOP);
 695
 696        devc->audio_mode &= ~PCM_ENABLE_INPUT;
 697
 698        /*
 699         * Clear interrupt by toggling
 700         * the IRQ_ACK bit in CTRL
 701         */
 702        if (inb(devc->hw.io_base + STATR) & IRQ_REQ)
 703                waveartist_iack(devc);
 704
 705//      devc->audio_mode &= ~PCM_ENABLE_INPUT;
 706
 707        spin_unlock_irqrestore(&waveartist_lock, flags);
 708}
 709
 710static void
 711waveartist_halt_output(int dev)
 712{
 713        wavnc_info      *devc = (wavnc_info *) audio_devs[dev]->devc;
 714        unsigned long   flags;
 715
 716        spin_lock_irqsave(&waveartist_lock, flags);
 717
 718        waveartist_cmd1(devc, WACMD_OUTPUTSTOP);
 719
 720        devc->audio_mode &= ~PCM_ENABLE_OUTPUT;
 721
 722        /*
 723         * Clear interrupt by toggling
 724         * the IRQ_ACK bit in CTRL
 725         */
 726        if (inb(devc->hw.io_base + STATR) & IRQ_REQ)
 727                waveartist_iack(devc);
 728
 729//      devc->audio_mode &= ~PCM_ENABLE_OUTPUT;
 730
 731        spin_unlock_irqrestore(&waveartist_lock, flags);
 732}
 733
 734static void
 735waveartist_trigger(int dev, int state)
 736{
 737        wavnc_info      *devc = (wavnc_info *) audio_devs[dev]->devc;
 738        wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
 739        unsigned long   flags;
 740
 741        if (debug_flg & DEBUG_TRIGGER) {
 742                printk("wavnc: audio trigger ");
 743                if (state & PCM_ENABLE_INPUT)
 744                        printk("in ");
 745                if (state & PCM_ENABLE_OUTPUT)
 746                        printk("out");
 747                printk("\n");
 748        }
 749
 750        spin_lock_irqsave(&waveartist_lock, flags);
 751
 752        state &= devc->audio_mode;
 753
 754        if (portc->open_mode & OPEN_READ &&
 755            state & PCM_ENABLE_INPUT)
 756                /*
 757                 * enable ADC Data Transfer to PC
 758                 */
 759                waveartist_cmd1(devc, WACMD_INPUTSTART);
 760
 761        if (portc->open_mode & OPEN_WRITE &&
 762            state & PCM_ENABLE_OUTPUT)
 763                /*
 764                 * enable DAC data transfer from PC
 765                 */
 766                waveartist_cmd1(devc, WACMD_OUTPUTSTART);
 767
 768        spin_unlock_irqrestore(&waveartist_lock, flags);
 769}
 770
 771static int
 772waveartist_set_speed(int dev, int arg)
 773{
 774        wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
 775
 776        if (arg <= 0)
 777                return portc->speed;
 778
 779        if (arg < 5000)
 780                arg = 5000;
 781        if (arg > 44100)
 782                arg = 44100;
 783
 784        portc->speed = arg;
 785        return portc->speed;
 786
 787}
 788
 789static short
 790waveartist_set_channels(int dev, short arg)
 791{
 792        wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
 793
 794        if (arg != 1 && arg != 2)
 795                return portc->channels;
 796
 797        portc->channels = arg;
 798        return arg;
 799}
 800
 801static unsigned int
 802waveartist_set_bits(int dev, unsigned int arg)
 803{
 804        wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
 805
 806        if (arg == 0)
 807                return portc->audio_format;
 808
 809        if ((arg != AFMT_U8) && (arg != AFMT_S16_LE) && (arg != AFMT_S8))
 810                arg = AFMT_U8;
 811
 812        portc->audio_format = arg;
 813
 814        return arg;
 815}
 816
 817static struct audio_driver waveartist_audio_driver = {
 818        .owner                  = THIS_MODULE,
 819        .open                   = waveartist_open,
 820        .close                  = waveartist_close,
 821        .output_block           = waveartist_output_block,
 822        .start_input            = waveartist_start_input,
 823        .ioctl                  = waveartist_ioctl,
 824        .prepare_for_input      = waveartist_prepare_for_input,
 825        .prepare_for_output     = waveartist_prepare_for_output,
 826        .halt_io                = waveartist_halt,
 827        .halt_input             = waveartist_halt_input,
 828        .halt_output            = waveartist_halt_output,
 829        .trigger                = waveartist_trigger,
 830        .set_speed              = waveartist_set_speed,
 831        .set_bits               = waveartist_set_bits,
 832        .set_channels           = waveartist_set_channels
 833};
 834
 835
 836static irqreturn_t
 837waveartist_intr(int irq, void *dev_id)
 838{
 839        wavnc_info *devc = dev_id;
 840        int        irqstatus, status;
 841
 842        spin_lock(&waveartist_lock);
 843        irqstatus = inb(devc->hw.io_base + IRQSTAT);
 844        status    = inb(devc->hw.io_base + STATR);
 845
 846        if (debug_flg & DEBUG_INTR)
 847                printk("waveartist_intr: stat=%02x, irqstat=%02x\n",
 848                       status, irqstatus);
 849
 850        if (status & IRQ_REQ)   /* Clear interrupt */
 851                waveartist_iack(devc);
 852        else
 853                printk(KERN_WARNING "waveartist: unexpected interrupt\n");
 854
 855        if (irqstatus & 0x01) {
 856                int temp = 1;
 857
 858                /* PCM buffer done
 859                 */
 860                if ((status & DMA0) && (devc->audio_mode & PCM_ENABLE_OUTPUT)) {
 861                        DMAbuf_outputintr(devc->playback_dev, 1);
 862                        temp = 0;
 863                }
 864                if ((status & DMA1) && (devc->audio_mode & PCM_ENABLE_INPUT)) {
 865                        DMAbuf_inputintr(devc->record_dev);
 866                        temp = 0;
 867                }
 868                if (temp)       //default:
 869                        printk(KERN_WARNING "waveartist: Unknown interrupt\n");
 870        }
 871        if (irqstatus & 0x2)
 872                // We do not use SB mode natively...
 873                printk(KERN_WARNING "waveartist: Unexpected SB interrupt...\n");
 874        spin_unlock(&waveartist_lock);
 875        return IRQ_HANDLED;
 876}
 877
 878/* -------------------------------------------------------------------------
 879 * Mixer stuff
 880 */
 881struct mix_ent {
 882        unsigned char   reg_l;
 883        unsigned char   reg_r;
 884        unsigned char   shift;
 885        unsigned char   max;
 886};
 887
 888static const struct mix_ent mix_devs[SOUND_MIXER_NRDEVICES] = {
 889        { 2, 6, 1,  7 }, /* SOUND_MIXER_VOLUME   */
 890        { 0, 0, 0,  0 }, /* SOUND_MIXER_BASS     */
 891        { 0, 0, 0,  0 }, /* SOUND_MIXER_TREBLE   */
 892        { 0, 0, 0,  0 }, /* SOUND_MIXER_SYNTH    */
 893        { 0, 0, 0,  0 }, /* SOUND_MIXER_PCM      */
 894        { 0, 0, 0,  0 }, /* SOUND_MIXER_SPEAKER  */
 895        { 0, 4, 6, 31 }, /* SOUND_MIXER_LINE     */
 896        { 2, 6, 4,  3 }, /* SOUND_MIXER_MIC      */
 897        { 0, 0, 0,  0 }, /* SOUND_MIXER_CD       */
 898        { 0, 0, 0,  0 }, /* SOUND_MIXER_IMIX     */
 899        { 0, 0, 0,  0 }, /* SOUND_MIXER_ALTPCM   */
 900#if 0
 901        { 3, 7, 0, 10 }, /* SOUND_MIXER_RECLEV   */
 902        { 0, 0, 0,  0 }, /* SOUND_MIXER_IGAIN    */
 903#else
 904        { 0, 0, 0,  0 }, /* SOUND_MIXER_RECLEV   */
 905        { 3, 7, 0,  7 }, /* SOUND_MIXER_IGAIN    */
 906#endif
 907        { 0, 0, 0,  0 }, /* SOUND_MIXER_OGAIN    */
 908        { 0, 4, 1, 31 }, /* SOUND_MIXER_LINE1    */
 909        { 1, 5, 6, 31 }, /* SOUND_MIXER_LINE2    */
 910        { 0, 0, 0,  0 }, /* SOUND_MIXER_LINE3    */
 911        { 0, 0, 0,  0 }, /* SOUND_MIXER_DIGITAL1 */
 912        { 0, 0, 0,  0 }, /* SOUND_MIXER_DIGITAL2 */
 913        { 0, 0, 0,  0 }, /* SOUND_MIXER_DIGITAL3 */
 914        { 0, 0, 0,  0 }, /* SOUND_MIXER_PHONEIN  */
 915        { 0, 0, 0,  0 }, /* SOUND_MIXER_PHONEOUT */
 916        { 0, 0, 0,  0 }, /* SOUND_MIXER_VIDEO    */
 917        { 0, 0, 0,  0 }, /* SOUND_MIXER_RADIO    */
 918        { 0, 0, 0,  0 }  /* SOUND_MIXER_MONITOR  */
 919};
 920
 921static void
 922waveartist_mixer_update(wavnc_info *devc, int whichDev)
 923{
 924        unsigned int lev_left, lev_right;
 925
 926        lev_left  = devc->levels[whichDev] & 0xff;
 927        lev_right = devc->levels[whichDev] >> 8;
 928
 929        if (lev_left > 100)
 930                lev_left = 100;
 931        if (lev_right > 100)
 932                lev_right = 100;
 933
 934#define SCALE(lev,max)  ((lev) * (max) / 100)
 935
 936        if (machine_is_netwinder() && whichDev == SOUND_MIXER_PHONEOUT)
 937                whichDev = SOUND_MIXER_VOLUME;
 938
 939        if (mix_devs[whichDev].reg_l || mix_devs[whichDev].reg_r) {
 940                const struct mix_ent *mix = mix_devs + whichDev;
 941                unsigned int mask, left, right;
 942
 943                mask = mix->max << mix->shift;
 944                lev_left  = SCALE(lev_left,  mix->max) << mix->shift;
 945                lev_right = SCALE(lev_right, mix->max) << mix->shift;
 946
 947                /* read left setting */
 948                left  = waveartist_cmd1_r(devc, WACMD_GET_LEVEL |
 949                                               mix->reg_l << 8);
 950
 951                /* read right setting */
 952                right = waveartist_cmd1_r(devc, WACMD_GET_LEVEL |
 953                                                mix->reg_r << 8);
 954
 955                left  = (left  & ~mask) | (lev_left  & mask);
 956                right = (right & ~mask) | (lev_right & mask);
 957
 958                /* write left,right back */
 959                waveartist_cmd3(devc, WACMD_SET_MIXER, left, right);
 960        } else {
 961                switch(whichDev) {
 962                case SOUND_MIXER_PCM:
 963                        waveartist_cmd3(devc, WACMD_SET_LEVEL,
 964                                        SCALE(lev_left,  32767),
 965                                        SCALE(lev_right, 32767));
 966                        break;
 967
 968                case SOUND_MIXER_SYNTH:
 969                        waveartist_cmd3(devc, 0x0100 | WACMD_SET_LEVEL,
 970                                        SCALE(lev_left,  32767),
 971                                        SCALE(lev_right, 32767));
 972                        break;
 973                }
 974        }
 975}
 976
 977/*
 978 * Set the ADC MUX to the specified values.  We do NOT do any
 979 * checking of the values passed, since we assume that the
 980 * relevant *_select_input function has done that for us.
 981 */
 982static void
 983waveartist_set_adc_mux(wavnc_info *devc, char left_dev, char right_dev)
 984{
 985        unsigned int reg_08, reg_09;
 986
 987        reg_08 = waveartist_cmd1_r(devc, WACMD_GET_LEVEL | 0x0800);
 988        reg_09 = waveartist_cmd1_r(devc, WACMD_GET_LEVEL | 0x0900);
 989
 990        reg_08 = (reg_08 & ~0x3f) | right_dev << 3 | left_dev;
 991
 992        waveartist_cmd3(devc, WACMD_SET_MIXER, reg_08, reg_09);
 993}
 994
 995/*
 996 * Decode a recording mask into a mixer selection as follows:
 997 *
 998 *     OSS Source       WA Source       Actual source
 999 *  SOUND_MASK_IMIX     Mixer           Mixer output (same as AD1848)
1000 *  SOUND_MASK_LINE     Line            Line in
1001 *  SOUND_MASK_LINE1    Aux 1           Aux 1 in
1002 *  SOUND_MASK_LINE2    Aux 2           Aux 2 in
1003 *  SOUND_MASK_MIC      Mic             Microphone
1004 */
1005static unsigned int
1006waveartist_select_input(wavnc_info *devc, unsigned int recmask,
1007                        unsigned char *dev_l, unsigned char *dev_r)
1008{
1009        unsigned int recdev = ADC_MUX_NONE;
1010
1011        if (recmask & SOUND_MASK_IMIX) {
1012                recmask = SOUND_MASK_IMIX;
1013                recdev = ADC_MUX_MIXER;
1014        } else if (recmask & SOUND_MASK_LINE2) {
1015                recmask = SOUND_MASK_LINE2;
1016                recdev = ADC_MUX_AUX2;
1017        } else if (recmask & SOUND_MASK_LINE1) {
1018                recmask = SOUND_MASK_LINE1;
1019                recdev = ADC_MUX_AUX1;
1020        } else if (recmask & SOUND_MASK_LINE) {
1021                recmask = SOUND_MASK_LINE;
1022                recdev = ADC_MUX_LINE;
1023        } else if (recmask & SOUND_MASK_MIC) {
1024                recmask = SOUND_MASK_MIC;
1025                recdev = ADC_MUX_MIC;
1026        }
1027
1028        *dev_l = *dev_r = recdev;
1029
1030        return recmask;
1031}
1032
1033static int
1034waveartist_decode_mixer(wavnc_info *devc, int dev, unsigned char lev_l,
1035                        unsigned char lev_r)
1036{
1037        switch (dev) {
1038        case SOUND_MIXER_VOLUME:
1039        case SOUND_MIXER_SYNTH:
1040        case SOUND_MIXER_PCM:
1041        case SOUND_MIXER_LINE:
1042        case SOUND_MIXER_MIC:
1043        case SOUND_MIXER_IGAIN:
1044        case SOUND_MIXER_LINE1:
1045        case SOUND_MIXER_LINE2:
1046                devc->levels[dev] = lev_l | lev_r << 8;
1047                break;
1048
1049        case SOUND_MIXER_IMIX:
1050                break;
1051
1052        default:
1053                dev = -EINVAL;
1054                break;
1055        }
1056
1057        return dev;
1058}
1059
1060static int waveartist_get_mixer(wavnc_info *devc, int dev)
1061{
1062        return devc->levels[dev];
1063}
1064
1065static const struct waveartist_mixer_info waveartist_mixer = {
1066        .supported_devs = SUPPORTED_MIXER_DEVICES | SOUND_MASK_IGAIN,
1067        .recording_devs = SOUND_MASK_LINE  | SOUND_MASK_MIC   |
1068                        SOUND_MASK_LINE1 | SOUND_MASK_LINE2 |
1069                        SOUND_MASK_IMIX,
1070        .stereo_devs    = (SUPPORTED_MIXER_DEVICES | SOUND_MASK_IGAIN) & ~
1071                        (SOUND_MASK_SPEAKER | SOUND_MASK_IMIX),
1072        .select_input   = waveartist_select_input,
1073        .decode_mixer   = waveartist_decode_mixer,
1074        .get_mixer      = waveartist_get_mixer,
1075};
1076
1077static void
1078waveartist_set_recmask(wavnc_info *devc, unsigned int recmask)
1079{
1080        unsigned char dev_l, dev_r;
1081
1082        recmask &= devc->mix->recording_devs;
1083
1084        /*
1085         * If more than one recording device selected,
1086         * disable the device that is currently in use.
1087         */
1088        if (hweight32(recmask) > 1)
1089                recmask &= ~devc->recmask;
1090
1091        /*
1092         * Translate the recording device mask into
1093         * the ADC multiplexer settings.
1094         */
1095        devc->recmask = devc->mix->select_input(devc, recmask,
1096                                                &dev_l, &dev_r);
1097
1098        waveartist_set_adc_mux(devc, dev_l, dev_r);
1099}
1100
1101static int
1102waveartist_set_mixer(wavnc_info *devc, int dev, unsigned int level)
1103{
1104        unsigned int lev_left  = level & 0x00ff;
1105        unsigned int lev_right = (level & 0xff00) >> 8;
1106
1107        if (lev_left > 100)
1108                lev_left = 100;
1109        if (lev_right > 100)
1110                lev_right = 100;
1111
1112        /*
1113         * Mono devices have their right volume forced to their
1114         * left volume.  (from ALSA driver OSS emulation).
1115         */
1116        if (!(devc->mix->stereo_devs & (1 << dev)))
1117                lev_right = lev_left;
1118
1119        dev = devc->mix->decode_mixer(devc, dev, lev_left, lev_right);
1120
1121        if (dev >= 0)
1122                waveartist_mixer_update(devc, dev);
1123
1124        return dev < 0 ? dev : 0;
1125}
1126
1127static int
1128waveartist_mixer_ioctl(int dev, unsigned int cmd, void __user * arg)
1129{
1130        wavnc_info *devc = (wavnc_info *)audio_devs[dev]->devc;
1131        int ret = 0, val, nr;
1132
1133        /*
1134         * All SOUND_MIXER_* ioctls use type 'M'
1135         */
1136        if (((cmd >> 8) & 255) != 'M')
1137                return -ENOIOCTLCMD;
1138
1139#ifdef CONFIG_ARCH_NETWINDER
1140        if (machine_is_netwinder()) {
1141                ret = vnc_private_ioctl(dev, cmd, arg);
1142                if (ret != -ENOIOCTLCMD)
1143                        return ret;
1144                else
1145                        ret = 0;
1146        }
1147#endif
1148
1149        nr = cmd & 0xff;
1150
1151        if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
1152                if (get_user(val, (int __user *)arg))
1153                        return -EFAULT;
1154
1155                switch (nr) {
1156                case SOUND_MIXER_RECSRC:
1157                        waveartist_set_recmask(devc, val);
1158                        break;
1159
1160                default:
1161                        ret = -EINVAL;
1162                        if (nr < SOUND_MIXER_NRDEVICES &&
1163                            devc->mix->supported_devs & (1 << nr))
1164                                ret = waveartist_set_mixer(devc, nr, val);
1165                }
1166        }
1167
1168        if (ret == 0 && _SIOC_DIR(cmd) & _SIOC_READ) {
1169                ret = -EINVAL;
1170
1171                switch (nr) {
1172                case SOUND_MIXER_RECSRC:
1173                        ret = devc->recmask;
1174                        break;
1175
1176                case SOUND_MIXER_DEVMASK:
1177                        ret = devc->mix->supported_devs;
1178                        break;
1179
1180                case SOUND_MIXER_STEREODEVS:
1181                        ret = devc->mix->stereo_devs;
1182                        break;
1183
1184                case SOUND_MIXER_RECMASK:
1185                        ret = devc->mix->recording_devs;
1186                        break;
1187
1188                case SOUND_MIXER_CAPS:
1189                        ret = SOUND_CAP_EXCL_INPUT;
1190                        break;
1191
1192                default:
1193                        if (nr < SOUND_MIXER_NRDEVICES)
1194                                ret = devc->mix->get_mixer(devc, nr);
1195                        break;
1196                }
1197
1198                if (ret >= 0)
1199                        ret = put_user(ret, (int __user *)arg) ? -EFAULT : 0;
1200        }
1201
1202        return ret;
1203}
1204
1205static struct mixer_operations waveartist_mixer_operations =
1206{
1207        .owner  = THIS_MODULE,
1208        .id     = "WaveArtist",
1209        .name   = "WaveArtist",
1210        .ioctl  = waveartist_mixer_ioctl
1211};
1212
1213static void
1214waveartist_mixer_reset(wavnc_info *devc)
1215{
1216        int i;
1217
1218        if (debug_flg & DEBUG_MIXER)
1219                printk("%s: mixer_reset\n", devc->hw.name);
1220
1221        /*
1222         * reset mixer cmd
1223         */
1224        waveartist_cmd1(devc, WACMD_RST_MIXER);
1225
1226        /*
1227         * set input for ADC to come from 'quiet'
1228         * turn on default modes
1229         */
1230        waveartist_cmd3(devc, WACMD_SET_MIXER, 0x9800, 0xa836);
1231
1232        /*
1233         * set mixer input select to none, RX filter gains 0 dB
1234         */
1235        waveartist_cmd3(devc, WACMD_SET_MIXER, 0x4c00, 0x8c00);
1236
1237        /*
1238         * set bit 0 reg 2 to 1 - unmute MonoOut
1239         */
1240        waveartist_cmd3(devc, WACMD_SET_MIXER, 0x2801, 0x6800);
1241
1242        /* set default input device = internal mic
1243         * current recording device = none
1244         */
1245        waveartist_set_recmask(devc, 0);
1246
1247        for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
1248                waveartist_mixer_update(devc, i);
1249}
1250
1251static int __init waveartist_init(wavnc_info *devc)
1252{
1253        wavnc_port_info *portc;
1254        char rev[3], dev_name[64];
1255        int my_dev;
1256
1257        if (waveartist_reset(devc))
1258                return -ENODEV;
1259
1260        sprintf(dev_name, "%s (%s", devc->hw.name, devc->chip_name);
1261
1262        if (waveartist_getrev(devc, rev)) {
1263                strcat(dev_name, " rev. ");
1264                strcat(dev_name, rev);
1265        }
1266        strcat(dev_name, ")");
1267
1268        conf_printf2(dev_name, devc->hw.io_base, devc->hw.irq,
1269                     devc->hw.dma, devc->hw.dma2);
1270
1271        portc = kzalloc(sizeof(wavnc_port_info), GFP_KERNEL);
1272        if (portc == NULL)
1273                goto nomem;
1274
1275        my_dev = sound_install_audiodrv(AUDIO_DRIVER_VERSION, dev_name,
1276                        &waveartist_audio_driver, sizeof(struct audio_driver),
1277                        devc->audio_flags, AFMT_U8 | AFMT_S16_LE | AFMT_S8,
1278                        devc, devc->hw.dma, devc->hw.dma2);
1279
1280        if (my_dev < 0)
1281                goto free;
1282
1283        audio_devs[my_dev]->portc = portc;
1284
1285        waveartist_mixer_reset(devc);
1286
1287        /*
1288         * clear any pending interrupt
1289         */
1290        waveartist_iack(devc);
1291
1292        if (request_irq(devc->hw.irq, waveartist_intr, 0, devc->hw.name, devc) < 0) {
1293                printk(KERN_ERR "%s: IRQ %d in use\n",
1294                        devc->hw.name, devc->hw.irq);
1295                goto uninstall;
1296        }
1297
1298        if (sound_alloc_dma(devc->hw.dma, devc->hw.name)) {
1299                printk(KERN_ERR "%s: Can't allocate DMA%d\n",
1300                        devc->hw.name, devc->hw.dma);
1301                goto uninstall_irq;
1302        }
1303
1304        if (devc->hw.dma != devc->hw.dma2 && devc->hw.dma2 != NO_DMA)
1305                if (sound_alloc_dma(devc->hw.dma2, devc->hw.name)) {
1306                        printk(KERN_ERR "%s: can't allocate DMA%d\n",
1307                                devc->hw.name, devc->hw.dma2);
1308                        goto uninstall_dma;
1309                }
1310
1311        waveartist_set_ctlr(&devc->hw, 0, DMA1_IE | DMA0_IE);
1312
1313        audio_devs[my_dev]->mixer_dev =
1314                sound_install_mixer(MIXER_DRIVER_VERSION,
1315                                dev_name,
1316                                &waveartist_mixer_operations,
1317                                sizeof(struct mixer_operations),
1318                                devc);
1319
1320        return my_dev;
1321
1322uninstall_dma:
1323        sound_free_dma(devc->hw.dma);
1324
1325uninstall_irq:
1326        free_irq(devc->hw.irq, devc);
1327
1328uninstall:
1329        sound_unload_audiodev(my_dev);
1330
1331free:
1332        kfree(portc);
1333
1334nomem:
1335        return -1;
1336}
1337
1338static int __init probe_waveartist(struct address_info *hw_config)
1339{
1340        wavnc_info *devc = &adev_info[nr_waveartist_devs];
1341
1342        if (nr_waveartist_devs >= MAX_AUDIO_DEV) {
1343                printk(KERN_WARNING "waveartist: too many audio devices\n");
1344                return 0;
1345        }
1346
1347        if (!request_region(hw_config->io_base, 15, hw_config->name))  {
1348                printk(KERN_WARNING "WaveArtist: I/O port conflict\n");
1349                return 0;
1350        }
1351
1352        if (hw_config->irq > 15 || hw_config->irq < 0) {
1353                release_region(hw_config->io_base, 15);
1354                printk(KERN_WARNING "WaveArtist: Bad IRQ %d\n",
1355                       hw_config->irq);
1356                return 0;
1357        }
1358
1359        if (hw_config->dma != 3) {
1360                release_region(hw_config->io_base, 15);
1361                printk(KERN_WARNING "WaveArtist: Bad DMA %d\n",
1362                       hw_config->dma);
1363                return 0;
1364        }
1365
1366        hw_config->name = "WaveArtist";
1367        devc->hw = *hw_config;
1368        devc->open_mode = 0;
1369        devc->chip_name = "RWA-010";
1370
1371        return 1;
1372}
1373
1374static void __init
1375attach_waveartist(struct address_info *hw, const struct waveartist_mixer_info *mix)
1376{
1377        wavnc_info *devc = &adev_info[nr_waveartist_devs];
1378
1379        /*
1380         * NOTE! If irq < 0, there is another driver which has allocated the
1381         *   IRQ so that this driver doesn't need to allocate/deallocate it.
1382         *   The actually used IRQ is ABS(irq).
1383         */
1384        devc->hw = *hw;
1385        devc->hw.irq = (hw->irq > 0) ? hw->irq : 0;
1386        devc->open_mode = 0;
1387        devc->playback_dev = 0;
1388        devc->record_dev = 0;
1389        devc->audio_flags = DMA_AUTOMODE;
1390        devc->levels = levels;
1391
1392        if (hw->dma != hw->dma2 && hw->dma2 != NO_DMA)
1393                devc->audio_flags |= DMA_DUPLEX;
1394
1395        devc->mix = mix;
1396        devc->dev_no = waveartist_init(devc);
1397
1398        if (devc->dev_no < 0)
1399                release_region(hw->io_base, 15);
1400        else {
1401#ifdef CONFIG_ARCH_NETWINDER
1402                if (machine_is_netwinder()) {
1403                        init_timer(&vnc_timer);
1404                        vnc_timer.function = vnc_slider_tick;
1405                        vnc_timer.expires  = jiffies;
1406                        vnc_timer.data     = nr_waveartist_devs;
1407                        add_timer(&vnc_timer);
1408
1409                        vnc_configure_mixer(devc, 0);
1410
1411                        devc->no_autoselect = 1;
1412                }
1413#endif
1414                nr_waveartist_devs += 1;
1415        }
1416}
1417
1418static void __exit unload_waveartist(struct address_info *hw)
1419{
1420        wavnc_info *devc = NULL;
1421        int i;
1422
1423        for (i = 0; i < nr_waveartist_devs; i++)
1424                if (hw->io_base == adev_info[i].hw.io_base) {
1425                        devc = adev_info + i;
1426                        break;
1427                }
1428
1429        if (devc != NULL) {
1430                int mixer;
1431
1432#ifdef CONFIG_ARCH_NETWINDER
1433                if (machine_is_netwinder())
1434                        del_timer(&vnc_timer);
1435#endif
1436
1437                release_region(devc->hw.io_base, 15);
1438
1439                waveartist_set_ctlr(&devc->hw, DMA1_IE|DMA0_IE, 0);
1440
1441                if (devc->hw.irq >= 0)
1442                        free_irq(devc->hw.irq, devc);
1443
1444                sound_free_dma(devc->hw.dma);
1445
1446                if (devc->hw.dma != devc->hw.dma2 &&
1447                    devc->hw.dma2 != NO_DMA)
1448                        sound_free_dma(devc->hw.dma2);
1449
1450                mixer = audio_devs[devc->dev_no]->mixer_dev;
1451
1452                if (mixer >= 0)
1453                        sound_unload_mixerdev(mixer);
1454
1455                if (devc->dev_no >= 0)
1456                        sound_unload_audiodev(devc->dev_no);
1457
1458                nr_waveartist_devs -= 1;
1459
1460                for (; i < nr_waveartist_devs; i++)
1461                        adev_info[i] = adev_info[i + 1];
1462        } else
1463                printk(KERN_WARNING "waveartist: can't find device "
1464                       "to unload\n");
1465}
1466
1467#ifdef CONFIG_ARCH_NETWINDER
1468
1469/*
1470 * Rebel.com Netwinder specifics...
1471 */
1472
1473#include <asm/hardware/dec21285.h>
1474 
1475#define VNC_TIMER_PERIOD (HZ/4) //check slider 4 times/sec
1476
1477#define MIXER_PRIVATE3_RESET    0x53570000
1478#define MIXER_PRIVATE3_READ     0x53570001
1479#define MIXER_PRIVATE3_WRITE    0x53570002
1480
1481#define VNC_MUTE_INTERNAL_SPKR  0x01    //the sw mute on/off control bit
1482#define VNC_MUTE_LINE_OUT       0x10
1483#define VNC_PHONE_DETECT        0x20
1484#define VNC_HANDSET_DETECT      0x40
1485#define VNC_DISABLE_AUTOSWITCH  0x80
1486
1487static inline void
1488vnc_mute_spkr(wavnc_info *devc)
1489{
1490        unsigned long flags;
1491
1492        spin_lock_irqsave(&nw_gpio_lock, flags);
1493        nw_cpld_modify(CPLD_UNMUTE, devc->spkr_mute_state ? 0 : CPLD_UNMUTE);
1494        spin_unlock_irqrestore(&nw_gpio_lock, flags);
1495}
1496
1497static void
1498vnc_mute_lout(wavnc_info *devc)
1499{
1500        unsigned int left, right;
1501
1502        left  = waveartist_cmd1_r(devc, WACMD_GET_LEVEL);
1503        right = waveartist_cmd1_r(devc, WACMD_GET_LEVEL | 0x400);
1504
1505        if (devc->line_mute_state) {
1506                left &= ~1;
1507                right &= ~1;
1508        } else {
1509                left |= 1;
1510                right |= 1;
1511        }
1512        waveartist_cmd3(devc, WACMD_SET_MIXER, left, right);
1513                
1514}
1515
1516static int
1517vnc_volume_slider(wavnc_info *devc)
1518{
1519        static signed int old_slider_volume;
1520        unsigned long flags;
1521        signed int volume = 255;
1522
1523        *CSR_TIMER1_LOAD = 0x00ffffff;
1524
1525        spin_lock_irqsave(&waveartist_lock, flags);
1526
1527        outb(0xFF, 0x201);
1528        *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV1;
1529
1530        while (volume && (inb(0x201) & 0x01))
1531                volume--;
1532
1533        *CSR_TIMER1_CNTL = 0;
1534
1535        spin_unlock_irqrestore(&waveartist_lock,flags);
1536        
1537        volume = 0x00ffffff - *CSR_TIMER1_VALUE;
1538
1539
1540#ifndef REVERSE
1541        volume = 150 - (volume >> 5);
1542#else
1543        volume = (volume >> 6) - 25;
1544#endif
1545
1546        if (volume < 0)
1547                volume = 0;
1548
1549        if (volume > 100)
1550                volume = 100;
1551
1552        /*
1553         * slider quite often reads +-8, so debounce this random noise
1554         */
1555        if (abs(volume - old_slider_volume) > 7) {
1556                old_slider_volume = volume;
1557
1558                if (debug_flg & DEBUG_MIXER)
1559                        printk(KERN_DEBUG "Slider volume: %d.\n", volume);
1560        }
1561
1562        return old_slider_volume;
1563}
1564
1565/*
1566 * Decode a recording mask into a mixer selection on the NetWinder
1567 * as follows:
1568 *
1569 *     OSS Source       WA Source       Actual source
1570 *  SOUND_MASK_IMIX     Mixer           Mixer output (same as AD1848)
1571 *  SOUND_MASK_LINE     Line            Line in
1572 *  SOUND_MASK_LINE1    Left Mic        Handset
1573 *  SOUND_MASK_PHONEIN  Left Aux        Telephone microphone
1574 *  SOUND_MASK_MIC      Right Mic       Builtin microphone
1575 */
1576static unsigned int
1577netwinder_select_input(wavnc_info *devc, unsigned int recmask,
1578                       unsigned char *dev_l, unsigned char *dev_r)
1579{
1580        unsigned int recdev_l = ADC_MUX_NONE, recdev_r = ADC_MUX_NONE;
1581
1582        if (recmask & SOUND_MASK_IMIX) {
1583                recmask = SOUND_MASK_IMIX;
1584                recdev_l = ADC_MUX_MIXER;
1585                recdev_r = ADC_MUX_MIXER;
1586        } else if (recmask & SOUND_MASK_LINE) {
1587                recmask = SOUND_MASK_LINE;
1588                recdev_l = ADC_MUX_LINE;
1589                recdev_r = ADC_MUX_LINE;
1590        } else if (recmask & SOUND_MASK_LINE1) {
1591                recmask = SOUND_MASK_LINE1;
1592                waveartist_cmd1(devc, WACMD_SET_MONO); /* left */
1593                recdev_l = ADC_MUX_MIC;
1594                recdev_r = ADC_MUX_NONE;
1595        } else if (recmask & SOUND_MASK_PHONEIN) {
1596                recmask = SOUND_MASK_PHONEIN;
1597                waveartist_cmd1(devc, WACMD_SET_MONO); /* left */
1598                recdev_l = ADC_MUX_AUX1;
1599                recdev_r = ADC_MUX_NONE;
1600        } else if (recmask & SOUND_MASK_MIC) {
1601                recmask = SOUND_MASK_MIC;
1602                waveartist_cmd1(devc, WACMD_SET_MONO | 0x100);  /* right */
1603                recdev_l = ADC_MUX_NONE;
1604                recdev_r = ADC_MUX_MIC;
1605        }
1606
1607        *dev_l = recdev_l;
1608        *dev_r = recdev_r;
1609
1610        return recmask;
1611}
1612
1613static int
1614netwinder_decode_mixer(wavnc_info *devc, int dev, unsigned char lev_l,
1615                       unsigned char lev_r)
1616{
1617        switch (dev) {
1618        case SOUND_MIXER_VOLUME:
1619        case SOUND_MIXER_SYNTH:
1620        case SOUND_MIXER_PCM:
1621        case SOUND_MIXER_LINE:
1622        case SOUND_MIXER_IGAIN:
1623                devc->levels[dev] = lev_l | lev_r << 8;
1624                break;
1625
1626        case SOUND_MIXER_MIC:           /* right mic only */
1627                devc->levels[SOUND_MIXER_MIC] &= 0xff;
1628                devc->levels[SOUND_MIXER_MIC] |= lev_l << 8;
1629                break;
1630
1631        case SOUND_MIXER_LINE1:         /* left mic only  */
1632                devc->levels[SOUND_MIXER_MIC] &= 0xff00;
1633                devc->levels[SOUND_MIXER_MIC] |= lev_l;
1634                dev = SOUND_MIXER_MIC;
1635                break;
1636
1637        case SOUND_MIXER_PHONEIN:       /* left aux only  */
1638                devc->levels[SOUND_MIXER_LINE1] = lev_l;
1639                dev = SOUND_MIXER_LINE1;
1640                break;
1641
1642        case SOUND_MIXER_IMIX:
1643        case SOUND_MIXER_PHONEOUT:
1644                break;
1645
1646        default:
1647                dev = -EINVAL;
1648                break;
1649        }
1650        return dev;
1651}
1652
1653static int netwinder_get_mixer(wavnc_info *devc, int dev)
1654{
1655        int levels;
1656
1657        switch (dev) {
1658        case SOUND_MIXER_VOLUME:
1659        case SOUND_MIXER_SYNTH:
1660        case SOUND_MIXER_PCM:
1661        case SOUND_MIXER_LINE:
1662        case SOUND_MIXER_IGAIN:
1663                levels = devc->levels[dev];
1664                break;
1665
1666        case SOUND_MIXER_MIC:           /* builtin mic: right mic only */
1667                levels = devc->levels[SOUND_MIXER_MIC] >> 8;
1668                levels |= levels << 8;
1669                break;
1670
1671        case SOUND_MIXER_LINE1:         /* handset mic: left mic only */
1672                levels = devc->levels[SOUND_MIXER_MIC] & 0xff;
1673                levels |= levels << 8;
1674                break;
1675
1676        case SOUND_MIXER_PHONEIN:       /* phone mic: left aux1 only */
1677                levels = devc->levels[SOUND_MIXER_LINE1] & 0xff;
1678                levels |= levels << 8;
1679                break;
1680
1681        default:
1682                levels = 0;
1683        }
1684
1685        return levels;
1686}
1687
1688/*
1689 * Waveartist specific mixer information.
1690 */
1691static const struct waveartist_mixer_info netwinder_mixer = {
1692        .supported_devs = SOUND_MASK_VOLUME  | SOUND_MASK_SYNTH   |
1693                        SOUND_MASK_PCM     | SOUND_MASK_SPEAKER |
1694                        SOUND_MASK_LINE    | SOUND_MASK_MIC     |
1695                        SOUND_MASK_IMIX    | SOUND_MASK_LINE1   |
1696                        SOUND_MASK_PHONEIN | SOUND_MASK_PHONEOUT|
1697                        SOUND_MASK_IGAIN,
1698
1699        .recording_devs = SOUND_MASK_LINE    | SOUND_MASK_MIC     |
1700                        SOUND_MASK_IMIX    | SOUND_MASK_LINE1   |
1701                        SOUND_MASK_PHONEIN,
1702
1703        .stereo_devs    = SOUND_MASK_VOLUME  | SOUND_MASK_SYNTH   |
1704                        SOUND_MASK_PCM     | SOUND_MASK_LINE    |
1705                        SOUND_MASK_IMIX    | SOUND_MASK_IGAIN,
1706
1707        .select_input   = netwinder_select_input,
1708        .decode_mixer   = netwinder_decode_mixer,
1709        .get_mixer      = netwinder_get_mixer,
1710};
1711
1712static void
1713vnc_configure_mixer(wavnc_info *devc, unsigned int recmask)
1714{
1715        if (!devc->no_autoselect) {
1716                if (devc->handset_detect) {
1717                        recmask = SOUND_MASK_LINE1;
1718                        devc->spkr_mute_state = devc->line_mute_state = 1;
1719                } else if (devc->telephone_detect) {
1720                        recmask = SOUND_MASK_PHONEIN;
1721                        devc->spkr_mute_state = devc->line_mute_state = 1;
1722                } else {
1723                        /* unless someone has asked for LINE-IN,
1724                         * we default to MIC
1725                         */
1726                        if ((devc->recmask & SOUND_MASK_LINE) == 0)
1727                                devc->recmask = SOUND_MASK_MIC;
1728                        devc->spkr_mute_state = devc->line_mute_state = 0;
1729                }
1730                vnc_mute_spkr(devc);
1731                vnc_mute_lout(devc);
1732
1733                if (recmask != devc->recmask)
1734                        waveartist_set_recmask(devc, recmask);
1735        }
1736}
1737
1738static int
1739vnc_slider(wavnc_info *devc)
1740{
1741        signed int slider_volume;
1742        unsigned int temp, old_hs, old_td;
1743
1744        /*
1745         * read the "buttons" state.
1746         *  Bit 4 = 0 means handset present
1747         *  Bit 5 = 1 means phone offhook
1748         */
1749        temp = inb(0x201);
1750
1751        old_hs = devc->handset_detect;
1752        old_td = devc->telephone_detect;
1753
1754        devc->handset_detect = !(temp & 0x10);
1755        devc->telephone_detect = !!(temp & 0x20);
1756
1757        if (!devc->no_autoselect &&
1758            (old_hs != devc->handset_detect ||
1759             old_td != devc->telephone_detect))
1760                vnc_configure_mixer(devc, devc->recmask);
1761
1762        slider_volume = vnc_volume_slider(devc);
1763
1764        /*
1765         * If we're using software controlled volume, and
1766         * the slider moves by more than 20%, then we
1767         * switch back to slider controlled volume.
1768         */
1769        if (abs(devc->slider_vol - slider_volume) > 20)
1770                devc->use_slider = 1;
1771
1772        /*
1773         * use only left channel
1774         */
1775        temp = levels[SOUND_MIXER_VOLUME] & 0xFF;
1776
1777        if (slider_volume != temp && devc->use_slider) {
1778                devc->slider_vol = slider_volume;
1779
1780                waveartist_set_mixer(devc, SOUND_MIXER_VOLUME,
1781                        slider_volume | slider_volume << 8);
1782
1783                return 1;
1784        }
1785
1786        return 0;
1787}
1788
1789static void
1790vnc_slider_tick(unsigned long data)
1791{
1792        int next_timeout;
1793
1794        if (vnc_slider(adev_info + data))
1795                next_timeout = 5;       // mixer reported change
1796        else
1797                next_timeout = VNC_TIMER_PERIOD;
1798
1799        mod_timer(&vnc_timer, jiffies + next_timeout);
1800}
1801
1802static int
1803vnc_private_ioctl(int dev, unsigned int cmd, int __user * arg)
1804{
1805        wavnc_info *devc = (wavnc_info *)audio_devs[dev]->devc;
1806        int val;
1807
1808        switch (cmd) {
1809        case SOUND_MIXER_PRIVATE1:
1810        {
1811                u_int prev_spkr_mute, prev_line_mute, prev_auto_state;
1812                int val;
1813
1814                if (get_user(val, arg))
1815                        return -EFAULT;
1816
1817                /* check if parameter is logical */
1818                if (val & ~(VNC_MUTE_INTERNAL_SPKR |
1819                            VNC_MUTE_LINE_OUT |
1820                            VNC_DISABLE_AUTOSWITCH))
1821                        return -EINVAL;
1822
1823                prev_auto_state = devc->no_autoselect;
1824                prev_spkr_mute  = devc->spkr_mute_state;
1825                prev_line_mute  = devc->line_mute_state;
1826
1827                devc->no_autoselect   = (val & VNC_DISABLE_AUTOSWITCH) ? 1 : 0;
1828                devc->spkr_mute_state = (val & VNC_MUTE_INTERNAL_SPKR) ? 1 : 0;
1829                devc->line_mute_state = (val & VNC_MUTE_LINE_OUT) ? 1 : 0;
1830
1831                if (prev_spkr_mute != devc->spkr_mute_state)
1832                        vnc_mute_spkr(devc);
1833
1834                if (prev_line_mute != devc->line_mute_state)
1835                        vnc_mute_lout(devc);
1836
1837                if (prev_auto_state != devc->no_autoselect)
1838                        vnc_configure_mixer(devc, devc->recmask);
1839
1840                return 0;
1841        }
1842
1843        case SOUND_MIXER_PRIVATE2:
1844                if (get_user(val, arg))
1845                        return -EFAULT;
1846
1847                switch (val) {
1848#define VNC_SOUND_PAUSE         0x53    //to pause the DSP
1849#define VNC_SOUND_RESUME        0x57    //to unpause the DSP
1850                case VNC_SOUND_PAUSE:
1851                        waveartist_cmd1(devc, 0x16);
1852                        break;
1853
1854                case VNC_SOUND_RESUME:
1855                        waveartist_cmd1(devc, 0x18);
1856                        break;
1857
1858                default:
1859                        return -EINVAL;
1860                }
1861                return 0;
1862
1863        /* private ioctl to allow bulk access to waveartist */
1864        case SOUND_MIXER_PRIVATE3:
1865        {
1866                unsigned long   flags;
1867                int             mixer_reg[15], i, val;
1868
1869                if (get_user(val, arg))
1870                        return -EFAULT;
1871                if (copy_from_user(mixer_reg, (void *)val, sizeof(mixer_reg)))
1872                        return -EFAULT;
1873
1874                switch (mixer_reg[14]) {
1875                case MIXER_PRIVATE3_RESET:
1876                        waveartist_mixer_reset(devc);
1877                        break;
1878
1879                case MIXER_PRIVATE3_WRITE:
1880                        waveartist_cmd3(devc, WACMD_SET_MIXER, mixer_reg[0], mixer_reg[4]);
1881                        waveartist_cmd3(devc, WACMD_SET_MIXER, mixer_reg[1], mixer_reg[5]);
1882                        waveartist_cmd3(devc, WACMD_SET_MIXER, mixer_reg[2], mixer_reg[6]);
1883                        waveartist_cmd3(devc, WACMD_SET_MIXER, mixer_reg[3], mixer_reg[7]);
1884                        waveartist_cmd3(devc, WACMD_SET_MIXER, mixer_reg[8], mixer_reg[9]);
1885
1886                        waveartist_cmd3(devc, WACMD_SET_LEVEL, mixer_reg[10], mixer_reg[11]);
1887                        waveartist_cmd3(devc, WACMD_SET_LEVEL, mixer_reg[12], mixer_reg[13]);
1888                        break;
1889
1890                case MIXER_PRIVATE3_READ:
1891                        spin_lock_irqsave(&waveartist_lock, flags);
1892
1893                        for (i = 0x30; i < 14 << 8; i += 1 << 8)
1894                                waveartist_cmd(devc, 1, &i, 1, mixer_reg + (i >> 8));
1895
1896                        spin_unlock_irqrestore(&waveartist_lock, flags);
1897
1898                        if (copy_to_user((void *)val, mixer_reg, sizeof(mixer_reg)))
1899                                return -EFAULT;
1900                        break;
1901
1902                default:
1903                        return -EINVAL;
1904                }
1905                return 0;
1906        }
1907
1908        /* read back the state from PRIVATE1 */
1909        case SOUND_MIXER_PRIVATE4:
1910                val = (devc->spkr_mute_state  ? VNC_MUTE_INTERNAL_SPKR : 0) |
1911                      (devc->line_mute_state  ? VNC_MUTE_LINE_OUT      : 0) |
1912                      (devc->handset_detect   ? VNC_HANDSET_DETECT     : 0) |
1913                      (devc->telephone_detect ? VNC_PHONE_DETECT       : 0) |
1914                      (devc->no_autoselect    ? VNC_DISABLE_AUTOSWITCH : 0);
1915
1916                return put_user(val, arg) ? -EFAULT : 0;
1917        }
1918
1919        if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
1920                /*
1921                 * special case for master volume: if we
1922                 * received this call - switch from hw
1923                 * volume control to a software volume
1924                 * control, till the hw volume is modified
1925                 * to signal that user wants to be back in
1926                 * hardware...
1927                 */
1928                if ((cmd & 0xff) == SOUND_MIXER_VOLUME)
1929                        devc->use_slider = 0;
1930
1931                /* speaker output            */
1932                if ((cmd & 0xff) == SOUND_MIXER_SPEAKER) {
1933                        unsigned int val, l, r;
1934
1935                        if (get_user(val, arg))
1936                                return -EFAULT;
1937
1938                        l = val & 0x7f;
1939                        r = (val & 0x7f00) >> 8;
1940                        val = (l + r) / 2;
1941                        devc->levels[SOUND_MIXER_SPEAKER] = val | (val << 8);
1942                        devc->spkr_mute_state = (val <= 50);
1943                        vnc_mute_spkr(devc);
1944                        return 0;
1945                }
1946        }
1947
1948        return -ENOIOCTLCMD;
1949}
1950
1951#endif
1952
1953static struct address_info cfg;
1954
1955static int attached;
1956
1957static int __initdata io = 0;
1958static int __initdata irq = 0;
1959static int __initdata dma = 0;
1960static int __initdata dma2 = 0;
1961
1962
1963static int __init init_waveartist(void)
1964{
1965        const struct waveartist_mixer_info *mix;
1966
1967        if (!io && machine_is_netwinder()) {
1968                /*
1969                 * The NetWinder WaveArtist is at a fixed address.
1970                 * If the user does not supply an address, use the
1971                 * well-known parameters.
1972                 */
1973                io   = 0x250;
1974                irq  = 12;
1975                dma  = 3;
1976                dma2 = 7;
1977        }
1978
1979        mix = &waveartist_mixer;
1980#ifdef CONFIG_ARCH_NETWINDER
1981        if (machine_is_netwinder())
1982                mix = &netwinder_mixer;
1983#endif
1984
1985        cfg.io_base = io;
1986        cfg.irq = irq;
1987        cfg.dma = dma;
1988        cfg.dma2 = dma2;
1989
1990        if (!probe_waveartist(&cfg))
1991                return -ENODEV;
1992
1993        attach_waveartist(&cfg, mix);
1994        attached = 1;
1995
1996        return 0;
1997}
1998
1999static void __exit cleanup_waveartist(void)
2000{
2001        if (attached)
2002                unload_waveartist(&cfg);
2003}
2004
2005module_init(init_waveartist);
2006module_exit(cleanup_waveartist);
2007
2008#ifndef MODULE
2009static int __init setup_waveartist(char *str)
2010{
2011        /* io, irq, dma, dma2 */
2012        int ints[5];
2013        
2014        str = get_options(str, ARRAY_SIZE(ints), ints);
2015        
2016        io      = ints[1];
2017        irq     = ints[2];
2018        dma     = ints[3];
2019        dma2    = ints[4];
2020
2021        return 1;
2022}
2023__setup("waveartist=", setup_waveartist);
2024#endif
2025
2026MODULE_DESCRIPTION("Rockwell WaveArtist RWA-010 sound driver");
2027module_param(io, int, 0);               /* IO base */
2028module_param(irq, int, 0);              /* IRQ */
2029module_param(dma, int, 0);              /* DMA */
2030module_param(dma2, int, 0);             /* DMA2 */
2031MODULE_LICENSE("GPL");
2032
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.