^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Driver EMU10K1X chips
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Parts of this code were adapted from audigyls.c driver which is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * BUGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * --
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * TODO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Chips (SB0200 model):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * - EMU10K1X-DBQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * - STAC 9708T
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <sound/ac97_codec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <sound/info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <sound/rawmidi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) MODULE_AUTHOR("Francisco Moraes <fmoraes@nc.rr.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) MODULE_DESCRIPTION("EMU10K1X");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) MODULE_SUPPORTED_DEVICE("{{Dell Creative Labs,SB Live!}");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) // module parameters (see "Module Parameters")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) module_param_array(index, int, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) MODULE_PARM_DESC(index, "Index value for the EMU10K1X soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) module_param_array(id, charp, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) MODULE_PARM_DESC(id, "ID string for the EMU10K1X soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) module_param_array(enable, bool, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) MODULE_PARM_DESC(enable, "Enable the EMU10K1X soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) // some definitions were borrowed from emu10k1 driver as they seem to be the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /************************************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* PCI function 0 registers, address = <val> + PCIBASE0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /************************************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define PTR 0x00 /* Indexed register set pointer register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* NOTE: The CHANNELNUM and ADDRESS words can */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /* be modified independently of each other. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define DATA 0x04 /* Indexed register set data register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define IPR 0x08 /* Global interrupt pending register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* Clear pending interrupts by writing a 1 to */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* the relevant bits and zero to the other bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define IPR_MIDITRANSBUFEMPTY 0x00000001 /* MIDI UART transmit buffer empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define IPR_MIDIRECVBUFEMPTY 0x00000002 /* MIDI UART receive buffer empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define IPR_CH_0_LOOP 0x00000800 /* Channel 0 loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define IPR_CH_0_HALF_LOOP 0x00000100 /* Channel 0 half loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define IPR_CAP_0_LOOP 0x00080000 /* Channel capture loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define IPR_CAP_0_HALF_LOOP 0x00010000 /* Channel capture half loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define INTE 0x0c /* Interrupt enable register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define INTE_MIDITXENABLE 0x00000001 /* Enable MIDI transmit-buffer-empty interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define INTE_MIDIRXENABLE 0x00000002 /* Enable MIDI receive-buffer-empty interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define INTE_CH_0_LOOP 0x00000800 /* Channel 0 loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define INTE_CH_0_HALF_LOOP 0x00000100 /* Channel 0 half loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define INTE_CAP_0_LOOP 0x00080000 /* Channel capture loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define INTE_CAP_0_HALF_LOOP 0x00010000 /* Channel capture half loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define HCFG 0x14 /* Hardware config register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define HCFG_LOCKSOUNDCACHE 0x00000008 /* 1 = Cancel bustmaster accesses to soundcache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* NOTE: This should generally never be used. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define HCFG_AUDIOENABLE 0x00000001 /* 0 = CODECs transmit zero-valued samples */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* Should be set to 1 when the EMU10K1 is */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* completely initialized. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define GPIO 0x18 /* Defaults: 00001080-Analog, 00001000-SPDIF. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define AC97DATA 0x1c /* AC97 register set data register (16 bit) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define AC97ADDRESS 0x1e /* AC97 register set address register (8 bit) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /********************************************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* Emu10k1x pointer-offset register set, accessed through the PTR and DATA registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /********************************************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define PLAYBACK_LIST_ADDR 0x00 /* Base DMA address of a list of pointers to each period/size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* One list entry: 4 bytes for DMA address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * 4 bytes for period_size << 16.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * One list entry is 8 bytes long.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * One list entry for each period in the buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define PLAYBACK_LIST_SIZE 0x01 /* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define PLAYBACK_POINTER 0x06 /* Playback period pointer. Sample currently in DAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define PLAYBACK_UNKNOWN1 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define PLAYBACK_UNKNOWN2 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /* Only one capture channel supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define CAPTURE_DMA_ADDR 0x10 /* Capture DMA address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define CAPTURE_BUFFER_SIZE 0x11 /* Capture buffer size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define CAPTURE_POINTER 0x12 /* Capture buffer pointer. Sample currently in ADC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define CAPTURE_UNKNOWN 0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /* From 0x20 - 0x3f, last samples played on each channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define TRIGGER_CHANNEL 0x40 /* Trigger channel playback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define TRIGGER_CHANNEL_0 0x00000001 /* Trigger channel 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define TRIGGER_CHANNEL_1 0x00000002 /* Trigger channel 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define TRIGGER_CHANNEL_2 0x00000004 /* Trigger channel 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define TRIGGER_CAPTURE 0x00000100 /* Trigger capture channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define ROUTING 0x41 /* Setup sound routing ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define ROUTING_FRONT_LEFT 0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define ROUTING_FRONT_RIGHT 0x00000002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define ROUTING_REAR_LEFT 0x00000004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define ROUTING_REAR_RIGHT 0x00000008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define ROUTING_CENTER_LFE 0x00010000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define SPCS0 0x42 /* SPDIF output Channel Status 0 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define SPCS1 0x43 /* SPDIF output Channel Status 1 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define SPCS2 0x44 /* SPDIF output Channel Status 2 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define SPCS_CLKACCYMASK 0x30000000 /* Clock accuracy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define SPCS_CLKACCY_1000PPM 0x00000000 /* 1000 parts per million */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define SPCS_CLKACCY_50PPM 0x10000000 /* 50 parts per million */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define SPCS_CLKACCY_VARIABLE 0x20000000 /* Variable accuracy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define SPCS_SAMPLERATEMASK 0x0f000000 /* Sample rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define SPCS_SAMPLERATE_44 0x00000000 /* 44.1kHz sample rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define SPCS_SAMPLERATE_48 0x02000000 /* 48kHz sample rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define SPCS_SAMPLERATE_32 0x03000000 /* 32kHz sample rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define SPCS_CHANNELNUMMASK 0x00f00000 /* Channel number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define SPCS_CHANNELNUM_UNSPEC 0x00000000 /* Unspecified channel number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define SPCS_CHANNELNUM_LEFT 0x00100000 /* Left channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define SPCS_CHANNELNUM_RIGHT 0x00200000 /* Right channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define SPCS_SOURCENUMMASK 0x000f0000 /* Source number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define SPCS_SOURCENUM_UNSPEC 0x00000000 /* Unspecified source number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define SPCS_GENERATIONSTATUS 0x00008000 /* Originality flag (see IEC-958 spec) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define SPCS_CATEGORYCODEMASK 0x00007f00 /* Category code (see IEC-958 spec) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define SPCS_MODEMASK 0x000000c0 /* Mode (see IEC-958 spec) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define SPCS_EMPHASISMASK 0x00000038 /* Emphasis */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define SPCS_EMPHASIS_NONE 0x00000000 /* No emphasis */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define SPCS_EMPHASIS_50_15 0x00000008 /* 50/15 usec 2 channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define SPCS_COPYRIGHT 0x00000004 /* Copyright asserted flag -- do not modify */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define SPCS_NOTAUDIODATA 0x00000002 /* 0 = Digital audio, 1 = not audio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define SPCS_PROFESSIONAL 0x00000001 /* 0 = Consumer (IEC-958), 1 = pro (AES3-1992) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #define SPDIF_SELECT 0x45 /* Enables SPDIF or Analogue outputs 0-Analogue, 0x700-SPDIF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /* This is the MPU port on the card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define MUDATA 0x47
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define MUCMD 0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define MUSTAT MUCMD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* From 0x50 - 0x5f, last samples captured */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * The hardware has 3 channels for playback and 1 for capture.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * - channel 0 is the front channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * - channel 1 is the rear channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * - channel 2 is the center/lfe channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * Volume is controlled by the AC97 for the front and rear channels by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * the PCM Playback Volume, Sigmatel Surround Playback Volume and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * Surround Playback Volume. The Sigmatel 4-Speaker Stereo switch affects
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * the front/rear channel mixing in the REAR OUT jack. When using the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * 4-Speaker Stereo, both front and rear channels will be mixed in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * REAR OUT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * The center/lfe channel has no volume control and cannot be muted during
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * playback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct emu10k1x_voice {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct emu10k1x *emu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) int number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) int use;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct emu10k1x_pcm *epcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) struct emu10k1x_pcm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) struct emu10k1x *emu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct snd_pcm_substream *substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct emu10k1x_voice *voice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) unsigned short running;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct emu10k1x_midi {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct emu10k1x *emu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct snd_rawmidi *rmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct snd_rawmidi_substream *substream_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct snd_rawmidi_substream *substream_output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) unsigned int midi_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) spinlock_t input_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) spinlock_t output_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) spinlock_t open_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int tx_enable, rx_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) int ipr_tx, ipr_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) void (*interrupt)(struct emu10k1x *emu, unsigned int status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) // definition of the chip-specific record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct emu10k1x {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct pci_dev *pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) unsigned long port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct resource *res_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) unsigned char revision; /* chip revision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) unsigned int serial; /* serial number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) unsigned short model; /* subsystem id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) spinlock_t emu_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) spinlock_t voice_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct snd_ac97 *ac97;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct emu10k1x_voice voices[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct emu10k1x_voice capture_voice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) u32 spdif_bits[3]; // SPDIF out setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct snd_dma_buffer dma_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct emu10k1x_midi midi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /* hardware definition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static const struct snd_pcm_hardware snd_emu10k1x_playback_hw = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) .info = (SNDRV_PCM_INFO_MMAP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) SNDRV_PCM_INFO_BLOCK_TRANSFER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) SNDRV_PCM_INFO_MMAP_VALID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) .formats = SNDRV_PCM_FMTBIT_S16_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) .rates = SNDRV_PCM_RATE_48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) .rate_min = 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) .rate_max = 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) .channels_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) .buffer_bytes_max = (32*1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) .period_bytes_min = 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) .period_bytes_max = (16*1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) .periods_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) .periods_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) .fifo_size = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static const struct snd_pcm_hardware snd_emu10k1x_capture_hw = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) .info = (SNDRV_PCM_INFO_MMAP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) SNDRV_PCM_INFO_BLOCK_TRANSFER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) SNDRV_PCM_INFO_MMAP_VALID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) .formats = SNDRV_PCM_FMTBIT_S16_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) .rates = SNDRV_PCM_RATE_48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) .rate_min = 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) .rate_max = 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) .channels_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) .buffer_bytes_max = (32*1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) .period_bytes_min = 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) .period_bytes_max = (16*1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) .periods_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) .periods_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) .fifo_size = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static unsigned int snd_emu10k1x_ptr_read(struct emu10k1x * emu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) unsigned int chn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) unsigned int regptr, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) regptr = (reg << 16) | chn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) spin_lock_irqsave(&emu->emu_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) outl(regptr, emu->port + PTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) val = inl(emu->port + DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) spin_unlock_irqrestore(&emu->emu_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static void snd_emu10k1x_ptr_write(struct emu10k1x *emu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) unsigned int chn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) unsigned int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) unsigned int regptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) regptr = (reg << 16) | chn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) spin_lock_irqsave(&emu->emu_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) outl(regptr, emu->port + PTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) outl(data, emu->port + DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) spin_unlock_irqrestore(&emu->emu_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) static void snd_emu10k1x_intr_enable(struct emu10k1x *emu, unsigned int intrenb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) unsigned int intr_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) spin_lock_irqsave(&emu->emu_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) intr_enable = inl(emu->port + INTE) | intrenb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) outl(intr_enable, emu->port + INTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) spin_unlock_irqrestore(&emu->emu_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static void snd_emu10k1x_intr_disable(struct emu10k1x *emu, unsigned int intrenb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) unsigned int intr_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) spin_lock_irqsave(&emu->emu_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) intr_enable = inl(emu->port + INTE) & ~intrenb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) outl(intr_enable, emu->port + INTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) spin_unlock_irqrestore(&emu->emu_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) static void snd_emu10k1x_gpio_write(struct emu10k1x *emu, unsigned int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) spin_lock_irqsave(&emu->emu_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) outl(value, emu->port + GPIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) spin_unlock_irqrestore(&emu->emu_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static void snd_emu10k1x_pcm_free_substream(struct snd_pcm_runtime *runtime)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) kfree(runtime->private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) static void snd_emu10k1x_pcm_interrupt(struct emu10k1x *emu, struct emu10k1x_voice *voice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) struct emu10k1x_pcm *epcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if ((epcm = voice->epcm) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (epcm->substream == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) dev_info(emu->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) "IRQ: position = 0x%x, period = 0x%x, size = 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) epcm->substream->ops->pointer(epcm->substream),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) snd_pcm_lib_period_bytes(epcm->substream),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) snd_pcm_lib_buffer_bytes(epcm->substream));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) snd_pcm_period_elapsed(epcm->substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /* open callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) static int snd_emu10k1x_playback_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) struct emu10k1x *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct emu10k1x_pcm *epcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (epcm == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) epcm->emu = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) epcm->substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) runtime->private_data = epcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) runtime->private_free = snd_emu10k1x_pcm_free_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) runtime->hw = snd_emu10k1x_playback_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /* close callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static int snd_emu10k1x_playback_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) /* hw_params callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) static int snd_emu10k1x_pcm_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) struct snd_pcm_hw_params *hw_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct emu10k1x_pcm *epcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (! epcm->voice) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) epcm->voice = &epcm->emu->voices[substream->pcm->device];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) epcm->voice->use = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) epcm->voice->epcm = epcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /* hw_free callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) static int snd_emu10k1x_pcm_hw_free(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) struct emu10k1x_pcm *epcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (runtime->private_data == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) epcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (epcm->voice) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) epcm->voice->use = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) epcm->voice->epcm = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) epcm->voice = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) /* prepare callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) static int snd_emu10k1x_pcm_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct emu10k1x *emu = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct emu10k1x_pcm *epcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) int voice = epcm->voice->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) u32 *table_base = (u32 *)(emu->dma_buffer.area+1024*voice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) for(i = 0; i < runtime->periods; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) *table_base++=runtime->dma_addr+(i*period_size_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) *table_base++=period_size_bytes<<16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_ADDR, voice, emu->dma_buffer.addr+1024*voice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_SIZE, voice, (runtime->periods - 1) << 19);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_PTR, voice, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) snd_emu10k1x_ptr_write(emu, PLAYBACK_POINTER, voice, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) snd_emu10k1x_ptr_write(emu, PLAYBACK_UNKNOWN1, voice, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) snd_emu10k1x_ptr_write(emu, PLAYBACK_UNKNOWN2, voice, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) snd_emu10k1x_ptr_write(emu, PLAYBACK_DMA_ADDR, voice, runtime->dma_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) snd_emu10k1x_ptr_write(emu, PLAYBACK_PERIOD_SIZE, voice, frames_to_bytes(runtime, runtime->period_size)<<16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) /* trigger callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) static int snd_emu10k1x_pcm_trigger(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) struct emu10k1x *emu = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct emu10k1x_pcm *epcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) int channel = epcm->voice->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) dev_dbg(emu->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) "trigger - emu10k1x = 0x%x, cmd = %i, pointer = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) (int)emu, cmd, (int)substream->ops->pointer(substream));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if(runtime->periods == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) snd_emu10k1x_intr_enable(emu, (INTE_CH_0_LOOP | INTE_CH_0_HALF_LOOP) << channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) snd_emu10k1x_intr_enable(emu, INTE_CH_0_LOOP << channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) epcm->running = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0)|(TRIGGER_CHANNEL_0<<channel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) epcm->running = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) snd_emu10k1x_intr_disable(emu, (INTE_CH_0_LOOP | INTE_CH_0_HALF_LOOP) << channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0) & ~(TRIGGER_CHANNEL_0<<channel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) result = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /* pointer callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) static snd_pcm_uframes_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) snd_emu10k1x_pcm_pointer(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) struct emu10k1x *emu = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) struct emu10k1x_pcm *epcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) int channel = epcm->voice->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) snd_pcm_uframes_t ptr = 0, ptr1 = 0, ptr2= 0,ptr3 = 0,ptr4 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (!epcm->running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) ptr3 = snd_emu10k1x_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) ptr1 = snd_emu10k1x_ptr_read(emu, PLAYBACK_POINTER, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) ptr4 = snd_emu10k1x_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if(ptr4 == 0 && ptr1 == frames_to_bytes(runtime, runtime->buffer_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (ptr3 != ptr4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) ptr1 = snd_emu10k1x_ptr_read(emu, PLAYBACK_POINTER, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) ptr2 = bytes_to_frames(runtime, ptr1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) ptr2 += (ptr4 >> 3) * runtime->period_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) ptr = ptr2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (ptr >= runtime->buffer_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) ptr -= runtime->buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /* operators */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static const struct snd_pcm_ops snd_emu10k1x_playback_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) .open = snd_emu10k1x_playback_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) .close = snd_emu10k1x_playback_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) .hw_params = snd_emu10k1x_pcm_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) .hw_free = snd_emu10k1x_pcm_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) .prepare = snd_emu10k1x_pcm_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) .trigger = snd_emu10k1x_pcm_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) .pointer = snd_emu10k1x_pcm_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) /* open_capture callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) static int snd_emu10k1x_pcm_open_capture(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) struct emu10k1x *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) struct emu10k1x_pcm *epcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (epcm == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) epcm->emu = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) epcm->substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) runtime->private_data = epcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) runtime->private_free = snd_emu10k1x_pcm_free_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) runtime->hw = snd_emu10k1x_capture_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) /* close callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) static int snd_emu10k1x_pcm_close_capture(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) /* hw_params callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) static int snd_emu10k1x_pcm_hw_params_capture(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) struct snd_pcm_hw_params *hw_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct emu10k1x_pcm *epcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (! epcm->voice) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (epcm->emu->capture_voice.use)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) epcm->voice = &epcm->emu->capture_voice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) epcm->voice->epcm = epcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) epcm->voice->use = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) /* hw_free callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) static int snd_emu10k1x_pcm_hw_free_capture(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) struct emu10k1x_pcm *epcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (runtime->private_data == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) epcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (epcm->voice) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) epcm->voice->use = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) epcm->voice->epcm = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) epcm->voice = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) /* prepare capture callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) static int snd_emu10k1x_pcm_prepare_capture(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) struct emu10k1x *emu = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) snd_emu10k1x_ptr_write(emu, CAPTURE_DMA_ADDR, 0, runtime->dma_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) snd_emu10k1x_ptr_write(emu, CAPTURE_BUFFER_SIZE, 0, frames_to_bytes(runtime, runtime->buffer_size)<<16); // buffer size in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) snd_emu10k1x_ptr_write(emu, CAPTURE_POINTER, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) snd_emu10k1x_ptr_write(emu, CAPTURE_UNKNOWN, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) /* trigger_capture callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) static int snd_emu10k1x_pcm_trigger_capture(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) struct emu10k1x *emu = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) struct emu10k1x_pcm *epcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) snd_emu10k1x_intr_enable(emu, INTE_CAP_0_LOOP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) INTE_CAP_0_HALF_LOOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0)|TRIGGER_CAPTURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) epcm->running = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) epcm->running = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) snd_emu10k1x_intr_disable(emu, INTE_CAP_0_LOOP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) INTE_CAP_0_HALF_LOOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0) & ~(TRIGGER_CAPTURE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) result = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) /* pointer_capture callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) static snd_pcm_uframes_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) snd_emu10k1x_pcm_pointer_capture(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) struct emu10k1x *emu = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) struct emu10k1x_pcm *epcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) snd_pcm_uframes_t ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (!epcm->running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) ptr = bytes_to_frames(runtime, snd_emu10k1x_ptr_read(emu, CAPTURE_POINTER, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (ptr >= runtime->buffer_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) ptr -= runtime->buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) static const struct snd_pcm_ops snd_emu10k1x_capture_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) .open = snd_emu10k1x_pcm_open_capture,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) .close = snd_emu10k1x_pcm_close_capture,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) .hw_params = snd_emu10k1x_pcm_hw_params_capture,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) .hw_free = snd_emu10k1x_pcm_hw_free_capture,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) .prepare = snd_emu10k1x_pcm_prepare_capture,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) .trigger = snd_emu10k1x_pcm_trigger_capture,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) .pointer = snd_emu10k1x_pcm_pointer_capture,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) static unsigned short snd_emu10k1x_ac97_read(struct snd_ac97 *ac97,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) unsigned short reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct emu10k1x *emu = ac97->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) unsigned short val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) spin_lock_irqsave(&emu->emu_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) outb(reg, emu->port + AC97ADDRESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) val = inw(emu->port + AC97DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) spin_unlock_irqrestore(&emu->emu_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) static void snd_emu10k1x_ac97_write(struct snd_ac97 *ac97,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) unsigned short reg, unsigned short val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) struct emu10k1x *emu = ac97->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) spin_lock_irqsave(&emu->emu_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) outb(reg, emu->port + AC97ADDRESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) outw(val, emu->port + AC97DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) spin_unlock_irqrestore(&emu->emu_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) static int snd_emu10k1x_ac97(struct emu10k1x *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) struct snd_ac97_bus *pbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) struct snd_ac97_template ac97;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) static const struct snd_ac97_bus_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) .write = snd_emu10k1x_ac97_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) .read = snd_emu10k1x_ac97_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) pbus->no_vra = 1; /* we don't need VRA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) memset(&ac97, 0, sizeof(ac97));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) ac97.private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) ac97.scaps = AC97_SCAP_NO_SPDIF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) return snd_ac97_mixer(pbus, &ac97, &chip->ac97);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) static int snd_emu10k1x_free(struct emu10k1x *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) snd_emu10k1x_ptr_write(chip, TRIGGER_CHANNEL, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) // disable interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) outl(0, chip->port + INTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) // disable audio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) /* release the irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (chip->irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) free_irq(chip->irq, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) // release the i/o port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) release_and_free_resource(chip->res_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) // release the DMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (chip->dma_buffer.area) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) snd_dma_free_pages(&chip->dma_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) pci_disable_device(chip->pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) // release the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) kfree(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) static int snd_emu10k1x_dev_free(struct snd_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) struct emu10k1x *chip = device->device_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) return snd_emu10k1x_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) static irqreturn_t snd_emu10k1x_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct emu10k1x *chip = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) struct emu10k1x_voice *pvoice = chip->voices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) status = inl(chip->port + IPR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (! status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) // capture interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (status & (IPR_CAP_0_LOOP | IPR_CAP_0_HALF_LOOP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) struct emu10k1x_voice *cap_voice = &chip->capture_voice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (cap_voice->use)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) snd_emu10k1x_pcm_interrupt(chip, cap_voice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) snd_emu10k1x_intr_disable(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) INTE_CAP_0_LOOP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) INTE_CAP_0_HALF_LOOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) mask = IPR_CH_0_LOOP|IPR_CH_0_HALF_LOOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) for (i = 0; i < 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (status & mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) if (pvoice->use)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) snd_emu10k1x_pcm_interrupt(chip, pvoice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) snd_emu10k1x_intr_disable(chip, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) pvoice++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) mask <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (status & (IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (chip->midi.interrupt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) chip->midi.interrupt(chip, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) snd_emu10k1x_intr_disable(chip, INTE_MIDITXENABLE|INTE_MIDIRXENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) // acknowledge the interrupt if necessary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) outl(status, chip->port + IPR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) /* dev_dbg(chip->card->dev, "interrupt %08x\n", status); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) static const struct snd_pcm_chmap_elem surround_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) { .channels = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) .map = { SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) static const struct snd_pcm_chmap_elem clfe_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) { .channels = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) .map = { SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) static int snd_emu10k1x_pcm(struct emu10k1x *emu, int device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) const struct snd_pcm_chmap_elem *map = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) int capture = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) if (device == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) capture = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) if ((err = snd_pcm_new(emu->card, "emu10k1x", device, 1, capture, &pcm)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) pcm->private_data = emu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) switch(device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1x_playback_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1x_capture_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1x_playback_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) pcm->info_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) switch(device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) strcpy(pcm->name, "EMU10K1X Front");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) map = snd_pcm_std_chmaps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) strcpy(pcm->name, "EMU10K1X Rear");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) map = surround_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) strcpy(pcm->name, "EMU10K1X Center/LFE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) map = clfe_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) emu->pcm = pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) &emu->pci->dev, 32*1024, 32*1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) return snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, map, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 1 << 2, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) static int snd_emu10k1x_create(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) struct pci_dev *pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) struct emu10k1x **rchip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) struct emu10k1x *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) int ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) static const struct snd_device_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) .dev_free = snd_emu10k1x_dev_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) *rchip = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if ((err = pci_enable_device(pci)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) dev_err(card->dev, "error to set 28bit mask DMA\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) pci_disable_device(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) chip = kzalloc(sizeof(*chip), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) if (chip == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) pci_disable_device(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) chip->card = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) chip->pci = pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) chip->irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) spin_lock_init(&chip->emu_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) spin_lock_init(&chip->voice_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) chip->port = pci_resource_start(pci, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) if ((chip->res_port = request_region(chip->port, 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) "EMU10K1X")) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) dev_err(card->dev, "cannot allocate the port 0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) chip->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) snd_emu10k1x_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (request_irq(pci->irq, snd_emu10k1x_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) IRQF_SHARED, KBUILD_MODNAME, chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) dev_err(card->dev, "cannot grab irq %d\n", pci->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) snd_emu10k1x_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) chip->irq = pci->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) card->sync_irq = chip->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) 4 * 1024, &chip->dma_buffer) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) snd_emu10k1x_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) pci_set_master(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) /* read revision & serial */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) chip->revision = pci->revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) dev_info(card->dev, "Model %04x Rev %08x Serial %08x\n", chip->model,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) chip->revision, chip->serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) outl(0, chip->port + INTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) for(ch = 0; ch < 3; ch++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) chip->voices[ch].emu = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) chip->voices[ch].number = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) * Init to 0x02109204 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) * Clock accuracy = 0 (1000ppm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) * Sample Rate = 2 (48kHz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) * Audio Channel = 1 (Left of 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) * Source Number = 0 (Unspecified)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) * Generation Status = 1 (Original for Cat Code 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) * Cat Code = 12 (Digital Signal Mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) * Mode = 0 (Mode 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) * Emphasis = 0 (None)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) * CP = 1 (Copyright unasserted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) * AN = 0 (Audio data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) * P = 0 (Consumer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) snd_emu10k1x_ptr_write(chip, SPCS0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) chip->spdif_bits[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) SPCS_GENERATIONSTATUS | 0x00001200 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) snd_emu10k1x_ptr_write(chip, SPCS1, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) chip->spdif_bits[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) SPCS_GENERATIONSTATUS | 0x00001200 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) snd_emu10k1x_ptr_write(chip, SPCS2, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) chip->spdif_bits[2] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) SPCS_GENERATIONSTATUS | 0x00001200 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) snd_emu10k1x_ptr_write(chip, SPDIF_SELECT, 0, 0x700); // disable SPDIF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) snd_emu10k1x_ptr_write(chip, ROUTING, 0, 0x1003F); // routing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) snd_emu10k1x_gpio_write(chip, 0x1080); // analog mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) chip, &ops)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) snd_emu10k1x_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) *rchip = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) static void snd_emu10k1x_proc_reg_read(struct snd_info_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) struct snd_info_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) struct emu10k1x *emu = entry->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) unsigned long value,value1,value2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) snd_iprintf(buffer, "Registers:\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) for(i = 0; i < 0x20; i+=4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) spin_lock_irqsave(&emu->emu_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) value = inl(emu->port + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) spin_unlock_irqrestore(&emu->emu_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) snd_iprintf(buffer, "Register %02X: %08lX\n", i, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) snd_iprintf(buffer, "\nRegisters\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) for(i = 0; i <= 0x48; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) value = snd_emu10k1x_ptr_read(emu, i, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if(i < 0x10 || (i >= 0x20 && i < 0x40)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) value1 = snd_emu10k1x_ptr_read(emu, i, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) value2 = snd_emu10k1x_ptr_read(emu, i, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) snd_iprintf(buffer, "%02X: %08lX %08lX %08lX\n", i, value, value1, value2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) snd_iprintf(buffer, "%02X: %08lX\n", i, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) static void snd_emu10k1x_proc_reg_write(struct snd_info_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) struct snd_info_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) struct emu10k1x *emu = entry->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) char line[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) unsigned int reg, channel_id , val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) while (!snd_info_get_line(buffer, line, sizeof(line))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) if (sscanf(line, "%x %x %x", ®, &channel_id, &val) != 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) if (reg < 0x49 && channel_id <= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) snd_emu10k1x_ptr_write(emu, reg, channel_id, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) static int snd_emu10k1x_proc_init(struct emu10k1x *emu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) snd_card_rw_proc_new(emu->card, "emu10k1x_regs", emu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) snd_emu10k1x_proc_reg_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) snd_emu10k1x_proc_reg_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) #define snd_emu10k1x_shared_spdif_info snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) static int snd_emu10k1x_shared_spdif_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) struct emu10k1x *emu = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) ucontrol->value.integer.value[0] = (snd_emu10k1x_ptr_read(emu, SPDIF_SELECT, 0) == 0x700) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) static int snd_emu10k1x_shared_spdif_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) struct emu10k1x *emu = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) val = ucontrol->value.integer.value[0] ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) // enable spdif output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) snd_emu10k1x_ptr_write(emu, SPDIF_SELECT, 0, 0x000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) snd_emu10k1x_ptr_write(emu, ROUTING, 0, 0x700);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) snd_emu10k1x_gpio_write(emu, 0x1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) // disable spdif output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) snd_emu10k1x_ptr_write(emu, SPDIF_SELECT, 0, 0x700);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) snd_emu10k1x_ptr_write(emu, ROUTING, 0, 0x1003F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) snd_emu10k1x_gpio_write(emu, 0x1080);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) static const struct snd_kcontrol_new snd_emu10k1x_shared_spdif =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) .name = "Analog/Digital Output Jack",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) .info = snd_emu10k1x_shared_spdif_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) .get = snd_emu10k1x_shared_spdif_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) .put = snd_emu10k1x_shared_spdif_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) static int snd_emu10k1x_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) static int snd_emu10k1x_spdif_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) struct emu10k1x *emu = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) static int snd_emu10k1x_spdif_get_mask(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) ucontrol->value.iec958.status[0] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) ucontrol->value.iec958.status[1] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) ucontrol->value.iec958.status[2] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) ucontrol->value.iec958.status[3] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) static int snd_emu10k1x_spdif_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) struct emu10k1x *emu = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) val = (ucontrol->value.iec958.status[0] << 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) (ucontrol->value.iec958.status[1] << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) (ucontrol->value.iec958.status[2] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) (ucontrol->value.iec958.status[3] << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) change = val != emu->spdif_bits[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) if (change) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) snd_emu10k1x_ptr_write(emu, SPCS0 + idx, 0, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) emu->spdif_bits[idx] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) static const struct snd_kcontrol_new snd_emu10k1x_spdif_mask_control =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) .access = SNDRV_CTL_ELEM_ACCESS_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) .iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) .count = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) .info = snd_emu10k1x_spdif_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) .get = snd_emu10k1x_spdif_get_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) static const struct snd_kcontrol_new snd_emu10k1x_spdif_control =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) .iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) .count = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) .info = snd_emu10k1x_spdif_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) .get = snd_emu10k1x_spdif_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) .put = snd_emu10k1x_spdif_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) static int snd_emu10k1x_mixer(struct emu10k1x *emu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) struct snd_kcontrol *kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) struct snd_card *card = emu->card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) if ((kctl = snd_ctl_new1(&snd_emu10k1x_spdif_mask_control, emu)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) if ((err = snd_ctl_add(card, kctl)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) if ((kctl = snd_ctl_new1(&snd_emu10k1x_shared_spdif, emu)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if ((err = snd_ctl_add(card, kctl)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) if ((kctl = snd_ctl_new1(&snd_emu10k1x_spdif_control, emu)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) if ((err = snd_ctl_add(card, kctl)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) #define EMU10K1X_MIDI_MODE_INPUT (1<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) #define EMU10K1X_MIDI_MODE_OUTPUT (1<<1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) static inline unsigned char mpu401_read(struct emu10k1x *emu, struct emu10k1x_midi *mpu, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) return (unsigned char)snd_emu10k1x_ptr_read(emu, mpu->port + idx, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) static inline void mpu401_write(struct emu10k1x *emu, struct emu10k1x_midi *mpu, int data, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) snd_emu10k1x_ptr_write(emu, mpu->port + idx, 0, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) #define mpu401_write_data(emu, mpu, data) mpu401_write(emu, mpu, data, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) #define mpu401_write_cmd(emu, mpu, data) mpu401_write(emu, mpu, data, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) #define mpu401_read_data(emu, mpu) mpu401_read(emu, mpu, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) #define mpu401_read_stat(emu, mpu) mpu401_read(emu, mpu, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) #define mpu401_input_avail(emu,mpu) (!(mpu401_read_stat(emu,mpu) & 0x80))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) #define mpu401_output_ready(emu,mpu) (!(mpu401_read_stat(emu,mpu) & 0x40))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) #define MPU401_RESET 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) #define MPU401_ENTER_UART 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) #define MPU401_ACK 0xfe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) static void mpu401_clear_rx(struct emu10k1x *emu, struct emu10k1x_midi *mpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) int timeout = 100000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) for (; timeout > 0 && mpu401_input_avail(emu, mpu); timeout--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) mpu401_read_data(emu, mpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) #ifdef CONFIG_SND_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) if (timeout <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) dev_err(emu->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) "cmd: clear rx timeout (status = 0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) mpu401_read_stat(emu, mpu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) static void do_emu10k1x_midi_interrupt(struct emu10k1x *emu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) struct emu10k1x_midi *midi, unsigned int status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) unsigned char byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) if (midi->rmidi == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) snd_emu10k1x_intr_disable(emu, midi->tx_enable | midi->rx_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) spin_lock(&midi->input_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) if ((status & midi->ipr_rx) && mpu401_input_avail(emu, midi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) mpu401_clear_rx(emu, midi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) byte = mpu401_read_data(emu, midi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) if (midi->substream_input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) snd_rawmidi_receive(midi->substream_input, &byte, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) spin_unlock(&midi->input_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) spin_lock(&midi->output_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) if ((status & midi->ipr_tx) && mpu401_output_ready(emu, midi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) if (midi->substream_output &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) mpu401_write_data(emu, midi, byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) snd_emu10k1x_intr_disable(emu, midi->tx_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) spin_unlock(&midi->output_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) static void snd_emu10k1x_midi_interrupt(struct emu10k1x *emu, unsigned int status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) do_emu10k1x_midi_interrupt(emu, &emu->midi, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) static int snd_emu10k1x_midi_cmd(struct emu10k1x * emu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) struct emu10k1x_midi *midi, unsigned char cmd, int ack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) int timeout, ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) spin_lock_irqsave(&midi->input_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) mpu401_write_data(emu, midi, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) /* mpu401_clear_rx(emu, midi); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) mpu401_write_cmd(emu, midi, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) if (ack) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) ok = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) timeout = 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) while (!ok && timeout-- > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (mpu401_input_avail(emu, midi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) if (mpu401_read_data(emu, midi) == MPU401_ACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) ok = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) if (!ok && mpu401_read_data(emu, midi) == MPU401_ACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) ok = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) ok = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) spin_unlock_irqrestore(&midi->input_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) if (!ok) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) dev_err(emu->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) "midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) cmd, emu->port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) mpu401_read_stat(emu, midi),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) mpu401_read_data(emu, midi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) static int snd_emu10k1x_midi_input_open(struct snd_rawmidi_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) struct emu10k1x *emu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) struct emu10k1x_midi *midi = substream->rmidi->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) emu = midi->emu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) if (snd_BUG_ON(!emu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) spin_lock_irqsave(&midi->open_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) midi->midi_mode |= EMU10K1X_MIDI_MODE_INPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) midi->substream_input = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) spin_unlock_irqrestore(&midi->open_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) goto error_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) goto error_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) spin_unlock_irqrestore(&midi->open_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) error_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) static int snd_emu10k1x_midi_output_open(struct snd_rawmidi_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) struct emu10k1x *emu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) struct emu10k1x_midi *midi = substream->rmidi->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) emu = midi->emu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) if (snd_BUG_ON(!emu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) spin_lock_irqsave(&midi->open_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) midi->midi_mode |= EMU10K1X_MIDI_MODE_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) midi->substream_output = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) spin_unlock_irqrestore(&midi->open_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) goto error_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) goto error_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) spin_unlock_irqrestore(&midi->open_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) error_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) static int snd_emu10k1x_midi_input_close(struct snd_rawmidi_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) struct emu10k1x *emu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) struct emu10k1x_midi *midi = substream->rmidi->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) emu = midi->emu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) if (snd_BUG_ON(!emu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) spin_lock_irqsave(&midi->open_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) snd_emu10k1x_intr_disable(emu, midi->rx_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) midi->midi_mode &= ~EMU10K1X_MIDI_MODE_INPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) midi->substream_input = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) spin_unlock_irqrestore(&midi->open_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) err = snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) spin_unlock_irqrestore(&midi->open_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) static int snd_emu10k1x_midi_output_close(struct snd_rawmidi_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) struct emu10k1x *emu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) struct emu10k1x_midi *midi = substream->rmidi->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) emu = midi->emu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) if (snd_BUG_ON(!emu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) spin_lock_irqsave(&midi->open_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) snd_emu10k1x_intr_disable(emu, midi->tx_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) midi->midi_mode &= ~EMU10K1X_MIDI_MODE_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) midi->substream_output = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) spin_unlock_irqrestore(&midi->open_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) err = snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) spin_unlock_irqrestore(&midi->open_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) static void snd_emu10k1x_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) struct emu10k1x *emu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) struct emu10k1x_midi *midi = substream->rmidi->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) emu = midi->emu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) if (snd_BUG_ON(!emu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) if (up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) snd_emu10k1x_intr_enable(emu, midi->rx_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) snd_emu10k1x_intr_disable(emu, midi->rx_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) static void snd_emu10k1x_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) struct emu10k1x *emu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) struct emu10k1x_midi *midi = substream->rmidi->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) emu = midi->emu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) if (snd_BUG_ON(!emu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) if (up) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) int max = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) unsigned char byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) /* try to send some amount of bytes here before interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) spin_lock_irqsave(&midi->output_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) while (max > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) if (mpu401_output_ready(emu, midi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) snd_rawmidi_transmit(substream, &byte, 1) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) /* no more data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) spin_unlock_irqrestore(&midi->output_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) mpu401_write_data(emu, midi, byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) max--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) spin_unlock_irqrestore(&midi->output_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) snd_emu10k1x_intr_enable(emu, midi->tx_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) snd_emu10k1x_intr_disable(emu, midi->tx_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) static const struct snd_rawmidi_ops snd_emu10k1x_midi_output =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) .open = snd_emu10k1x_midi_output_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) .close = snd_emu10k1x_midi_output_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) .trigger = snd_emu10k1x_midi_output_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) static const struct snd_rawmidi_ops snd_emu10k1x_midi_input =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) .open = snd_emu10k1x_midi_input_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) .close = snd_emu10k1x_midi_input_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) .trigger = snd_emu10k1x_midi_input_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) static void snd_emu10k1x_midi_free(struct snd_rawmidi *rmidi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) struct emu10k1x_midi *midi = rmidi->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) midi->interrupt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) midi->rmidi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) static int emu10k1x_midi_init(struct emu10k1x *emu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) struct emu10k1x_midi *midi, int device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) struct snd_rawmidi *rmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) if ((err = snd_rawmidi_new(emu->card, name, device, 1, 1, &rmidi)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) midi->emu = emu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) spin_lock_init(&midi->open_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) spin_lock_init(&midi->input_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) spin_lock_init(&midi->output_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) strcpy(rmidi->name, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_emu10k1x_midi_output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_emu10k1x_midi_input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) SNDRV_RAWMIDI_INFO_INPUT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) SNDRV_RAWMIDI_INFO_DUPLEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) rmidi->private_data = midi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) rmidi->private_free = snd_emu10k1x_midi_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) midi->rmidi = rmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) static int snd_emu10k1x_midi(struct emu10k1x *emu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) struct emu10k1x_midi *midi = &emu->midi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) if ((err = emu10k1x_midi_init(emu, midi, 0, "EMU10K1X MPU-401 (UART)")) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) midi->tx_enable = INTE_MIDITXENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) midi->rx_enable = INTE_MIDIRXENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) midi->port = MUDATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) midi->ipr_tx = IPR_MIDITRANSBUFEMPTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) midi->ipr_rx = IPR_MIDIRECVBUFEMPTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) midi->interrupt = snd_emu10k1x_midi_interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) static int snd_emu10k1x_probe(struct pci_dev *pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) const struct pci_device_id *pci_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) static int dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) struct emu10k1x *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) if (dev >= SNDRV_CARDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) if (!enable[dev]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) dev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 0, &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) if ((err = snd_emu10k1x_create(card, pci, &chip)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) if ((err = snd_emu10k1x_pcm(chip, 0)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) if ((err = snd_emu10k1x_pcm(chip, 1)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) if ((err = snd_emu10k1x_pcm(chip, 2)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) if ((err = snd_emu10k1x_ac97(chip)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) if ((err = snd_emu10k1x_mixer(chip)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) if ((err = snd_emu10k1x_midi(chip)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) snd_emu10k1x_proc_init(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) strcpy(card->driver, "EMU10K1X");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) strcpy(card->shortname, "Dell Sound Blaster Live!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) sprintf(card->longname, "%s at 0x%lx irq %i",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) card->shortname, chip->port, chip->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) if ((err = snd_card_register(card)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) pci_set_drvdata(pci, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) dev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) static void snd_emu10k1x_remove(struct pci_dev *pci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) snd_card_free(pci_get_drvdata(pci));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) // PCI IDs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) static const struct pci_device_id snd_emu10k1x_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) { PCI_VDEVICE(CREATIVE, 0x0006), 0 }, /* Dell OEM version (EMU10K1) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) { 0, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) MODULE_DEVICE_TABLE(pci, snd_emu10k1x_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) // pci_driver definition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) static struct pci_driver emu10k1x_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) .name = KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) .id_table = snd_emu10k1x_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) .probe = snd_emu10k1x_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) .remove = snd_emu10k1x_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) module_pci_driver(emu10k1x_driver);