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