Lines Matching +full:scaled +full:- +full:output +full:- +full:hz

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
128 * (in case crackling is due to overloaded output clipping)
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
140 * if you set PCM output switch to "pre 3D" instead of "post 3D".
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 */
240 MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). De…
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); in snd_azf3328_codec_outb()
346 return inb(codec->io_base + reg); in snd_azf3328_codec_inb()
355 outw(value, codec->io_base + reg); in snd_azf3328_codec_outw()
361 return inw(codec->io_base + reg); in snd_azf3328_codec_inw()
369 unsigned long addr = codec->io_base + reg; in snd_azf3328_codec_outl_multi()
375 } while (--count); in snd_azf3328_codec_outl_multi()
382 return inl(codec->io_base + reg); in snd_azf3328_codec_inl()
388 outb(value, chip->ctrl_io + reg); in snd_azf3328_ctrl_outb()
394 return inb(chip->ctrl_io + reg); in snd_azf3328_ctrl_inb()
400 return inw(chip->ctrl_io + reg); in snd_azf3328_ctrl_inw()
406 outw(value, chip->ctrl_io + reg); in snd_azf3328_ctrl_outw()
412 outl(value, chip->ctrl_io + reg); in snd_azf3328_ctrl_outl()
418 outb(value, chip->game_io + reg); in snd_azf3328_game_outb()
424 outw(value, chip->game_io + reg); in snd_azf3328_game_outw()
430 return inb(chip->game_io + reg); in snd_azf3328_game_inb()
436 return inw(chip->game_io + reg); in snd_azf3328_game_inw()
442 outw(value, chip->mixer_io + reg); in snd_azf3328_mixer_outw()
448 return inw(chip->mixer_io + reg); in snd_azf3328_mixer_inw()
458 unsigned long portbase = chip->mixer_io + reg + 1; in snd_azf3328_mixer_mute_control()
510 dev_warn(chip->card->dev, in snd_azf3328_mixer_ac97_map_unsupported()
517 * to compensate for the issue of a rather AC97-incompatible hardware layout.
536 * mono/stereo-based sequence of azf vs. AC97 control series, in snd_azf3328_mixer_ac97_map_reg_idx()
544 * (snd_ac97_rename_vol_ctl() etc.) - that's it. in snd_azf3328_mixer_ac97_map_reg_idx()
571 /* azf3328 supports the low-numbered and low-spec:ed range in snd_azf3328_mixer_ac97_map_reg_idx()
576 /* a translation-only entry means it's real read/write: */ in snd_azf3328_mixer_ac97_map_reg_idx()
590 * given a base-AC97-advertised card, in snd_azf3328_mixer_ac97_map_reg_idx()
591 * but let's just emulate it anyway :-P in snd_azf3328_mixer_ac97_map_reg_idx()
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; in snd_azf3328_mixer_ac97_read()
646 dev_dbg(chip->card->dev, "snd_azf3328_mixer_ac97_read reg_ac97 %u\n", in snd_azf3328_mixer_ac97_read()
701 const struct snd_azf3328 *chip = ac97->private_data; in snd_azf3328_mixer_ac97_write()
705 dev_dbg(chip->card->dev, in snd_azf3328_mixer_ac97_write()
759 ac97.pci = chip->pci; in snd_azf3328_mixer_new()
767 rc = snd_ac97_bus(chip->card, 0, &ops, NULL, &bus); in snd_azf3328_mixer_new()
769 rc = snd_ac97_mixer(bus, &ac97, &chip->ac97); in snd_azf3328_mixer_new()
776 dev_err(chip->card->dev, "AC97 init failed, err %d!\n", rc); in snd_azf3328_mixer_new()
792 unsigned long portbase = chip->mixer_io + reg; in snd_azf3328_mixer_write_volume_gradually()
805 left_change = (curr_vol_left > dst_vol_left) ? -1 : 1; in snd_azf3328_mixer_write_volume_gradually()
811 right_change = (curr_vol_right > dst_vol_right) ? -1 : 1; in snd_azf3328_mixer_write_volume_gradually()
859 r->reg = val & 0xff; in snd_azf3328_mixer_reg_decode()
860 r->lchan_shift = (val >> 8) & 0x0f; in snd_azf3328_mixer_reg_decode()
861 r->rchan_shift = (val >> 12) & 0x0f; in snd_azf3328_mixer_reg_decode()
862 r->mask = (val >> 16) & 0xff; in snd_azf3328_mixer_reg_decode()
863 r->invert = (val >> 24) & 1; in snd_azf3328_mixer_reg_decode()
864 r->stereo = (val >> 25) & 1; in snd_azf3328_mixer_reg_decode()
865 r->enum_c = (val >> 26) & 0x0f; in snd_azf3328_mixer_reg_decode()
913 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); in snd_azf3328_info_mixer()
914 uinfo->type = reg.mask == 1 ? in snd_azf3328_info_mixer()
916 uinfo->count = reg.stereo + 1; in snd_azf3328_info_mixer()
917 uinfo->value.integer.min = 0; in snd_azf3328_info_mixer()
918 uinfo->value.integer.max = reg.mask; in snd_azf3328_info_mixer()
930 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); in snd_azf3328_get_mixer()
935 val = reg.mask - val; in snd_azf3328_get_mixer()
936 ucontrol->value.integer.value[0] = val; in snd_azf3328_get_mixer()
940 val = reg.mask - val; in snd_azf3328_get_mixer()
941 ucontrol->value.integer.value[1] = val; in snd_azf3328_get_mixer()
943 dev_dbg(chip->card->dev, in snd_azf3328_get_mixer()
944 "get: %02x is %04x -> vol %02lx|%02lx (shift %02d|%02d, mask %02x, inv. %d, stereo %d)\n", in snd_azf3328_get_mixer()
946 ucontrol->value.integer.value[0], ucontrol->value.integer.value[1], in snd_azf3328_get_mixer()
959 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); in snd_azf3328_put_mixer()
961 val = ucontrol->value.integer.value[0] & reg.mask; in snd_azf3328_put_mixer()
963 val = reg.mask - val; in snd_azf3328_put_mixer()
967 val = ucontrol->value.integer.value[1] & reg.mask; in snd_azf3328_put_mixer()
969 val = reg.mask - val; in snd_azf3328_put_mixer()
982 dev_dbg(chip->card->dev, in snd_azf3328_put_mixer()
983 "put: %02x to %02lx|%02lx, oreg %04x; shift %02d|%02d -> nreg %04x; after: %04x\n", in snd_azf3328_put_mixer()
984 reg.reg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1], in snd_azf3328_put_mixer()
1010 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); in snd_azf3328_info_mixer_enum()
1039 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); in snd_azf3328_get_mixer_enum()
1042 ucontrol->value.enumerated.item[0] = (val >> 8) & (reg.enum_c - 1); in snd_azf3328_get_mixer_enum()
1043 ucontrol->value.enumerated.item[1] = (val >> 0) & (reg.enum_c - 1); in snd_azf3328_get_mixer_enum()
1045 ucontrol->value.enumerated.item[0] = (val >> reg.lchan_shift) & (reg.enum_c - 1); in snd_azf3328_get_mixer_enum()
1047 dev_dbg(chip->card->dev, in snd_azf3328_get_mixer_enum()
1048 "get_enum: %02x is %04x -> %d|%d (shift %02d, enum_c %d)\n", in snd_azf3328_get_mixer_enum()
1049 reg.reg, val, ucontrol->value.enumerated.item[0], ucontrol->value.enumerated.item[1], in snd_azf3328_get_mixer_enum()
1062 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); in snd_azf3328_put_mixer_enum()
1066 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U || in snd_azf3328_put_mixer_enum()
1067 ucontrol->value.enumerated.item[1] > reg.enum_c - 1U) in snd_azf3328_put_mixer_enum()
1068 return -EINVAL; in snd_azf3328_put_mixer_enum()
1069 val = (ucontrol->value.enumerated.item[0] << 8) | in snd_azf3328_put_mixer_enum()
1070 (ucontrol->value.enumerated.item[1] << 0); in snd_azf3328_put_mixer_enum()
1072 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U) in snd_azf3328_put_mixer_enum()
1073 return -EINVAL; in snd_azf3328_put_mixer_enum()
1074 val &= ~((reg.enum_c - 1) << reg.lchan_shift); in snd_azf3328_put_mixer_enum()
1075 val |= (ucontrol->value.enumerated.item[0] << reg.lchan_shift); in snd_azf3328_put_mixer_enum()
1080 dev_dbg(chip->card->dev, in snd_azf3328_put_mixer_enum()
1116 AZF3328_MIXER_ENUM("Mono Output Select", IDX_MIXER_ADVCTL2, 2, 9),
1117 …AZF3328_MIXER_ENUM("PCM Output Route", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front …
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)) in snd_azf3328_mixer_new()
1168 return -EINVAL; in snd_azf3328_mixer_new()
1170 card = chip->card; in snd_azf3328_mixer_new()
1186 err = snd_ctl_add(chip->card, snd_ctl_new1(sw, chip)); in snd_azf3328_mixer_new()
1191 strcpy(card->mixername, "AZF3328 mixer"); in snd_azf3328_mixer_new()
1229 /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */ in snd_azf3328_codec_setfmt()
1230 /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */ in snd_azf3328_codec_setfmt()
1231 /* val = 0xff0a; 47m30.599s (4764,891Hz; -> 4800Hz???) yup, 4803Hz */ in snd_azf3328_codec_setfmt()
1232 /* val = 0xff0c; 57m0.510s (4010,263Hz; -> 4000Hz???) yup, 4003Hz */ in snd_azf3328_codec_setfmt()
1233 /* val = 0xff05; 5m11.556s (... -> 44100Hz) */ in snd_azf3328_codec_setfmt()
1234 /* val = 0xff03; 10m21.529s (21872,463Hz; -> 22050Hz???) */ in snd_azf3328_codec_setfmt()
1235 /* val = 0xff0f; 20m41.883s (10937,993Hz; -> 11025Hz???) */ in snd_azf3328_codec_setfmt()
1236 /* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */ in snd_azf3328_codec_setfmt()
1237 /* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */ in snd_azf3328_codec_setfmt()
1247 spin_lock_irqsave(codec->lock, flags); in snd_azf3328_codec_setfmt()
1253 * audio output with an annoying click in case of 8/16bit format change in snd_azf3328_codec_setfmt()
1257 * FIXME: does this have some side effects for full-duplex in snd_azf3328_codec_setfmt()
1259 /* do it for non-capture codecs only */ in snd_azf3328_codec_setfmt()
1260 if (codec->type != AZF_CODEC_CAPTURE) in snd_azf3328_codec_setfmt()
1270 spin_unlock_irqrestore(codec->lock, flags); in snd_azf3328_codec_setfmt()
1279 * it should never matter since output should always in snd_azf3328_codec_setfmt_lowpower()
1292 chip->shadow_reg_ctrl_6AH |= bitmask; in snd_azf3328_ctrl_reg_6AH_update()
1294 chip->shadow_reg_ctrl_6AH &= ~bitmask; in snd_azf3328_ctrl_reg_6AH_update()
1295 dev_dbg(chip->card->dev, in snd_azf3328_ctrl_reg_6AH_update()
1297 bitmask, do_mask, chip->shadow_reg_ctrl_6AH); in snd_azf3328_ctrl_reg_6AH_update()
1298 snd_azf3328_ctrl_outw(chip, IDX_IO_6AH, chip->shadow_reg_ctrl_6AH); in snd_azf3328_ctrl_reg_6AH_update()
1304 dev_dbg(chip->card->dev, "codec_enable %d\n", enable); in snd_azf3328_ctrl_enable_codecs()
1318 struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type]; in snd_azf3328_ctrl_codec_activity()
1319 bool need_change = (codec->running != enable); in snd_azf3328_ctrl_codec_activity()
1321 dev_dbg(chip->card->dev, in snd_azf3328_ctrl_codec_activity()
1323 codec->name, enable, need_change in snd_azf3328_ctrl_codec_activity()
1345 ((!chip->codecs[peer_codecs[codec_type].other1] in snd_azf3328_ctrl_codec_activity()
1347 && (!chip->codecs[peer_codecs[codec_type].other2] in snd_azf3328_ctrl_codec_activity()
1357 codec->running = enable; in snd_azf3328_ctrl_codec_activity()
1373 if (!codec->running) { in snd_azf3328_codec_setdmaa()
1391 dev_dbg(chip->card->dev, in snd_azf3328_codec_setdmaa()
1402 area_length--; |* max. index *| in snd_azf3328_codec_setdmaa()
1408 spin_lock_irqsave(codec->lock, flags); in snd_azf3328_codec_setdmaa()
1412 spin_unlock_irqrestore(codec->lock, flags); in snd_azf3328_codec_setdmaa()
1419 struct snd_pcm_runtime *runtime = substream->runtime; in snd_azf3328_pcm_prepare()
1420 struct snd_azf3328_codec_data *codec = runtime->private_data; in snd_azf3328_pcm_prepare()
1426 codec->dma_base = runtime->dma_addr; in snd_azf3328_pcm_prepare()
1430 runtime->rate, in snd_azf3328_pcm_prepare()
1431 snd_pcm_format_width(runtime->format), in snd_azf3328_pcm_prepare()
1432 runtime->channels); in snd_azf3328_pcm_prepare()
1434 runtime->dma_addr, count, size); in snd_azf3328_pcm_prepare()
1443 struct snd_pcm_runtime *runtime = substream->runtime; in snd_azf3328_pcm_trigger()
1444 struct snd_azf3328_codec_data *codec = runtime->private_data; in snd_azf3328_pcm_trigger()
1448 bool is_main_mixer_playback_codec = (AZF_CODEC_PLAYBACK == codec->type); in snd_azf3328_pcm_trigger()
1452 dev_dbg(chip->card->dev, "START PCM %s\n", codec->name); in snd_azf3328_pcm_trigger()
1463 runtime->rate, in snd_azf3328_pcm_trigger()
1464 snd_pcm_format_width(runtime->format), in snd_azf3328_pcm_trigger()
1465 runtime->channels); in snd_azf3328_pcm_trigger()
1467 spin_lock(codec->lock); in snd_azf3328_pcm_trigger()
1477 spin_unlock(codec->lock); in snd_azf3328_pcm_trigger()
1479 snd_azf3328_codec_setdmaa(chip, codec, runtime->dma_addr, in snd_azf3328_pcm_trigger()
1484 spin_lock(codec->lock); in snd_azf3328_pcm_trigger()
1508 spin_unlock(codec->lock); in snd_azf3328_pcm_trigger()
1509 snd_azf3328_ctrl_codec_activity(chip, codec->type, 1); in snd_azf3328_pcm_trigger()
1519 dev_dbg(chip->card->dev, "PCM STARTED %s\n", codec->name); in snd_azf3328_pcm_trigger()
1522 dev_dbg(chip->card->dev, "PCM RESUME %s\n", codec->name); in snd_azf3328_pcm_trigger()
1524 spin_lock(codec->lock); in snd_azf3328_pcm_trigger()
1525 if (codec->running) in snd_azf3328_pcm_trigger()
1531 spin_unlock(codec->lock); in snd_azf3328_pcm_trigger()
1534 dev_dbg(chip->card->dev, "PCM STOP %s\n", codec->name); in snd_azf3328_pcm_trigger()
1544 spin_lock(codec->lock); in snd_azf3328_pcm_trigger()
1559 spin_unlock(codec->lock); in snd_azf3328_pcm_trigger()
1560 snd_azf3328_ctrl_codec_activity(chip, codec->type, 0); in snd_azf3328_pcm_trigger()
1570 dev_dbg(chip->card->dev, "PCM STOPPED %s\n", codec->name); in snd_azf3328_pcm_trigger()
1573 dev_dbg(chip->card->dev, "PCM SUSPEND %s\n", codec->name); in snd_azf3328_pcm_trigger()
1589 return -EINVAL; in snd_azf3328_pcm_trigger()
1600 substream->runtime->private_data; in snd_azf3328_pcm_pointer()
1608 result -= snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_START_1); in snd_azf3328_pcm_pointer()
1610 result -= codec->dma_base; in snd_azf3328_pcm_pointer()
1612 frmres = bytes_to_frames( substream->runtime, result); in snd_azf3328_pcm_pointer()
1613 dev_dbg(substream->pcm->card->dev, "%08li %s @ 0x%8lx, frames %8ld\n", in snd_azf3328_pcm_pointer()
1614 jiffies, codec->name, result, frmres); in snd_azf3328_pcm_pointer()
1627 chip->game_io+IDX_GAME_HWCONFIG, in snd_azf3328_gameport_irq_enable()
1639 chip->game_io+IDX_GAME_HWCONFIG, in snd_azf3328_gameport_legacy_address_enable()
1651 chip->game_io+IDX_GAME_HWCONFIG, in snd_azf3328_gameport_set_counter_frequency()
1656 chip->game_io+IDX_GAME_HWCONFIG, in snd_azf3328_gameport_set_counter_frequency()
1675 * (we do not want axis reading in interrupt handler - too much load!) in snd_azf3328_gameport_interrupt()
1677 dev_dbg(chip->card->dev, "gameport irq\n"); in snd_azf3328_gameport_interrupt()
1689 dev_dbg(chip->card->dev, "gameport_open, mode %d\n", mode); in snd_azf3328_gameport_open()
1696 res = -1; in snd_azf3328_gameport_open()
1712 dev_dbg(chip->card->dev, "gameport_close\n"); in snd_azf3328_gameport_close()
1732 spin_lock_irqsave(&chip->reg_lock, flags); in snd_azf3328_gameport_cooked_read()
1748 for (i = 0; i < ARRAY_SIZE(chip->axes); ++i) { in snd_azf3328_gameport_cooked_read()
1753 chip->axes[i] = snd_azf3328_game_inw( in snd_azf3328_gameport_cooked_read()
1769 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_azf3328_gameport_cooked_read()
1771 for (i = 0; i < ARRAY_SIZE(chip->axes); i++) { in snd_azf3328_gameport_cooked_read()
1772 axes[i] = chip->axes[i]; in snd_azf3328_gameport_cooked_read()
1774 axes[i] = -1; in snd_azf3328_gameport_cooked_read()
1777 dev_dbg(chip->card->dev, "cooked_read: axes %d %d %d %d buttons %d\n", in snd_azf3328_gameport_cooked_read()
1788 chip->gameport = gp = gameport_allocate_port(); in snd_azf3328_gameport()
1790 dev_err(chip->card->dev, "cannot alloc memory for gameport\n"); in snd_azf3328_gameport()
1791 return -ENOMEM; in snd_azf3328_gameport()
1795 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci)); in snd_azf3328_gameport()
1796 gameport_set_dev_parent(gp, &chip->pci->dev); in snd_azf3328_gameport()
1797 gp->io = chip->game_io; in snd_azf3328_gameport()
1800 gp->open = snd_azf3328_gameport_open; in snd_azf3328_gameport()
1801 gp->close = snd_azf3328_gameport_close; in snd_azf3328_gameport()
1802 gp->fuzz = 16; /* seems ok */ in snd_azf3328_gameport()
1803 gp->cooked_read = snd_azf3328_gameport_cooked_read; in snd_azf3328_gameport()
1812 gameport_register_port(chip->gameport); in snd_azf3328_gameport()
1820 if (chip->gameport) { in snd_azf3328_gameport_free()
1821 gameport_unregister_port(chip->gameport); in snd_azf3328_gameport_free()
1822 chip->gameport = NULL; in snd_azf3328_gameport_free()
1828 snd_azf3328_gameport(struct snd_azf3328 *chip, int dev) { return -ENOSYS; } in snd_azf3328_gameport()
1834 dev_warn(chip->card->dev, "huh, game port IRQ occurred!?\n"); in snd_azf3328_gameport_interrupt()
1843 dev_dbg(chip->card->dev, in snd_azf3328_irq_log_unknown_type()
1866 spin_lock(codec->lock); in snd_azf3328_pcm_interrupt()
1870 spin_unlock(codec->lock); in snd_azf3328_pcm_interrupt()
1872 if (codec->substream) { in snd_azf3328_pcm_interrupt()
1873 snd_pcm_period_elapsed(codec->substream); in snd_azf3328_pcm_interrupt()
1874 dev_dbg(chip->card->dev, "%s period done (#%x), @ %x\n", in snd_azf3328_pcm_interrupt()
1875 codec->name, in snd_azf3328_pcm_interrupt()
1880 dev_warn(chip->card->dev, "irq handler problem!\n"); in snd_azf3328_pcm_interrupt()
1902 dev_dbg(chip->card->dev, in snd_azf3328_interrupt()
1904 irq_count++ /* debug-only */, in snd_azf3328_interrupt()
1908 /* dev_dbg(chip->card->dev, "timer %ld\n", in snd_azf3328_interrupt()
1912 if (chip->timer) in snd_azf3328_interrupt()
1913 snd_timer_interrupt(chip->timer, chip->timer->sticks); in snd_azf3328_interrupt()
1915 spin_lock(&chip->reg_lock); in snd_azf3328_interrupt()
1917 spin_unlock(&chip->reg_lock); in snd_azf3328_interrupt()
1918 dev_dbg(chip->card->dev, "timer IRQ\n"); in snd_azf3328_interrupt()
1922 snd_azf3328_pcm_interrupt(chip, chip->codecs, status); in snd_azf3328_interrupt()
1930 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data); in snd_azf3328_interrupt()
1934 dev_dbg(chip->card->dev, "MPU401 IRQ\n"); in snd_azf3328_interrupt()
2009 struct snd_pcm_runtime *runtime = substream->runtime; in snd_azf3328_pcm_open()
2010 struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type]; in snd_azf3328_pcm_open()
2012 codec->substream = substream; in snd_azf3328_pcm_open()
2014 /* same parameters for all our codecs - at least we think so... */ in snd_azf3328_pcm_open()
2015 runtime->hw = snd_azf3328_hardware; in snd_azf3328_pcm_open()
2019 runtime->private_data = codec; in snd_azf3328_pcm_open()
2046 substream->runtime->private_data; in snd_azf3328_pcm_close()
2048 codec->substream = NULL; in snd_azf3328_pcm_close()
2087 err = snd_pcm_new(chip->card, "AZF3328 DSP", AZF_PCMDEV_STD, in snd_azf3328_pcm()
2096 pcm->private_data = chip; in snd_azf3328_pcm()
2097 pcm->info_flags = 0; in snd_azf3328_pcm()
2098 strcpy(pcm->name, chip->card->shortname); in snd_azf3328_pcm()
2100 chip->pcm[AZF_CODEC_PLAYBACK] = pcm; in snd_azf3328_pcm()
2101 chip->pcm[AZF_CODEC_CAPTURE] = pcm; in snd_azf3328_pcm()
2103 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, &chip->pci->dev, in snd_azf3328_pcm()
2106 err = snd_pcm_new(chip->card, "AZF3328 I2S OUT", AZF_PCMDEV_I2S_OUT, in snd_azf3328_pcm()
2113 pcm->private_data = chip; in snd_azf3328_pcm()
2114 pcm->info_flags = 0; in snd_azf3328_pcm()
2115 strcpy(pcm->name, chip->card->shortname); in snd_azf3328_pcm()
2116 chip->pcm[AZF_CODEC_I2S_OUT] = pcm; in snd_azf3328_pcm()
2118 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, &chip->pci->dev, in snd_azf3328_pcm()
2128 *** but announcing those attributes to user-space would make programs
2131 *** Thus I chose to announce a down-scaled virtual timer to the outside and
2144 delay = ((timer->sticks * seqtimer_scaling) - 1) & TIMER_VALUE_MASK; in snd_azf3328_timer_start()
2146 /* uhoh, that's not good, since user-space won't know about in snd_azf3328_timer_start()
2150 dev_dbg(chip->card->dev, "delay was too low (%d)!\n", delay); in snd_azf3328_timer_start()
2153 dev_dbg(chip->card->dev, "setting timer countdown value %d\n", delay); in snd_azf3328_timer_start()
2155 spin_lock_irqsave(&chip->reg_lock, flags); in snd_azf3328_timer_start()
2157 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_azf3328_timer_start()
2168 spin_lock_irqsave(&chip->reg_lock, flags); in snd_azf3328_timer_stop()
2171 YES indeed, otherwise a rogue timer operation - which prompts in snd_azf3328_timer_stop()
2172 ALSA(?) to call repeated stop() in vain, but NOT start() - in snd_azf3328_timer_stop()
2177 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_azf3328_timer_stop()
2209 tid.card = chip->card->number; in snd_azf3328_timer()
2216 err = snd_timer_new(chip->card, "AZF3328", &tid, &timer); in snd_azf3328_timer()
2220 strcpy(timer->name, "AZF3328 timer"); in snd_azf3328_timer()
2221 timer->private_data = chip; in snd_azf3328_timer()
2222 timer->hw = snd_azf3328_timer_hw; in snd_azf3328_timer()
2224 chip->timer = timer; in snd_azf3328_timer()
2239 struct snd_azf3328 *chip = card->private_data; in snd_azf3328_free()
2243 snd_azf3328_timer_stop(chip->timer); in snd_azf3328_free()
2275 dev_dbg(chip->card->dev, in snd_azf3328_debug_show_ports()
2278 chip->ctrl_io, chip->game_io, chip->mpu_io, in snd_azf3328_debug_show_ports()
2279 chip->opl3_io, chip->mixer_io, chip->irq); in snd_azf3328_debug_show_ports()
2281 dev_dbg(chip->card->dev, in snd_azf3328_debug_show_ports()
2291 dev_dbg(chip->card->dev, in snd_azf3328_debug_show_ports()
2292 "mpu_io 0x%04x\n", inb(chip->mpu_io + tmp)); in snd_azf3328_debug_show_ports()
2295 dev_dbg(chip->card->dev, in snd_azf3328_debug_show_ports()
2300 dev_dbg(chip->card->dev, in snd_azf3328_debug_show_ports()
2312 dev_dbg(chip->card->dev, in snd_azf3328_debug_show_ports()
2317 dev_dbg(chip->card->dev, in snd_azf3328_debug_show_ports()
2327 struct snd_azf3328 *chip = card->private_data; in snd_azf3328_create()
2337 spin_lock_init(&chip->reg_lock); in snd_azf3328_create()
2338 chip->card = card; in snd_azf3328_create()
2339 chip->pci = pci; in snd_azf3328_create()
2340 chip->irq = -1; in snd_azf3328_create()
2343 if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(24))) { in snd_azf3328_create()
2344 dev_err(card->dev, in snd_azf3328_create()
2347 return -ENXIO; in snd_azf3328_create()
2354 chip->ctrl_io = pci_resource_start(pci, 0); in snd_azf3328_create()
2355 chip->game_io = pci_resource_start(pci, 1); in snd_azf3328_create()
2356 chip->mpu_io = pci_resource_start(pci, 2); in snd_azf3328_create()
2357 chip->opl3_io = pci_resource_start(pci, 3); in snd_azf3328_create()
2358 chip->mixer_io = pci_resource_start(pci, 4); in snd_azf3328_create()
2360 codec_setup = &chip->codecs[AZF_CODEC_PLAYBACK]; in snd_azf3328_create()
2361 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_PLAYBACK; in snd_azf3328_create()
2362 codec_setup->lock = &chip->reg_lock; in snd_azf3328_create()
2363 codec_setup->type = AZF_CODEC_PLAYBACK; in snd_azf3328_create()
2364 codec_setup->name = "PLAYBACK"; in snd_azf3328_create()
2366 codec_setup = &chip->codecs[AZF_CODEC_CAPTURE]; in snd_azf3328_create()
2367 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_CAPTURE; in snd_azf3328_create()
2368 codec_setup->lock = &chip->reg_lock; in snd_azf3328_create()
2369 codec_setup->type = AZF_CODEC_CAPTURE; in snd_azf3328_create()
2370 codec_setup->name = "CAPTURE"; in snd_azf3328_create()
2372 codec_setup = &chip->codecs[AZF_CODEC_I2S_OUT]; in snd_azf3328_create()
2373 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_I2S_OUT; in snd_azf3328_create()
2374 codec_setup->lock = &chip->reg_lock; in snd_azf3328_create()
2375 codec_setup->type = AZF_CODEC_I2S_OUT; in snd_azf3328_create()
2376 codec_setup->name = "I2S_OUT"; in snd_azf3328_create()
2378 if (devm_request_irq(&pci->dev, pci->irq, snd_azf3328_interrupt, in snd_azf3328_create()
2380 dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq); in snd_azf3328_create()
2381 return -EBUSY; in snd_azf3328_create()
2383 chip->irq = pci->irq; in snd_azf3328_create()
2384 card->sync_irq = chip->irq; in snd_azf3328_create()
2385 card->private_free = snd_azf3328_free; in snd_azf3328_create()
2402 &chip->codecs[codec_type]; in snd_azf3328_create()
2406 codec->running = true; in snd_azf3328_create()
2409 spin_lock_irq(codec->lock); in snd_azf3328_create()
2412 spin_unlock_irq(codec->lock); in snd_azf3328_create()
2428 return -ENODEV; in __snd_azf3328_probe()
2431 return -ENOENT; in __snd_azf3328_probe()
2434 err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, in __snd_azf3328_probe()
2438 chip = card->private_data; in __snd_azf3328_probe()
2440 strcpy(card->driver, "AZF3328"); in __snd_azf3328_probe()
2441 strcpy(card->shortname, "Aztech AZF3328 (PCI168)"); in __snd_azf3328_probe()
2443 err = snd_azf3328_create(card, pci, pci_id->driver_data); in __snd_azf3328_probe()
2451 MPU401_HW_AZT2320, chip->mpu_io, in __snd_azf3328_probe()
2453 -1, &chip->rmidi in __snd_azf3328_probe()
2456 dev_err(card->dev, "no MPU-401 device at 0x%lx?\n", in __snd_azf3328_probe()
2457 chip->mpu_io in __snd_azf3328_probe()
2470 if (snd_opl3_create(card, chip->opl3_io, chip->opl3_io+2, in __snd_azf3328_probe()
2472 dev_err(card->dev, "no OPL3 device at 0x%lx-0x%lx?\n", in __snd_azf3328_probe()
2473 chip->opl3_io, chip->opl3_io+2 in __snd_azf3328_probe()
2483 opl3->private_data = chip; in __snd_azf3328_probe()
2486 sprintf(card->longname, "%s at 0x%lx, irq %i", in __snd_azf3328_probe()
2487 card->shortname, chip->ctrl_io, chip->irq); in __snd_azf3328_probe()
2494 dev_info(card->dev, in __snd_azf3328_probe()
2495 "Sound driver for Aztech AZF3328-based soundcards such as PCI168.\n"); in __snd_azf3328_probe()
2496 dev_info(card->dev, in __snd_azf3328_probe()
2498 dev_info(card->dev, in __snd_azf3328_probe()
2500 dev_info(card->dev, in __snd_azf3328_probe()
2501 "User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n", in __snd_azf3328_probe()
2515 return snd_card_free_on_error(&pci->dev, __snd_azf3328_probe(pci, pci_id)); in snd_azf3328_probe()
2526 dev_dbg(chip->card->dev, "suspend: io 0x%04lx: 0x%08x\n", in snd_azf3328_suspend_regs()
2544 dev_dbg(chip->card->dev, in snd_azf3328_resume_regs()
2545 "resume: io 0x%04lx: 0x%08x --> 0x%08x\n", in snd_azf3328_resume_regs()
2556 snd_ac97_suspend(chip->ac97); in snd_azf3328_suspend_ac97()
2558 snd_azf3328_suspend_regs(chip, chip->mixer_io, in snd_azf3328_suspend_ac97()
2559 ARRAY_SIZE(chip->saved_regs_mixer), chip->saved_regs_mixer); in snd_azf3328_suspend_ac97()
2571 snd_ac97_resume(chip->ac97); in snd_azf3328_resume_ac97()
2573 snd_azf3328_resume_regs(chip, chip->saved_regs_mixer, chip->mixer_io, in snd_azf3328_resume_ac97()
2574 ARRAY_SIZE(chip->saved_regs_mixer)); in snd_azf3328_resume_ac97()
2580 outw(((u16 *)chip->saved_regs_mixer)[1], chip->mixer_io + 2); in snd_azf3328_resume_ac97()
2588 struct snd_azf3328 *chip = card->private_data; in snd_azf3328_suspend()
2595 snd_azf3328_suspend_regs(chip, chip->ctrl_io, in snd_azf3328_suspend()
2596 ARRAY_SIZE(chip->saved_regs_ctrl), chip->saved_regs_ctrl); in snd_azf3328_suspend()
2598 /* manually store the one currently relevant write-only reg, too */ in snd_azf3328_suspend()
2599 saved_regs_ctrl_u16 = (u16 *)chip->saved_regs_ctrl; in snd_azf3328_suspend()
2600 saved_regs_ctrl_u16[IDX_IO_6AH / 2] = chip->shadow_reg_ctrl_6AH; in snd_azf3328_suspend()
2602 snd_azf3328_suspend_regs(chip, chip->game_io, in snd_azf3328_suspend()
2603 ARRAY_SIZE(chip->saved_regs_game), chip->saved_regs_game); in snd_azf3328_suspend()
2604 snd_azf3328_suspend_regs(chip, chip->mpu_io, in snd_azf3328_suspend()
2605 ARRAY_SIZE(chip->saved_regs_mpu), chip->saved_regs_mpu); in snd_azf3328_suspend()
2606 snd_azf3328_suspend_regs(chip, chip->opl3_io, in snd_azf3328_suspend()
2607 ARRAY_SIZE(chip->saved_regs_opl3), chip->saved_regs_opl3); in snd_azf3328_suspend()
2615 const struct snd_azf3328 *chip = card->private_data; in snd_azf3328_resume()
2617 snd_azf3328_resume_regs(chip, chip->saved_regs_game, chip->game_io, in snd_azf3328_resume()
2618 ARRAY_SIZE(chip->saved_regs_game)); in snd_azf3328_resume()
2619 snd_azf3328_resume_regs(chip, chip->saved_regs_mpu, chip->mpu_io, in snd_azf3328_resume()
2620 ARRAY_SIZE(chip->saved_regs_mpu)); in snd_azf3328_resume()
2621 snd_azf3328_resume_regs(chip, chip->saved_regs_opl3, chip->opl3_io, in snd_azf3328_resume()
2622 ARRAY_SIZE(chip->saved_regs_opl3)); in snd_azf3328_resume()
2626 snd_azf3328_resume_regs(chip, chip->saved_regs_ctrl, chip->ctrl_io, in snd_azf3328_resume()
2627 ARRAY_SIZE(chip->saved_regs_ctrl)); in snd_azf3328_resume()