411 lines · c
1/* SPDX-License-Identifier: GPL-2.0-or-later */2#ifndef __SOUND_YMFPCI_H3#define __SOUND_YMFPCI_H4 5/*6 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>7 * Definitions for Yahama YMF724/740/744/754 chips8 */9 10#include <sound/pcm.h>11#include <sound/rawmidi.h>12#include <sound/ac97_codec.h>13#include <sound/timer.h>14#include <linux/gameport.h>15 16/*17 * Direct registers18 */19 20#define YMFREG(chip, reg) (chip->port + YDSXGR_##reg)21 22#define YDSXGR_INTFLAG 0x000423#define YDSXGR_ACTIVITY 0x000624#define YDSXGR_GLOBALCTRL 0x000825#define YDSXGR_ZVCTRL 0x000A26#define YDSXGR_TIMERCTRL 0x001027#define YDSXGR_TIMERCOUNT 0x001228#define YDSXGR_SPDIFOUTCTRL 0x001829#define YDSXGR_SPDIFOUTSTATUS 0x001C30#define YDSXGR_EEPROMCTRL 0x002031#define YDSXGR_SPDIFINCTRL 0x003432#define YDSXGR_SPDIFINSTATUS 0x003833#define YDSXGR_DSPPROGRAMDL 0x004834#define YDSXGR_DLCNTRL 0x004C35#define YDSXGR_GPIOININTFLAG 0x005036#define YDSXGR_GPIOININTENABLE 0x005237#define YDSXGR_GPIOINSTATUS 0x005438#define YDSXGR_GPIOOUTCTRL 0x005639#define YDSXGR_GPIOFUNCENABLE 0x005840#define YDSXGR_GPIOTYPECONFIG 0x005A41#define YDSXGR_AC97CMDDATA 0x006042#define YDSXGR_AC97CMDADR 0x006243#define YDSXGR_PRISTATUSDATA 0x006444#define YDSXGR_PRISTATUSADR 0x006645#define YDSXGR_SECSTATUSDATA 0x006846#define YDSXGR_SECSTATUSADR 0x006A47#define YDSXGR_SECCONFIG 0x007048#define YDSXGR_LEGACYOUTVOL 0x008049#define YDSXGR_LEGACYOUTVOLL 0x008050#define YDSXGR_LEGACYOUTVOLR 0x008251#define YDSXGR_NATIVEDACOUTVOL 0x008452#define YDSXGR_NATIVEDACOUTVOLL 0x008453#define YDSXGR_NATIVEDACOUTVOLR 0x008654#define YDSXGR_ZVOUTVOL 0x008855#define YDSXGR_ZVOUTVOLL 0x008856#define YDSXGR_ZVOUTVOLR 0x008A57#define YDSXGR_SECADCOUTVOL 0x008C58#define YDSXGR_SECADCOUTVOLL 0x008C59#define YDSXGR_SECADCOUTVOLR 0x008E60#define YDSXGR_PRIADCOUTVOL 0x009061#define YDSXGR_PRIADCOUTVOLL 0x009062#define YDSXGR_PRIADCOUTVOLR 0x009263#define YDSXGR_LEGACYLOOPVOL 0x009464#define YDSXGR_LEGACYLOOPVOLL 0x009465#define YDSXGR_LEGACYLOOPVOLR 0x009666#define YDSXGR_NATIVEDACLOOPVOL 0x009867#define YDSXGR_NATIVEDACLOOPVOLL 0x009868#define YDSXGR_NATIVEDACLOOPVOLR 0x009A69#define YDSXGR_ZVLOOPVOL 0x009C70#define YDSXGR_ZVLOOPVOLL 0x009E71#define YDSXGR_ZVLOOPVOLR 0x009E72#define YDSXGR_SECADCLOOPVOL 0x00A073#define YDSXGR_SECADCLOOPVOLL 0x00A074#define YDSXGR_SECADCLOOPVOLR 0x00A275#define YDSXGR_PRIADCLOOPVOL 0x00A476#define YDSXGR_PRIADCLOOPVOLL 0x00A477#define YDSXGR_PRIADCLOOPVOLR 0x00A678#define YDSXGR_NATIVEADCINVOL 0x00A879#define YDSXGR_NATIVEADCINVOLL 0x00A880#define YDSXGR_NATIVEADCINVOLR 0x00AA81#define YDSXGR_NATIVEDACINVOL 0x00AC82#define YDSXGR_NATIVEDACINVOLL 0x00AC83#define YDSXGR_NATIVEDACINVOLR 0x00AE84#define YDSXGR_BUF441OUTVOL 0x00B085#define YDSXGR_BUF441OUTVOLL 0x00B086#define YDSXGR_BUF441OUTVOLR 0x00B287#define YDSXGR_BUF441LOOPVOL 0x00B488#define YDSXGR_BUF441LOOPVOLL 0x00B489#define YDSXGR_BUF441LOOPVOLR 0x00B690#define YDSXGR_SPDIFOUTVOL 0x00B891#define YDSXGR_SPDIFOUTVOLL 0x00B892#define YDSXGR_SPDIFOUTVOLR 0x00BA93#define YDSXGR_SPDIFLOOPVOL 0x00BC94#define YDSXGR_SPDIFLOOPVOLL 0x00BC95#define YDSXGR_SPDIFLOOPVOLR 0x00BE96#define YDSXGR_ADCSLOTSR 0x00C097#define YDSXGR_RECSLOTSR 0x00C498#define YDSXGR_ADCFORMAT 0x00C899#define YDSXGR_RECFORMAT 0x00CC100#define YDSXGR_P44SLOTSR 0x00D0101#define YDSXGR_STATUS 0x0100102#define YDSXGR_CTRLSELECT 0x0104103#define YDSXGR_MODE 0x0108104#define YDSXGR_SAMPLECOUNT 0x010C105#define YDSXGR_NUMOFSAMPLES 0x0110106#define YDSXGR_CONFIG 0x0114107#define YDSXGR_PLAYCTRLSIZE 0x0140108#define YDSXGR_RECCTRLSIZE 0x0144109#define YDSXGR_EFFCTRLSIZE 0x0148110#define YDSXGR_WORKSIZE 0x014C111#define YDSXGR_MAPOFREC 0x0150112#define YDSXGR_MAPOFEFFECT 0x0154113#define YDSXGR_PLAYCTRLBASE 0x0158114#define YDSXGR_RECCTRLBASE 0x015C115#define YDSXGR_EFFCTRLBASE 0x0160116#define YDSXGR_WORKBASE 0x0164117#define YDSXGR_DSPINSTRAM 0x1000118#define YDSXGR_CTRLINSTRAM 0x4000119 120#define YDSXG_AC97READCMD 0x8000121#define YDSXG_AC97WRITECMD 0x0000122 123#define PCIR_DSXG_LEGACY 0x40124#define PCIR_DSXG_ELEGACY 0x42125#define PCIR_DSXG_CTRL 0x48126#define PCIR_DSXG_PWRCTRL1 0x4a127#define PCIR_DSXG_PWRCTRL2 0x4e128#define PCIR_DSXG_FMBASE 0x60129#define PCIR_DSXG_SBBASE 0x62130#define PCIR_DSXG_MPU401BASE 0x64131#define PCIR_DSXG_JOYBASE 0x66132 133#define YDSXG_DSPLENGTH 0x0080134#define YDSXG_CTRLLENGTH 0x3000135 136#define YDSXG_DEFAULT_WORK_SIZE 0x0400137 138#define YDSXG_PLAYBACK_VOICES 64139#define YDSXG_CAPTURE_VOICES 2140#define YDSXG_EFFECT_VOICES 5141 142#define YMFPCI_LEGACY_SBEN (1 << 0) /* soundblaster enable */143#define YMFPCI_LEGACY_FMEN (1 << 1) /* OPL3 enable */144#define YMFPCI_LEGACY_JPEN (1 << 2) /* joystick enable */145#define YMFPCI_LEGACY_MEN (1 << 3) /* MPU401 enable */146#define YMFPCI_LEGACY_MIEN (1 << 4) /* MPU RX irq enable */147#define YMFPCI_LEGACY_IOBITS (1 << 5) /* i/o bits range, 0 = 16bit, 1 =10bit */148#define YMFPCI_LEGACY_SDMA (3 << 6) /* SB DMA select */149#define YMFPCI_LEGACY_SBIRQ (7 << 8) /* SB IRQ select */150#define YMFPCI_LEGACY_MPUIRQ (7 << 11) /* MPU IRQ select */151#define YMFPCI_LEGACY_SIEN (1 << 14) /* serialized IRQ */152#define YMFPCI_LEGACY_LAD (1 << 15) /* legacy audio disable */153 154#define YMFPCI_LEGACY2_FMIO (3 << 0) /* OPL3 i/o address (724/740) */155#define YMFPCI_LEGACY2_SBIO (3 << 2) /* SB i/o address (724/740) */156#define YMFPCI_LEGACY2_MPUIO (3 << 4) /* MPU401 i/o address (724/740) */157#define YMFPCI_LEGACY2_JSIO (3 << 6) /* joystick i/o address (724/740) */158#define YMFPCI_LEGACY2_MAIM (1 << 8) /* MPU401 ack intr mask */159#define YMFPCI_LEGACY2_SMOD (3 << 11) /* SB DMA mode */160#define YMFPCI_LEGACY2_SBVER (3 << 13) /* SB version select */161#define YMFPCI_LEGACY2_IMOD (1 << 15) /* legacy IRQ mode */162/* SIEN:IMOD 0:0 = legacy irq, 0:1 = INTA, 1:0 = serialized IRQ */163 164#if IS_REACHABLE(CONFIG_GAMEPORT)165#define SUPPORT_JOYSTICK166#endif167 168/*169 *170 */171 172struct snd_ymfpci_playback_bank {173 __le32 format;174 __le32 loop_default;175 __le32 base; /* 32-bit address */176 __le32 loop_start; /* 32-bit offset */177 __le32 loop_end; /* 32-bit offset */178 __le32 loop_frac; /* 8-bit fraction - loop_start */179 __le32 delta_end; /* pitch delta end */180 __le32 lpfK_end;181 __le32 eg_gain_end;182 __le32 left_gain_end;183 __le32 right_gain_end;184 __le32 eff1_gain_end;185 __le32 eff2_gain_end;186 __le32 eff3_gain_end;187 __le32 lpfQ;188 __le32 status;189 __le32 num_of_frames;190 __le32 loop_count;191 __le32 start;192 __le32 start_frac;193 __le32 delta;194 __le32 lpfK;195 __le32 eg_gain;196 __le32 left_gain;197 __le32 right_gain;198 __le32 eff1_gain;199 __le32 eff2_gain;200 __le32 eff3_gain;201 __le32 lpfD1;202 __le32 lpfD2;203 };204 205struct snd_ymfpci_capture_bank {206 __le32 base; /* 32-bit address */207 __le32 loop_end; /* 32-bit offset */208 __le32 start; /* 32-bit offset */209 __le32 num_of_loops; /* counter */210};211 212struct snd_ymfpci_effect_bank {213 __le32 base; /* 32-bit address */214 __le32 loop_end; /* 32-bit offset */215 __le32 start; /* 32-bit offset */216 __le32 temp;217};218 219struct snd_ymfpci_pcm;220struct snd_ymfpci;221 222enum snd_ymfpci_voice_type {223 YMFPCI_PCM,224 YMFPCI_SYNTH,225 YMFPCI_MIDI226};227 228struct snd_ymfpci_voice {229 struct snd_ymfpci *chip;230 int number;231 unsigned int use: 1,232 pcm: 1,233 synth: 1,234 midi: 1;235 struct snd_ymfpci_playback_bank *bank;236 dma_addr_t bank_addr;237 void (*interrupt)(struct snd_ymfpci *chip, struct snd_ymfpci_voice *voice);238 struct snd_ymfpci_pcm *ypcm;239};240 241enum snd_ymfpci_pcm_type {242 PLAYBACK_VOICE,243 CAPTURE_REC,244 CAPTURE_AC97,245 EFFECT_DRY_LEFT,246 EFFECT_DRY_RIGHT,247 EFFECT_EFF1,248 EFFECT_EFF2,249 EFFECT_EFF3250};251 252struct snd_ymfpci_pcm {253 struct snd_ymfpci *chip;254 enum snd_ymfpci_pcm_type type;255 struct snd_pcm_substream *substream;256 struct snd_ymfpci_voice *voices[2]; /* playback only */257 unsigned int running: 1,258 use_441_slot: 1,259 output_front: 1,260 output_rear: 1,261 swap_rear: 1;262 unsigned int update_pcm_vol;263 u32 period_size; /* cached from runtime->period_size */264 u32 buffer_size; /* cached from runtime->buffer_size */265 u32 period_pos;266 u32 last_pos;267 u32 capture_bank_number;268 u32 shift;269};270 271static const int saved_regs_index[] = {272 /* spdif */273 YDSXGR_SPDIFOUTCTRL,274 YDSXGR_SPDIFOUTSTATUS,275 YDSXGR_SPDIFINCTRL,276 /* volumes */277 YDSXGR_PRIADCLOOPVOL,278 YDSXGR_NATIVEDACINVOL,279 YDSXGR_NATIVEDACOUTVOL,280 YDSXGR_BUF441OUTVOL,281 YDSXGR_NATIVEADCINVOL,282 YDSXGR_SPDIFLOOPVOL,283 YDSXGR_SPDIFOUTVOL,284 YDSXGR_ZVOUTVOL,285 YDSXGR_LEGACYOUTVOL,286 /* address bases */287 YDSXGR_PLAYCTRLBASE,288 YDSXGR_RECCTRLBASE,289 YDSXGR_EFFCTRLBASE,290 YDSXGR_WORKBASE,291 /* capture set up */292 YDSXGR_MAPOFREC,293 YDSXGR_RECFORMAT,294 YDSXGR_RECSLOTSR,295 YDSXGR_ADCFORMAT,296 YDSXGR_ADCSLOTSR,297};298#define YDSXGR_NUM_SAVED_REGS ARRAY_SIZE(saved_regs_index)299 300static const int pci_saved_regs_index[] = {301 /* All Chips */302 PCIR_DSXG_LEGACY,303 PCIR_DSXG_ELEGACY,304 /* YMF 744/754 */305 PCIR_DSXG_FMBASE,306 PCIR_DSXG_SBBASE,307 PCIR_DSXG_MPU401BASE,308 PCIR_DSXG_JOYBASE,309};310#define DSXG_PCI_NUM_SAVED_REGS ARRAY_SIZE(pci_saved_regs_index)311#define DSXG_PCI_NUM_SAVED_LEGACY_REGS 2312static_assert(DSXG_PCI_NUM_SAVED_LEGACY_REGS <= DSXG_PCI_NUM_SAVED_REGS);313 314struct snd_ymfpci {315 int irq;316 317 unsigned int device_id; /* PCI device ID */318 unsigned char rev; /* PCI revision */319 unsigned long reg_area_phys;320 void __iomem *reg_area_virt;321 322 u16 old_legacy_ctrl;323#ifdef SUPPORT_JOYSTICK324 struct gameport *gameport;325#endif326 327 struct snd_dma_buffer *work_ptr;328 329 unsigned int bank_size_playback;330 unsigned int bank_size_capture;331 unsigned int bank_size_effect;332 unsigned int work_size;333 334 void *bank_base_playback;335 void *bank_base_capture;336 void *bank_base_effect;337 void *work_base;338 dma_addr_t bank_base_playback_addr;339 dma_addr_t bank_base_capture_addr;340 dma_addr_t bank_base_effect_addr;341 dma_addr_t work_base_addr;342 struct snd_dma_buffer ac3_tmp_base;343 344 __le32 *ctrl_playback;345 struct snd_ymfpci_playback_bank *bank_playback[YDSXG_PLAYBACK_VOICES][2];346 struct snd_ymfpci_capture_bank *bank_capture[YDSXG_CAPTURE_VOICES][2];347 struct snd_ymfpci_effect_bank *bank_effect[YDSXG_EFFECT_VOICES][2];348 349 int start_count;350 351 u32 active_bank;352 struct snd_ymfpci_voice voices[64];353 int src441_used;354 355 struct snd_ac97_bus *ac97_bus;356 struct snd_ac97 *ac97;357 struct snd_rawmidi *rawmidi;358 struct snd_timer *timer;359 unsigned int timer_ticks;360 361 struct pci_dev *pci;362 struct snd_card *card;363 struct snd_pcm *pcm;364 struct snd_pcm *pcm2;365 struct snd_pcm *pcm_spdif;366 struct snd_pcm *pcm_4ch;367 struct snd_pcm_substream *capture_substream[YDSXG_CAPTURE_VOICES];368 struct snd_pcm_substream *effect_substream[YDSXG_EFFECT_VOICES];369 struct snd_kcontrol *ctl_vol_recsrc;370 struct snd_kcontrol *ctl_vol_adcrec;371 struct snd_kcontrol *ctl_vol_spdifrec;372 unsigned short spdif_bits, spdif_pcm_bits;373 struct snd_kcontrol *spdif_pcm_ctl;374 int mode_dup4ch;375 int rear_opened;376 int spdif_opened;377 struct snd_ymfpci_pcm_mixer {378 u16 left;379 u16 right;380 struct snd_kcontrol *ctl;381 } pcm_mixer[32];382 383 spinlock_t reg_lock;384 spinlock_t voice_lock;385 wait_queue_head_t interrupt_sleep;386 atomic_t interrupt_sleep_count;387 struct snd_info_entry *proc_entry;388 const struct firmware *dsp_microcode;389 const struct firmware *controller_microcode;390 391 u32 saved_regs[YDSXGR_NUM_SAVED_REGS];392 u32 saved_ydsxgr_mode;393 u16 saved_dsxg_pci_regs[DSXG_PCI_NUM_SAVED_REGS];394};395 396int snd_ymfpci_create(struct snd_card *card,397 struct pci_dev *pci,398 u16 old_legacy_ctrl);399void snd_ymfpci_free_gameport(struct snd_ymfpci *chip);400 401extern const struct dev_pm_ops snd_ymfpci_pm;402 403int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device);404int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device);405int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device);406int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device);407int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch);408int snd_ymfpci_timer(struct snd_ymfpci *chip, int device);409 410#endif /* __SOUND_YMFPCI_H */411