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