Lines Matching +full:adc +full:- +full:res +full:- +full:names

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.
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()
372 outl(value, codec->io_base + reg); in snd_azf3328_codec_outl()
380 unsigned long addr = codec->io_base + reg; in snd_azf3328_codec_outl_multi()
386 } while (--count); in snd_azf3328_codec_outl_multi()
393 return inl(codec->io_base + reg); in snd_azf3328_codec_inl()
399 outb(value, chip->ctrl_io + reg); in snd_azf3328_ctrl_outb()
405 return inb(chip->ctrl_io + reg); in snd_azf3328_ctrl_inb()
411 return inw(chip->ctrl_io + reg); in snd_azf3328_ctrl_inw()
417 outw(value, chip->ctrl_io + reg); in snd_azf3328_ctrl_outw()
423 outl(value, chip->ctrl_io + reg); in snd_azf3328_ctrl_outl()
429 outb(value, chip->game_io + reg); in snd_azf3328_game_outb()
435 outw(value, chip->game_io + reg); in snd_azf3328_game_outw()
441 return inb(chip->game_io + reg); in snd_azf3328_game_inb()
447 return inw(chip->game_io + reg); in snd_azf3328_game_inw()
453 outw(value, chip->mixer_io + reg); in snd_azf3328_mixer_outw()
459 return inw(chip->mixer_io + reg); in snd_azf3328_mixer_inw()
469 unsigned long portbase = chip->mixer_io + reg + 1; in snd_azf3328_mixer_mute_control()
521 dev_warn(chip->card->dev, in snd_azf3328_mixer_ac97_map_unsupported()
528 * to compensate for the issue of a rather AC97-incompatible hardware layout.
547 * mono/stereo-based sequence of azf vs. AC97 control series, in snd_azf3328_mixer_ac97_map_reg_idx()
555 * (snd_ac97_rename_vol_ctl() etc.) - that's it. in snd_azf3328_mixer_ac97_map_reg_idx()
582 /* azf3328 supports the low-numbered and low-spec:ed range in snd_azf3328_mixer_ac97_map_reg_idx()
587 /* a translation-only entry means it's real read/write: */ in snd_azf3328_mixer_ac97_map_reg_idx()
601 * given a base-AC97-advertised card, in snd_azf3328_mixer_ac97_map_reg_idx()
602 * but let's just emulate it anyway :-P in snd_azf3328_mixer_ac97_map_reg_idx()
623 vendor-specific 3D enhancement
641 * (there might be some devices such as the MR 2800-W
652 const struct snd_azf3328 *chip = ac97->private_data; in snd_azf3328_mixer_ac97_read()
657 dev_dbg(chip->card->dev, "snd_azf3328_mixer_ac97_read reg_ac97 %u\n", in snd_azf3328_mixer_ac97_read()
712 const struct snd_azf3328 *chip = ac97->private_data; in snd_azf3328_mixer_ac97_write()
716 dev_dbg(chip->card->dev, in snd_azf3328_mixer_ac97_write()
770 ac97.pci = chip->pci; in snd_azf3328_mixer_new()
778 rc = snd_ac97_bus(chip->card, 0, &ops, NULL, &bus); in snd_azf3328_mixer_new()
780 rc = snd_ac97_mixer(bus, &ac97, &chip->ac97); in snd_azf3328_mixer_new()
787 dev_err(chip->card->dev, "AC97 init failed, err %d!\n", rc); in snd_azf3328_mixer_new()
803 unsigned long portbase = chip->mixer_io + reg; in snd_azf3328_mixer_write_volume_gradually()
816 left_change = (curr_vol_left > dst_vol_left) ? -1 : 1; in snd_azf3328_mixer_write_volume_gradually()
822 right_change = (curr_vol_right > dst_vol_right) ? -1 : 1; in snd_azf3328_mixer_write_volume_gradually()
870 r->reg = val & 0xff; in snd_azf3328_mixer_reg_decode()
871 r->lchan_shift = (val >> 8) & 0x0f; in snd_azf3328_mixer_reg_decode()
872 r->rchan_shift = (val >> 12) & 0x0f; in snd_azf3328_mixer_reg_decode()
873 r->mask = (val >> 16) & 0xff; in snd_azf3328_mixer_reg_decode()
874 r->invert = (val >> 24) & 1; in snd_azf3328_mixer_reg_decode()
875 r->stereo = (val >> 25) & 1; in snd_azf3328_mixer_reg_decode()
876 r->enum_c = (val >> 26) & 0x0f; in snd_azf3328_mixer_reg_decode()
924 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); in snd_azf3328_info_mixer()
925 uinfo->type = reg.mask == 1 ? in snd_azf3328_info_mixer()
927 uinfo->count = reg.stereo + 1; in snd_azf3328_info_mixer()
928 uinfo->value.integer.min = 0; in snd_azf3328_info_mixer()
929 uinfo->value.integer.max = reg.mask; in snd_azf3328_info_mixer()
941 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); in snd_azf3328_get_mixer()
946 val = reg.mask - val; in snd_azf3328_get_mixer()
947 ucontrol->value.integer.value[0] = val; in snd_azf3328_get_mixer()
951 val = reg.mask - val; in snd_azf3328_get_mixer()
952 ucontrol->value.integer.value[1] = val; in snd_azf3328_get_mixer()
954 dev_dbg(chip->card->dev, in snd_azf3328_get_mixer()
955 "get: %02x is %04x -> vol %02lx|%02lx (shift %02d|%02d, mask %02x, inv. %d, stereo %d)\n", in snd_azf3328_get_mixer()
957 ucontrol->value.integer.value[0], ucontrol->value.integer.value[1], in snd_azf3328_get_mixer()
970 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); in snd_azf3328_put_mixer()
972 val = ucontrol->value.integer.value[0] & reg.mask; in snd_azf3328_put_mixer()
974 val = reg.mask - val; in snd_azf3328_put_mixer()
978 val = ucontrol->value.integer.value[1] & reg.mask; in snd_azf3328_put_mixer()
980 val = reg.mask - val; in snd_azf3328_put_mixer()
993 dev_dbg(chip->card->dev, in snd_azf3328_put_mixer()
994 "put: %02x to %02lx|%02lx, oreg %04x; shift %02d|%02d -> nreg %04x; after: %04x\n", in snd_azf3328_put_mixer()
995 reg.reg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1], in snd_azf3328_put_mixer()
1021 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); in snd_azf3328_info_mixer_enum()
1050 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); in snd_azf3328_get_mixer_enum()
1053 ucontrol->value.enumerated.item[0] = (val >> 8) & (reg.enum_c - 1); in snd_azf3328_get_mixer_enum()
1054 ucontrol->value.enumerated.item[1] = (val >> 0) & (reg.enum_c - 1); in snd_azf3328_get_mixer_enum()
1056 ucontrol->value.enumerated.item[0] = (val >> reg.lchan_shift) & (reg.enum_c - 1); in snd_azf3328_get_mixer_enum()
1058 dev_dbg(chip->card->dev, in snd_azf3328_get_mixer_enum()
1059 "get_enum: %02x is %04x -> %d|%d (shift %02d, enum_c %d)\n", in snd_azf3328_get_mixer_enum()
1060 reg.reg, val, ucontrol->value.enumerated.item[0], ucontrol->value.enumerated.item[1], in snd_azf3328_get_mixer_enum()
1073 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); in snd_azf3328_put_mixer_enum()
1077 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U || in snd_azf3328_put_mixer_enum()
1078 ucontrol->value.enumerated.item[1] > reg.enum_c - 1U) in snd_azf3328_put_mixer_enum()
1079 return -EINVAL; in snd_azf3328_put_mixer_enum()
1080 val = (ucontrol->value.enumerated.item[0] << 8) | in snd_azf3328_put_mixer_enum()
1081 (ucontrol->value.enumerated.item[1] << 0); in snd_azf3328_put_mixer_enum()
1083 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U) in snd_azf3328_put_mixer_enum()
1084 return -EINVAL; in snd_azf3328_put_mixer_enum()
1085 val &= ~((reg.enum_c - 1) << reg.lchan_shift); in snd_azf3328_put_mixer_enum()
1086 val |= (ucontrol->value.enumerated.item[0] << reg.lchan_shift); in snd_azf3328_put_mixer_enum()
1091 dev_dbg(chip->card->dev, in snd_azf3328_put_mixer_enum()
1129 AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0),
1130 AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0),
1131 AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0),
1132 AZF3328_MIXER_VOL_SPECIAL("3D Control - Width", IDX_MIXER_ADVCTL1, 0x07, 1, 0), /* "3D Width" */
1133 AZF3328_MIXER_VOL_SPECIAL("3D Control - Depth", IDX_MIXER_ADVCTL1, 0x03, 8, 0), /* "Hifi 3D" */
1178 if (snd_BUG_ON(!chip || !chip->card)) in snd_azf3328_mixer_new()
1179 return -EINVAL; in snd_azf3328_mixer_new()
1181 card = chip->card; in snd_azf3328_mixer_new()
1197 err = snd_ctl_add(chip->card, snd_ctl_new1(sw, chip)); in snd_azf3328_mixer_new()
1202 strcpy(card->mixername, "AZF3328 mixer"); in snd_azf3328_mixer_new()
1223 /* the AZF3328 names it "5510" for some strange reason */ in snd_azf3328_codec_setfmt()
1240 /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */ in snd_azf3328_codec_setfmt()
1241 /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */ in snd_azf3328_codec_setfmt()
1242 /* val = 0xff0a; 47m30.599s (4764,891Hz; -> 4800Hz???) yup, 4803Hz */ in snd_azf3328_codec_setfmt()
1243 /* val = 0xff0c; 57m0.510s (4010,263Hz; -> 4000Hz???) yup, 4003Hz */ in snd_azf3328_codec_setfmt()
1244 /* val = 0xff05; 5m11.556s (... -> 44100Hz) */ in snd_azf3328_codec_setfmt()
1245 /* val = 0xff03; 10m21.529s (21872,463Hz; -> 22050Hz???) */ in snd_azf3328_codec_setfmt()
1246 /* val = 0xff0f; 20m41.883s (10937,993Hz; -> 11025Hz???) */ in snd_azf3328_codec_setfmt()
1247 /* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */ in snd_azf3328_codec_setfmt()
1248 /* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */ in snd_azf3328_codec_setfmt()
1258 spin_lock_irqsave(codec->lock, flags); in snd_azf3328_codec_setfmt()
1265 * (maybe shutting down DAC/ADC?), thus immediately in snd_azf3328_codec_setfmt()
1268 * FIXME: does this have some side effects for full-duplex in snd_azf3328_codec_setfmt()
1270 /* do it for non-capture codecs only */ in snd_azf3328_codec_setfmt()
1271 if (codec->type != AZF_CODEC_CAPTURE) in snd_azf3328_codec_setfmt()
1281 spin_unlock_irqrestore(codec->lock, flags); in snd_azf3328_codec_setfmt()
1303 chip->shadow_reg_ctrl_6AH |= bitmask; in snd_azf3328_ctrl_reg_6AH_update()
1305 chip->shadow_reg_ctrl_6AH &= ~bitmask; in snd_azf3328_ctrl_reg_6AH_update()
1306 dev_dbg(chip->card->dev, in snd_azf3328_ctrl_reg_6AH_update()
1308 bitmask, do_mask, chip->shadow_reg_ctrl_6AH); in snd_azf3328_ctrl_reg_6AH_update()
1309 snd_azf3328_ctrl_outw(chip, IDX_IO_6AH, chip->shadow_reg_ctrl_6AH); in snd_azf3328_ctrl_reg_6AH_update()
1315 dev_dbg(chip->card->dev, "codec_enable %d\n", enable); in snd_azf3328_ctrl_enable_codecs()
1329 struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type]; in snd_azf3328_ctrl_codec_activity()
1330 bool need_change = (codec->running != enable); in snd_azf3328_ctrl_codec_activity()
1332 dev_dbg(chip->card->dev, in snd_azf3328_ctrl_codec_activity()
1334 codec->name, enable, need_change in snd_azf3328_ctrl_codec_activity()
1356 ((!chip->codecs[peer_codecs[codec_type].other1] in snd_azf3328_ctrl_codec_activity()
1358 && (!chip->codecs[peer_codecs[codec_type].other2] in snd_azf3328_ctrl_codec_activity()
1368 codec->running = enable; in snd_azf3328_ctrl_codec_activity()
1384 if (!codec->running) { in snd_azf3328_codec_setdmaa()
1402 dev_dbg(chip->card->dev, in snd_azf3328_codec_setdmaa()
1413 area_length--; |* max. index *| in snd_azf3328_codec_setdmaa()
1419 spin_lock_irqsave(codec->lock, flags); in snd_azf3328_codec_setdmaa()
1423 spin_unlock_irqrestore(codec->lock, flags); in snd_azf3328_codec_setdmaa()
1430 struct snd_pcm_runtime *runtime = substream->runtime; in snd_azf3328_pcm_prepare()
1431 struct snd_azf3328_codec_data *codec = runtime->private_data; in snd_azf3328_pcm_prepare()
1437 codec->dma_base = runtime->dma_addr; in snd_azf3328_pcm_prepare()
1441 runtime->rate, in snd_azf3328_pcm_prepare()
1442 snd_pcm_format_width(runtime->format), in snd_azf3328_pcm_prepare()
1443 runtime->channels); in snd_azf3328_pcm_prepare()
1445 runtime->dma_addr, count, size); in snd_azf3328_pcm_prepare()
1454 struct snd_pcm_runtime *runtime = substream->runtime; in snd_azf3328_pcm_trigger()
1455 struct snd_azf3328_codec_data *codec = runtime->private_data; in snd_azf3328_pcm_trigger()
1459 bool is_main_mixer_playback_codec = (AZF_CODEC_PLAYBACK == codec->type); in snd_azf3328_pcm_trigger()
1463 dev_dbg(chip->card->dev, "START PCM %s\n", codec->name); in snd_azf3328_pcm_trigger()
1474 runtime->rate, in snd_azf3328_pcm_trigger()
1475 snd_pcm_format_width(runtime->format), in snd_azf3328_pcm_trigger()
1476 runtime->channels); in snd_azf3328_pcm_trigger()
1478 spin_lock(codec->lock); in snd_azf3328_pcm_trigger()
1488 spin_unlock(codec->lock); in snd_azf3328_pcm_trigger()
1490 snd_azf3328_codec_setdmaa(chip, codec, runtime->dma_addr, in snd_azf3328_pcm_trigger()
1495 spin_lock(codec->lock); in snd_azf3328_pcm_trigger()
1519 spin_unlock(codec->lock); in snd_azf3328_pcm_trigger()
1520 snd_azf3328_ctrl_codec_activity(chip, codec->type, 1); in snd_azf3328_pcm_trigger()
1530 dev_dbg(chip->card->dev, "PCM STARTED %s\n", codec->name); in snd_azf3328_pcm_trigger()
1533 dev_dbg(chip->card->dev, "PCM RESUME %s\n", codec->name); in snd_azf3328_pcm_trigger()
1535 spin_lock(codec->lock); in snd_azf3328_pcm_trigger()
1536 if (codec->running) in snd_azf3328_pcm_trigger()
1542 spin_unlock(codec->lock); in snd_azf3328_pcm_trigger()
1545 dev_dbg(chip->card->dev, "PCM STOP %s\n", codec->name); in snd_azf3328_pcm_trigger()
1555 spin_lock(codec->lock); in snd_azf3328_pcm_trigger()
1570 spin_unlock(codec->lock); in snd_azf3328_pcm_trigger()
1571 snd_azf3328_ctrl_codec_activity(chip, codec->type, 0); in snd_azf3328_pcm_trigger()
1581 dev_dbg(chip->card->dev, "PCM STOPPED %s\n", codec->name); in snd_azf3328_pcm_trigger()
1584 dev_dbg(chip->card->dev, "PCM SUSPEND %s\n", codec->name); in snd_azf3328_pcm_trigger()
1600 return -EINVAL; in snd_azf3328_pcm_trigger()
1611 substream->runtime->private_data; in snd_azf3328_pcm_pointer()
1619 result -= snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_START_1); in snd_azf3328_pcm_pointer()
1621 result -= codec->dma_base; in snd_azf3328_pcm_pointer()
1623 frmres = bytes_to_frames( substream->runtime, result); in snd_azf3328_pcm_pointer()
1624 dev_dbg(substream->pcm->card->dev, "%08li %s @ 0x%8lx, frames %8ld\n", in snd_azf3328_pcm_pointer()
1625 jiffies, codec->name, result, frmres); in snd_azf3328_pcm_pointer()
1638 chip->game_io+IDX_GAME_HWCONFIG, in snd_azf3328_gameport_irq_enable()
1650 chip->game_io+IDX_GAME_HWCONFIG, in snd_azf3328_gameport_legacy_address_enable()
1662 chip->game_io+IDX_GAME_HWCONFIG, in snd_azf3328_gameport_set_counter_frequency()
1667 chip->game_io+IDX_GAME_HWCONFIG, in snd_azf3328_gameport_set_counter_frequency()
1686 * (we do not want axis reading in interrupt handler - too much load!) in snd_azf3328_gameport_interrupt()
1688 dev_dbg(chip->card->dev, "gameport irq\n"); in snd_azf3328_gameport_interrupt()
1698 int res; in snd_azf3328_gameport_open() local
1700 dev_dbg(chip->card->dev, "gameport_open, mode %d\n", mode); in snd_azf3328_gameport_open()
1704 res = 0; in snd_azf3328_gameport_open()
1707 res = -1; in snd_azf3328_gameport_open()
1713 snd_azf3328_gameport_axis_circuit_enable(chip, (res == 0)); in snd_azf3328_gameport_open()
1715 return res; in snd_azf3328_gameport_open()
1723 dev_dbg(chip->card->dev, "gameport_close\n"); in snd_azf3328_gameport_close()
1743 spin_lock_irqsave(&chip->reg_lock, flags); in snd_azf3328_gameport_cooked_read()
1759 for (i = 0; i < ARRAY_SIZE(chip->axes); ++i) { in snd_azf3328_gameport_cooked_read()
1764 chip->axes[i] = snd_azf3328_game_inw( in snd_azf3328_gameport_cooked_read()
1780 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_azf3328_gameport_cooked_read()
1782 for (i = 0; i < ARRAY_SIZE(chip->axes); i++) { in snd_azf3328_gameport_cooked_read()
1783 axes[i] = chip->axes[i]; in snd_azf3328_gameport_cooked_read()
1785 axes[i] = -1; in snd_azf3328_gameport_cooked_read()
1788 dev_dbg(chip->card->dev, "cooked_read: axes %d %d %d %d buttons %d\n", in snd_azf3328_gameport_cooked_read()
1799 chip->gameport = gp = gameport_allocate_port(); in snd_azf3328_gameport()
1801 dev_err(chip->card->dev, "cannot alloc memory for gameport\n"); in snd_azf3328_gameport()
1802 return -ENOMEM; in snd_azf3328_gameport()
1806 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci)); in snd_azf3328_gameport()
1807 gameport_set_dev_parent(gp, &chip->pci->dev); in snd_azf3328_gameport()
1808 gp->io = chip->game_io; in snd_azf3328_gameport()
1811 gp->open = snd_azf3328_gameport_open; in snd_azf3328_gameport()
1812 gp->close = snd_azf3328_gameport_close; in snd_azf3328_gameport()
1813 gp->fuzz = 16; /* seems ok */ in snd_azf3328_gameport()
1814 gp->cooked_read = snd_azf3328_gameport_cooked_read; in snd_azf3328_gameport()
1823 gameport_register_port(chip->gameport); in snd_azf3328_gameport()
1831 if (chip->gameport) { in snd_azf3328_gameport_free()
1832 gameport_unregister_port(chip->gameport); in snd_azf3328_gameport_free()
1833 chip->gameport = NULL; in snd_azf3328_gameport_free()
1839 snd_azf3328_gameport(struct snd_azf3328 *chip, int dev) { return -ENOSYS; } in snd_azf3328_gameport()
1845 dev_warn(chip->card->dev, "huh, game port IRQ occurred!?\n"); in snd_azf3328_gameport_interrupt()
1854 dev_dbg(chip->card->dev, in snd_azf3328_irq_log_unknown_type()
1877 spin_lock(codec->lock); in snd_azf3328_pcm_interrupt()
1881 spin_unlock(codec->lock); in snd_azf3328_pcm_interrupt()
1883 if (codec->substream) { in snd_azf3328_pcm_interrupt()
1884 snd_pcm_period_elapsed(codec->substream); in snd_azf3328_pcm_interrupt()
1885 dev_dbg(chip->card->dev, "%s period done (#%x), @ %x\n", in snd_azf3328_pcm_interrupt()
1886 codec->name, in snd_azf3328_pcm_interrupt()
1891 dev_warn(chip->card->dev, "irq handler problem!\n"); in snd_azf3328_pcm_interrupt()
1913 dev_dbg(chip->card->dev, in snd_azf3328_interrupt()
1915 irq_count++ /* debug-only */, in snd_azf3328_interrupt()
1919 /* dev_dbg(chip->card->dev, "timer %ld\n", in snd_azf3328_interrupt()
1923 if (chip->timer) in snd_azf3328_interrupt()
1924 snd_timer_interrupt(chip->timer, chip->timer->sticks); in snd_azf3328_interrupt()
1926 spin_lock(&chip->reg_lock); in snd_azf3328_interrupt()
1928 spin_unlock(&chip->reg_lock); in snd_azf3328_interrupt()
1929 dev_dbg(chip->card->dev, "timer IRQ\n"); in snd_azf3328_interrupt()
1933 snd_azf3328_pcm_interrupt(chip, chip->codecs, status); in snd_azf3328_interrupt()
1941 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data); in snd_azf3328_interrupt()
1945 dev_dbg(chip->card->dev, "MPU401 IRQ\n"); in snd_azf3328_interrupt()
2020 struct snd_pcm_runtime *runtime = substream->runtime; in snd_azf3328_pcm_open()
2021 struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type]; in snd_azf3328_pcm_open()
2023 codec->substream = substream; in snd_azf3328_pcm_open()
2025 /* same parameters for all our codecs - at least we think so... */ in snd_azf3328_pcm_open()
2026 runtime->hw = snd_azf3328_hardware; in snd_azf3328_pcm_open()
2030 runtime->private_data = codec; in snd_azf3328_pcm_open()
2057 substream->runtime->private_data; in snd_azf3328_pcm_close()
2059 codec->substream = NULL; in snd_azf3328_pcm_close()
2098 err = snd_pcm_new(chip->card, "AZF3328 DSP", AZF_PCMDEV_STD, in snd_azf3328_pcm()
2107 pcm->private_data = chip; in snd_azf3328_pcm()
2108 pcm->info_flags = 0; in snd_azf3328_pcm()
2109 strcpy(pcm->name, chip->card->shortname); in snd_azf3328_pcm()
2111 chip->pcm[AZF_CODEC_PLAYBACK] = pcm; in snd_azf3328_pcm()
2112 chip->pcm[AZF_CODEC_CAPTURE] = pcm; in snd_azf3328_pcm()
2114 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, &chip->pci->dev, in snd_azf3328_pcm()
2117 err = snd_pcm_new(chip->card, "AZF3328 I2S OUT", AZF_PCMDEV_I2S_OUT, in snd_azf3328_pcm()
2124 pcm->private_data = chip; in snd_azf3328_pcm()
2125 pcm->info_flags = 0; in snd_azf3328_pcm()
2126 strcpy(pcm->name, chip->card->shortname); in snd_azf3328_pcm()
2127 chip->pcm[AZF_CODEC_I2S_OUT] = pcm; in snd_azf3328_pcm()
2129 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, &chip->pci->dev, in snd_azf3328_pcm()
2139 *** but announcing those attributes to user-space would make programs
2142 *** Thus I chose to announce a down-scaled virtual timer to the outside and
2155 delay = ((timer->sticks * seqtimer_scaling) - 1) & TIMER_VALUE_MASK; in snd_azf3328_timer_start()
2157 /* uhoh, that's not good, since user-space won't know about in snd_azf3328_timer_start()
2161 dev_dbg(chip->card->dev, "delay was too low (%d)!\n", delay); in snd_azf3328_timer_start()
2164 dev_dbg(chip->card->dev, "setting timer countdown value %d\n", delay); in snd_azf3328_timer_start()
2166 spin_lock_irqsave(&chip->reg_lock, flags); in snd_azf3328_timer_start()
2168 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_azf3328_timer_start()
2179 spin_lock_irqsave(&chip->reg_lock, flags); in snd_azf3328_timer_stop()
2182 YES indeed, otherwise a rogue timer operation - which prompts in snd_azf3328_timer_stop()
2183 ALSA(?) to call repeated stop() in vain, but NOT start() - in snd_azf3328_timer_stop()
2188 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_azf3328_timer_stop()
2220 tid.card = chip->card->number; in snd_azf3328_timer()
2227 err = snd_timer_new(chip->card, "AZF3328", &tid, &timer); in snd_azf3328_timer()
2231 strcpy(timer->name, "AZF3328 timer"); in snd_azf3328_timer()
2232 timer->private_data = chip; in snd_azf3328_timer()
2233 timer->hw = snd_azf3328_timer_hw; in snd_azf3328_timer()
2235 chip->timer = timer; in snd_azf3328_timer()
2250 struct snd_azf3328 *chip = card->private_data; in snd_azf3328_free()
2254 snd_azf3328_timer_stop(chip->timer); in snd_azf3328_free()
2286 dev_dbg(chip->card->dev, in snd_azf3328_debug_show_ports()
2289 chip->ctrl_io, chip->game_io, chip->mpu_io, in snd_azf3328_debug_show_ports()
2290 chip->opl3_io, chip->mixer_io, chip->irq); in snd_azf3328_debug_show_ports()
2292 dev_dbg(chip->card->dev, in snd_azf3328_debug_show_ports()
2302 dev_dbg(chip->card->dev, in snd_azf3328_debug_show_ports()
2303 "mpu_io 0x%04x\n", inb(chip->mpu_io + tmp)); in snd_azf3328_debug_show_ports()
2306 dev_dbg(chip->card->dev, in snd_azf3328_debug_show_ports()
2311 dev_dbg(chip->card->dev, in snd_azf3328_debug_show_ports()
2323 dev_dbg(chip->card->dev, in snd_azf3328_debug_show_ports()
2328 dev_dbg(chip->card->dev, in snd_azf3328_debug_show_ports()
2338 struct snd_azf3328 *chip = card->private_data; in snd_azf3328_create()
2348 spin_lock_init(&chip->reg_lock); in snd_azf3328_create()
2349 chip->card = card; in snd_azf3328_create()
2350 chip->pci = pci; in snd_azf3328_create()
2351 chip->irq = -1; in snd_azf3328_create()
2354 if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(24))) { in snd_azf3328_create()
2355 dev_err(card->dev, in snd_azf3328_create()
2358 return -ENXIO; in snd_azf3328_create()
2365 chip->ctrl_io = pci_resource_start(pci, 0); in snd_azf3328_create()
2366 chip->game_io = pci_resource_start(pci, 1); in snd_azf3328_create()
2367 chip->mpu_io = pci_resource_start(pci, 2); in snd_azf3328_create()
2368 chip->opl3_io = pci_resource_start(pci, 3); in snd_azf3328_create()
2369 chip->mixer_io = pci_resource_start(pci, 4); in snd_azf3328_create()
2371 codec_setup = &chip->codecs[AZF_CODEC_PLAYBACK]; in snd_azf3328_create()
2372 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_PLAYBACK; in snd_azf3328_create()
2373 codec_setup->lock = &chip->reg_lock; in snd_azf3328_create()
2374 codec_setup->type = AZF_CODEC_PLAYBACK; in snd_azf3328_create()
2375 codec_setup->name = "PLAYBACK"; in snd_azf3328_create()
2377 codec_setup = &chip->codecs[AZF_CODEC_CAPTURE]; in snd_azf3328_create()
2378 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_CAPTURE; in snd_azf3328_create()
2379 codec_setup->lock = &chip->reg_lock; in snd_azf3328_create()
2380 codec_setup->type = AZF_CODEC_CAPTURE; in snd_azf3328_create()
2381 codec_setup->name = "CAPTURE"; in snd_azf3328_create()
2383 codec_setup = &chip->codecs[AZF_CODEC_I2S_OUT]; in snd_azf3328_create()
2384 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_I2S_OUT; in snd_azf3328_create()
2385 codec_setup->lock = &chip->reg_lock; in snd_azf3328_create()
2386 codec_setup->type = AZF_CODEC_I2S_OUT; in snd_azf3328_create()
2387 codec_setup->name = "I2S_OUT"; in snd_azf3328_create()
2389 if (devm_request_irq(&pci->dev, pci->irq, snd_azf3328_interrupt, in snd_azf3328_create()
2391 dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq); in snd_azf3328_create()
2392 return -EBUSY; in snd_azf3328_create()
2394 chip->irq = pci->irq; in snd_azf3328_create()
2395 card->sync_irq = chip->irq; in snd_azf3328_create()
2396 card->private_free = snd_azf3328_free; in snd_azf3328_create()
2413 &chip->codecs[codec_type]; in snd_azf3328_create()
2417 codec->running = true; in snd_azf3328_create()
2420 spin_lock_irq(codec->lock); in snd_azf3328_create()
2423 spin_unlock_irq(codec->lock); in snd_azf3328_create()
2439 return -ENODEV; in __snd_azf3328_probe()
2442 return -ENOENT; in __snd_azf3328_probe()
2445 err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, in __snd_azf3328_probe()
2449 chip = card->private_data; in __snd_azf3328_probe()
2451 strcpy(card->driver, "AZF3328"); in __snd_azf3328_probe()
2452 strcpy(card->shortname, "Aztech AZF3328 (PCI168)"); in __snd_azf3328_probe()
2454 err = snd_azf3328_create(card, pci, pci_id->driver_data); in __snd_azf3328_probe()
2462 MPU401_HW_AZT2320, chip->mpu_io, in __snd_azf3328_probe()
2464 -1, &chip->rmidi in __snd_azf3328_probe()
2467 dev_err(card->dev, "no MPU-401 device at 0x%lx?\n", in __snd_azf3328_probe()
2468 chip->mpu_io in __snd_azf3328_probe()
2481 if (snd_opl3_create(card, chip->opl3_io, chip->opl3_io+2, in __snd_azf3328_probe()
2483 dev_err(card->dev, "no OPL3 device at 0x%lx-0x%lx?\n", in __snd_azf3328_probe()
2484 chip->opl3_io, chip->opl3_io+2 in __snd_azf3328_probe()
2494 opl3->private_data = chip; in __snd_azf3328_probe()
2497 sprintf(card->longname, "%s at 0x%lx, irq %i", in __snd_azf3328_probe()
2498 card->shortname, chip->ctrl_io, chip->irq); in __snd_azf3328_probe()
2505 dev_info(card->dev, in __snd_azf3328_probe()
2506 "Sound driver for Aztech AZF3328-based soundcards such as PCI168.\n"); in __snd_azf3328_probe()
2507 dev_info(card->dev, in __snd_azf3328_probe()
2509 dev_info(card->dev, in __snd_azf3328_probe()
2511 dev_info(card->dev, in __snd_azf3328_probe()
2512 "User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n", in __snd_azf3328_probe()
2526 return snd_card_free_on_error(&pci->dev, __snd_azf3328_probe(pci, pci_id)); in snd_azf3328_probe()
2538 dev_dbg(chip->card->dev, "suspend: io 0x%04lx: 0x%08x\n", in snd_azf3328_suspend_regs()
2556 dev_dbg(chip->card->dev, in snd_azf3328_resume_regs()
2557 "resume: io 0x%04lx: 0x%08x --> 0x%08x\n", in snd_azf3328_resume_regs()
2568 snd_ac97_suspend(chip->ac97); in snd_azf3328_suspend_ac97()
2570 snd_azf3328_suspend_regs(chip, chip->mixer_io, in snd_azf3328_suspend_ac97()
2571 ARRAY_SIZE(chip->saved_regs_mixer), chip->saved_regs_mixer); in snd_azf3328_suspend_ac97()
2583 snd_ac97_resume(chip->ac97); in snd_azf3328_resume_ac97()
2585 snd_azf3328_resume_regs(chip, chip->saved_regs_mixer, chip->mixer_io, in snd_azf3328_resume_ac97()
2586 ARRAY_SIZE(chip->saved_regs_mixer)); in snd_azf3328_resume_ac97()
2592 outw(((u16 *)chip->saved_regs_mixer)[1], chip->mixer_io + 2); in snd_azf3328_resume_ac97()
2600 struct snd_azf3328 *chip = card->private_data; in snd_azf3328_suspend()
2607 snd_azf3328_suspend_regs(chip, chip->ctrl_io, in snd_azf3328_suspend()
2608 ARRAY_SIZE(chip->saved_regs_ctrl), chip->saved_regs_ctrl); in snd_azf3328_suspend()
2610 /* manually store the one currently relevant write-only reg, too */ in snd_azf3328_suspend()
2611 saved_regs_ctrl_u16 = (u16 *)chip->saved_regs_ctrl; in snd_azf3328_suspend()
2612 saved_regs_ctrl_u16[IDX_IO_6AH / 2] = chip->shadow_reg_ctrl_6AH; in snd_azf3328_suspend()
2614 snd_azf3328_suspend_regs(chip, chip->game_io, in snd_azf3328_suspend()
2615 ARRAY_SIZE(chip->saved_regs_game), chip->saved_regs_game); in snd_azf3328_suspend()
2616 snd_azf3328_suspend_regs(chip, chip->mpu_io, in snd_azf3328_suspend()
2617 ARRAY_SIZE(chip->saved_regs_mpu), chip->saved_regs_mpu); in snd_azf3328_suspend()
2618 snd_azf3328_suspend_regs(chip, chip->opl3_io, in snd_azf3328_suspend()
2619 ARRAY_SIZE(chip->saved_regs_opl3), chip->saved_regs_opl3); in snd_azf3328_suspend()
2627 const struct snd_azf3328 *chip = card->private_data; in snd_azf3328_resume()
2629 snd_azf3328_resume_regs(chip, chip->saved_regs_game, chip->game_io, in snd_azf3328_resume()
2630 ARRAY_SIZE(chip->saved_regs_game)); in snd_azf3328_resume()
2631 snd_azf3328_resume_regs(chip, chip->saved_regs_mpu, chip->mpu_io, in snd_azf3328_resume()
2632 ARRAY_SIZE(chip->saved_regs_mpu)); in snd_azf3328_resume()
2633 snd_azf3328_resume_regs(chip, chip->saved_regs_opl3, chip->opl3_io, in snd_azf3328_resume()
2634 ARRAY_SIZE(chip->saved_regs_opl3)); in snd_azf3328_resume()
2638 snd_azf3328_resume_regs(chip, chip->saved_regs_ctrl, chip->ctrl_io, in snd_azf3328_resume()
2639 ARRAY_SIZE(chip->saved_regs_ctrl)); in snd_azf3328_resume()