Lines Matching +full:odd +full:- +full:numbered
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
3 * Copyright (C) 2002, 2005 - 2011 by Andreas Mohr <andi AT lisas.de>
7 * found in a Fujitsu-Siemens PC ("Cordant", aluminum case).
13 * Keywords: Windows XP Vista 168nt4-125.zip 168win95-125.zip PCI 168 download
17 * despite the high level of Internet ignorance - as usual :-P -
18 * about very good support for this card - on Linux!)
25 * in the first place >:-P}),
34 * for compatibility reasons) from Azfin (joint-venture of Aztech and Fincitec,
36 * Fincitec-related company ARSmikro) has the following features:
38 * - compatibility & compliance:
39 * - Microsoft PC 97 ("PC 97 Hardware Design Guide",
41 * - Microsoft PC 98 Baseline Audio
42 * - MPU401 UART
43 * - Sound Blaster Emulation (DOS Box)
44 * - builtin AC97 conformant codec (SNR over 80dB)
54 * Well, not quite: now ac97 layer is much improved (bus-specific ops!),
55 * thus I was able to implement support - it's actually working quite well.
56 * An interesting item might be Aztech AMR 2800-W, since it's an AC97
57 * modem card which might reveal the Aztech-specific codec ID which
59 * where the advertising datasheet says it's AC97-based and has a
61 * - builtin genuine OPL3 - verified to work fine, 20080506
62 * - full duplex 16bit playback/record at independent sampling rate
63 * - MPU401 (+ legacy address support, claimed by one official spec sheet)
65 * - game port (legacy address support)
66 * - builtin DirectInput support, helps reduce CPU overhead (interrupt-driven
67 * features supported). - See common term "Digital Enhanced Game Port"...
68 * (probably DirectInput 3.0 spec - confirm)
69 * - builtin 3D enhancement (said to be YAMAHA Ymersion)
70 * - built-in General DirectX timer having a 20 bits counter
72 * - I2S serial output port for external DAC
74 * - supports 33MHz PCI spec 2.1, PCI power management 1.0, compliant with ACPI
75 * - supports hardware volume control
76 * - single chip low cost solution (128 pin QFP)
77 * - supports programmable Sub-vendor and Sub-system ID [24C02 SEEPROM chip]
84 * - PCI168 AP(W) card: power amplifier with 4 Watts/channel at 4 Ohms
88 * since it additionally supports the card's 1MHz DirectX timer - just try
89 * the following snd-seq module parameters etc.:
90 * - options snd-seq seq_default_timer_class=2 seq_default_timer_sclass=0
93 * - "timidity -iAv -B2,8 -Os -EFreverb=0"
94 * - "pmidi -p 128:0 jazz.mid"
99 * aconnect -o
101 * sbiload -Dhw:x,y --opl3 /usr/share/sounds/opl3/std.o3 ......./drums.o3
102 * where x,y is the xx-yy number as given in hwdep.
104 * pmidi -p a:b jazz.mid
107 * NOTE: power use during OPL3 playback is _VERY_ high (70W --> 90W!)
112 * adplay/adplug-utils might soon offer hardware-based OPL3 playback, too.
118 * - no DMA crackling on SiS735: 0x50DC/0x1801/16
119 * - unknown performance: 0x50DC/0x1801/10
127 * - use speaker (amplifier) output instead of headphone output
129 * - plug card into a different PCI slot, preferably one that isn't shared
131 * - get rid of PCI VGA card, use AGP instead
132 * - upgrade or downgrade BIOS
133 * - fiddle with PCI latency settings (setpci -v -s BUSID latency_timer=XX)
135 * - Disable ACPI/power management/"Auto Detect RAM/PCI Clk" in BIOS
138 * - full-duplex might *still* be problematic, however a recent test was fine
139 * - (non-bug) "Bass/Treble or 3D settings don't work" - they do get evaluated
142 * (e.g. kmix, gamix) - unfortunately several are!!
143 * - locking is not entirely clean, especially the audio stream activity
144 * ints --> may be racy
145 * - an _unconnected_ secondary joystick at the gameport will be reported
146 * to be "active" (floating values, not precisely -1) due to the way we need
150 * - use PCI_VDEVICE
151 * - verify driver status on x86_64
152 * - test multi-card driver operation
153 * - (ab)use 1MHz DirectX timer as kernel clocksource
154 * - test MPU401 MIDI playback etc.
155 * - add more power micro-management (disable various units of the card
161 * - figure out what all unknown port bits are responsible for
162 * - figure out some cleverly evil scheme to possibly make ALSA AC97 code
165 * - use MMIO (memory-mapped I/O)? Slightly faster access, e.g. for gameport.
176 #include <linux/dma-mapping.h>
207 to dump the card's I/O ports (those listed in lspci -v -v):
214 2>/dev/null| hexdump -C
226 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
252 spinlock_t *lock; /* TODO: convert to our own per-codec lock member */
260 /* often-used fields towards beginning, then grouped */
292 /* register 0x6a is write-only, thus need to remember setting.
340 outb(value, codec->io_base + reg);
346 return inb(codec->io_base + reg);
355 outw(value, codec->io_base + reg);
361 return inw(codec->io_base + reg);
369 unsigned long addr = codec->io_base + reg;
375 } while (--count);
382 return inl(codec->io_base + reg);
388 outb(value, chip->ctrl_io + reg);
394 return inb(chip->ctrl_io + reg);
400 return inw(chip->ctrl_io + reg);
406 outw(value, chip->ctrl_io + reg);
412 outl(value, chip->ctrl_io + reg);
418 outb(value, chip->game_io + reg);
424 outw(value, chip->game_io + reg);
430 return inb(chip->game_io + reg);
436 return inw(chip->game_io + reg);
442 outw(value, chip->mixer_io + reg);
448 return inw(chip->mixer_io + reg);
458 unsigned long portbase = chip->mixer_io + reg + 1;
510 dev_warn(chip->card->dev,
517 * to compensate for the issue of a rather AC97-incompatible hardware layout.
536 * mono/stereo-based sequence of azf vs. AC97 control series,
544 * (snd_ac97_rename_vol_ctl() etc.) - that's it.
571 /* azf3328 supports the low-numbered and low-spec:ed range
576 /* a translation-only entry means it's real read/write: */
590 * given a base-AC97-advertised card,
591 * but let's just emulate it anyway :-P
612 vendor-specific 3D enhancement
630 * (there might be some devices such as the MR 2800-W
641 const struct snd_azf3328 *chip = ac97->private_data;
646 dev_dbg(chip->card->dev, "snd_azf3328_mixer_ac97_read reg_ac97 %u\n",
701 const struct snd_azf3328 *chip = ac97->private_data;
705 dev_dbg(chip->card->dev,
759 ac97.pci = chip->pci;
767 rc = snd_ac97_bus(chip->card, 0, &ops, NULL, &bus);
769 rc = snd_ac97_mixer(bus, &ac97, &chip->ac97);
776 dev_err(chip->card->dev, "AC97 init failed, err %d!\n", rc);
792 unsigned long portbase = chip->mixer_io + reg;
805 left_change = (curr_vol_left > dst_vol_left) ? -1 : 1;
811 right_change = (curr_vol_right > dst_vol_right) ? -1 : 1;
859 r->reg = val & 0xff;
860 r->lchan_shift = (val >> 8) & 0x0f;
861 r->rchan_shift = (val >> 12) & 0x0f;
862 r->mask = (val >> 16) & 0xff;
863 r->invert = (val >> 24) & 1;
864 r->stereo = (val >> 25) & 1;
865 r->enum_c = (val >> 26) & 0x0f;
913 snd_azf3328_mixer_reg_decode(®, kcontrol->private_value);
914 uinfo->type = reg.mask == 1 ?
916 uinfo->count = reg.stereo + 1;
917 uinfo->value.integer.min = 0;
918 uinfo->value.integer.max = reg.mask;
930 snd_azf3328_mixer_reg_decode(®, kcontrol->private_value);
935 val = reg.mask - val;
936 ucontrol->value.integer.value[0] = val;
940 val = reg.mask - val;
941 ucontrol->value.integer.value[1] = val;
943 dev_dbg(chip->card->dev,
944 "get: %02x is %04x -> vol %02lx|%02lx (shift %02d|%02d, mask %02x, inv. %d, stereo %d)\n",
946 ucontrol->value.integer.value[0], ucontrol->value.integer.value[1],
959 snd_azf3328_mixer_reg_decode(®, kcontrol->private_value);
961 val = ucontrol->value.integer.value[0] & reg.mask;
963 val = reg.mask - val;
967 val = ucontrol->value.integer.value[1] & reg.mask;
969 val = reg.mask - val;
982 dev_dbg(chip->card->dev,
983 "put: %02x to %02lx|%02lx, oreg %04x; shift %02d|%02d -> nreg %04x; after: %04x\n",
984 reg.reg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1],
1010 snd_azf3328_mixer_reg_decode(®, kcontrol->private_value);
1039 snd_azf3328_mixer_reg_decode(®, kcontrol->private_value);
1042 ucontrol->value.enumerated.item[0] = (val >> 8) & (reg.enum_c - 1);
1043 ucontrol->value.enumerated.item[1] = (val >> 0) & (reg.enum_c - 1);
1045 ucontrol->value.enumerated.item[0] = (val >> reg.lchan_shift) & (reg.enum_c - 1);
1047 dev_dbg(chip->card->dev,
1048 "get_enum: %02x is %04x -> %d|%d (shift %02d, enum_c %d)\n",
1049 reg.reg, val, ucontrol->value.enumerated.item[0], ucontrol->value.enumerated.item[1],
1062 snd_azf3328_mixer_reg_decode(®, kcontrol->private_value);
1066 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U ||
1067 ucontrol->value.enumerated.item[1] > reg.enum_c - 1U)
1068 return -EINVAL;
1069 val = (ucontrol->value.enumerated.item[0] << 8) |
1070 (ucontrol->value.enumerated.item[1] << 0);
1072 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U)
1073 return -EINVAL;
1074 val &= ~((reg.enum_c - 1) << reg.lchan_shift);
1075 val |= (ucontrol->value.enumerated.item[0] << reg.lchan_shift);
1080 dev_dbg(chip->card->dev,
1118 AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0),
1119 AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0),
1120 AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0),
1121 AZF3328_MIXER_VOL_SPECIAL("3D Control - Width", IDX_MIXER_ADVCTL1, 0x07, 1, 0), /* "3D Width" */
1122 AZF3328_MIXER_VOL_SPECIAL("3D Control - Depth", IDX_MIXER_ADVCTL1, 0x03, 8, 0), /* "Hifi 3D" */
1167 if (snd_BUG_ON(!chip || !chip->card))
1168 return -EINVAL;
1170 card = chip->card;
1186 err = snd_ctl_add(chip->card, snd_ctl_new1(sw, chip));
1191 strscpy(card->mixername, "AZF3328 mixer");
1228 /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */
1229 /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */
1230 /* val = 0xff0a; 47m30.599s (4764,891Hz; -> 4800Hz???) yup, 4803Hz */
1231 /* val = 0xff0c; 57m0.510s (4010,263Hz; -> 4000Hz???) yup, 4003Hz */
1232 /* val = 0xff05; 5m11.556s (... -> 44100Hz) */
1233 /* val = 0xff03; 10m21.529s (21872,463Hz; -> 22050Hz???) */
1234 /* val = 0xff0f; 20m41.883s (10937,993Hz; -> 11025Hz???) */
1235 /* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */
1236 /* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */
1246 guard(spinlock_irqsave)(codec->lock);
1256 * FIXME: does this have some side effects for full-duplex
1258 /* do it for non-capture codecs only */
1259 if (codec->type != AZF_CODEC_CAPTURE)
1289 chip->shadow_reg_ctrl_6AH |= bitmask;
1291 chip->shadow_reg_ctrl_6AH &= ~bitmask;
1292 dev_dbg(chip->card->dev,
1294 bitmask, do_mask, chip->shadow_reg_ctrl_6AH);
1295 snd_azf3328_ctrl_outw(chip, IDX_IO_6AH, chip->shadow_reg_ctrl_6AH);
1301 dev_dbg(chip->card->dev, "codec_enable %d\n", enable);
1315 struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
1316 bool need_change = (codec->running != enable);
1318 dev_dbg(chip->card->dev,
1320 codec->name, enable, need_change
1342 ((!chip->codecs[peer_codecs[codec_type].other1]
1344 && (!chip->codecs[peer_codecs[codec_type].other2]
1354 codec->running = enable;
1366 WARN_ONCE(period_bytes & 1, "odd period length!?\n");
1370 if (!codec->running) {
1386 dev_dbg(chip->card->dev,
1397 area_length--; |* max. index *|
1403 guard(spinlock_irqsave)(codec->lock);
1413 struct snd_pcm_runtime *runtime = substream->runtime;
1414 struct snd_azf3328_codec_data *codec = runtime->private_data;
1420 codec->dma_base = runtime->dma_addr;
1424 runtime->rate,
1425 snd_pcm_format_width(runtime->format),
1426 runtime->channels);
1428 runtime->dma_addr, count, size);
1437 struct snd_pcm_runtime *runtime = substream->runtime;
1438 struct snd_azf3328_codec_data *codec = runtime->private_data;
1442 bool is_main_mixer_playback_codec = (AZF_CODEC_PLAYBACK == codec->type);
1446 dev_dbg(chip->card->dev, "START PCM %s\n", codec->name);
1457 runtime->rate,
1458 snd_pcm_format_width(runtime->format),
1459 runtime->channels);
1461 scoped_guard(spinlock, codec->lock) {
1473 snd_azf3328_codec_setdmaa(chip, codec, runtime->dma_addr,
1478 scoped_guard(spinlock, codec->lock) {
1503 snd_azf3328_ctrl_codec_activity(chip, codec->type, 1);
1513 dev_dbg(chip->card->dev, "PCM STARTED %s\n", codec->name);
1516 dev_dbg(chip->card->dev, "PCM RESUME %s\n", codec->name);
1518 scoped_guard(spinlock, codec->lock) {
1519 if (codec->running)
1528 dev_dbg(chip->card->dev, "PCM STOP %s\n", codec->name);
1538 scoped_guard(spinlock, codec->lock) {
1554 snd_azf3328_ctrl_codec_activity(chip, codec->type, 0);
1564 dev_dbg(chip->card->dev, "PCM STOPPED %s\n", codec->name);
1567 dev_dbg(chip->card->dev, "PCM SUSPEND %s\n", codec->name);
1583 return -EINVAL;
1594 substream->runtime->private_data;
1602 result -= snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_START_1);
1604 result -= codec->dma_base;
1606 frmres = bytes_to_frames( substream->runtime, result);
1607 dev_dbg(substream->pcm->card->dev, "%08li %s @ 0x%8lx, frames %8ld\n",
1608 jiffies, codec->name, result, frmres);
1621 chip->game_io+IDX_GAME_HWCONFIG,
1633 chip->game_io+IDX_GAME_HWCONFIG,
1645 chip->game_io+IDX_GAME_HWCONFIG,
1650 chip->game_io+IDX_GAME_HWCONFIG,
1669 * (we do not want axis reading in interrupt handler - too much load!)
1671 dev_dbg(chip->card->dev, "gameport irq\n");
1683 dev_dbg(chip->card->dev, "gameport_open, mode %d\n", mode);
1690 res = -1;
1706 dev_dbg(chip->card->dev, "gameport_close\n");
1725 guard(spinlock_irqsave)(&chip->reg_lock);
1741 for (i = 0; i < ARRAY_SIZE(chip->axes); ++i) {
1746 chip->axes[i] = snd_azf3328_game_inw(
1763 for (i = 0; i < ARRAY_SIZE(chip->axes); i++) {
1764 axes[i] = chip->axes[i];
1766 axes[i] = -1;
1769 dev_dbg(chip->card->dev, "cooked_read: axes %d %d %d %d buttons %d\n",
1780 chip->gameport = gp = gameport_allocate_port();
1782 dev_err(chip->card->dev, "cannot alloc memory for gameport\n");
1783 return -ENOMEM;
1787 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
1788 gameport_set_dev_parent(gp, &chip->pci->dev);
1789 gp->io = chip->game_io;
1792 gp->open = snd_azf3328_gameport_open;
1793 gp->close = snd_azf3328_gameport_close;
1794 gp->fuzz = 16; /* seems ok */
1795 gp->cooked_read = snd_azf3328_gameport_cooked_read;
1804 gameport_register_port(chip->gameport);
1812 if (chip->gameport) {
1813 gameport_unregister_port(chip->gameport);
1814 chip->gameport = NULL;
1820 snd_azf3328_gameport(struct snd_azf3328 *chip, int dev) { return -ENOSYS; }
1826 dev_warn(chip->card->dev, "huh, game port IRQ occurred!?\n");
1835 dev_dbg(chip->card->dev,
1858 scoped_guard(spinlock, codec->lock) {
1864 if (codec->substream) {
1865 snd_pcm_period_elapsed(codec->substream);
1866 dev_dbg(chip->card->dev, "%s period done (#%x), @ %x\n",
1867 codec->name,
1872 dev_warn(chip->card->dev, "irq handler problem!\n");
1894 dev_dbg(chip->card->dev,
1896 irq_count++ /* debug-only */,
1900 /* dev_dbg(chip->card->dev, "timer %ld\n",
1904 if (chip->timer)
1905 snd_timer_interrupt(chip->timer, chip->timer->sticks);
1907 scoped_guard(spinlock, &chip->reg_lock) {
1910 dev_dbg(chip->card->dev, "timer IRQ\n");
1914 snd_azf3328_pcm_interrupt(chip, chip->codecs, status);
1922 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
1926 dev_dbg(chip->card->dev, "MPU401 IRQ\n");
2001 struct snd_pcm_runtime *runtime = substream->runtime;
2002 struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
2004 codec->substream = substream;
2006 /* same parameters for all our codecs - at least we think so... */
2007 runtime->hw = snd_azf3328_hardware;
2011 runtime->private_data = codec;
2038 substream->runtime->private_data;
2040 codec->substream = NULL;
2079 err = snd_pcm_new(chip->card, "AZF3328 DSP", AZF_PCMDEV_STD,
2088 pcm->private_data = chip;
2089 pcm->info_flags = 0;
2090 strscpy(pcm->name, chip->card->shortname);
2092 chip->pcm[AZF_CODEC_PLAYBACK] = pcm;
2093 chip->pcm[AZF_CODEC_CAPTURE] = pcm;
2095 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, &chip->pci->dev,
2098 err = snd_pcm_new(chip->card, "AZF3328 I2S OUT", AZF_PCMDEV_I2S_OUT,
2105 pcm->private_data = chip;
2106 pcm->info_flags = 0;
2107 strscpy(pcm->name, chip->card->shortname);
2108 chip->pcm[AZF_CODEC_I2S_OUT] = pcm;
2110 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, &chip->pci->dev,
2120 *** but announcing those attributes to user-space would make programs
2123 *** Thus I chose to announce a down-scaled virtual timer to the outside and
2135 delay = ((timer->sticks * seqtimer_scaling) - 1) & TIMER_VALUE_MASK;
2137 /* uhoh, that's not good, since user-space won't know about
2141 dev_dbg(chip->card->dev, "delay was too low (%d)!\n", delay);
2144 dev_dbg(chip->card->dev, "setting timer countdown value %d\n", delay);
2146 guard(spinlock_irqsave)(&chip->reg_lock);
2157 guard(spinlock_irqsave)(&chip->reg_lock);
2160 YES indeed, otherwise a rogue timer operation - which prompts
2161 ALSA(?) to call repeated stop() in vain, but NOT start() -
2197 tid.card = chip->card->number;
2204 err = snd_timer_new(chip->card, "AZF3328", &tid, &timer);
2208 strscpy(timer->name, "AZF3328 timer");
2209 timer->private_data = chip;
2210 timer->hw = snd_azf3328_timer_hw;
2212 chip->timer = timer;
2227 struct snd_azf3328 *chip = card->private_data;
2231 snd_azf3328_timer_stop(chip->timer);
2263 dev_dbg(chip->card->dev,
2266 chip->ctrl_io, chip->game_io, chip->mpu_io,
2267 chip->opl3_io, chip->mixer_io, chip->irq);
2269 dev_dbg(chip->card->dev,
2279 dev_dbg(chip->card->dev,
2280 "mpu_io 0x%04x\n", inb(chip->mpu_io + tmp));
2283 dev_dbg(chip->card->dev,
2288 dev_dbg(chip->card->dev,
2300 dev_dbg(chip->card->dev,
2305 dev_dbg(chip->card->dev,
2315 struct snd_azf3328 *chip = card->private_data;
2325 spin_lock_init(&chip->reg_lock);
2326 chip->card = card;
2327 chip->pci = pci;
2328 chip->irq = -1;
2331 if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(24))) {
2332 dev_err(card->dev,
2335 return -ENXIO;
2342 chip->ctrl_io = pci_resource_start(pci, 0);
2343 chip->game_io = pci_resource_start(pci, 1);
2344 chip->mpu_io = pci_resource_start(pci, 2);
2345 chip->opl3_io = pci_resource_start(pci, 3);
2346 chip->mixer_io = pci_resource_start(pci, 4);
2348 codec_setup = &chip->codecs[AZF_CODEC_PLAYBACK];
2349 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_PLAYBACK;
2350 codec_setup->lock = &chip->reg_lock;
2351 codec_setup->type = AZF_CODEC_PLAYBACK;
2352 codec_setup->name = "PLAYBACK";
2354 codec_setup = &chip->codecs[AZF_CODEC_CAPTURE];
2355 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_CAPTURE;
2356 codec_setup->lock = &chip->reg_lock;
2357 codec_setup->type = AZF_CODEC_CAPTURE;
2358 codec_setup->name = "CAPTURE";
2360 codec_setup = &chip->codecs[AZF_CODEC_I2S_OUT];
2361 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_I2S_OUT;
2362 codec_setup->lock = &chip->reg_lock;
2363 codec_setup->type = AZF_CODEC_I2S_OUT;
2364 codec_setup->name = "I2S_OUT";
2366 if (devm_request_irq(&pci->dev, pci->irq, snd_azf3328_interrupt,
2368 dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
2369 return -EBUSY;
2371 chip->irq = pci->irq;
2372 card->sync_irq = chip->irq;
2373 card->private_free = snd_azf3328_free;
2390 &chip->codecs[codec_type];
2394 codec->running = true;
2397 guard(spinlock_irq)(codec->lock);
2415 return -ENODEV;
2418 return -ENOENT;
2421 err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
2425 chip = card->private_data;
2427 strscpy(card->driver, "AZF3328");
2428 strscpy(card->shortname, "Aztech AZF3328 (PCI168)");
2430 err = snd_azf3328_create(card, pci, pci_id->driver_data);
2438 MPU401_HW_AZT2320, chip->mpu_io,
2440 -1, &chip->rmidi
2443 dev_err(card->dev, "no MPU-401 device at 0x%lx?\n",
2444 chip->mpu_io
2457 if (snd_opl3_create(card, chip->opl3_io, chip->opl3_io+2,
2459 dev_err(card->dev, "no OPL3 device at 0x%lx-0x%lx?\n",
2460 chip->opl3_io, chip->opl3_io+2
2470 opl3->private_data = chip;
2473 sprintf(card->longname, "%s at 0x%lx, irq %i",
2474 card->shortname, chip->ctrl_io, chip->irq);
2481 dev_info(card->dev,
2482 "Sound driver for Aztech AZF3328-based soundcards such as PCI168.\n");
2483 dev_info(card->dev,
2485 dev_info(card->dev,
2487 dev_info(card->dev,
2488 "User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n",
2502 return snd_card_free_on_error(&pci->dev, __snd_azf3328_probe(pci, pci_id));
2513 dev_dbg(chip->card->dev, "suspend: io 0x%04lx: 0x%08x\n",
2531 dev_dbg(chip->card->dev,
2532 "resume: io 0x%04lx: 0x%08x --> 0x%08x\n",
2543 snd_ac97_suspend(chip->ac97);
2545 snd_azf3328_suspend_regs(chip, chip->mixer_io,
2546 ARRAY_SIZE(chip->saved_regs_mixer), chip->saved_regs_mixer);
2558 snd_ac97_resume(chip->ac97);
2560 snd_azf3328_resume_regs(chip, chip->saved_regs_mixer, chip->mixer_io,
2561 ARRAY_SIZE(chip->saved_regs_mixer));
2567 outw(((u16 *)chip->saved_regs_mixer)[1], chip->mixer_io + 2);
2575 struct snd_azf3328 *chip = card->private_data;
2582 snd_azf3328_suspend_regs(chip, chip->ctrl_io,
2583 ARRAY_SIZE(chip->saved_regs_ctrl), chip->saved_regs_ctrl);
2585 /* manually store the one currently relevant write-only reg, too */
2586 saved_regs_ctrl_u16 = (u16 *)chip->saved_regs_ctrl;
2587 saved_regs_ctrl_u16[IDX_IO_6AH / 2] = chip->shadow_reg_ctrl_6AH;
2589 snd_azf3328_suspend_regs(chip, chip->game_io,
2590 ARRAY_SIZE(chip->saved_regs_game), chip->saved_regs_game);
2591 snd_azf3328_suspend_regs(chip, chip->mpu_io,
2592 ARRAY_SIZE(chip->saved_regs_mpu), chip->saved_regs_mpu);
2593 snd_azf3328_suspend_regs(chip, chip->opl3_io,
2594 ARRAY_SIZE(chip->saved_regs_opl3), chip->saved_regs_opl3);
2602 const struct snd_azf3328 *chip = card->private_data;
2604 snd_azf3328_resume_regs(chip, chip->saved_regs_game, chip->game_io,
2605 ARRAY_SIZE(chip->saved_regs_game));
2606 snd_azf3328_resume_regs(chip, chip->saved_regs_mpu, chip->mpu_io,
2607 ARRAY_SIZE(chip->saved_regs_mpu));
2608 snd_azf3328_resume_regs(chip, chip->saved_regs_opl3, chip->opl3_io,
2609 ARRAY_SIZE(chip->saved_regs_opl3));
2613 snd_azf3328_resume_regs(chip, chip->saved_regs_ctrl, chip->ctrl_io,
2614 ARRAY_SIZE(chip->saved_regs_ctrl));