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.
342 outb(value, codec->io_base + reg); in snd_azf3328_codec_outb()
348 return inb(codec->io_base + reg); in snd_azf3328_codec_inb()
357 outw(value, codec->io_base + reg); in snd_azf3328_codec_outw()
363 return inw(codec->io_base + reg); in snd_azf3328_codec_inw()
371 unsigned long addr = codec->io_base + reg; in snd_azf3328_codec_outl_multi()
377 } while (--count); in snd_azf3328_codec_outl_multi()
384 return inl(codec->io_base + reg); in snd_azf3328_codec_inl()
390 outb(value, chip->ctrl_io + reg); in snd_azf3328_ctrl_outb()
396 return inb(chip->ctrl_io + reg); in snd_azf3328_ctrl_inb()
402 return inw(chip->ctrl_io + reg); in snd_azf3328_ctrl_inw()
408 outw(value, chip->ctrl_io + reg); in snd_azf3328_ctrl_outw()
414 outl(value, chip->ctrl_io + reg); in snd_azf3328_ctrl_outl()
420 outb(value, chip->game_io + reg); in snd_azf3328_game_outb()
426 outw(value, chip->game_io + reg); in snd_azf3328_game_outw()
432 return inb(chip->game_io + reg); in snd_azf3328_game_inb()
438 return inw(chip->game_io + reg); in snd_azf3328_game_inw()
444 outw(value, chip->mixer_io + reg); in snd_azf3328_mixer_outw()
450 return inw(chip->mixer_io + reg); in snd_azf3328_mixer_inw()
460 unsigned long portbase = chip->mixer_io + reg + 1; in snd_azf3328_mixer_mute_control()
512 dev_warn(chip->card->dev, in snd_azf3328_mixer_ac97_map_unsupported()
519 * to compensate for the issue of a rather AC97-incompatible hardware layout.
538 * mono/stereo-based sequence of azf vs. AC97 control series, in snd_azf3328_mixer_ac97_map_reg_idx()
546 * (snd_ac97_rename_vol_ctl() etc.) - that's it. in snd_azf3328_mixer_ac97_map_reg_idx()
573 /* azf3328 supports the low-numbered and low-spec:ed range in snd_azf3328_mixer_ac97_map_reg_idx()
578 /* a translation-only entry means it's real read/write: */ in snd_azf3328_mixer_ac97_map_reg_idx()
592 * given a base-AC97-advertised card, in snd_azf3328_mixer_ac97_map_reg_idx()
593 * but let's just emulate it anyway :-P in snd_azf3328_mixer_ac97_map_reg_idx()
614 vendor-specific 3D enhancement
632 * (there might be some devices such as the MR 2800-W
643 const struct snd_azf3328 *chip = ac97->private_data; in snd_azf3328_mixer_ac97_read()
648 dev_dbg(chip->card->dev, "snd_azf3328_mixer_ac97_read reg_ac97 %u\n", in snd_azf3328_mixer_ac97_read()
703 const struct snd_azf3328 *chip = ac97->private_data; in snd_azf3328_mixer_ac97_write()
707 dev_dbg(chip->card->dev, in snd_azf3328_mixer_ac97_write()
761 ac97.pci = chip->pci; in snd_azf3328_mixer_new()
769 rc = snd_ac97_bus(chip->card, 0, &ops, NULL, &bus); in snd_azf3328_mixer_new()
771 rc = snd_ac97_mixer(bus, &ac97, &chip->ac97); in snd_azf3328_mixer_new()
778 dev_err(chip->card->dev, "AC97 init failed, err %d!\n", rc); in snd_azf3328_mixer_new()
794 unsigned long portbase = chip->mixer_io + reg; in snd_azf3328_mixer_write_volume_gradually()
807 left_change = (curr_vol_left > dst_vol_left) ? -1 : 1; in snd_azf3328_mixer_write_volume_gradually()
813 right_change = (curr_vol_right > dst_vol_right) ? -1 : 1; in snd_azf3328_mixer_write_volume_gradually()
861 r->reg = val & 0xff; in snd_azf3328_mixer_reg_decode()
862 r->lchan_shift = (val >> 8) & 0x0f; in snd_azf3328_mixer_reg_decode()
863 r->rchan_shift = (val >> 12) & 0x0f; in snd_azf3328_mixer_reg_decode()
864 r->mask = (val >> 16) & 0xff; in snd_azf3328_mixer_reg_decode()
865 r->invert = (val >> 24) & 1; in snd_azf3328_mixer_reg_decode()
866 r->stereo = (val >> 25) & 1; in snd_azf3328_mixer_reg_decode()
867 r->enum_c = (val >> 26) & 0x0f; in snd_azf3328_mixer_reg_decode()
915 snd_azf3328_mixer_reg_decode(®, kcontrol->private_value); in snd_azf3328_info_mixer()
916 uinfo->type = reg.mask == 1 ? in snd_azf3328_info_mixer()
918 uinfo->count = reg.stereo + 1; in snd_azf3328_info_mixer()
919 uinfo->value.integer.min = 0; in snd_azf3328_info_mixer()
920 uinfo->value.integer.max = reg.mask; in snd_azf3328_info_mixer()
932 snd_azf3328_mixer_reg_decode(®, kcontrol->private_value); in snd_azf3328_get_mixer()
937 val = reg.mask - val; in snd_azf3328_get_mixer()
938 ucontrol->value.integer.value[0] = val; in snd_azf3328_get_mixer()
942 val = reg.mask - val; in snd_azf3328_get_mixer()
943 ucontrol->value.integer.value[1] = val; in snd_azf3328_get_mixer()
945 dev_dbg(chip->card->dev, in snd_azf3328_get_mixer()
946 "get: %02x is %04x -> vol %02lx|%02lx (shift %02d|%02d, mask %02x, inv. %d, stereo %d)\n", in snd_azf3328_get_mixer()
948 ucontrol->value.integer.value[0], ucontrol->value.integer.value[1], in snd_azf3328_get_mixer()
961 snd_azf3328_mixer_reg_decode(®, kcontrol->private_value); in snd_azf3328_put_mixer()
963 val = ucontrol->value.integer.value[0] & reg.mask; in snd_azf3328_put_mixer()
965 val = reg.mask - val; in snd_azf3328_put_mixer()
969 val = ucontrol->value.integer.value[1] & reg.mask; in snd_azf3328_put_mixer()
971 val = reg.mask - val; in snd_azf3328_put_mixer()
984 dev_dbg(chip->card->dev, in snd_azf3328_put_mixer()
985 "put: %02x to %02lx|%02lx, oreg %04x; shift %02d|%02d -> nreg %04x; after: %04x\n", in snd_azf3328_put_mixer()
986 reg.reg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1], in snd_azf3328_put_mixer()
1012 snd_azf3328_mixer_reg_decode(®, kcontrol->private_value); in snd_azf3328_info_mixer_enum()
1041 snd_azf3328_mixer_reg_decode(®, kcontrol->private_value); in snd_azf3328_get_mixer_enum()
1044 ucontrol->value.enumerated.item[0] = (val >> 8) & (reg.enum_c - 1); in snd_azf3328_get_mixer_enum()
1045 ucontrol->value.enumerated.item[1] = (val >> 0) & (reg.enum_c - 1); in snd_azf3328_get_mixer_enum()
1047 ucontrol->value.enumerated.item[0] = (val >> reg.lchan_shift) & (reg.enum_c - 1); in snd_azf3328_get_mixer_enum()
1049 dev_dbg(chip->card->dev, in snd_azf3328_get_mixer_enum()
1050 "get_enum: %02x is %04x -> %d|%d (shift %02d, enum_c %d)\n", in snd_azf3328_get_mixer_enum()
1051 reg.reg, val, ucontrol->value.enumerated.item[0], ucontrol->value.enumerated.item[1], in snd_azf3328_get_mixer_enum()
1064 snd_azf3328_mixer_reg_decode(®, kcontrol->private_value); in snd_azf3328_put_mixer_enum()
1068 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U || in snd_azf3328_put_mixer_enum()
1069 ucontrol->value.enumerated.item[1] > reg.enum_c - 1U) in snd_azf3328_put_mixer_enum()
1070 return -EINVAL; in snd_azf3328_put_mixer_enum()
1071 val = (ucontrol->value.enumerated.item[0] << 8) | in snd_azf3328_put_mixer_enum()
1072 (ucontrol->value.enumerated.item[1] << 0); in snd_azf3328_put_mixer_enum()
1074 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U) in snd_azf3328_put_mixer_enum()
1075 return -EINVAL; in snd_azf3328_put_mixer_enum()
1076 val &= ~((reg.enum_c - 1) << reg.lchan_shift); in snd_azf3328_put_mixer_enum()
1077 val |= (ucontrol->value.enumerated.item[0] << reg.lchan_shift); in snd_azf3328_put_mixer_enum()
1082 dev_dbg(chip->card->dev, in snd_azf3328_put_mixer_enum()
1118 AZF3328_MIXER_ENUM("Mono Output Select", IDX_MIXER_ADVCTL2, 2, 9),
1119 …AZF3328_MIXER_ENUM("PCM Output Route", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front …
1120 AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0),
1121 AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0),
1122 AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0),
1123 AZF3328_MIXER_VOL_SPECIAL("3D Control - Width", IDX_MIXER_ADVCTL1, 0x07, 1, 0), /* "3D Width" */
1124 AZF3328_MIXER_VOL_SPECIAL("3D Control - Depth", IDX_MIXER_ADVCTL1, 0x03, 8, 0), /* "Hifi 3D" */
1169 if (snd_BUG_ON(!chip || !chip->card)) in snd_azf3328_mixer_new()
1170 return -EINVAL; in snd_azf3328_mixer_new()
1172 card = chip->card; in snd_azf3328_mixer_new()
1188 err = snd_ctl_add(chip->card, snd_ctl_new1(sw, chip)); in snd_azf3328_mixer_new()
1193 strcpy(card->mixername, "AZF3328 mixer"); in snd_azf3328_mixer_new()
1231 /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */ in snd_azf3328_codec_setfmt()
1232 /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */ in snd_azf3328_codec_setfmt()
1233 /* val = 0xff0a; 47m30.599s (4764,891Hz; -> 4800Hz???) yup, 4803Hz */ in snd_azf3328_codec_setfmt()
1234 /* val = 0xff0c; 57m0.510s (4010,263Hz; -> 4000Hz???) yup, 4003Hz */ in snd_azf3328_codec_setfmt()
1235 /* val = 0xff05; 5m11.556s (... -> 44100Hz) */ in snd_azf3328_codec_setfmt()
1236 /* val = 0xff03; 10m21.529s (21872,463Hz; -> 22050Hz???) */ in snd_azf3328_codec_setfmt()
1237 /* val = 0xff0f; 20m41.883s (10937,993Hz; -> 11025Hz???) */ in snd_azf3328_codec_setfmt()
1238 /* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */ in snd_azf3328_codec_setfmt()
1239 /* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */ in snd_azf3328_codec_setfmt()
1249 spin_lock_irqsave(codec->lock, flags); in snd_azf3328_codec_setfmt()
1255 * audio output with an annoying click in case of 8/16bit format change in snd_azf3328_codec_setfmt()
1259 * FIXME: does this have some side effects for full-duplex in snd_azf3328_codec_setfmt()
1261 /* do it for non-capture codecs only */ in snd_azf3328_codec_setfmt()
1262 if (codec->type != AZF_CODEC_CAPTURE) in snd_azf3328_codec_setfmt()
1272 spin_unlock_irqrestore(codec->lock, flags); in snd_azf3328_codec_setfmt()
1281 * it should never matter since output should always in snd_azf3328_codec_setfmt_lowpower()
1294 chip->shadow_reg_ctrl_6AH |= bitmask; in snd_azf3328_ctrl_reg_6AH_update()
1296 chip->shadow_reg_ctrl_6AH &= ~bitmask; in snd_azf3328_ctrl_reg_6AH_update()
1297 dev_dbg(chip->card->dev, in snd_azf3328_ctrl_reg_6AH_update()
1299 bitmask, do_mask, chip->shadow_reg_ctrl_6AH); in snd_azf3328_ctrl_reg_6AH_update()
1300 snd_azf3328_ctrl_outw(chip, IDX_IO_6AH, chip->shadow_reg_ctrl_6AH); in snd_azf3328_ctrl_reg_6AH_update()
1306 dev_dbg(chip->card->dev, "codec_enable %d\n", enable); in snd_azf3328_ctrl_enable_codecs()
1320 struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type]; in snd_azf3328_ctrl_codec_activity()
1321 bool need_change = (codec->running != enable); in snd_azf3328_ctrl_codec_activity()
1323 dev_dbg(chip->card->dev, in snd_azf3328_ctrl_codec_activity()
1325 codec->name, enable, need_change in snd_azf3328_ctrl_codec_activity()
1347 ((!chip->codecs[peer_codecs[codec_type].other1] in snd_azf3328_ctrl_codec_activity()
1349 && (!chip->codecs[peer_codecs[codec_type].other2] in snd_azf3328_ctrl_codec_activity()
1359 codec->running = enable; in snd_azf3328_ctrl_codec_activity()
1375 if (!codec->running) { in snd_azf3328_codec_setdmaa()
1393 dev_dbg(chip->card->dev, in snd_azf3328_codec_setdmaa()
1404 area_length--; |* max. index *| in snd_azf3328_codec_setdmaa()
1410 spin_lock_irqsave(codec->lock, flags); in snd_azf3328_codec_setdmaa()
1414 spin_unlock_irqrestore(codec->lock, flags); in snd_azf3328_codec_setdmaa()
1421 struct snd_pcm_runtime *runtime = substream->runtime; in snd_azf3328_pcm_prepare()
1422 struct snd_azf3328_codec_data *codec = runtime->private_data; in snd_azf3328_pcm_prepare()
1428 codec->dma_base = runtime->dma_addr; in snd_azf3328_pcm_prepare()
1432 runtime->rate, in snd_azf3328_pcm_prepare()
1433 snd_pcm_format_width(runtime->format), in snd_azf3328_pcm_prepare()
1434 runtime->channels); in snd_azf3328_pcm_prepare()
1436 runtime->dma_addr, count, size); in snd_azf3328_pcm_prepare()
1445 struct snd_pcm_runtime *runtime = substream->runtime; in snd_azf3328_pcm_trigger()
1446 struct snd_azf3328_codec_data *codec = runtime->private_data; in snd_azf3328_pcm_trigger()
1450 bool is_main_mixer_playback_codec = (AZF_CODEC_PLAYBACK == codec->type); in snd_azf3328_pcm_trigger()
1454 dev_dbg(chip->card->dev, "START PCM %s\n", codec->name); in snd_azf3328_pcm_trigger()
1465 runtime->rate, in snd_azf3328_pcm_trigger()
1466 snd_pcm_format_width(runtime->format), in snd_azf3328_pcm_trigger()
1467 runtime->channels); in snd_azf3328_pcm_trigger()
1469 spin_lock(codec->lock); in snd_azf3328_pcm_trigger()
1479 spin_unlock(codec->lock); in snd_azf3328_pcm_trigger()
1481 snd_azf3328_codec_setdmaa(chip, codec, runtime->dma_addr, in snd_azf3328_pcm_trigger()
1486 spin_lock(codec->lock); in snd_azf3328_pcm_trigger()
1510 spin_unlock(codec->lock); in snd_azf3328_pcm_trigger()
1511 snd_azf3328_ctrl_codec_activity(chip, codec->type, 1); in snd_azf3328_pcm_trigger()
1521 dev_dbg(chip->card->dev, "PCM STARTED %s\n", codec->name); in snd_azf3328_pcm_trigger()
1524 dev_dbg(chip->card->dev, "PCM RESUME %s\n", codec->name); in snd_azf3328_pcm_trigger()
1526 spin_lock(codec->lock); in snd_azf3328_pcm_trigger()
1527 if (codec->running) in snd_azf3328_pcm_trigger()
1533 spin_unlock(codec->lock); in snd_azf3328_pcm_trigger()
1536 dev_dbg(chip->card->dev, "PCM STOP %s\n", codec->name); in snd_azf3328_pcm_trigger()
1546 spin_lock(codec->lock); in snd_azf3328_pcm_trigger()
1561 spin_unlock(codec->lock); in snd_azf3328_pcm_trigger()
1562 snd_azf3328_ctrl_codec_activity(chip, codec->type, 0); in snd_azf3328_pcm_trigger()
1572 dev_dbg(chip->card->dev, "PCM STOPPED %s\n", codec->name); in snd_azf3328_pcm_trigger()
1575 dev_dbg(chip->card->dev, "PCM SUSPEND %s\n", codec->name); in snd_azf3328_pcm_trigger()
1591 return -EINVAL; in snd_azf3328_pcm_trigger()
1602 substream->runtime->private_data; in snd_azf3328_pcm_pointer()
1610 result -= snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_START_1); in snd_azf3328_pcm_pointer()
1612 result -= codec->dma_base; in snd_azf3328_pcm_pointer()
1614 frmres = bytes_to_frames( substream->runtime, result); in snd_azf3328_pcm_pointer()
1615 dev_dbg(substream->pcm->card->dev, "%08li %s @ 0x%8lx, frames %8ld\n", in snd_azf3328_pcm_pointer()
1616 jiffies, codec->name, result, frmres); in snd_azf3328_pcm_pointer()
1629 chip->game_io+IDX_GAME_HWCONFIG, in snd_azf3328_gameport_irq_enable()
1641 chip->game_io+IDX_GAME_HWCONFIG, in snd_azf3328_gameport_legacy_address_enable()
1653 chip->game_io+IDX_GAME_HWCONFIG, in snd_azf3328_gameport_set_counter_frequency()
1658 chip->game_io+IDX_GAME_HWCONFIG, in snd_azf3328_gameport_set_counter_frequency()
1677 * (we do not want axis reading in interrupt handler - too much load!) in snd_azf3328_gameport_interrupt()
1679 dev_dbg(chip->card->dev, "gameport irq\n"); in snd_azf3328_gameport_interrupt()
1691 dev_dbg(chip->card->dev, "gameport_open, mode %d\n", mode); in snd_azf3328_gameport_open()
1698 res = -1; in snd_azf3328_gameport_open()
1714 dev_dbg(chip->card->dev, "gameport_close\n"); in snd_azf3328_gameport_close()
1734 spin_lock_irqsave(&chip->reg_lock, flags); in snd_azf3328_gameport_cooked_read()
1750 for (i = 0; i < ARRAY_SIZE(chip->axes); ++i) { in snd_azf3328_gameport_cooked_read()
1755 chip->axes[i] = snd_azf3328_game_inw( in snd_azf3328_gameport_cooked_read()
1771 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_azf3328_gameport_cooked_read()
1773 for (i = 0; i < ARRAY_SIZE(chip->axes); i++) { in snd_azf3328_gameport_cooked_read()
1774 axes[i] = chip->axes[i]; in snd_azf3328_gameport_cooked_read()
1776 axes[i] = -1; in snd_azf3328_gameport_cooked_read()
1779 dev_dbg(chip->card->dev, "cooked_read: axes %d %d %d %d buttons %d\n", in snd_azf3328_gameport_cooked_read()
1790 chip->gameport = gp = gameport_allocate_port(); in snd_azf3328_gameport()
1792 dev_err(chip->card->dev, "cannot alloc memory for gameport\n"); in snd_azf3328_gameport()
1793 return -ENOMEM; in snd_azf3328_gameport()
1797 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci)); in snd_azf3328_gameport()
1798 gameport_set_dev_parent(gp, &chip->pci->dev); in snd_azf3328_gameport()
1799 gp->io = chip->game_io; in snd_azf3328_gameport()
1802 gp->open = snd_azf3328_gameport_open; in snd_azf3328_gameport()
1803 gp->close = snd_azf3328_gameport_close; in snd_azf3328_gameport()
1804 gp->fuzz = 16; /* seems ok */ in snd_azf3328_gameport()
1805 gp->cooked_read = snd_azf3328_gameport_cooked_read; in snd_azf3328_gameport()
1814 gameport_register_port(chip->gameport); in snd_azf3328_gameport()
1822 if (chip->gameport) { in snd_azf3328_gameport_free()
1823 gameport_unregister_port(chip->gameport); in snd_azf3328_gameport_free()
1824 chip->gameport = NULL; in snd_azf3328_gameport_free()
1830 snd_azf3328_gameport(struct snd_azf3328 *chip, int dev) { return -ENOSYS; } in snd_azf3328_gameport()
1836 dev_warn(chip->card->dev, "huh, game port IRQ occurred!?\n"); in snd_azf3328_gameport_interrupt()
1845 dev_dbg(chip->card->dev, in snd_azf3328_irq_log_unknown_type()
1868 spin_lock(codec->lock); in snd_azf3328_pcm_interrupt()
1872 spin_unlock(codec->lock); in snd_azf3328_pcm_interrupt()
1874 if (codec->substream) { in snd_azf3328_pcm_interrupt()
1875 snd_pcm_period_elapsed(codec->substream); in snd_azf3328_pcm_interrupt()
1876 dev_dbg(chip->card->dev, "%s period done (#%x), @ %x\n", in snd_azf3328_pcm_interrupt()
1877 codec->name, in snd_azf3328_pcm_interrupt()
1882 dev_warn(chip->card->dev, "irq handler problem!\n"); in snd_azf3328_pcm_interrupt()
1904 dev_dbg(chip->card->dev, in snd_azf3328_interrupt()
1906 irq_count++ /* debug-only */, in snd_azf3328_interrupt()
1910 /* dev_dbg(chip->card->dev, "timer %ld\n", in snd_azf3328_interrupt()
1914 if (chip->timer) in snd_azf3328_interrupt()
1915 snd_timer_interrupt(chip->timer, chip->timer->sticks); in snd_azf3328_interrupt()
1917 spin_lock(&chip->reg_lock); in snd_azf3328_interrupt()
1919 spin_unlock(&chip->reg_lock); in snd_azf3328_interrupt()
1920 dev_dbg(chip->card->dev, "timer IRQ\n"); in snd_azf3328_interrupt()
1924 snd_azf3328_pcm_interrupt(chip, chip->codecs, status); in snd_azf3328_interrupt()
1932 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data); in snd_azf3328_interrupt()
1936 dev_dbg(chip->card->dev, "MPU401 IRQ\n"); in snd_azf3328_interrupt()
2011 struct snd_pcm_runtime *runtime = substream->runtime; in snd_azf3328_pcm_open()
2012 struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type]; in snd_azf3328_pcm_open()
2014 codec->substream = substream; in snd_azf3328_pcm_open()
2016 /* same parameters for all our codecs - at least we think so... */ in snd_azf3328_pcm_open()
2017 runtime->hw = snd_azf3328_hardware; in snd_azf3328_pcm_open()
2021 runtime->private_data = codec; in snd_azf3328_pcm_open()
2048 substream->runtime->private_data; in snd_azf3328_pcm_close()
2050 codec->substream = NULL; in snd_azf3328_pcm_close()
2089 err = snd_pcm_new(chip->card, "AZF3328 DSP", AZF_PCMDEV_STD, in snd_azf3328_pcm()
2098 pcm->private_data = chip; in snd_azf3328_pcm()
2099 pcm->info_flags = 0; in snd_azf3328_pcm()
2100 strcpy(pcm->name, chip->card->shortname); in snd_azf3328_pcm()
2102 chip->pcm[AZF_CODEC_PLAYBACK] = pcm; in snd_azf3328_pcm()
2103 chip->pcm[AZF_CODEC_CAPTURE] = pcm; in snd_azf3328_pcm()
2105 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, &chip->pci->dev, in snd_azf3328_pcm()
2108 err = snd_pcm_new(chip->card, "AZF3328 I2S OUT", AZF_PCMDEV_I2S_OUT, in snd_azf3328_pcm()
2115 pcm->private_data = chip; in snd_azf3328_pcm()
2116 pcm->info_flags = 0; in snd_azf3328_pcm()
2117 strcpy(pcm->name, chip->card->shortname); in snd_azf3328_pcm()
2118 chip->pcm[AZF_CODEC_I2S_OUT] = pcm; in snd_azf3328_pcm()
2120 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, &chip->pci->dev, in snd_azf3328_pcm()
2130 *** but announcing those attributes to user-space would make programs
2133 *** Thus I chose to announce a down-scaled virtual timer to the outside and
2146 delay = ((timer->sticks * seqtimer_scaling) - 1) & TIMER_VALUE_MASK; in snd_azf3328_timer_start()
2148 /* uhoh, that's not good, since user-space won't know about in snd_azf3328_timer_start()
2152 dev_dbg(chip->card->dev, "delay was too low (%d)!\n", delay); in snd_azf3328_timer_start()
2155 dev_dbg(chip->card->dev, "setting timer countdown value %d\n", delay); in snd_azf3328_timer_start()
2157 spin_lock_irqsave(&chip->reg_lock, flags); in snd_azf3328_timer_start()
2159 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_azf3328_timer_start()
2170 spin_lock_irqsave(&chip->reg_lock, flags); in snd_azf3328_timer_stop()
2173 YES indeed, otherwise a rogue timer operation - which prompts in snd_azf3328_timer_stop()
2174 ALSA(?) to call repeated stop() in vain, but NOT start() - in snd_azf3328_timer_stop()
2179 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_azf3328_timer_stop()
2211 tid.card = chip->card->number; in snd_azf3328_timer()
2218 err = snd_timer_new(chip->card, "AZF3328", &tid, &timer); in snd_azf3328_timer()
2222 strcpy(timer->name, "AZF3328 timer"); in snd_azf3328_timer()
2223 timer->private_data = chip; in snd_azf3328_timer()
2224 timer->hw = snd_azf3328_timer_hw; in snd_azf3328_timer()
2226 chip->timer = timer; in snd_azf3328_timer()
2241 struct snd_azf3328 *chip = card->private_data; in snd_azf3328_free()
2245 snd_azf3328_timer_stop(chip->timer); in snd_azf3328_free()
2277 dev_dbg(chip->card->dev, in snd_azf3328_debug_show_ports()
2280 chip->ctrl_io, chip->game_io, chip->mpu_io, in snd_azf3328_debug_show_ports()
2281 chip->opl3_io, chip->mixer_io, chip->irq); in snd_azf3328_debug_show_ports()
2283 dev_dbg(chip->card->dev, in snd_azf3328_debug_show_ports()
2293 dev_dbg(chip->card->dev, in snd_azf3328_debug_show_ports()
2294 "mpu_io 0x%04x\n", inb(chip->mpu_io + tmp)); in snd_azf3328_debug_show_ports()
2297 dev_dbg(chip->card->dev, in snd_azf3328_debug_show_ports()
2302 dev_dbg(chip->card->dev, in snd_azf3328_debug_show_ports()
2314 dev_dbg(chip->card->dev, in snd_azf3328_debug_show_ports()
2319 dev_dbg(chip->card->dev, in snd_azf3328_debug_show_ports()
2329 struct snd_azf3328 *chip = card->private_data; in snd_azf3328_create()
2339 spin_lock_init(&chip->reg_lock); in snd_azf3328_create()
2340 chip->card = card; in snd_azf3328_create()
2341 chip->pci = pci; in snd_azf3328_create()
2342 chip->irq = -1; in snd_azf3328_create()
2345 if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(24))) { in snd_azf3328_create()
2346 dev_err(card->dev, in snd_azf3328_create()
2349 return -ENXIO; in snd_azf3328_create()
2356 chip->ctrl_io = pci_resource_start(pci, 0); in snd_azf3328_create()
2357 chip->game_io = pci_resource_start(pci, 1); in snd_azf3328_create()
2358 chip->mpu_io = pci_resource_start(pci, 2); in snd_azf3328_create()
2359 chip->opl3_io = pci_resource_start(pci, 3); in snd_azf3328_create()
2360 chip->mixer_io = pci_resource_start(pci, 4); in snd_azf3328_create()
2362 codec_setup = &chip->codecs[AZF_CODEC_PLAYBACK]; in snd_azf3328_create()
2363 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_PLAYBACK; in snd_azf3328_create()
2364 codec_setup->lock = &chip->reg_lock; in snd_azf3328_create()
2365 codec_setup->type = AZF_CODEC_PLAYBACK; in snd_azf3328_create()
2366 codec_setup->name = "PLAYBACK"; in snd_azf3328_create()
2368 codec_setup = &chip->codecs[AZF_CODEC_CAPTURE]; in snd_azf3328_create()
2369 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_CAPTURE; in snd_azf3328_create()
2370 codec_setup->lock = &chip->reg_lock; in snd_azf3328_create()
2371 codec_setup->type = AZF_CODEC_CAPTURE; in snd_azf3328_create()
2372 codec_setup->name = "CAPTURE"; in snd_azf3328_create()
2374 codec_setup = &chip->codecs[AZF_CODEC_I2S_OUT]; in snd_azf3328_create()
2375 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_I2S_OUT; in snd_azf3328_create()
2376 codec_setup->lock = &chip->reg_lock; in snd_azf3328_create()
2377 codec_setup->type = AZF_CODEC_I2S_OUT; in snd_azf3328_create()
2378 codec_setup->name = "I2S_OUT"; in snd_azf3328_create()
2380 if (devm_request_irq(&pci->dev, pci->irq, snd_azf3328_interrupt, in snd_azf3328_create()
2382 dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq); in snd_azf3328_create()
2383 return -EBUSY; in snd_azf3328_create()
2385 chip->irq = pci->irq; in snd_azf3328_create()
2386 card->sync_irq = chip->irq; in snd_azf3328_create()
2387 card->private_free = snd_azf3328_free; in snd_azf3328_create()
2404 &chip->codecs[codec_type]; in snd_azf3328_create()
2408 codec->running = true; in snd_azf3328_create()
2411 spin_lock_irq(codec->lock); in snd_azf3328_create()
2414 spin_unlock_irq(codec->lock); in snd_azf3328_create()
2430 return -ENODEV; in __snd_azf3328_probe()
2433 return -ENOENT; in __snd_azf3328_probe()
2436 err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, in __snd_azf3328_probe()
2440 chip = card->private_data; in __snd_azf3328_probe()
2442 strcpy(card->driver, "AZF3328"); in __snd_azf3328_probe()
2443 strcpy(card->shortname, "Aztech AZF3328 (PCI168)"); in __snd_azf3328_probe()
2445 err = snd_azf3328_create(card, pci, pci_id->driver_data); in __snd_azf3328_probe()
2453 MPU401_HW_AZT2320, chip->mpu_io, in __snd_azf3328_probe()
2455 -1, &chip->rmidi in __snd_azf3328_probe()
2458 dev_err(card->dev, "no MPU-401 device at 0x%lx?\n", in __snd_azf3328_probe()
2459 chip->mpu_io in __snd_azf3328_probe()
2472 if (snd_opl3_create(card, chip->opl3_io, chip->opl3_io+2, in __snd_azf3328_probe()
2474 dev_err(card->dev, "no OPL3 device at 0x%lx-0x%lx?\n", in __snd_azf3328_probe()
2475 chip->opl3_io, chip->opl3_io+2 in __snd_azf3328_probe()
2485 opl3->private_data = chip; in __snd_azf3328_probe()
2488 sprintf(card->longname, "%s at 0x%lx, irq %i", in __snd_azf3328_probe()
2489 card->shortname, chip->ctrl_io, chip->irq); in __snd_azf3328_probe()
2496 dev_info(card->dev, in __snd_azf3328_probe()
2497 "Sound driver for Aztech AZF3328-based soundcards such as PCI168.\n"); in __snd_azf3328_probe()
2498 dev_info(card->dev, in __snd_azf3328_probe()
2500 dev_info(card->dev, in __snd_azf3328_probe()
2502 dev_info(card->dev, in __snd_azf3328_probe()
2503 "User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n", in __snd_azf3328_probe()
2517 return snd_card_free_on_error(&pci->dev, __snd_azf3328_probe(pci, pci_id)); in snd_azf3328_probe()
2529 dev_dbg(chip->card->dev, "suspend: io 0x%04lx: 0x%08x\n", in snd_azf3328_suspend_regs()
2547 dev_dbg(chip->card->dev, in snd_azf3328_resume_regs()
2548 "resume: io 0x%04lx: 0x%08x --> 0x%08x\n", in snd_azf3328_resume_regs()
2559 snd_ac97_suspend(chip->ac97); in snd_azf3328_suspend_ac97()
2561 snd_azf3328_suspend_regs(chip, chip->mixer_io, in snd_azf3328_suspend_ac97()
2562 ARRAY_SIZE(chip->saved_regs_mixer), chip->saved_regs_mixer); in snd_azf3328_suspend_ac97()
2574 snd_ac97_resume(chip->ac97); in snd_azf3328_resume_ac97()
2576 snd_azf3328_resume_regs(chip, chip->saved_regs_mixer, chip->mixer_io, in snd_azf3328_resume_ac97()
2577 ARRAY_SIZE(chip->saved_regs_mixer)); in snd_azf3328_resume_ac97()
2583 outw(((u16 *)chip->saved_regs_mixer)[1], chip->mixer_io + 2); in snd_azf3328_resume_ac97()
2591 struct snd_azf3328 *chip = card->private_data; in snd_azf3328_suspend()
2598 snd_azf3328_suspend_regs(chip, chip->ctrl_io, in snd_azf3328_suspend()
2599 ARRAY_SIZE(chip->saved_regs_ctrl), chip->saved_regs_ctrl); in snd_azf3328_suspend()
2601 /* manually store the one currently relevant write-only reg, too */ in snd_azf3328_suspend()
2602 saved_regs_ctrl_u16 = (u16 *)chip->saved_regs_ctrl; in snd_azf3328_suspend()
2603 saved_regs_ctrl_u16[IDX_IO_6AH / 2] = chip->shadow_reg_ctrl_6AH; in snd_azf3328_suspend()
2605 snd_azf3328_suspend_regs(chip, chip->game_io, in snd_azf3328_suspend()
2606 ARRAY_SIZE(chip->saved_regs_game), chip->saved_regs_game); in snd_azf3328_suspend()
2607 snd_azf3328_suspend_regs(chip, chip->mpu_io, in snd_azf3328_suspend()
2608 ARRAY_SIZE(chip->saved_regs_mpu), chip->saved_regs_mpu); in snd_azf3328_suspend()
2609 snd_azf3328_suspend_regs(chip, chip->opl3_io, in snd_azf3328_suspend()
2610 ARRAY_SIZE(chip->saved_regs_opl3), chip->saved_regs_opl3); in snd_azf3328_suspend()
2618 const struct snd_azf3328 *chip = card->private_data; in snd_azf3328_resume()
2620 snd_azf3328_resume_regs(chip, chip->saved_regs_game, chip->game_io, in snd_azf3328_resume()
2621 ARRAY_SIZE(chip->saved_regs_game)); in snd_azf3328_resume()
2622 snd_azf3328_resume_regs(chip, chip->saved_regs_mpu, chip->mpu_io, in snd_azf3328_resume()
2623 ARRAY_SIZE(chip->saved_regs_mpu)); in snd_azf3328_resume()
2624 snd_azf3328_resume_regs(chip, chip->saved_regs_opl3, chip->opl3_io, in snd_azf3328_resume()
2625 ARRAY_SIZE(chip->saved_regs_opl3)); in snd_azf3328_resume()
2629 snd_azf3328_resume_regs(chip, chip->saved_regs_ctrl, chip->ctrl_io, in snd_azf3328_resume()
2630 ARRAY_SIZE(chip->saved_regs_ctrl)); in snd_azf3328_resume()