linux/sound/pci/azt3328.c
<<
>>
Prefs
   1/*
   2 *  azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
   3 *  Copyright (C) 2002, 2005 - 2008 by Andreas Mohr <andi AT lisas.de>
   4 *
   5 *  Framework borrowed from Bart Hartgers's als4000.c.
   6 *  Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801),
   7 *  found in a Fujitsu-Siemens PC ("Cordant", aluminum case).
   8 *  Other versions are:
   9 *  PCI168 A(W), sub ID 1800
  10 *  PCI168 A/AP, sub ID 8000
  11 *  Please give me feedback in case you try my driver with one of these!!
  12 *
  13 * GPL LICENSE
  14 *  This program is free software; you can redistribute it and/or modify
  15 *  it under the terms of the GNU General Public License as published by
  16 *  the Free Software Foundation; either version 2 of the License, or
  17 *  (at your option) any later version.
  18 *
  19 *  This program is distributed in the hope that it will be useful,
  20 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  21 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22 *  GNU General Public License for more details.
  23
  24 *  You should have received a copy of the GNU General Public License
  25 *  along with this program; if not, write to the Free Software
  26 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  27 *
  28 * NOTES
  29 *  Since Aztech does not provide any chipset documentation,
  30 *  even on repeated request to various addresses,
  31 *  and the answer that was finally given was negative
  32 *  (and I was stupid enough to manage to get hold of a PCI168 soundcard
  33 *  in the first place >:-P}),
  34 *  I was forced to base this driver on reverse engineering
  35 *  (3 weeks' worth of evenings filled with driver work).
  36 *  (and no, I did NOT go the easy way: to pick up a SB PCI128 for 9 Euros)
  37 *
  38 *  It is quite likely that the AZF3328 chip is the PCI cousin of the
  39 *  AZF3318 ("azt1020 pnp", "MM Pro 16") ISA chip, given very similar specs.
  40 *
  41 *  The AZF3328 chip (note: AZF3328, *not* AZT3328, that's just the driver name
  42 *  for compatibility reasons) from Azfin (joint-venture of Aztech and Fincitec,
  43 *  Fincitec acquired by National Semiconductor in 2002, together with the
  44 *  Fincitec-related company ARSmikro) has the following features:
  45 *
  46 *  - compatibility & compliance:
  47 *    - Microsoft PC 97 ("PC 97 Hardware Design Guide",
  48 *                       http://www.microsoft.com/whdc/archive/pcguides.mspx)
  49 *    - Microsoft PC 98 Baseline Audio
  50 *    - MPU401 UART
  51 *    - Sound Blaster Emulation (DOS Box)
  52 *  - builtin AC97 conformant codec (SNR over 80dB)
  53 *    Note that "conformant" != "compliant"!! this chip's mixer register layout
  54 *    *differs* from the standard AC97 layout:
  55 *    they chose to not implement the headphone register (which is not a
  56 *    problem since it's merely optional), yet when doing this, they committed
  57 *    the grave sin of letting other registers follow immediately instead of
  58 *    keeping a headphone dummy register, thereby shifting the mixer register
  59 *    addresses illegally. So far unfortunately it looks like the very flexible
  60 *    ALSA AC97 support is still not enough to easily compensate for such a
  61 *    grave layout violation despite all tweaks and quirks mechanisms it offers.
  62 *  - builtin genuine OPL3 - verified to work fine, 20080506
  63 *  - full duplex 16bit playback/record at independent sampling rate
  64 *  - MPU401 (+ legacy address support, claimed by one official spec sheet)
  65 *    FIXME: how to enable legacy addr??
  66 *  - game port (legacy address support)
  67 *  - builtin DirectInput support, helps reduce CPU overhead (interrupt-driven
  68 *    features supported). - See common term "Digital Enhanced Game Port"...
  69 *    (probably DirectInput 3.0 spec - confirm)
  70 *  - builtin 3D enhancement (said to be YAMAHA Ymersion)
  71 *  - built-in General DirectX timer having a 20 bits counter
  72 *    with 1us resolution (see below!)
  73 *  - I2S serial output port for external DAC
  74 *  - supports 33MHz PCI spec 2.1, PCI power management 1.0, compliant with ACPI
  75 *  - supports hardware volume control
  76 *  - single chip low cost solution (128 pin QFP)
  77 *  - supports programmable Sub-vendor and Sub-system ID
  78 *    required for Microsoft's logo compliance (FIXME: where?)
  79 *    At least the Trident 4D Wave DX has one bit somewhere
  80 *    to enable writes to PCI subsystem VID registers, that should be it.
  81 *    This might easily be in extended PCI reg space, since PCI168 also has
  82 *    some custom data starting at 0x80. What kind of config settings
  83 *    are located in our extended PCI space anyway??
  84 *  - PCI168 AP(W) card: power amplifier with 4 Watts/channel at 4 Ohms
  85 *
  86 *  Note that this driver now is actually *better* than the Windows driver,
  87 *  since it additionally supports the card's 1MHz DirectX timer - just try
  88 *  the following snd-seq module parameters etc.:
  89 *  - options snd-seq seq_default_timer_class=2 seq_default_timer_sclass=0
  90 *    seq_default_timer_card=0 seq_client_load=1 seq_default_timer_device=0
  91 *    seq_default_timer_subdevice=0 seq_default_timer_resolution=1000000
  92 *  - "timidity -iAv -B2,8 -Os -EFreverb=0"
  93 *  - "pmidi -p 128:0 jazz.mid"
  94 *
  95 *  OPL3 hardware playback testing, try something like:
  96 *  cat /proc/asound/hwdep
  97 *  and
  98 *  aconnect -o
  99 *  Then use
 100 *  sbiload -Dhw:x,y --opl3 /usr/share/sounds/opl3/std.o3 ......./drums.o3
 101 *  where x,y is the xx-yy number as given in hwdep.
 102 *  Then try
 103 *  pmidi -p a:b jazz.mid
 104 *  where a:b is the client number plus 0 usually, as given by aconnect above.
 105 *  Oh, and make sure to unmute the FM mixer control (doh!)
 106 *  NOTE: power use during OPL3 playback is _VERY_ high (70W --> 90W!)
 107 *  despite no CPU activity, possibly due to hindering ACPI idling somehow.
 108 *  Shouldn't be a problem of the AZF3328 chip itself, I'd hope.
 109 *  Higher PCM / FM mixer levels seem to conflict (causes crackling),
 110 *  at least sometimes.   Maybe even use with hardware sequencer timer above :)
 111 *  adplay/adplug-utils might soon offer hardware-based OPL3 playback, too.
 112 *
 113 *  Certain PCI versions of this card are susceptible to DMA traffic underruns
 114 *  in some systems (resulting in sound crackling/clicking/popping),
 115 *  probably because they don't have a DMA FIFO buffer or so.
 116 *  Overview (PCI ID/PCI subID/PCI rev.):
 117 *  - no DMA crackling on SiS735: 0x50DC/0x1801/16
 118 *  - unknown performance: 0x50DC/0x1801/10
 119 *    (well, it's not bad on an Athlon 1800 with now very optimized IRQ handler)
 120 *
 121 *  Crackling happens with VIA chipsets or, in my case, an SiS735, which is
 122 *  supposed to be very fast and supposed to get rid of crackling much
 123 *  better than a VIA, yet ironically I still get crackling, like many other
 124 *  people with the same chipset.
 125 *  Possible remedies:
 126 *  - use speaker (amplifier) output instead of headphone output
 127 *    (in case crackling is due to overloaded output clipping)
 128 *  - plug card into a different PCI slot, preferrably one that isn't shared
 129 *    too much (this helps a lot, but not completely!)
 130 *  - get rid of PCI VGA card, use AGP instead
 131 *  - upgrade or downgrade BIOS
 132 *  - fiddle with PCI latency settings (setpci -v -s BUSID latency_timer=XX)
 133 *    Not too helpful.
 134 *  - Disable ACPI/power management/"Auto Detect RAM/PCI Clk" in BIOS
 135 *
 136 * BUGS
 137 *  - full-duplex might *still* be problematic, however a recent test was fine
 138 *  - (non-bug) "Bass/Treble or 3D settings don't work" - they do get evaluated
 139 *    if you set PCM output switch to "pre 3D" instead of "post 3D".
 140 *    If this can't be set, then get a mixer application that Isn't Stupid (tm)
 141 *    (e.g. kmix, gamix) - unfortunately several are!!
 142 *  - locking is not entirely clean, especially the audio stream activity
 143 *    ints --> may be racy
 144 *  - an _unconnected_ secondary joystick at the gameport will be reported
 145 *    to be "active" (floating values, not precisely -1) due to the way we need
 146 *    to read the Digital Enhanced Game Port. Not sure whether it is fixable.
 147 *
 148 * TODO
 149 *  - test MPU401 MIDI playback etc.
 150 *  - add more power micro-management (disable various units of the card
 151 *    as long as they're unused). However this requires more I/O ports which I
 152 *    haven't figured out yet and which thus might not even exist...
 153 *    The standard suspend/resume functionality could probably make use of
 154 *    some improvement, too...
 155 *  - figure out what all unknown port bits are responsible for
 156 *  - figure out some cleverly evil scheme to possibly make ALSA AC97 code
 157 *    fully accept our quite incompatible ""AC97"" mixer and thus save some
 158 *    code (but I'm not too optimistic that doing this is possible at all)
 159 *  - use MMIO (memory-mapped I/O)? Slightly faster access, e.g. for gameport.
 160 */
 161
 162#include <asm/io.h>
 163#include <linux/init.h>
 164#include <linux/pci.h>
 165#include <linux/delay.h>
 166#include <linux/slab.h>
 167#include <linux/gameport.h>
 168#include <linux/moduleparam.h>
 169#include <linux/dma-mapping.h>
 170#include <sound/core.h>
 171#include <sound/control.h>
 172#include <sound/pcm.h>
 173#include <sound/rawmidi.h>
 174#include <sound/mpu401.h>
 175#include <sound/opl3.h>
 176#include <sound/initval.h>
 177#include "azt3328.h"
 178
 179MODULE_AUTHOR("Andreas Mohr <andi AT lisas.de>");
 180MODULE_DESCRIPTION("Aztech AZF3328 (PCI168)");
 181MODULE_LICENSE("GPL");
 182MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
 183
 184#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
 185#define SUPPORT_GAMEPORT 1
 186#endif
 187
 188#define DEBUG_MISC      0
 189#define DEBUG_CALLS     0
 190#define DEBUG_MIXER     0
 191#define DEBUG_PLAY_REC  0
 192#define DEBUG_IO        0
 193#define DEBUG_TIMER     0
 194#define DEBUG_GAME      0
 195#define MIXER_TESTING   0
 196
 197#if DEBUG_MISC
 198#define snd_azf3328_dbgmisc(format, args...) printk(KERN_ERR format, ##args)
 199#else
 200#define snd_azf3328_dbgmisc(format, args...)
 201#endif
 202
 203#if DEBUG_CALLS
 204#define snd_azf3328_dbgcalls(format, args...) printk(format, ##args)
 205#define snd_azf3328_dbgcallenter() printk(KERN_ERR "--> %s\n", __func__)
 206#define snd_azf3328_dbgcallleave() printk(KERN_ERR "<-- %s\n", __func__)
 207#else
 208#define snd_azf3328_dbgcalls(format, args...)
 209#define snd_azf3328_dbgcallenter()
 210#define snd_azf3328_dbgcallleave()
 211#endif
 212
 213#if DEBUG_MIXER
 214#define snd_azf3328_dbgmixer(format, args...) printk(format, ##args)
 215#else
 216#define snd_azf3328_dbgmixer(format, args...)
 217#endif
 218
 219#if DEBUG_PLAY_REC
 220#define snd_azf3328_dbgplay(format, args...) printk(KERN_ERR format, ##args)
 221#else
 222#define snd_azf3328_dbgplay(format, args...)
 223#endif
 224
 225#if DEBUG_MISC
 226#define snd_azf3328_dbgtimer(format, args...) printk(KERN_ERR format, ##args)
 227#else
 228#define snd_azf3328_dbgtimer(format, args...)
 229#endif
 230
 231#if DEBUG_GAME
 232#define snd_azf3328_dbggame(format, args...) printk(KERN_ERR format, ##args)
 233#else
 234#define snd_azf3328_dbggame(format, args...)
 235#endif
 236
 237static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;      /* Index 0-MAX */
 238module_param_array(index, int, NULL, 0444);
 239MODULE_PARM_DESC(index, "Index value for AZF3328 soundcard.");
 240
 241static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;       /* ID for this card */
 242module_param_array(id, charp, NULL, 0444);
 243MODULE_PARM_DESC(id, "ID string for AZF3328 soundcard.");
 244
 245static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;      /* Enable this card */
 246module_param_array(enable, bool, NULL, 0444);
 247MODULE_PARM_DESC(enable, "Enable AZF3328 soundcard.");
 248
 249static int seqtimer_scaling = 128;
 250module_param(seqtimer_scaling, int, 0444);
 251MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128.");
 252
 253struct snd_azf3328_audio_stream {
 254        struct snd_pcm_substream *substream;
 255        int enabled;
 256        int running;
 257        unsigned long portbase;
 258};
 259
 260enum snd_azf3328_stream_index {
 261  AZF_PLAYBACK = 0,
 262  AZF_CAPTURE = 1,
 263};
 264
 265struct snd_azf3328 {
 266        /* often-used fields towards beginning, then grouped */
 267
 268        unsigned long codec_io; /* usually 0xb000, size 128 */
 269        unsigned long game_io;  /* usually 0xb400, size 8 */
 270        unsigned long mpu_io;   /* usually 0xb800, size 4 */
 271        unsigned long opl3_io; /* usually 0xbc00, size 8 */
 272        unsigned long mixer_io; /* usually 0xc000, size 64 */
 273
 274        spinlock_t reg_lock;
 275
 276        struct snd_timer *timer;
 277
 278        struct snd_pcm *pcm;
 279        struct snd_azf3328_audio_stream audio_stream[2];
 280
 281        struct snd_card *card;
 282        struct snd_rawmidi *rmidi;
 283
 284#ifdef SUPPORT_GAMEPORT
 285        struct gameport *gameport;
 286        int axes[4];
 287#endif
 288
 289        struct pci_dev *pci;
 290        int irq;
 291
 292        /* register 0x6a is write-only, thus need to remember setting.
 293         * If we need to add more registers here, then we might try to fold this
 294         * into some transparent combined shadow register handling with
 295         * CONFIG_PM register storage below, but that's slightly difficult. */
 296        u16 shadow_reg_codec_6AH;
 297
 298#ifdef CONFIG_PM
 299        /* register value containers for power management
 300         * Note: not always full I/O range preserved (just like Win driver!) */
 301        u16 saved_regs_codec[AZF_IO_SIZE_CODEC_PM / 2];
 302        u16 saved_regs_game [AZF_IO_SIZE_GAME_PM / 2];
 303        u16 saved_regs_mpu  [AZF_IO_SIZE_MPU_PM / 2];
 304        u16 saved_regs_opl3 [AZF_IO_SIZE_OPL3_PM / 2];
 305        u16 saved_regs_mixer[AZF_IO_SIZE_MIXER_PM / 2];
 306#endif
 307};
 308
 309static const struct pci_device_id snd_azf3328_ids[] = {
 310        { 0x122D, 0x50DC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },   /* PCI168/3328 */
 311        { 0x122D, 0x80DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },   /* 3328 */
 312        { 0, }
 313};
 314
 315MODULE_DEVICE_TABLE(pci, snd_azf3328_ids);
 316
 317
 318static int
 319snd_azf3328_io_reg_setb(unsigned reg, u8 mask, int do_set)
 320{
 321        u8 prev = inb(reg), new;
 322
 323        new = (do_set) ? (prev|mask) : (prev & ~mask);
 324        /* we need to always write the new value no matter whether it differs
 325         * or not, since some register bits don't indicate their setting */
 326        outb(new, reg);
 327        if (new != prev)
 328                return 1;
 329
 330        return 0;
 331}
 332
 333static inline void
 334snd_azf3328_codec_outb(const struct snd_azf3328 *chip, unsigned reg, u8 value)
 335{
 336        outb(value, chip->codec_io + reg);
 337}
 338
 339static inline u8
 340snd_azf3328_codec_inb(const struct snd_azf3328 *chip, unsigned reg)
 341{
 342        return inb(chip->codec_io + reg);
 343}
 344
 345static inline void
 346snd_azf3328_codec_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
 347{
 348        outw(value, chip->codec_io + reg);
 349}
 350
 351static inline u16
 352snd_azf3328_codec_inw(const struct snd_azf3328 *chip, unsigned reg)
 353{
 354        return inw(chip->codec_io + reg);
 355}
 356
 357static inline void
 358snd_azf3328_codec_outl(const struct snd_azf3328 *chip, unsigned reg, u32 value)
 359{
 360        outl(value, chip->codec_io + reg);
 361}
 362
 363static inline u32
 364snd_azf3328_codec_inl(const struct snd_azf3328 *chip, unsigned reg)
 365{
 366        return inl(chip->codec_io + reg);
 367}
 368
 369static inline void
 370snd_azf3328_game_outb(const struct snd_azf3328 *chip, unsigned reg, u8 value)
 371{
 372        outb(value, chip->game_io + reg);
 373}
 374
 375static inline void
 376snd_azf3328_game_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
 377{
 378        outw(value, chip->game_io + reg);
 379}
 380
 381static inline u8
 382snd_azf3328_game_inb(const struct snd_azf3328 *chip, unsigned reg)
 383{
 384        return inb(chip->game_io + reg);
 385}
 386
 387static inline u16
 388snd_azf3328_game_inw(const struct snd_azf3328 *chip, unsigned reg)
 389{
 390        return inw(chip->game_io + reg);
 391}
 392
 393static inline void
 394snd_azf3328_mixer_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
 395{
 396        outw(value, chip->mixer_io + reg);
 397}
 398
 399static inline u16
 400snd_azf3328_mixer_inw(const struct snd_azf3328 *chip, unsigned reg)
 401{
 402        return inw(chip->mixer_io + reg);
 403}
 404
 405#define AZF_MUTE_BIT 0x80
 406
 407static int
 408snd_azf3328_mixer_set_mute(const struct snd_azf3328 *chip,
 409                           unsigned reg, int do_mute
 410)
 411{
 412        unsigned long portbase = chip->mixer_io + reg + 1;
 413        int updated;
 414
 415        /* the mute bit is on the *second* (i.e. right) register of a
 416         * left/right channel setting */
 417        updated = snd_azf3328_io_reg_setb(portbase, AZF_MUTE_BIT, do_mute);
 418
 419        /* indicate whether it was muted before */
 420        return (do_mute) ? !updated : updated;
 421}
 422
 423static void
 424snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip,
 425                                         unsigned reg,
 426                                         unsigned char dst_vol_left,
 427                                         unsigned char dst_vol_right,
 428                                         int chan_sel, int delay
 429)
 430{
 431        unsigned long portbase = chip->mixer_io + reg;
 432        unsigned char curr_vol_left = 0, curr_vol_right = 0;
 433        int left_change = 0, right_change = 0;
 434
 435        snd_azf3328_dbgcallenter();
 436
 437        if (chan_sel & SET_CHAN_LEFT) {
 438                curr_vol_left  = inb(portbase + 1);
 439
 440                /* take care of muting flag contained in left channel */
 441                if (curr_vol_left & AZF_MUTE_BIT)
 442                        dst_vol_left |= AZF_MUTE_BIT;
 443                else
 444                        dst_vol_left &= ~AZF_MUTE_BIT;
 445
 446                left_change = (curr_vol_left > dst_vol_left) ? -1 : 1;
 447        }
 448
 449        if (chan_sel & SET_CHAN_RIGHT) {
 450                curr_vol_right = inb(portbase + 0);
 451
 452                right_change = (curr_vol_right > dst_vol_right) ? -1 : 1;
 453        }
 454
 455        do {
 456                if (left_change) {
 457                        if (curr_vol_left != dst_vol_left) {
 458                                curr_vol_left += left_change;
 459                                outb(curr_vol_left, portbase + 1);
 460                        } else
 461                            left_change = 0;
 462                }
 463                if (right_change) {
 464                        if (curr_vol_right != dst_vol_right) {
 465                                curr_vol_right += right_change;
 466
 467                        /* during volume change, the right channel is crackling
 468                         * somewhat more than the left channel, unfortunately.
 469                         * This seems to be a hardware issue. */
 470                                outb(curr_vol_right, portbase + 0);
 471                        } else
 472                            right_change = 0;
 473                }
 474                if (delay)
 475                        mdelay(delay);
 476        } while ((left_change) || (right_change));
 477        snd_azf3328_dbgcallleave();
 478}
 479
 480/*
 481 * general mixer element
 482 */
 483struct azf3328_mixer_reg {
 484        unsigned reg;
 485        unsigned int lchan_shift, rchan_shift;
 486        unsigned int mask;
 487        unsigned int invert: 1;
 488        unsigned int stereo: 1;
 489        unsigned int enum_c: 4;
 490};
 491
 492#define COMPOSE_MIXER_REG(reg,lchan_shift,rchan_shift,mask,invert,stereo,enum_c) \
 493 ((reg) | (lchan_shift << 8) | (rchan_shift << 12) | \
 494  (mask << 16) | \
 495  (invert << 24) | \
 496  (stereo << 25) | \
 497  (enum_c << 26))
 498
 499static void snd_azf3328_mixer_reg_decode(struct azf3328_mixer_reg *r, unsigned long val)
 500{
 501        r->reg = val & 0xff;
 502        r->lchan_shift = (val >> 8) & 0x0f;
 503        r->rchan_shift = (val >> 12) & 0x0f;
 504        r->mask = (val >> 16) & 0xff;
 505        r->invert = (val >> 24) & 1;
 506        r->stereo = (val >> 25) & 1;
 507        r->enum_c = (val >> 26) & 0x0f;
 508}
 509
 510/*
 511 * mixer switches/volumes
 512 */
 513
 514#define AZF3328_MIXER_SWITCH(xname, reg, shift, invert) \
 515{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
 516  .info = snd_azf3328_info_mixer, \
 517  .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
 518  .private_value = COMPOSE_MIXER_REG(reg, shift, 0, 0x1, invert, 0, 0), \
 519}
 520
 521#define AZF3328_MIXER_VOL_STEREO(xname, reg, mask, invert) \
 522{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
 523  .info = snd_azf3328_info_mixer, \
 524  .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
 525  .private_value = COMPOSE_MIXER_REG(reg, 8, 0, mask, invert, 1, 0), \
 526}
 527
 528#define AZF3328_MIXER_VOL_MONO(xname, reg, mask, is_right_chan) \
 529{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
 530  .info = snd_azf3328_info_mixer, \
 531  .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
 532  .private_value = COMPOSE_MIXER_REG(reg, is_right_chan ? 0 : 8, 0, mask, 1, 0, 0), \
 533}
 534
 535#define AZF3328_MIXER_VOL_SPECIAL(xname, reg, mask, shift, invert) \
 536{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
 537  .info = snd_azf3328_info_mixer, \
 538  .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
 539  .private_value = COMPOSE_MIXER_REG(reg, shift, 0, mask, invert, 0, 0), \
 540}
 541
 542#define AZF3328_MIXER_ENUM(xname, reg, enum_c, shift) \
 543{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
 544  .info = snd_azf3328_info_mixer_enum, \
 545  .get = snd_azf3328_get_mixer_enum, .put = snd_azf3328_put_mixer_enum, \
 546  .private_value = COMPOSE_MIXER_REG(reg, shift, 0, 0, 0, 0, enum_c), \
 547}
 548
 549static int
 550snd_azf3328_info_mixer(struct snd_kcontrol *kcontrol,
 551                       struct snd_ctl_elem_info *uinfo)
 552{
 553        struct azf3328_mixer_reg reg;
 554
 555        snd_azf3328_dbgcallenter();
 556        snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
 557        uinfo->type = reg.mask == 1 ?
 558                SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
 559        uinfo->count = reg.stereo + 1;
 560        uinfo->value.integer.min = 0;
 561        uinfo->value.integer.max = reg.mask;
 562        snd_azf3328_dbgcallleave();
 563        return 0;
 564}
 565
 566static int
 567snd_azf3328_get_mixer(struct snd_kcontrol *kcontrol,
 568                      struct snd_ctl_elem_value *ucontrol)
 569{
 570        struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
 571        struct azf3328_mixer_reg reg;
 572        unsigned int oreg, val;
 573
 574        snd_azf3328_dbgcallenter();
 575        snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
 576
 577        oreg = snd_azf3328_mixer_inw(chip, reg.reg);
 578        val = (oreg >> reg.lchan_shift) & reg.mask;
 579        if (reg.invert)
 580                val = reg.mask - val;
 581        ucontrol->value.integer.value[0] = val;
 582        if (reg.stereo) {
 583                val = (oreg >> reg.rchan_shift) & reg.mask;
 584                if (reg.invert)
 585                        val = reg.mask - val;
 586                ucontrol->value.integer.value[1] = val;
 587        }
 588        snd_azf3328_dbgmixer("get: %02x is %04x -> vol %02lx|%02lx "
 589                             "(shift %02d|%02d, mask %02x, inv. %d, stereo %d)\n",
 590                reg.reg, oreg,
 591                ucontrol->value.integer.value[0], ucontrol->value.integer.value[1],
 592                reg.lchan_shift, reg.rchan_shift, reg.mask, reg.invert, reg.stereo);
 593        snd_azf3328_dbgcallleave();
 594        return 0;
 595}
 596
 597static int
 598snd_azf3328_put_mixer(struct snd_kcontrol *kcontrol,
 599                      struct snd_ctl_elem_value *ucontrol)
 600{
 601        struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
 602        struct azf3328_mixer_reg reg;
 603        unsigned int oreg, nreg, val;
 604
 605        snd_azf3328_dbgcallenter();
 606        snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
 607        oreg = snd_azf3328_mixer_inw(chip, reg.reg);
 608        val = ucontrol->value.integer.value[0] & reg.mask;
 609        if (reg.invert)
 610                val = reg.mask - val;
 611        nreg = oreg & ~(reg.mask << reg.lchan_shift);
 612        nreg |= (val << reg.lchan_shift);
 613        if (reg.stereo) {
 614                val = ucontrol->value.integer.value[1] & reg.mask;
 615                if (reg.invert)
 616                        val = reg.mask - val;
 617                nreg &= ~(reg.mask << reg.rchan_shift);
 618                nreg |= (val << reg.rchan_shift);
 619        }
 620        if (reg.mask >= 0x07) /* it's a volume control, so better take care */
 621                snd_azf3328_mixer_write_volume_gradually(
 622                        chip, reg.reg, nreg >> 8, nreg & 0xff,
 623                        /* just set both channels, doesn't matter */
 624                        SET_CHAN_LEFT|SET_CHAN_RIGHT,
 625                        0);
 626        else
 627                snd_azf3328_mixer_outw(chip, reg.reg, nreg);
 628
 629        snd_azf3328_dbgmixer("put: %02x to %02lx|%02lx, "
 630                             "oreg %04x; shift %02d|%02d -> nreg %04x; after: %04x\n",
 631                reg.reg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1],
 632                oreg, reg.lchan_shift, reg.rchan_shift,
 633                nreg, snd_azf3328_mixer_inw(chip, reg.reg));
 634        snd_azf3328_dbgcallleave();
 635        return (nreg != oreg);
 636}
 637
 638static int
 639snd_azf3328_info_mixer_enum(struct snd_kcontrol *kcontrol,
 640                            struct snd_ctl_elem_info *uinfo)
 641{
 642        static const char * const texts1[] = {
 643                "Mic1", "Mic2"
 644        };
 645        static const char * const texts2[] = {
 646                "Mix", "Mic"
 647        };
 648        static const char * const texts3[] = {
 649                "Mic", "CD", "Video", "Aux",
 650                "Line", "Mix", "Mix Mono", "Phone"
 651        };
 652        static const char * const texts4[] = {
 653                "pre 3D", "post 3D"
 654        };
 655        struct azf3328_mixer_reg reg;
 656        const char * const *p = NULL;
 657
 658        snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
 659        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 660        uinfo->count = (reg.reg == IDX_MIXER_REC_SELECT) ? 2 : 1;
 661        uinfo->value.enumerated.items = reg.enum_c;
 662        if (uinfo->value.enumerated.item > reg.enum_c - 1U)
 663                uinfo->value.enumerated.item = reg.enum_c - 1U;
 664        if (reg.reg == IDX_MIXER_ADVCTL2) {
 665                switch(reg.lchan_shift) {
 666                case 8: /* modem out sel */
 667                        p = texts1;
 668                        break;
 669                case 9: /* mono sel source */
 670                        p = texts2;
 671                        break;
 672                case 15: /* PCM Out Path */
 673                        p = texts4;
 674                        break;
 675                }
 676        } else
 677        if (reg.reg == IDX_MIXER_REC_SELECT)
 678                p = texts3;
 679
 680        strcpy(uinfo->value.enumerated.name, p[uinfo->value.enumerated.item]);
 681        return 0;
 682}
 683
 684static int
 685snd_azf3328_get_mixer_enum(struct snd_kcontrol *kcontrol,
 686                           struct snd_ctl_elem_value *ucontrol)
 687{
 688        struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
 689        struct azf3328_mixer_reg reg;
 690        unsigned short val;
 691
 692        snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
 693        val = snd_azf3328_mixer_inw(chip, reg.reg);
 694        if (reg.reg == IDX_MIXER_REC_SELECT) {
 695                ucontrol->value.enumerated.item[0] = (val >> 8) & (reg.enum_c - 1);
 696                ucontrol->value.enumerated.item[1] = (val >> 0) & (reg.enum_c - 1);
 697        } else
 698                ucontrol->value.enumerated.item[0] = (val >> reg.lchan_shift) & (reg.enum_c - 1);
 699
 700        snd_azf3328_dbgmixer("get_enum: %02x is %04x -> %d|%d (shift %02d, enum_c %d)\n",
 701                reg.reg, val, ucontrol->value.enumerated.item[0], ucontrol->value.enumerated.item[1],
 702                reg.lchan_shift, reg.enum_c);
 703        return 0;
 704}
 705
 706static int
 707snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol,
 708                           struct snd_ctl_elem_value *ucontrol)
 709{
 710        struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
 711        struct azf3328_mixer_reg reg;
 712        unsigned int oreg, nreg, val;
 713
 714        snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
 715        oreg = snd_azf3328_mixer_inw(chip, reg.reg);
 716        val = oreg;
 717        if (reg.reg == IDX_MIXER_REC_SELECT) {
 718                if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U ||
 719                ucontrol->value.enumerated.item[1] > reg.enum_c - 1U)
 720                        return -EINVAL;
 721                val = (ucontrol->value.enumerated.item[0] << 8) |
 722                      (ucontrol->value.enumerated.item[1] << 0);
 723        } else {
 724                if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U)
 725                        return -EINVAL;
 726                val &= ~((reg.enum_c - 1) << reg.lchan_shift);
 727                val |= (ucontrol->value.enumerated.item[0] << reg.lchan_shift);
 728        }
 729        snd_azf3328_mixer_outw(chip, reg.reg, val);
 730        nreg = val;
 731
 732        snd_azf3328_dbgmixer("put_enum: %02x to %04x, oreg %04x\n", reg.reg, val, oreg);
 733        return (nreg != oreg);
 734}
 735
 736static struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = {
 737        AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1),
 738        AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1),
 739        AZF3328_MIXER_SWITCH("PCM Playback Switch", IDX_MIXER_WAVEOUT, 15, 1),
 740        AZF3328_MIXER_VOL_STEREO("PCM Playback Volume",
 741                                        IDX_MIXER_WAVEOUT, 0x1f, 1),
 742        AZF3328_MIXER_SWITCH("PCM 3D Bypass Playback Switch",
 743                                        IDX_MIXER_ADVCTL2, 7, 1),
 744        AZF3328_MIXER_SWITCH("FM Playback Switch", IDX_MIXER_FMSYNTH, 15, 1),
 745        AZF3328_MIXER_VOL_STEREO("FM Playback Volume", IDX_MIXER_FMSYNTH, 0x1f, 1),
 746        AZF3328_MIXER_SWITCH("CD Playback Switch", IDX_MIXER_CDAUDIO, 15, 1),
 747        AZF3328_MIXER_VOL_STEREO("CD Playback Volume", IDX_MIXER_CDAUDIO, 0x1f, 1),
 748        AZF3328_MIXER_SWITCH("Capture Switch", IDX_MIXER_REC_VOLUME, 15, 1),
 749        AZF3328_MIXER_VOL_STEREO("Capture Volume", IDX_MIXER_REC_VOLUME, 0x0f, 0),
 750        AZF3328_MIXER_ENUM("Capture Source", IDX_MIXER_REC_SELECT, 8, 0),
 751        AZF3328_MIXER_SWITCH("Mic Playback Switch", IDX_MIXER_MIC, 15, 1),
 752        AZF3328_MIXER_VOL_MONO("Mic Playback Volume", IDX_MIXER_MIC, 0x1f, 1),
 753        AZF3328_MIXER_SWITCH("Mic Boost (+20dB)", IDX_MIXER_MIC, 6, 0),
 754        AZF3328_MIXER_SWITCH("Line Playback Switch", IDX_MIXER_LINEIN, 15, 1),
 755        AZF3328_MIXER_VOL_STEREO("Line Playback Volume", IDX_MIXER_LINEIN, 0x1f, 1),
 756        AZF3328_MIXER_SWITCH("PC Speaker Playback Switch", IDX_MIXER_PCBEEP, 15, 1),
 757        AZF3328_MIXER_VOL_SPECIAL("PC Speaker Playback Volume", IDX_MIXER_PCBEEP, 0x0f, 1, 1),
 758        AZF3328_MIXER_SWITCH("Video Playback Switch", IDX_MIXER_VIDEO, 15, 1),
 759        AZF3328_MIXER_VOL_STEREO("Video Playback Volume", IDX_MIXER_VIDEO, 0x1f, 1),
 760        AZF3328_MIXER_SWITCH("Aux Playback Switch", IDX_MIXER_AUX, 15, 1),
 761        AZF3328_MIXER_VOL_STEREO("Aux Playback Volume", IDX_MIXER_AUX, 0x1f, 1),
 762        AZF3328_MIXER_SWITCH("Modem Playback Switch", IDX_MIXER_MODEMOUT, 15, 1),
 763        AZF3328_MIXER_VOL_MONO("Modem Playback Volume", IDX_MIXER_MODEMOUT, 0x1f, 1),
 764        AZF3328_MIXER_SWITCH("Modem Capture Switch", IDX_MIXER_MODEMIN, 15, 1),
 765        AZF3328_MIXER_VOL_MONO("Modem Capture Volume", IDX_MIXER_MODEMIN, 0x1f, 1),
 766        AZF3328_MIXER_ENUM("Mic Select", IDX_MIXER_ADVCTL2, 2, 8),
 767        AZF3328_MIXER_ENUM("Mono Output Select", IDX_MIXER_ADVCTL2, 2, 9),
 768        AZF3328_MIXER_ENUM("PCM Output Route", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front since it controls *both* 3D and Bass/Treble! */
 769        AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0),
 770        AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0),
 771        AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0),
 772        AZF3328_MIXER_VOL_SPECIAL("3D Control - Width", IDX_MIXER_ADVCTL1, 0x07, 1, 0), /* "3D Width" */
 773        AZF3328_MIXER_VOL_SPECIAL("3D Control - Depth", IDX_MIXER_ADVCTL1, 0x03, 8, 0), /* "Hifi 3D" */
 774#if MIXER_TESTING
 775        AZF3328_MIXER_SWITCH("0", IDX_MIXER_ADVCTL2, 0, 0),
 776        AZF3328_MIXER_SWITCH("1", IDX_MIXER_ADVCTL2, 1, 0),
 777        AZF3328_MIXER_SWITCH("2", IDX_MIXER_ADVCTL2, 2, 0),
 778        AZF3328_MIXER_SWITCH("3", IDX_MIXER_ADVCTL2, 3, 0),
 779        AZF3328_MIXER_SWITCH("4", IDX_MIXER_ADVCTL2, 4, 0),
 780        AZF3328_MIXER_SWITCH("5", IDX_MIXER_ADVCTL2, 5, 0),
 781        AZF3328_MIXER_SWITCH("6", IDX_MIXER_ADVCTL2, 6, 0),
 782        AZF3328_MIXER_SWITCH("7", IDX_MIXER_ADVCTL2, 7, 0),
 783        AZF3328_MIXER_SWITCH("8", IDX_MIXER_ADVCTL2, 8, 0),
 784        AZF3328_MIXER_SWITCH("9", IDX_MIXER_ADVCTL2, 9, 0),
 785        AZF3328_MIXER_SWITCH("10", IDX_MIXER_ADVCTL2, 10, 0),
 786        AZF3328_MIXER_SWITCH("11", IDX_MIXER_ADVCTL2, 11, 0),
 787        AZF3328_MIXER_SWITCH("12", IDX_MIXER_ADVCTL2, 12, 0),
 788        AZF3328_MIXER_SWITCH("13", IDX_MIXER_ADVCTL2, 13, 0),
 789        AZF3328_MIXER_SWITCH("14", IDX_MIXER_ADVCTL2, 14, 0),
 790        AZF3328_MIXER_SWITCH("15", IDX_MIXER_ADVCTL2, 15, 0),
 791#endif
 792};
 793
 794static u16 __devinitdata snd_azf3328_init_values[][2] = {
 795        { IDX_MIXER_PLAY_MASTER,        MIXER_MUTE_MASK|0x1f1f },
 796        { IDX_MIXER_MODEMOUT,           MIXER_MUTE_MASK|0x1f1f },
 797        { IDX_MIXER_BASSTREBLE,         0x0000 },
 798        { IDX_MIXER_PCBEEP,             MIXER_MUTE_MASK|0x1f1f },
 799        { IDX_MIXER_MODEMIN,            MIXER_MUTE_MASK|0x1f1f },
 800        { IDX_MIXER_MIC,                MIXER_MUTE_MASK|0x001f },
 801        { IDX_MIXER_LINEIN,             MIXER_MUTE_MASK|0x1f1f },
 802        { IDX_MIXER_CDAUDIO,            MIXER_MUTE_MASK|0x1f1f },
 803        { IDX_MIXER_VIDEO,              MIXER_MUTE_MASK|0x1f1f },
 804        { IDX_MIXER_AUX,                MIXER_MUTE_MASK|0x1f1f },
 805        { IDX_MIXER_WAVEOUT,            MIXER_MUTE_MASK|0x1f1f },
 806        { IDX_MIXER_FMSYNTH,            MIXER_MUTE_MASK|0x1f1f },
 807        { IDX_MIXER_REC_VOLUME,         MIXER_MUTE_MASK|0x0707 },
 808};
 809
 810static int __devinit
 811snd_azf3328_mixer_new(struct snd_azf3328 *chip)
 812{
 813        struct snd_card *card;
 814        const struct snd_kcontrol_new *sw;
 815        unsigned int idx;
 816        int err;
 817
 818        snd_azf3328_dbgcallenter();
 819        if (snd_BUG_ON(!chip || !chip->card))
 820                return -EINVAL;
 821
 822        card = chip->card;
 823
 824        /* mixer reset */
 825        snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
 826
 827        /* mute and zero volume channels */
 828        for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_init_values); ++idx) {
 829                snd_azf3328_mixer_outw(chip,
 830                        snd_azf3328_init_values[idx][0],
 831                        snd_azf3328_init_values[idx][1]);
 832        }
 833
 834        /* add mixer controls */
 835        sw = snd_azf3328_mixer_controls;
 836        for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_mixer_controls);
 837                        ++idx, ++sw) {
 838                if ((err = snd_ctl_add(chip->card, snd_ctl_new1(sw, chip))) < 0)
 839                        return err;
 840        }
 841        snd_component_add(card, "AZF3328 mixer");
 842        strcpy(card->mixername, "AZF3328 mixer");
 843
 844        snd_azf3328_dbgcallleave();
 845        return 0;
 846}
 847
 848static int
 849snd_azf3328_hw_params(struct snd_pcm_substream *substream,
 850                                 struct snd_pcm_hw_params *hw_params)
 851{
 852        int res;
 853        snd_azf3328_dbgcallenter();
 854        res = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 855        snd_azf3328_dbgcallleave();
 856        return res;
 857}
 858
 859static int
 860snd_azf3328_hw_free(struct snd_pcm_substream *substream)
 861{
 862        snd_azf3328_dbgcallenter();
 863        snd_pcm_lib_free_pages(substream);
 864        snd_azf3328_dbgcallleave();
 865        return 0;
 866}
 867
 868static void
 869snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
 870                               unsigned reg,
 871                               enum azf_freq_t bitrate,
 872                               unsigned int format_width,
 873                               unsigned int channels
 874)
 875{
 876        u16 val = 0xff00;
 877        unsigned long flags;
 878
 879        snd_azf3328_dbgcallenter();
 880        switch (bitrate) {
 881        case AZF_FREQ_4000:  val |= SOUNDFORMAT_FREQ_SUSPECTED_4000; break;
 882        case AZF_FREQ_4800:  val |= SOUNDFORMAT_FREQ_SUSPECTED_4800; break;
 883        case AZF_FREQ_5512:
 884                /* the AZF3328 names it "5510" for some strange reason */
 885                             val |= SOUNDFORMAT_FREQ_5510; break;
 886        case AZF_FREQ_6620:  val |= SOUNDFORMAT_FREQ_6620; break;
 887        case AZF_FREQ_8000:  val |= SOUNDFORMAT_FREQ_8000; break;
 888        case AZF_FREQ_9600:  val |= SOUNDFORMAT_FREQ_9600; break;
 889        case AZF_FREQ_11025: val |= SOUNDFORMAT_FREQ_11025; break;
 890        case AZF_FREQ_13240: val |= SOUNDFORMAT_FREQ_SUSPECTED_13240; break;
 891        case AZF_FREQ_16000: val |= SOUNDFORMAT_FREQ_16000; break;
 892        case AZF_FREQ_22050: val |= SOUNDFORMAT_FREQ_22050; break;
 893        case AZF_FREQ_32000: val |= SOUNDFORMAT_FREQ_32000; break;
 894        default:
 895                snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
 896                /* fall-through */
 897        case AZF_FREQ_44100: val |= SOUNDFORMAT_FREQ_44100; break;
 898        case AZF_FREQ_48000: val |= SOUNDFORMAT_FREQ_48000; break;
 899        case AZF_FREQ_66200: val |= SOUNDFORMAT_FREQ_SUSPECTED_66200; break;
 900        }
 901        /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */
 902        /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */
 903        /* val = 0xff0a; 47m30.599s (4764,891Hz; -> 4800Hz???) yup, 4803Hz */
 904        /* val = 0xff0c; 57m0.510s (4010,263Hz; -> 4000Hz???) yup, 4003Hz */
 905        /* val = 0xff05; 5m11.556s (... -> 44100Hz) */
 906        /* val = 0xff03; 10m21.529s (21872,463Hz; -> 22050Hz???) */
 907        /* val = 0xff0f; 20m41.883s (10937,993Hz; -> 11025Hz???) */
 908        /* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */
 909        /* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */
 910
 911        if (channels == 2)
 912                val |= SOUNDFORMAT_FLAG_2CHANNELS;
 913
 914        if (format_width == 16)
 915                val |= SOUNDFORMAT_FLAG_16BIT;
 916
 917        spin_lock_irqsave(&chip->reg_lock, flags);
 918
 919        /* set bitrate/format */
 920        snd_azf3328_codec_outw(chip, reg, val);
 921
 922        /* changing the bitrate/format settings switches off the
 923         * audio output with an annoying click in case of 8/16bit format change
 924         * (maybe shutting down DAC/ADC?), thus immediately
 925         * do some tweaking to reenable it and get rid of the clicking
 926         * (FIXME: yes, it works, but what exactly am I doing here?? :)
 927         * FIXME: does this have some side effects for full-duplex
 928         * or other dramatic side effects? */
 929        if (reg == IDX_IO_PLAY_SOUNDFORMAT) /* only do it for playback */
 930                snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
 931                        snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) |
 932                        DMA_PLAY_SOMETHING1 |
 933                        DMA_PLAY_SOMETHING2 |
 934                        SOMETHING_ALMOST_ALWAYS_SET |
 935                        DMA_EPILOGUE_SOMETHING |
 936                        DMA_SOMETHING_ELSE
 937                );
 938
 939        spin_unlock_irqrestore(&chip->reg_lock, flags);
 940        snd_azf3328_dbgcallleave();
 941}
 942
 943static inline void
 944snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328 *chip,
 945                            unsigned reg
 946)
 947{
 948        /* choose lowest frequency for low power consumption.
 949         * While this will cause louder noise due to rather coarse frequency,
 950         * it should never matter since output should always
 951         * get disabled properly when idle anyway. */
 952        snd_azf3328_codec_setfmt(chip, reg, AZF_FREQ_4000, 8, 1);
 953}
 954
 955static void
 956snd_azf3328_codec_reg_6AH_update(struct snd_azf3328 *chip,
 957                                        unsigned bitmask,
 958                                        int enable
 959)
 960{
 961        if (enable)
 962                chip->shadow_reg_codec_6AH &= ~bitmask;
 963        else
 964                chip->shadow_reg_codec_6AH |= bitmask;
 965        snd_azf3328_dbgplay("6AH_update mask 0x%04x enable %d: val 0x%04x\n",
 966                        bitmask, enable, chip->shadow_reg_codec_6AH);
 967        snd_azf3328_codec_outw(chip, IDX_IO_6AH, chip->shadow_reg_codec_6AH);
 968}
 969
 970static inline void
 971snd_azf3328_codec_enable(struct snd_azf3328 *chip, int enable)
 972{
 973        snd_azf3328_dbgplay("codec_enable %d\n", enable);
 974        /* no idea what exactly is being done here, but I strongly assume it's
 975         * PM related */
 976        snd_azf3328_codec_reg_6AH_update(
 977                chip, IO_6A_PAUSE_PLAYBACK_BIT8, enable
 978        );
 979}
 980
 981static void
 982snd_azf3328_codec_activity(struct snd_azf3328 *chip,
 983                                enum snd_azf3328_stream_index stream_type,
 984                                int enable
 985)
 986{
 987        int need_change = (chip->audio_stream[stream_type].running != enable);
 988
 989        snd_azf3328_dbgplay(
 990                "codec_activity: type %d, enable %d, need_change %d\n",
 991                                stream_type, enable, need_change
 992        );
 993        if (need_change) {
 994                enum snd_azf3328_stream_index other =
 995                        (stream_type == AZF_PLAYBACK) ?
 996                                AZF_CAPTURE : AZF_PLAYBACK;
 997                /* small check to prevent shutting down the other party
 998                 * in case it's active */
 999                if ((enable) || !(chip->audio_stream[other].running))
1000                        snd_azf3328_codec_enable(chip, enable);
1001
1002                /* ...and adjust clock, too
1003                 * (reduce noise and power consumption) */
1004                if (!enable)
1005                        snd_azf3328_codec_setfmt_lowpower(
1006                                chip,
1007                                chip->audio_stream[stream_type].portbase
1008                                        + IDX_IO_PLAY_SOUNDFORMAT
1009                        );
1010        }
1011        chip->audio_stream[stream_type].running = enable;
1012}
1013
1014static void
1015snd_azf3328_setdmaa(struct snd_azf3328 *chip,
1016                                long unsigned int addr,
1017                                unsigned int count,
1018                                unsigned int size,
1019                                enum snd_azf3328_stream_index stream_type
1020)
1021{
1022        snd_azf3328_dbgcallenter();
1023        if (!chip->audio_stream[stream_type].running) {
1024                /* AZF3328 uses a two buffer pointer DMA playback approach */
1025
1026                unsigned long flags, portbase, addr_area2;
1027
1028                /* width 32bit (prevent overflow): */
1029                unsigned long count_areas, count_tmp;
1030
1031                portbase = chip->audio_stream[stream_type].portbase;
1032                count_areas = size/2;
1033                addr_area2 = addr+count_areas;
1034                count_areas--; /* max. index */
1035                snd_azf3328_dbgplay("set DMA: buf1 %08lx[%lu], buf2 %08lx[%lu]\n", addr, count_areas, addr_area2, count_areas);
1036
1037                /* build combined I/O buffer length word */
1038                count_tmp = count_areas;
1039                count_areas |= (count_tmp << 16);
1040                spin_lock_irqsave(&chip->reg_lock, flags);
1041                outl(addr, portbase + IDX_IO_PLAY_DMA_START_1);
1042                outl(addr_area2, portbase + IDX_IO_PLAY_DMA_START_2);
1043                outl(count_areas, portbase + IDX_IO_PLAY_DMA_LEN_1);
1044                spin_unlock_irqrestore(&chip->reg_lock, flags);
1045        }
1046        snd_azf3328_dbgcallleave();
1047}
1048
1049static int
1050snd_azf3328_playback_prepare(struct snd_pcm_substream *substream)
1051{
1052#if 0
1053        struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1054        struct snd_pcm_runtime *runtime = substream->runtime;
1055        unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1056        unsigned int count = snd_pcm_lib_period_bytes(substream);
1057#endif
1058
1059        snd_azf3328_dbgcallenter();
1060#if 0
1061        snd_azf3328_codec_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT,
1062                runtime->rate,
1063                snd_pcm_format_width(runtime->format),
1064                runtime->channels);
1065        snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, AZF_PLAYBACK);
1066#endif
1067        snd_azf3328_dbgcallleave();
1068        return 0;
1069}
1070
1071static int
1072snd_azf3328_capture_prepare(struct snd_pcm_substream *substream)
1073{
1074#if 0
1075        struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1076        struct snd_pcm_runtime *runtime = substream->runtime;
1077        unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1078        unsigned int count = snd_pcm_lib_period_bytes(substream);
1079#endif
1080
1081        snd_azf3328_dbgcallenter();
1082#if 0
1083        snd_azf3328_codec_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
1084                runtime->rate,
1085                snd_pcm_format_width(runtime->format),
1086                runtime->channels);
1087        snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, AZF_CAPTURE);
1088#endif
1089        snd_azf3328_dbgcallleave();
1090        return 0;
1091}
1092
1093static int
1094snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
1095{
1096        struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1097        struct snd_pcm_runtime *runtime = substream->runtime;
1098        int result = 0;
1099        unsigned int status1;
1100        int previously_muted;
1101
1102        snd_azf3328_dbgcalls("snd_azf3328_playback_trigger cmd %d\n", cmd);
1103
1104        switch (cmd) {
1105        case SNDRV_PCM_TRIGGER_START:
1106                snd_azf3328_dbgplay("START PLAYBACK\n");
1107
1108                /* mute WaveOut (avoid clicking during setup) */
1109                previously_muted =
1110                        snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
1111
1112                snd_azf3328_codec_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT,
1113                        runtime->rate,
1114                        snd_pcm_format_width(runtime->format),
1115                        runtime->channels);
1116
1117                spin_lock(&chip->reg_lock);
1118                /* first, remember current value: */
1119                status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS);
1120
1121                /* stop playback */
1122                status1 &= ~DMA_RESUME;
1123                snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
1124
1125                /* FIXME: clear interrupts or what??? */
1126                snd_azf3328_codec_outw(chip, IDX_IO_PLAY_IRQTYPE, 0xffff);
1127                spin_unlock(&chip->reg_lock);
1128
1129                snd_azf3328_setdmaa(chip, runtime->dma_addr,
1130                        snd_pcm_lib_period_bytes(substream),
1131                        snd_pcm_lib_buffer_bytes(substream),
1132                        AZF_PLAYBACK);
1133
1134                spin_lock(&chip->reg_lock);
1135#ifdef WIN9X
1136                /* FIXME: enable playback/recording??? */
1137                status1 |= DMA_PLAY_SOMETHING1 | DMA_PLAY_SOMETHING2;
1138                snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
1139
1140                /* start playback again */
1141                /* FIXME: what is this value (0x0010)??? */
1142                status1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
1143                snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
1144#else /* NT4 */
1145                snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
1146                        0x0000);
1147                snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
1148                        DMA_PLAY_SOMETHING1);
1149                snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
1150                        DMA_PLAY_SOMETHING1 |
1151                        DMA_PLAY_SOMETHING2);
1152                snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
1153                        DMA_RESUME |
1154                        SOMETHING_ALMOST_ALWAYS_SET |
1155                        DMA_EPILOGUE_SOMETHING |
1156                        DMA_SOMETHING_ELSE);
1157#endif
1158                spin_unlock(&chip->reg_lock);
1159                snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 1);
1160
1161                /* now unmute WaveOut */
1162                if (!previously_muted)
1163                        snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
1164
1165                snd_azf3328_dbgplay("STARTED PLAYBACK\n");
1166                break;
1167        case SNDRV_PCM_TRIGGER_RESUME:
1168                snd_azf3328_dbgplay("RESUME PLAYBACK\n");
1169                /* resume playback if we were active */
1170                spin_lock(&chip->reg_lock);
1171                if (chip->audio_stream[AZF_PLAYBACK].running)
1172                        snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
1173                                snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) | DMA_RESUME);
1174                spin_unlock(&chip->reg_lock);
1175                break;
1176        case SNDRV_PCM_TRIGGER_STOP:
1177                snd_azf3328_dbgplay("STOP PLAYBACK\n");
1178
1179                /* mute WaveOut (avoid clicking during setup) */
1180                previously_muted =
1181                        snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
1182
1183                spin_lock(&chip->reg_lock);
1184                /* first, remember current value: */
1185                status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS);
1186
1187                /* stop playback */
1188                status1 &= ~DMA_RESUME;
1189                snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
1190
1191                /* hmm, is this really required? we're resetting the same bit
1192                 * immediately thereafter... */
1193                status1 |= DMA_PLAY_SOMETHING1;
1194                snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
1195
1196                status1 &= ~DMA_PLAY_SOMETHING1;
1197                snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
1198                spin_unlock(&chip->reg_lock);
1199                snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 0);
1200
1201                /* now unmute WaveOut */
1202                if (!previously_muted)
1203                        snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
1204
1205                snd_azf3328_dbgplay("STOPPED PLAYBACK\n");
1206                break;
1207        case SNDRV_PCM_TRIGGER_SUSPEND:
1208                snd_azf3328_dbgplay("SUSPEND PLAYBACK\n");
1209                /* make sure playback is stopped */
1210                snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
1211                        snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) & ~DMA_RESUME);
1212                break;
1213        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1214                snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
1215                break;
1216        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1217                snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
1218                break;
1219        default:
1220                printk(KERN_ERR "FIXME: unknown trigger mode!\n");
1221                return -EINVAL;
1222        }
1223
1224        snd_azf3328_dbgcallleave();
1225        return result;
1226}
1227
1228/* this is just analogous to playback; I'm not quite sure whether recording
1229 * should actually be triggered like that */
1230static int
1231snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1232{
1233        struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1234        struct snd_pcm_runtime *runtime = substream->runtime;
1235        int result = 0;
1236        unsigned int status1;
1237
1238        snd_azf3328_dbgcalls("snd_azf3328_capture_trigger cmd %d\n", cmd);
1239
1240        switch (cmd) {
1241        case SNDRV_PCM_TRIGGER_START:
1242
1243                snd_azf3328_dbgplay("START CAPTURE\n");
1244
1245                snd_azf3328_codec_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
1246                        runtime->rate,
1247                        snd_pcm_format_width(runtime->format),
1248                        runtime->channels);
1249
1250                spin_lock(&chip->reg_lock);
1251                /* first, remember current value: */
1252                status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS);
1253
1254                /* stop recording */
1255                status1 &= ~DMA_RESUME;
1256                snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1257
1258                /* FIXME: clear interrupts or what??? */
1259                snd_azf3328_codec_outw(chip, IDX_IO_REC_IRQTYPE, 0xffff);
1260                spin_unlock(&chip->reg_lock);
1261
1262                snd_azf3328_setdmaa(chip, runtime->dma_addr,
1263                        snd_pcm_lib_period_bytes(substream),
1264                        snd_pcm_lib_buffer_bytes(substream),
1265                        AZF_CAPTURE);
1266
1267                spin_lock(&chip->reg_lock);
1268#ifdef WIN9X
1269                /* FIXME: enable playback/recording??? */
1270                status1 |= DMA_PLAY_SOMETHING1 | DMA_PLAY_SOMETHING2;
1271                snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1272
1273                /* start capture again */
1274                /* FIXME: what is this value (0x0010)??? */
1275                status1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
1276                snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1277#else
1278                snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1279                        0x0000);
1280                snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1281                        DMA_PLAY_SOMETHING1);
1282                snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1283                        DMA_PLAY_SOMETHING1 |
1284                        DMA_PLAY_SOMETHING2);
1285                snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1286                        DMA_RESUME |
1287                        SOMETHING_ALMOST_ALWAYS_SET |
1288                        DMA_EPILOGUE_SOMETHING |
1289                        DMA_SOMETHING_ELSE);
1290#endif
1291                spin_unlock(&chip->reg_lock);
1292                snd_azf3328_codec_activity(chip, AZF_CAPTURE, 1);
1293
1294                snd_azf3328_dbgplay("STARTED CAPTURE\n");
1295                break;
1296        case SNDRV_PCM_TRIGGER_RESUME:
1297                snd_azf3328_dbgplay("RESUME CAPTURE\n");
1298                /* resume recording if we were active */
1299                spin_lock(&chip->reg_lock);
1300                if (chip->audio_stream[AZF_CAPTURE].running)
1301                        snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1302                                snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS) | DMA_RESUME);
1303                spin_unlock(&chip->reg_lock);
1304                break;
1305        case SNDRV_PCM_TRIGGER_STOP:
1306                snd_azf3328_dbgplay("STOP CAPTURE\n");
1307
1308                spin_lock(&chip->reg_lock);
1309                /* first, remember current value: */
1310                status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS);
1311
1312                /* stop recording */
1313                status1 &= ~DMA_RESUME;
1314                snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1315
1316                status1 |= DMA_PLAY_SOMETHING1;
1317                snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1318
1319                status1 &= ~DMA_PLAY_SOMETHING1;
1320                snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1321                spin_unlock(&chip->reg_lock);
1322                snd_azf3328_codec_activity(chip, AZF_CAPTURE, 0);
1323
1324                snd_azf3328_dbgplay("STOPPED CAPTURE\n");
1325                break;
1326        case SNDRV_PCM_TRIGGER_SUSPEND:
1327                snd_azf3328_dbgplay("SUSPEND CAPTURE\n");
1328                /* make sure recording is stopped */
1329                snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1330                        snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS) & ~DMA_RESUME);
1331                break;
1332        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1333                snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
1334                break;
1335        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1336                snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
1337                break;
1338        default:
1339                printk(KERN_ERR "FIXME: unknown trigger mode!\n");
1340                return -EINVAL;
1341        }
1342
1343        snd_azf3328_dbgcallleave();
1344        return result;
1345}
1346
1347static snd_pcm_uframes_t
1348snd_azf3328_playback_pointer(struct snd_pcm_substream *substream)
1349{
1350        struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1351        unsigned long bufptr, result;
1352        snd_pcm_uframes_t frmres;
1353
1354#ifdef QUERY_HARDWARE
1355        bufptr = snd_azf3328_codec_inl(chip, IDX_IO_PLAY_DMA_START_1);
1356#else
1357        bufptr = substream->runtime->dma_addr;
1358#endif
1359        result = snd_azf3328_codec_inl(chip, IDX_IO_PLAY_DMA_CURRPOS);
1360
1361        /* calculate offset */
1362        result -= bufptr;
1363        frmres = bytes_to_frames( substream->runtime, result);
1364        snd_azf3328_dbgplay("PLAY @ 0x%8lx, frames %8ld\n", result, frmres);
1365        return frmres;
1366}
1367
1368static snd_pcm_uframes_t
1369snd_azf3328_capture_pointer(struct snd_pcm_substream *substream)
1370{
1371        struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1372        unsigned long bufptr, result;
1373        snd_pcm_uframes_t frmres;
1374
1375#ifdef QUERY_HARDWARE
1376        bufptr = snd_azf3328_codec_inl(chip, IDX_IO_REC_DMA_START_1);
1377#else
1378        bufptr = substream->runtime->dma_addr;
1379#endif
1380        result = snd_azf3328_codec_inl(chip, IDX_IO_REC_DMA_CURRPOS);
1381
1382        /* calculate offset */
1383        result -= bufptr;
1384        frmres = bytes_to_frames( substream->runtime, result);
1385        snd_azf3328_dbgplay("REC  @ 0x%8lx, frames %8ld\n", result, frmres);
1386        return frmres;
1387}
1388
1389/******************************************************************/
1390
1391#ifdef SUPPORT_GAMEPORT
1392static inline void
1393snd_azf3328_gameport_irq_enable(struct snd_azf3328 *chip, int enable)
1394{
1395        snd_azf3328_io_reg_setb(
1396                chip->game_io+IDX_GAME_HWCONFIG,
1397                GAME_HWCFG_IRQ_ENABLE,
1398                enable
1399        );
1400}
1401
1402static inline void
1403snd_azf3328_gameport_legacy_address_enable(struct snd_azf3328 *chip, int enable)
1404{
1405        snd_azf3328_io_reg_setb(
1406                chip->game_io+IDX_GAME_HWCONFIG,
1407                GAME_HWCFG_LEGACY_ADDRESS_ENABLE,
1408                enable
1409        );
1410}
1411
1412static inline void
1413snd_azf3328_gameport_axis_circuit_enable(struct snd_azf3328 *chip, int enable)
1414{
1415        snd_azf3328_codec_reg_6AH_update(
1416                chip, IO_6A_SOMETHING2_GAMEPORT, enable
1417        );
1418}
1419
1420static inline void
1421snd_azf3328_gameport_interrupt(struct snd_azf3328 *chip)
1422{
1423        /*
1424         * skeleton handler only
1425         * (we do not want axis reading in interrupt handler - too much load!)
1426         */
1427        snd_azf3328_dbggame("gameport irq\n");
1428
1429         /* this should ACK the gameport IRQ properly, hopefully. */
1430        snd_azf3328_game_inw(chip, IDX_GAME_AXIS_VALUE);
1431}
1432
1433static int
1434snd_azf3328_gameport_open(struct gameport *gameport, int mode)
1435{
1436        struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1437        int res;
1438
1439        snd_azf3328_dbggame("gameport_open, mode %d\n", mode);
1440        switch (mode) {
1441        case GAMEPORT_MODE_COOKED:
1442        case GAMEPORT_MODE_RAW:
1443                res = 0;
1444                break;
1445        default:
1446                res = -1;
1447                break;
1448        }
1449
1450        snd_azf3328_gameport_axis_circuit_enable(chip, (res == 0));
1451
1452        return res;
1453}
1454
1455static void
1456snd_azf3328_gameport_close(struct gameport *gameport)
1457{
1458        struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1459
1460        snd_azf3328_dbggame("gameport_close\n");
1461        snd_azf3328_gameport_axis_circuit_enable(chip, 0);
1462}
1463
1464static int
1465snd_azf3328_gameport_cooked_read(struct gameport *gameport,
1466                                 int *axes,
1467                                 int *buttons
1468)
1469{
1470        struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1471        int i;
1472        u8 val;
1473        unsigned long flags;
1474
1475        if (snd_BUG_ON(!chip))
1476                return 0;
1477
1478        spin_lock_irqsave(&chip->reg_lock, flags);
1479        val = snd_azf3328_game_inb(chip, IDX_GAME_LEGACY_COMPATIBLE);
1480        *buttons = (~(val) >> 4) & 0xf;
1481
1482        /* ok, this one is a bit dirty: cooked_read is being polled by a timer,
1483         * thus we're atomic and cannot actively wait in here
1484         * (which would be useful for us since it probably would be better
1485         * to trigger a measurement in here, then wait a short amount of
1486         * time until it's finished, then read values of _this_ measurement).
1487         *
1488         * Thus we simply resort to reading values if they're available already
1489         * and trigger the next measurement.
1490         */
1491
1492        val = snd_azf3328_game_inb(chip, IDX_GAME_AXES_CONFIG);
1493        if (val & GAME_AXES_SAMPLING_READY) {
1494                for (i = 0; i < 4; ++i) {
1495                        /* configure the axis to read */
1496                        val = (i << 4) | 0x0f;
1497                        snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val);
1498
1499                        chip->axes[i] = snd_azf3328_game_inw(
1500                                                chip, IDX_GAME_AXIS_VALUE
1501                                        );
1502                }
1503        }
1504
1505        /* trigger next axes sampling, to be evaluated the next time we
1506         * enter this function */
1507
1508        /* for some very, very strange reason we cannot enable
1509         * Measurement Ready monitoring for all axes here,
1510         * at least not when only one joystick connected */
1511        val = 0x03; /* we're able to monitor axes 1 and 2 only */
1512        snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val);
1513
1514        snd_azf3328_game_outw(chip, IDX_GAME_AXIS_VALUE, 0xffff);
1515        spin_unlock_irqrestore(&chip->reg_lock, flags);
1516
1517        for (i = 0; i < 4; i++) {
1518                axes[i] = chip->axes[i];
1519                if (axes[i] == 0xffff)
1520                        axes[i] = -1;
1521        }
1522
1523        snd_azf3328_dbggame("cooked_read: axes %d %d %d %d buttons %d\n",
1524                axes[0], axes[1], axes[2], axes[3], *buttons
1525        );
1526
1527        return 0;
1528}
1529
1530static int __devinit
1531snd_azf3328_gameport(struct snd_azf3328 *chip, int dev)
1532{
1533        struct gameport *gp;
1534
1535        chip->gameport = gp = gameport_allocate_port();
1536        if (!gp) {
1537                printk(KERN_ERR "azt3328: cannot alloc memory for gameport\n");
1538                return -ENOMEM;
1539        }
1540
1541        gameport_set_name(gp, "AZF3328 Gameport");
1542        gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
1543        gameport_set_dev_parent(gp, &chip->pci->dev);
1544        gp->io = chip->game_io;
1545        gameport_set_port_data(gp, chip);
1546
1547        gp->open = snd_azf3328_gameport_open;
1548        gp->close = snd_azf3328_gameport_close;
1549        gp->fuzz = 16; /* seems ok */
1550        gp->cooked_read = snd_azf3328_gameport_cooked_read;
1551
1552        /* DISABLE legacy address: we don't need it! */
1553        snd_azf3328_gameport_legacy_address_enable(chip, 0);
1554
1555        snd_azf3328_gameport_axis_circuit_enable(chip, 0);
1556
1557        gameport_register_port(chip->gameport);
1558
1559        return 0;
1560}
1561
1562static void
1563snd_azf3328_gameport_free(struct snd_azf3328 *chip)
1564{
1565        if (chip->gameport) {
1566                gameport_unregister_port(chip->gameport);
1567                chip->gameport = NULL;
1568        }
1569        snd_azf3328_gameport_irq_enable(chip, 0);
1570}
1571#else
1572static inline int
1573snd_azf3328_gameport(struct snd_azf3328 *chip, int dev) { return -ENOSYS; }
1574static inline void
1575snd_azf3328_gameport_free(struct snd_azf3328 *chip) { }
1576static inline void
1577snd_azf3328_gameport_interrupt(struct snd_azf3328 *chip)
1578{
1579        printk(KERN_WARNING "huh, game port IRQ occurred!?\n");
1580}
1581#endif /* SUPPORT_GAMEPORT */
1582
1583/******************************************************************/
1584
1585static inline void
1586snd_azf3328_irq_log_unknown_type(u8 which)
1587{
1588        snd_azf3328_dbgplay(
1589        "azt3328: unknown IRQ type (%x) occurred, please report!\n",
1590                which
1591        );
1592}
1593
1594static irqreturn_t
1595snd_azf3328_interrupt(int irq, void *dev_id)
1596{
1597        struct snd_azf3328 *chip = dev_id;
1598        u8 status, which;
1599#if DEBUG_PLAY_REC
1600        static unsigned long irq_count;
1601#endif
1602
1603        status = snd_azf3328_codec_inb(chip, IDX_IO_IRQSTATUS);
1604
1605        /* fast path out, to ease interrupt sharing */
1606        if (!(status &
1607                (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_GAMEPORT|IRQ_MPU401|IRQ_TIMER)
1608        ))
1609                return IRQ_NONE; /* must be interrupt for another device */
1610
1611        snd_azf3328_dbgplay(
1612                "irq_count %ld! IDX_IO_PLAY_FLAGS %04x, "
1613                "IDX_IO_PLAY_IRQTYPE %04x, IDX_IO_IRQSTATUS %04x\n",
1614                        irq_count++ /* debug-only */,
1615                        snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS),
1616                        snd_azf3328_codec_inw(chip, IDX_IO_PLAY_IRQTYPE),
1617                        status
1618        );
1619
1620        if (status & IRQ_TIMER) {
1621                /* snd_azf3328_dbgplay("timer %ld\n",
1622                        snd_azf3328_codec_inl(chip, IDX_IO_TIMER_VALUE)
1623                                & TIMER_VALUE_MASK
1624                ); */
1625                if (chip->timer)
1626                        snd_timer_interrupt(chip->timer, chip->timer->sticks);
1627                /* ACK timer */
1628                spin_lock(&chip->reg_lock);
1629                snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x07);
1630                spin_unlock(&chip->reg_lock);
1631                snd_azf3328_dbgplay("azt3328: timer IRQ\n");
1632        }
1633        if (status & IRQ_PLAYBACK) {
1634                spin_lock(&chip->reg_lock);
1635                which = snd_azf3328_codec_inb(chip, IDX_IO_PLAY_IRQTYPE);
1636                /* ack all IRQ types immediately */
1637                snd_azf3328_codec_outb(chip, IDX_IO_PLAY_IRQTYPE, which);
1638                spin_unlock(&chip->reg_lock);
1639
1640                if (chip->pcm && chip->audio_stream[AZF_PLAYBACK].substream) {
1641                        snd_pcm_period_elapsed(
1642                                chip->audio_stream[AZF_PLAYBACK].substream
1643                        );
1644                        snd_azf3328_dbgplay("PLAY period done (#%x), @ %x\n",
1645                                which,
1646                                snd_azf3328_codec_inl(
1647                                        chip, IDX_IO_PLAY_DMA_CURRPOS
1648                                )
1649                        );
1650                } else
1651                        printk(KERN_WARNING "azt3328: irq handler problem!\n");
1652                if (which & IRQ_PLAY_SOMETHING)
1653                        snd_azf3328_irq_log_unknown_type(which);
1654        }
1655        if (status & IRQ_RECORDING) {
1656                spin_lock(&chip->reg_lock);
1657                which = snd_azf3328_codec_inb(chip, IDX_IO_REC_IRQTYPE);
1658                /* ack all IRQ types immediately */
1659                snd_azf3328_codec_outb(chip, IDX_IO_REC_IRQTYPE, which);
1660                spin_unlock(&chip->reg_lock);
1661
1662                if (chip->pcm && chip->audio_stream[AZF_CAPTURE].substream) {
1663                        snd_pcm_period_elapsed(
1664                                chip->audio_stream[AZF_CAPTURE].substream
1665                        );
1666                        snd_azf3328_dbgplay("REC  period done (#%x), @ %x\n",
1667                                which,
1668                                snd_azf3328_codec_inl(
1669                                        chip, IDX_IO_REC_DMA_CURRPOS
1670                                )
1671                        );
1672                } else
1673                        printk(KERN_WARNING "azt3328: irq handler problem!\n");
1674                if (which & IRQ_REC_SOMETHING)
1675                        snd_azf3328_irq_log_unknown_type(which);
1676        }
1677        if (status & IRQ_GAMEPORT)
1678                snd_azf3328_gameport_interrupt(chip);
1679        /* MPU401 has less critical IRQ requirements
1680         * than timer and playback/recording, right? */
1681        if (status & IRQ_MPU401) {
1682                snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
1683
1684                /* hmm, do we have to ack the IRQ here somehow?
1685                 * If so, then I don't know how... */
1686                snd_azf3328_dbgplay("azt3328: MPU401 IRQ\n");
1687        }
1688        return IRQ_HANDLED;
1689}
1690
1691/*****************************************************************/
1692
1693static const struct snd_pcm_hardware snd_azf3328_playback =
1694{
1695        /* FIXME!! Correct? */
1696        .info =                 SNDRV_PCM_INFO_MMAP |
1697                                SNDRV_PCM_INFO_INTERLEAVED |
1698                                SNDRV_PCM_INFO_MMAP_VALID,
1699        .formats =              SNDRV_PCM_FMTBIT_S8 |
1700                                SNDRV_PCM_FMTBIT_U8 |
1701                                SNDRV_PCM_FMTBIT_S16_LE |
1702                                SNDRV_PCM_FMTBIT_U16_LE,
1703        .rates =                SNDRV_PCM_RATE_5512 |
1704                                SNDRV_PCM_RATE_8000_48000 |
1705                                SNDRV_PCM_RATE_KNOT,
1706        .rate_min =             AZF_FREQ_4000,
1707        .rate_max =             AZF_FREQ_66200,
1708        .channels_min =         1,
1709        .channels_max =         2,
1710        .buffer_bytes_max =     65536,
1711        .period_bytes_min =     64,
1712        .period_bytes_max =     65536,
1713        .periods_min =          1,
1714        .periods_max =          1024,
1715        /* FIXME: maybe that card actually has a FIFO?
1716         * Hmm, it seems newer revisions do have one, but we still don't know
1717         * its size... */
1718        .fifo_size =            0,
1719};
1720
1721static const struct snd_pcm_hardware snd_azf3328_capture =
1722{
1723        /* FIXME */
1724        .info =                 SNDRV_PCM_INFO_MMAP |
1725                                SNDRV_PCM_INFO_INTERLEAVED |
1726                                SNDRV_PCM_INFO_MMAP_VALID,
1727        .formats =              SNDRV_PCM_FMTBIT_S8 |
1728                                SNDRV_PCM_FMTBIT_U8 |
1729                                SNDRV_PCM_FMTBIT_S16_LE |
1730                                SNDRV_PCM_FMTBIT_U16_LE,
1731        .rates =                SNDRV_PCM_RATE_5512 |
1732                                SNDRV_PCM_RATE_8000_48000 |
1733                                SNDRV_PCM_RATE_KNOT,
1734        .rate_min =             AZF_FREQ_4000,
1735        .rate_max =             AZF_FREQ_66200,
1736        .channels_min =         1,
1737        .channels_max =         2,
1738        .buffer_bytes_max =     65536,
1739        .period_bytes_min =     64,
1740        .period_bytes_max =     65536,
1741        .periods_min =          1,
1742        .periods_max =          1024,
1743        .fifo_size =            0,
1744};
1745
1746
1747static unsigned int snd_azf3328_fixed_rates[] = {
1748        AZF_FREQ_4000,
1749        AZF_FREQ_4800,
1750        AZF_FREQ_5512,
1751        AZF_FREQ_6620,
1752        AZF_FREQ_8000,
1753        AZF_FREQ_9600,
1754        AZF_FREQ_11025,
1755        AZF_FREQ_13240,
1756        AZF_FREQ_16000,
1757        AZF_FREQ_22050,
1758        AZF_FREQ_32000,
1759        AZF_FREQ_44100,
1760        AZF_FREQ_48000,
1761        AZF_FREQ_66200
1762};
1763
1764static struct snd_pcm_hw_constraint_list snd_azf3328_hw_constraints_rates = {
1765        .count = ARRAY_SIZE(snd_azf3328_fixed_rates),
1766        .list = snd_azf3328_fixed_rates,
1767        .mask = 0,
1768};
1769
1770/*****************************************************************/
1771
1772static int
1773snd_azf3328_playback_open(struct snd_pcm_substream *substream)
1774{
1775        struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1776        struct snd_pcm_runtime *runtime = substream->runtime;
1777
1778        snd_azf3328_dbgcallenter();
1779        chip->audio_stream[AZF_PLAYBACK].substream = substream;
1780        runtime->hw = snd_azf3328_playback;
1781        snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1782                                   &snd_azf3328_hw_constraints_rates);
1783        snd_azf3328_dbgcallleave();
1784        return 0;
1785}
1786
1787static int
1788snd_azf3328_capture_open(struct snd_pcm_substream *substream)
1789{
1790        struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1791        struct snd_pcm_runtime *runtime = substream->runtime;
1792
1793        snd_azf3328_dbgcallenter();
1794        chip->audio_stream[AZF_CAPTURE].substream = substream;
1795        runtime->hw = snd_azf3328_capture;
1796        snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1797                                   &snd_azf3328_hw_constraints_rates);
1798        snd_azf3328_dbgcallleave();
1799        return 0;
1800}
1801
1802static int
1803snd_azf3328_playback_close(struct snd_pcm_substream *substream)
1804{
1805        struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1806
1807        snd_azf3328_dbgcallenter();
1808        chip->audio_stream[AZF_PLAYBACK].substream = NULL;
1809        snd_azf3328_dbgcallleave();
1810        return 0;
1811}
1812
1813static int
1814snd_azf3328_capture_close(struct snd_pcm_substream *substream)
1815{
1816        struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1817
1818        snd_azf3328_dbgcallenter();
1819        chip->audio_stream[AZF_CAPTURE].substream = NULL;
1820        snd_azf3328_dbgcallleave();
1821        return 0;
1822}
1823
1824/******************************************************************/
1825
1826static struct snd_pcm_ops snd_azf3328_playback_ops = {
1827        .open =         snd_azf3328_playback_open,
1828        .close =        snd_azf3328_playback_close,
1829        .ioctl =        snd_pcm_lib_ioctl,
1830        .hw_params =    snd_azf3328_hw_params,
1831        .hw_free =      snd_azf3328_hw_free,
1832        .prepare =      snd_azf3328_playback_prepare,
1833        .trigger =      snd_azf3328_playback_trigger,
1834        .pointer =      snd_azf3328_playback_pointer
1835};
1836
1837static struct snd_pcm_ops snd_azf3328_capture_ops = {
1838        .open =         snd_azf3328_capture_open,
1839        .close =        snd_azf3328_capture_close,
1840        .ioctl =        snd_pcm_lib_ioctl,
1841        .hw_params =    snd_azf3328_hw_params,
1842        .hw_free =      snd_azf3328_hw_free,
1843        .prepare =      snd_azf3328_capture_prepare,
1844        .trigger =      snd_azf3328_capture_trigger,
1845        .pointer =      snd_azf3328_capture_pointer
1846};
1847
1848static int __devinit
1849snd_azf3328_pcm(struct snd_azf3328 *chip, int device)
1850{
1851        struct snd_pcm *pcm;
1852        int err;
1853
1854        snd_azf3328_dbgcallenter();
1855        if ((err = snd_pcm_new(chip->card, "AZF3328 DSP", device, 1, 1, &pcm)) < 0)
1856                return err;
1857        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_azf3328_playback_ops);
1858        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_azf3328_capture_ops);
1859
1860        pcm->private_data = chip;
1861        pcm->info_flags = 0;
1862        strcpy(pcm->name, chip->card->shortname);
1863        chip->pcm = pcm;
1864
1865        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1866                                              snd_dma_pci_data(chip->pci), 64*1024, 64*1024);
1867
1868        snd_azf3328_dbgcallleave();
1869        return 0;
1870}
1871
1872/******************************************************************/
1873
1874/*** NOTE: the physical timer resolution actually is 1024000 ticks per second
1875 *** (probably derived from main crystal via a divider of 24),
1876 *** but announcing those attributes to user-space would make programs
1877 *** configure the timer to a 1 tick value, resulting in an absolutely fatal
1878 *** timer IRQ storm.
1879 *** Thus I chose to announce a down-scaled virtual timer to the outside and
1880 *** calculate real timer countdown values internally.
1881 *** (the scale factor can be set via module parameter "seqtimer_scaling").
1882 ***/
1883
1884static int
1885snd_azf3328_timer_start(struct snd_timer *timer)
1886{
1887        struct snd_azf3328 *chip;
1888        unsigned long flags;
1889        unsigned int delay;
1890
1891        snd_azf3328_dbgcallenter();
1892        chip = snd_timer_chip(timer);
1893        delay = ((timer->sticks * seqtimer_scaling) - 1) & TIMER_VALUE_MASK;
1894        if (delay < 49) {
1895                /* uhoh, that's not good, since user-space won't know about
1896                 * this timing tweak
1897                 * (we need to do it to avoid a lockup, though) */
1898
1899                snd_azf3328_dbgtimer("delay was too low (%d)!\n", delay);
1900                delay = 49; /* minimum time is 49 ticks */
1901        }
1902        snd_azf3328_dbgtimer("setting timer countdown value %d, add COUNTDOWN|IRQ\n", delay);
1903        delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE;
1904        spin_lock_irqsave(&chip->reg_lock, flags);
1905        snd_azf3328_codec_outl(chip, IDX_IO_TIMER_VALUE, delay);
1906        spin_unlock_irqrestore(&chip->reg_lock, flags);
1907        snd_azf3328_dbgcallleave();
1908        return 0;
1909}
1910
1911static int
1912snd_azf3328_timer_stop(struct snd_timer *timer)
1913{
1914        struct snd_azf3328 *chip;
1915        unsigned long flags;
1916
1917        snd_azf3328_dbgcallenter();
1918        chip = snd_timer_chip(timer);
1919        spin_lock_irqsave(&chip->reg_lock, flags);
1920        /* disable timer countdown and interrupt */
1921        /* FIXME: should we write TIMER_IRQ_ACK here? */
1922        snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0);
1923        spin_unlock_irqrestore(&chip->reg_lock, flags);
1924        snd_azf3328_dbgcallleave();
1925        return 0;
1926}
1927
1928
1929static int
1930snd_azf3328_timer_precise_resolution(struct snd_timer *timer,
1931                                               unsigned long *num, unsigned long *den)
1932{
1933        snd_azf3328_dbgcallenter();
1934        *num = 1;
1935        *den = 1024000 / seqtimer_scaling;
1936        snd_azf3328_dbgcallleave();
1937        return 0;
1938}
1939
1940static struct snd_timer_hardware snd_azf3328_timer_hw = {
1941        .flags = SNDRV_TIMER_HW_AUTO,
1942        .resolution = 977, /* 1000000/1024000 = 0.9765625us */
1943        .ticks = 1024000, /* max tick count, defined by the value register; actually it's not 1024000, but 1048576, but we don't care */
1944        .start = snd_azf3328_timer_start,
1945        .stop = snd_azf3328_timer_stop,
1946        .precise_resolution = snd_azf3328_timer_precise_resolution,
1947};
1948
1949static int __devinit
1950snd_azf3328_timer(struct snd_azf3328 *chip, int device)
1951{
1952        struct snd_timer *timer = NULL;
1953        struct snd_timer_id tid;
1954        int err;
1955
1956        snd_azf3328_dbgcallenter();
1957        tid.dev_class = SNDRV_TIMER_CLASS_CARD;
1958        tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
1959        tid.card = chip->card->number;
1960        tid.device = device;
1961        tid.subdevice = 0;
1962
1963        snd_azf3328_timer_hw.resolution *= seqtimer_scaling;
1964        snd_azf3328_timer_hw.ticks /= seqtimer_scaling;
1965
1966        err = snd_timer_new(chip->card, "AZF3328", &tid, &timer);
1967        if (err < 0)
1968                goto out;
1969
1970        strcpy(timer->name, "AZF3328 timer");
1971        timer->private_data = chip;
1972        timer->hw = snd_azf3328_timer_hw;
1973
1974        chip->timer = timer;
1975
1976        snd_azf3328_timer_stop(timer);
1977
1978        err = 0;
1979
1980out:
1981        snd_azf3328_dbgcallleave();
1982        return err;
1983}
1984
1985/******************************************************************/
1986
1987static int
1988snd_azf3328_free(struct snd_azf3328 *chip)
1989{
1990        if (chip->irq < 0)
1991                goto __end_hw;
1992
1993        /* reset (close) mixer:
1994         * first mute master volume, then reset
1995         */
1996        snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
1997        snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
1998
1999        snd_azf3328_timer_stop(chip->timer);
2000        snd_azf3328_gameport_free(chip);
2001
2002        if (chip->irq >= 0)
2003                synchronize_irq(chip->irq);
2004__end_hw:
2005        if (chip->irq >= 0)
2006                free_irq(chip->irq, chip);
2007        pci_release_regions(chip->pci);
2008        pci_disable_device(chip->pci);
2009
2010        kfree(chip);
2011        return 0;
2012}
2013
2014static int
2015snd_azf3328_dev_free(struct snd_device *device)
2016{
2017        struct snd_azf3328 *chip = device->device_data;
2018        return snd_azf3328_free(chip);
2019}
2020
2021#if 0
2022/* check whether a bit can be modified */
2023static void
2024snd_azf3328_test_bit(unsigned unsigned reg, int bit)
2025{
2026        unsigned char val, valoff, valon;
2027
2028        val = inb(reg);
2029
2030        outb(val & ~(1 << bit), reg);
2031        valoff = inb(reg);
2032
2033        outb(val|(1 << bit), reg);
2034        valon = inb(reg);
2035
2036        outb(val, reg);
2037
2038        printk(KERN_ERR "reg %04x bit %d: %02x %02x %02x\n",
2039                                reg, bit, val, valoff, valon
2040        );
2041}
2042#endif
2043
2044static inline void
2045snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip)
2046{
2047#if DEBUG_MISC
2048        u16 tmp;
2049
2050        snd_azf3328_dbgmisc(
2051                "codec_io 0x%lx, game_io 0x%lx, mpu_io 0x%lx, "
2052                "opl3_io 0x%lx, mixer_io 0x%lx, irq %d\n",
2053                chip->codec_io, chip->game_io, chip->mpu_io,
2054                chip->opl3_io, chip->mixer_io, chip->irq
2055        );
2056
2057        snd_azf3328_dbgmisc("game %02x %02x %02x %02x %02x %02x\n",
2058                snd_azf3328_game_inb(chip, 0),
2059                snd_azf3328_game_inb(chip, 1),
2060                snd_azf3328_game_inb(chip, 2),
2061                snd_azf3328_game_inb(chip, 3),
2062                snd_azf3328_game_inb(chip, 4),
2063                snd_azf3328_game_inb(chip, 5)
2064        );
2065
2066        for (tmp = 0; tmp < 0x07; tmp += 1)
2067                snd_azf3328_dbgmisc("mpu_io 0x%04x\n", inb(chip->mpu_io + tmp));
2068
2069        for (tmp = 0; tmp <= 0x07; tmp += 1)
2070                snd_azf3328_dbgmisc("0x%02x: game200 0x%04x, game208 0x%04x\n",
2071                        tmp, inb(0x200 + tmp), inb(0x208 + tmp));
2072
2073        for (tmp = 0; tmp <= 0x01; tmp += 1)
2074                snd_azf3328_dbgmisc(
2075                        "0x%02x: mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, "
2076                        "mpu330 0x%04x opl388 0x%04x opl38c 0x%04x\n",
2077                                tmp,
2078                                inb(0x300 + tmp),
2079                                inb(0x310 + tmp),
2080                                inb(0x320 + tmp),
2081                                inb(0x330 + tmp),
2082                                inb(0x388 + tmp),
2083                                inb(0x38c + tmp)
2084                );
2085
2086        for (tmp = 0; tmp < AZF_IO_SIZE_CODEC; tmp += 2)
2087                snd_azf3328_dbgmisc("codec 0x%02x: 0x%04x\n",
2088                        tmp, snd_azf3328_codec_inw(chip, tmp)
2089                );
2090
2091        for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2)
2092                snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n",
2093                        tmp, snd_azf3328_mixer_inw(chip, tmp)
2094                );
2095#endif /* DEBUG_MISC */
2096}
2097
2098static int __devinit
2099snd_azf3328_create(struct snd_card *card,
2100                   struct pci_dev *pci,
2101                   unsigned long device_type,
2102                   struct snd_azf3328 **rchip)
2103{
2104        struct snd_azf3328 *chip;
2105        int err;
2106        static struct snd_device_ops ops = {
2107                .dev_free =     snd_azf3328_dev_free,
2108        };
2109        u16 tmp;
2110
2111        *rchip = NULL;
2112
2113        err = pci_enable_device(pci);
2114        if (err < 0)
2115                return err;
2116
2117        chip = kzalloc(sizeof(*chip), GFP_KERNEL);
2118        if (chip == NULL) {
2119                err = -ENOMEM;
2120                goto out_err;
2121        }
2122        spin_lock_init(&chip->reg_lock);
2123        chip->card = card;
2124        chip->pci = pci;
2125        chip->irq = -1;
2126
2127        /* check if we can restrict PCI DMA transfers to 24 bits */
2128        if (pci_set_dma_mask(pci, DMA_24BIT_MASK) < 0 ||
2129            pci_set_consistent_dma_mask(pci, DMA_24BIT_MASK) < 0) {
2130                snd_printk(KERN_ERR "architecture does not support "
2131                                        "24bit PCI busmaster DMA\n"
2132                );
2133                err = -ENXIO;
2134                goto out_err;
2135        }
2136
2137        err = pci_request_regions(pci, "Aztech AZF3328");
2138        if (err < 0)
2139                goto out_err;
2140
2141        chip->codec_io = pci_resource_start(pci, 0);
2142        chip->game_io  = pci_resource_start(pci, 1);
2143        chip->mpu_io   = pci_resource_start(pci, 2);
2144        chip->opl3_io = pci_resource_start(pci, 3);
2145        chip->mixer_io = pci_resource_start(pci, 4);
2146
2147        chip->audio_stream[AZF_PLAYBACK].portbase = chip->codec_io + 0x00;
2148        chip->audio_stream[AZF_CAPTURE].portbase   = chip->codec_io + 0x20;
2149
2150        if (request_irq(pci->irq, snd_azf3328_interrupt,
2151                        IRQF_SHARED, card->shortname, chip)) {
2152                snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
2153                err = -EBUSY;
2154                goto out_err;
2155        }
2156        chip->irq = pci->irq;
2157        pci_set_master(pci);
2158        synchronize_irq(chip->irq);
2159
2160        snd_azf3328_debug_show_ports(chip);
2161
2162        err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
2163        if (err < 0)
2164                goto out_err;
2165
2166        /* create mixer interface & switches */
2167        err = snd_azf3328_mixer_new(chip);
2168        if (err < 0)
2169                goto out_err;
2170
2171        /* shutdown codecs to save power */
2172                /* have snd_azf3328_codec_activity() act properly */
2173        chip->audio_stream[AZF_PLAYBACK].running = 1;
2174        snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 0);
2175
2176        /* standard chip init stuff */
2177                /* default IRQ init value */
2178        tmp = DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE;
2179
2180        spin_lock_irq(&chip->reg_lock);
2181        snd_azf3328_codec_outb(chip, IDX_IO_PLAY_FLAGS, tmp);
2182        snd_azf3328_codec_outb(chip, IDX_IO_REC_FLAGS, tmp);
2183        snd_azf3328_codec_outb(chip, IDX_IO_SOMETHING_FLAGS, tmp);
2184        spin_unlock_irq(&chip->reg_lock);
2185
2186        snd_card_set_dev(card, &pci->dev);
2187
2188        *rchip = chip;
2189
2190        err = 0;
2191        goto out;
2192
2193out_err:
2194        if (chip)
2195                snd_azf3328_free(chip);
2196        pci_disable_device(pci);
2197
2198out:
2199        return err;
2200}
2201
2202static int __devinit
2203snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
2204{
2205        static int dev;
2206        struct snd_card *card;
2207        struct snd_azf3328 *chip;
2208        struct snd_opl3 *opl3;
2209        int err;
2210
2211        snd_azf3328_dbgcallenter();
2212        if (dev >= SNDRV_CARDS)
2213                return -ENODEV;
2214        if (!enable[dev]) {
2215                dev++;
2216                return -ENOENT;
2217        }
2218
2219        card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
2220        if (card == NULL)
2221                return -ENOMEM;
2222
2223        strcpy(card->driver, "AZF3328");
2224        strcpy(card->shortname, "Aztech AZF3328 (PCI168)");
2225
2226        err = snd_azf3328_create(card, pci, pci_id->driver_data, &chip);
2227        if (err < 0)
2228                goto out_err;
2229
2230        card->private_data = chip;
2231
2232        err = snd_mpu401_uart_new(
2233                card, 0, MPU401_HW_MPU401, chip->mpu_io, MPU401_INFO_INTEGRATED,
2234                pci->irq, 0, &chip->rmidi
2235        );
2236        if (err < 0) {
2237                snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n",
2238                                chip->mpu_io
2239                );
2240                goto out_err;
2241        }
2242
2243        err = snd_azf3328_timer(chip, 0);
2244        if (err < 0)
2245                goto out_err;
2246
2247        err = snd_azf3328_pcm(chip, 0);
2248        if (err < 0)
2249                goto out_err;
2250
2251        if (snd_opl3_create(card, chip->opl3_io, chip->opl3_io+2,
2252                            OPL3_HW_AUTO, 1, &opl3) < 0) {
2253                snd_printk(KERN_ERR "azf3328: no OPL3 device at 0x%lx-0x%lx?\n",
2254                           chip->opl3_io, chip->opl3_io+2
2255                );
2256        } else {
2257                /* need to use IDs 1, 2 since ID 0 is snd_azf3328_timer above */
2258                err = snd_opl3_timer_new(opl3, 1, 2);
2259                if (err < 0)
2260                        goto out_err;
2261                err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
2262                if (err < 0)
2263                        goto out_err;
2264        }
2265
2266        opl3->private_data = chip;
2267
2268        sprintf(card->longname, "%s at 0x%lx, irq %i",
2269                card->shortname, chip->codec_io, chip->irq);
2270
2271        err = snd_card_register(card);
2272        if (err < 0)
2273                goto out_err;
2274
2275#ifdef MODULE
2276        printk(
2277"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168.\n"
2278"azt3328: Hardware was completely undocumented, unfortunately.\n"
2279"azt3328: Feel free to contact andi AT lisas.de for bug reports etc.!\n"
2280"azt3328: User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n",
2281        1024000 / seqtimer_scaling, seqtimer_scaling);
2282#endif
2283
2284        snd_azf3328_gameport(chip, dev);
2285
2286        pci_set_drvdata(pci, card);
2287        dev++;
2288
2289        err = 0;
2290        goto out;
2291
2292out_err:
2293        snd_printk(KERN_ERR "azf3328: something failed, exiting\n");
2294        snd_card_free(card);
2295
2296out:
2297        snd_azf3328_dbgcallleave();
2298        return err;
2299}
2300
2301static void __devexit
2302snd_azf3328_remove(struct pci_dev *pci)
2303{
2304        snd_azf3328_dbgcallenter();
2305        snd_card_free(pci_get_drvdata(pci));
2306        pci_set_drvdata(pci, NULL);
2307        snd_azf3328_dbgcallleave();
2308}
2309
2310#ifdef CONFIG_PM
2311static int
2312snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
2313{
2314        struct snd_card *card = pci_get_drvdata(pci);
2315        struct snd_azf3328 *chip = card->private_data;
2316        unsigned reg;
2317
2318        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2319
2320        snd_pcm_suspend_all(chip->pcm);
2321
2322        for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; ++reg)
2323                chip->saved_regs_mixer[reg] = inw(chip->mixer_io + reg * 2);
2324
2325        /* make sure to disable master volume etc. to prevent looping sound */
2326        snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
2327        snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
2328
2329        for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; ++reg)
2330                chip->saved_regs_codec[reg] = inw(chip->codec_io + reg * 2);
2331
2332        /* manually store the one currently relevant write-only reg, too */
2333        chip->saved_regs_codec[IDX_IO_6AH / 2] = chip->shadow_reg_codec_6AH;
2334
2335        for (reg = 0; reg < AZF_IO_SIZE_GAME_PM / 2; ++reg)
2336                chip->saved_regs_game[reg] = inw(chip->game_io + reg * 2);
2337        for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; ++reg)
2338                chip->saved_regs_mpu[reg] = inw(chip->mpu_io + reg * 2);
2339        for (reg = 0; reg < AZF_IO_SIZE_OPL3_PM / 2; ++reg)
2340                chip->saved_regs_opl3[reg] = inw(chip->opl3_io + reg * 2);
2341
2342        pci_disable_device(pci);
2343        pci_save_state(pci);
2344        pci_set_power_state(pci, pci_choose_state(pci, state));
2345        return 0;
2346}
2347
2348static int
2349snd_azf3328_resume(struct pci_dev *pci)
2350{
2351        struct snd_card *card = pci_get_drvdata(pci);
2352        struct snd_azf3328 *chip = card->private_data;
2353        unsigned reg;
2354
2355        pci_set_power_state(pci, PCI_D0);
2356        pci_restore_state(pci);
2357        if (pci_enable_device(pci) < 0) {
2358                printk(KERN_ERR "azt3328: pci_enable_device failed, "
2359                       "disabling device\n");
2360                snd_card_disconnect(card);
2361                return -EIO;
2362        }
2363        pci_set_master(pci);
2364
2365        for (reg = 0; reg < AZF_IO_SIZE_GAME_PM / 2; ++reg)
2366                outw(chip->saved_regs_game[reg], chip->game_io + reg * 2);
2367        for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; ++reg)
2368                outw(chip->saved_regs_mpu[reg], chip->mpu_io + reg * 2);
2369        for (reg = 0; reg < AZF_IO_SIZE_OPL3_PM / 2; ++reg)
2370                outw(chip->saved_regs_opl3[reg], chip->opl3_io + reg * 2);
2371        for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; ++reg)
2372                outw(chip->saved_regs_mixer[reg], chip->mixer_io + reg * 2);
2373        for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; ++reg)
2374                outw(chip->saved_regs_codec[reg], chip->codec_io + reg * 2);
2375
2376        snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2377        return 0;
2378}
2379#endif /* CONFIG_PM */
2380
2381
2382static struct pci_driver driver = {
2383        .name = "AZF3328",
2384        .id_table = snd_azf3328_ids,
2385        .probe = snd_azf3328_probe,
2386        .remove = __devexit_p(snd_azf3328_remove),
2387#ifdef CONFIG_PM
2388        .suspend = snd_azf3328_suspend,
2389        .resume = snd_azf3328_resume,
2390#endif
2391};
2392
2393static int __init
2394alsa_card_azf3328_init(void)
2395{
2396        int err;
2397        snd_azf3328_dbgcallenter();
2398        err = pci_register_driver(&driver);
2399        snd_azf3328_dbgcallleave();
2400        return err;
2401}
2402
2403static void __exit
2404alsa_card_azf3328_exit(void)
2405{
2406        snd_azf3328_dbgcallenter();
2407        pci_unregister_driver(&driver);
2408        snd_azf3328_dbgcallleave();
2409}
2410
2411module_init(alsa_card_azf3328_init)
2412module_exit(alsa_card_azf3328_exit)
2413
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.