^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) * Driver for ESS Solo-1 (ES1938, ES1946, ES1969) soundcard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) by Jaromir Koutek <miri@punknet.cz>,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Jaroslav Kysela <perex@perex.cz>,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Thomas Sailer <sailer@ife.ee.ethz.ch>,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Abramo Bagnara <abramo@alsa-project.org>,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Markus Gruber <gruber@eikon.tum.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Rewritten from sonicvibes.c source.
^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) * Rewrite better spinlocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) NOTES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) - Capture data is written unaligned starting from dma_base + 1 so I need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) disable mmap and to add a copy callback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) - After several cycle of the following:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) while : ; do arecord -d1 -f cd -t raw | aplay -f cd ; done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) a "playback write error (DMA or IRQ trouble?)" may happen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) This is due to playback interrupts not generated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) I suspect a timing issue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) - Sometimes the interrupt handler is invoked wrongly during playback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) This generates some harmless "Unexpected hw_pointer: wrong interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) acknowledge".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) I've seen that using small period sizes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) Reproducible with:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) mpg123 test.mp3 &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) hdparm -t -T /dev/hda
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/gameport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <sound/control.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <sound/opl3.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <sound/mpu401.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <sound/tlv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) MODULE_AUTHOR("Jaromir Koutek <miri@punknet.cz>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) MODULE_DESCRIPTION("ESS Solo-1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) MODULE_SUPPORTED_DEVICE("{{ESS,ES1938},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) "{ESS,ES1946},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) "{ESS,ES1969},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) "{TerraTec,128i PCI}}");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #if IS_REACHABLE(CONFIG_GAMEPORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define SUPPORT_JOYSTICK 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) module_param_array(index, int, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) MODULE_PARM_DESC(index, "Index value for ESS Solo-1 soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) module_param_array(id, charp, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) MODULE_PARM_DESC(id, "ID string for ESS Solo-1 soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) module_param_array(enable, bool, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) MODULE_PARM_DESC(enable, "Enable ESS Solo-1 soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define SLIO_REG(chip, x) ((chip)->io_port + ESSIO_REG_##x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define SLDM_REG(chip, x) ((chip)->ddma_port + ESSDM_REG_##x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define SLSB_REG(chip, x) ((chip)->sb_port + ESSSB_REG_##x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define SL_PCI_LEGACYCONTROL 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define SL_PCI_CONFIG 0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define SL_PCI_DDMACONTROL 0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define ESSIO_REG_AUDIO2DMAADDR 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define ESSIO_REG_AUDIO2DMACOUNT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define ESSIO_REG_AUDIO2MODE 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define ESSIO_REG_IRQCONTROL 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define ESSDM_REG_DMAADDR 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define ESSDM_REG_DMACOUNT 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define ESSDM_REG_DMACOMMAND 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define ESSDM_REG_DMASTATUS 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define ESSDM_REG_DMAMODE 0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define ESSDM_REG_DMACLEAR 0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define ESSDM_REG_DMAMASK 0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define ESSSB_REG_FMLOWADDR 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define ESSSB_REG_FMHIGHADDR 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define ESSSB_REG_MIXERADDR 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define ESSSB_REG_MIXERDATA 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define ESSSB_IREG_AUDIO1 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define ESSSB_IREG_MICMIX 0x1a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define ESSSB_IREG_RECSRC 0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define ESSSB_IREG_MASTER 0x32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define ESSSB_IREG_FM 0x36
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define ESSSB_IREG_AUXACD 0x38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define ESSSB_IREG_AUXB 0x3a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define ESSSB_IREG_PCSPEAKER 0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define ESSSB_IREG_LINE 0x3e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define ESSSB_IREG_SPATCONTROL 0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define ESSSB_IREG_SPATLEVEL 0x52
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define ESSSB_IREG_MASTER_LEFT 0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define ESSSB_IREG_MASTER_RIGHT 0x62
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define ESSSB_IREG_MPU401CONTROL 0x64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define ESSSB_IREG_MICMIXRECORD 0x68
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define ESSSB_IREG_AUDIO2RECORD 0x69
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define ESSSB_IREG_AUXACDRECORD 0x6a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define ESSSB_IREG_FMRECORD 0x6b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define ESSSB_IREG_AUXBRECORD 0x6c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define ESSSB_IREG_MONO 0x6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define ESSSB_IREG_LINERECORD 0x6e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define ESSSB_IREG_MONORECORD 0x6f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define ESSSB_IREG_AUDIO2SAMPLE 0x70
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define ESSSB_IREG_AUDIO2MODE 0x71
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define ESSSB_IREG_AUDIO2FILTER 0x72
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define ESSSB_IREG_AUDIO2TCOUNTL 0x74
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define ESSSB_IREG_AUDIO2TCOUNTH 0x76
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define ESSSB_IREG_AUDIO2CONTROL1 0x78
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define ESSSB_IREG_AUDIO2CONTROL2 0x7a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define ESSSB_IREG_AUDIO2 0x7c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define ESSSB_REG_RESET 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define ESSSB_REG_READDATA 0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define ESSSB_REG_WRITEDATA 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define ESSSB_REG_READSTATUS 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define ESSSB_REG_STATUS 0x0e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define ESS_CMD_EXTSAMPLERATE 0xa1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define ESS_CMD_FILTERDIV 0xa2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define ESS_CMD_DMACNTRELOADL 0xa4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define ESS_CMD_DMACNTRELOADH 0xa5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define ESS_CMD_ANALOGCONTROL 0xa8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define ESS_CMD_IRQCONTROL 0xb1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define ESS_CMD_DRQCONTROL 0xb2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define ESS_CMD_RECLEVEL 0xb4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define ESS_CMD_SETFORMAT 0xb6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define ESS_CMD_SETFORMAT2 0xb7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define ESS_CMD_DMACONTROL 0xb8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define ESS_CMD_DMATYPE 0xb9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define ESS_CMD_OFFSETLEFT 0xba
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define ESS_CMD_OFFSETRIGHT 0xbb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define ESS_CMD_READREG 0xc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define ESS_CMD_ENABLEEXT 0xc6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define ESS_CMD_PAUSEDMA 0xd0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define ESS_CMD_ENABLEAUDIO1 0xd1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #define ESS_CMD_STOPAUDIO1 0xd3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define ESS_CMD_AUDIO1STATUS 0xd8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define ESS_CMD_CONTDMA 0xd4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define ESS_CMD_TESTIRQ 0xf2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define ESS_RECSRC_MIC 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define ESS_RECSRC_AUXACD 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define ESS_RECSRC_AUXB 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define ESS_RECSRC_LINE 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #define ESS_RECSRC_NONE 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define DAC1 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define ADC1 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define DAC2 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define SAVED_REG_SIZE 32 /* max. number of registers to save */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct es1938 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) unsigned long io_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) unsigned long sb_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) unsigned long vc_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) unsigned long mpu_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) unsigned long game_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) unsigned long ddma_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) unsigned char irqmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) unsigned char revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct snd_kcontrol *hw_volume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct snd_kcontrol *hw_switch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct snd_kcontrol *master_volume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct snd_kcontrol *master_switch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct pci_dev *pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct snd_pcm_substream *capture_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct snd_pcm_substream *playback1_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct snd_pcm_substream *playback2_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct snd_rawmidi *rmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) unsigned int dma1_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) unsigned int dma2_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) unsigned int dma1_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) unsigned int dma2_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) unsigned int dma1_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) unsigned int dma2_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) unsigned int last_capture_dmaaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) unsigned int active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) spinlock_t reg_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) spinlock_t mixer_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct snd_info_entry *proc_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #ifdef SUPPORT_JOYSTICK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct gameport *gameport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) unsigned char saved_regs[SAVED_REG_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static const struct pci_device_id snd_es1938_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) { PCI_VDEVICE(ESS, 0x1969), 0, }, /* Solo-1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) { 0, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) MODULE_DEVICE_TABLE(pci, snd_es1938_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) #define RESET_LOOP_TIMEOUT 0x10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) #define WRITE_LOOP_TIMEOUT 0x10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) #define GET_LOOP_TIMEOUT 0x01000
^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) * Write to a mixer register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * -----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static void snd_es1938_mixer_write(struct es1938 *chip, unsigned char reg, unsigned char val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) spin_lock_irqsave(&chip->mixer_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) outb(reg, SLSB_REG(chip, MIXERADDR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) outb(val, SLSB_REG(chip, MIXERDATA));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) spin_unlock_irqrestore(&chip->mixer_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) dev_dbg(chip->card->dev, "Mixer reg %02x set to %02x\n", reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /* -----------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * Read from a mixer register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * -----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static int snd_es1938_mixer_read(struct es1938 *chip, unsigned char reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) int data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) spin_lock_irqsave(&chip->mixer_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) outb(reg, SLSB_REG(chip, MIXERADDR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) data = inb(SLSB_REG(chip, MIXERDATA));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) spin_unlock_irqrestore(&chip->mixer_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) dev_dbg(chip->card->dev, "Mixer reg %02x now is %02x\n", reg, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) /* -----------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * Write to some bits of a mixer register (return old value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * -----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static int snd_es1938_mixer_bits(struct es1938 *chip, unsigned char reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) unsigned char mask, unsigned char val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) unsigned char old, new, oval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) spin_lock_irqsave(&chip->mixer_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) outb(reg, SLSB_REG(chip, MIXERADDR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) old = inb(SLSB_REG(chip, MIXERDATA));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) oval = old & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (val != oval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) new = (old & ~mask) | (val & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) outb(new, SLSB_REG(chip, MIXERDATA));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) dev_dbg(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) "Mixer reg %02x was %02x, set to %02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) reg, old, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) spin_unlock_irqrestore(&chip->mixer_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return oval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /* -----------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * Write command to Controller Registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * -----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static void snd_es1938_write_cmd(struct es1938 *chip, unsigned char cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) unsigned char v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) for (i = 0; i < WRITE_LOOP_TIMEOUT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (!(v = inb(SLSB_REG(chip, READSTATUS)) & 0x80)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) outb(cmd, SLSB_REG(chip, WRITEDATA));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) dev_err(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) "snd_es1938_write_cmd timeout (0x02%x/0x02%x)\n", cmd, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /* -----------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * Read the Read Data Buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * -----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static int snd_es1938_get_byte(struct es1938 *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) unsigned char v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) for (i = GET_LOOP_TIMEOUT; i; i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if ((v = inb(SLSB_REG(chip, STATUS))) & 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return inb(SLSB_REG(chip, READDATA));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) dev_err(chip->card->dev, "get_byte timeout: status 0x02%x\n", v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^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) * Write value cmd register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * -----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static void snd_es1938_write(struct es1938 *chip, unsigned char reg, unsigned char val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) spin_lock_irqsave(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) snd_es1938_write_cmd(chip, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) snd_es1938_write_cmd(chip, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) spin_unlock_irqrestore(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) dev_dbg(chip->card->dev, "Reg %02x set to %02x\n", reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /* -----------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * Read data from cmd register and return it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * -----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static unsigned char snd_es1938_read(struct es1938 *chip, unsigned char reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) unsigned char val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) spin_lock_irqsave(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) snd_es1938_write_cmd(chip, ESS_CMD_READREG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) snd_es1938_write_cmd(chip, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) val = snd_es1938_get_byte(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) spin_unlock_irqrestore(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) dev_dbg(chip->card->dev, "Reg %02x now is %02x\n", reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /* -----------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * Write data to cmd register and return old value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * -----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static int snd_es1938_bits(struct es1938 *chip, unsigned char reg, unsigned char mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) unsigned char val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) unsigned char old, new, oval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) spin_lock_irqsave(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) snd_es1938_write_cmd(chip, ESS_CMD_READREG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) snd_es1938_write_cmd(chip, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) old = snd_es1938_get_byte(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) oval = old & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (val != oval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) snd_es1938_write_cmd(chip, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) new = (old & ~mask) | (val & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) snd_es1938_write_cmd(chip, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) dev_dbg(chip->card->dev, "Reg %02x was %02x, set to %02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) reg, old, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) spin_unlock_irqrestore(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return oval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /* --------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * Reset the chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * --------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static void snd_es1938_reset(struct es1938 *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) outb(3, SLSB_REG(chip, RESET));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) inb(SLSB_REG(chip, RESET));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) outb(0, SLSB_REG(chip, RESET));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) for (i = 0; i < RESET_LOOP_TIMEOUT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (inb(SLSB_REG(chip, STATUS)) & 0x80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (inb(SLSB_REG(chip, READDATA)) == 0xaa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) goto __next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) dev_err(chip->card->dev, "ESS Solo-1 reset failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) __next:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) snd_es1938_write_cmd(chip, ESS_CMD_ENABLEEXT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /* Demand transfer DMA: 4 bytes per DMA request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) snd_es1938_write(chip, ESS_CMD_DMATYPE, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /* Change behaviour of register A1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 4x oversampling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 2nd channel DAC asynchronous */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2MODE, 0x32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) /* enable/select DMA channel and IRQ channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) snd_es1938_bits(chip, ESS_CMD_IRQCONTROL, 0xf0, 0x50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) snd_es1938_bits(chip, ESS_CMD_DRQCONTROL, 0xf0, 0x50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) snd_es1938_write_cmd(chip, ESS_CMD_ENABLEAUDIO1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) /* Set spatializer parameters to recommended values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) snd_es1938_mixer_write(chip, 0x54, 0x8f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) snd_es1938_mixer_write(chip, 0x56, 0x95);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) snd_es1938_mixer_write(chip, 0x58, 0x94);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) snd_es1938_mixer_write(chip, 0x5a, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /* --------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * Reset the FIFOs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * --------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) static void snd_es1938_reset_fifo(struct es1938 *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) outb(2, SLSB_REG(chip, RESET));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) outb(0, SLSB_REG(chip, RESET));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) static const struct snd_ratnum clocks[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) .num = 793800,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) .den_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) .den_max = 128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) .den_step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) .num = 768000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) .den_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) .den_max = 128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) .den_step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static const struct snd_pcm_hw_constraint_ratnums hw_constraints_clocks = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) .nrats = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) .rats = clocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) static void snd_es1938_rate_set(struct es1938 *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) unsigned int bits, div0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (runtime->rate_num == clocks[0].num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) bits = 128 - runtime->rate_den;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) bits = 256 - runtime->rate_den;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) /* set filter register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) div0 = 256 - 7160000*20/(8*82*runtime->rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (mode == DAC2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) snd_es1938_mixer_write(chip, 0x70, bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) snd_es1938_mixer_write(chip, 0x72, div0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) snd_es1938_write(chip, 0xA1, bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) snd_es1938_write(chip, 0xA2, div0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) /* --------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * Configure Solo1 builtin DMA Controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) * --------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) static void snd_es1938_playback1_setdma(struct es1938 *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) outb(0x00, SLIO_REG(chip, AUDIO2MODE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) outl(chip->dma2_start, SLIO_REG(chip, AUDIO2DMAADDR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) outw(0, SLIO_REG(chip, AUDIO2DMACOUNT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) outw(chip->dma2_size, SLIO_REG(chip, AUDIO2DMACOUNT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) static void snd_es1938_playback2_setdma(struct es1938 *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /* Enable DMA controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) outb(0xc4, SLDM_REG(chip, DMACOMMAND));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) /* 1. Master reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) outb(0, SLDM_REG(chip, DMACLEAR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* 2. Mask DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) outb(1, SLDM_REG(chip, DMAMASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) outb(0x18, SLDM_REG(chip, DMAMODE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) outl(chip->dma1_start, SLDM_REG(chip, DMAADDR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) outw(chip->dma1_size - 1, SLDM_REG(chip, DMACOUNT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) /* 3. Unmask DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) outb(0, SLDM_REG(chip, DMAMASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) static void snd_es1938_capture_setdma(struct es1938 *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) /* Enable DMA controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) outb(0xc4, SLDM_REG(chip, DMACOMMAND));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) /* 1. Master reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) outb(0, SLDM_REG(chip, DMACLEAR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) /* 2. Mask DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) outb(1, SLDM_REG(chip, DMAMASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) outb(0x14, SLDM_REG(chip, DMAMODE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) outl(chip->dma1_start, SLDM_REG(chip, DMAADDR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) chip->last_capture_dmaaddr = chip->dma1_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) outw(chip->dma1_size - 1, SLDM_REG(chip, DMACOUNT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) /* 3. Unmask DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) outb(0, SLDM_REG(chip, DMAMASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) /* ----------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) * *** PCM part ***
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) static int snd_es1938_capture_trigger(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) struct es1938 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) val = 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) chip->active |= ADC1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) val = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) chip->active &= ~ADC1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) snd_es1938_write(chip, ESS_CMD_DMACONTROL, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static int snd_es1938_playback1_trigger(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) struct es1938 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) /* According to the documentation this should be:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 0x13 but that value may randomly swap stereo channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL1, 0x92);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL1, 0x93);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) /* This two stage init gives the FIFO -> DAC connection time to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * settle before first data from DMA flows in. This should ensure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) * no swapping of stereo channels. Report a bug if otherwise :-) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) outb(0x0a, SLIO_REG(chip, AUDIO2MODE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) chip->active |= DAC2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) outb(0, SLIO_REG(chip, AUDIO2MODE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) chip->active &= ~DAC2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) static int snd_es1938_playback2_trigger(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) struct es1938 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) val = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) chip->active |= DAC1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) chip->active &= ~DAC1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) snd_es1938_write(chip, ESS_CMD_DMACONTROL, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static int snd_es1938_playback_trigger(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) switch (substream->number) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return snd_es1938_playback1_trigger(substream, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return snd_es1938_playback2_trigger(substream, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) snd_BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) /* --------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) * First channel for Extended Mode Audio 1 ADC Operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) * --------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static int snd_es1938_capture_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) struct es1938 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) int u, is8, mono;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) unsigned int size = snd_pcm_lib_buffer_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) unsigned int count = snd_pcm_lib_period_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) chip->dma1_size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) chip->dma1_start = runtime->dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) mono = (runtime->channels > 1) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) is8 = snd_pcm_format_width(runtime->format) == 16 ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) u = snd_pcm_format_unsigned(runtime->format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) chip->dma1_shift = 2 - mono - is8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) snd_es1938_reset_fifo(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) /* program type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) snd_es1938_bits(chip, ESS_CMD_ANALOGCONTROL, 0x03, (mono ? 2 : 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) /* set clock and counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) snd_es1938_rate_set(chip, substream, ADC1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) count = 0x10000 - count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) snd_es1938_write(chip, ESS_CMD_DMACNTRELOADL, count & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) snd_es1938_write(chip, ESS_CMD_DMACNTRELOADH, count >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) /* initialize and configure ADC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) snd_es1938_write(chip, ESS_CMD_SETFORMAT2, u ? 0x51 : 0x71);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) snd_es1938_write(chip, ESS_CMD_SETFORMAT2, 0x90 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) (u ? 0x00 : 0x20) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) (is8 ? 0x00 : 0x04) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) (mono ? 0x40 : 0x08));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) // snd_es1938_reset_fifo(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) /* 11. configure system interrupt controller and DMA controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) snd_es1938_capture_setdma(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) /* ------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * Second Audio channel DAC Operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * ------------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) static int snd_es1938_playback1_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) struct es1938 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) int u, is8, mono;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) unsigned int size = snd_pcm_lib_buffer_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) unsigned int count = snd_pcm_lib_period_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) chip->dma2_size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) chip->dma2_start = runtime->dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) mono = (runtime->channels > 1) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) is8 = snd_pcm_format_width(runtime->format) == 16 ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) u = snd_pcm_format_unsigned(runtime->format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) chip->dma2_shift = 2 - mono - is8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) snd_es1938_reset_fifo(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) /* set clock and counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) snd_es1938_rate_set(chip, substream, DAC2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) count >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) count = 0x10000 - count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2TCOUNTL, count & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2TCOUNTH, count >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) /* initialize and configure Audio 2 DAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL2, 0x40 | (u ? 0 : 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) (mono ? 0 : 2) | (is8 ? 0 : 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) /* program DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) snd_es1938_playback1_setdma(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) static int snd_es1938_playback2_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct es1938 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) int u, is8, mono;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) unsigned int size = snd_pcm_lib_buffer_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) unsigned int count = snd_pcm_lib_period_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) chip->dma1_size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) chip->dma1_start = runtime->dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) mono = (runtime->channels > 1) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) is8 = snd_pcm_format_width(runtime->format) == 16 ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) u = snd_pcm_format_unsigned(runtime->format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) chip->dma1_shift = 2 - mono - is8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) count = 0x10000 - count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) /* reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) snd_es1938_reset_fifo(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) snd_es1938_bits(chip, ESS_CMD_ANALOGCONTROL, 0x03, (mono ? 2 : 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) /* set clock and counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) snd_es1938_rate_set(chip, substream, DAC1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) snd_es1938_write(chip, ESS_CMD_DMACNTRELOADL, count & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) snd_es1938_write(chip, ESS_CMD_DMACNTRELOADH, count >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) /* initialized and configure DAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) snd_es1938_write(chip, ESS_CMD_SETFORMAT, u ? 0x80 : 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) snd_es1938_write(chip, ESS_CMD_SETFORMAT, u ? 0x51 : 0x71);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) snd_es1938_write(chip, ESS_CMD_SETFORMAT2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 0x90 | (mono ? 0x40 : 0x08) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) (is8 ? 0x00 : 0x04) | (u ? 0x00 : 0x20));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) /* program DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) snd_es1938_playback2_setdma(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) static int snd_es1938_playback_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) switch (substream->number) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) return snd_es1938_playback1_prepare(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return snd_es1938_playback2_prepare(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) snd_BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) /* during the incrementing of dma counters the DMA register reads sometimes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) returns garbage. To ensure a valid hw pointer, the following checks which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) should be very unlikely to fail are used:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) - is the current DMA address in the valid DMA range ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) - is the sum of DMA address and DMA counter pointing to the last DMA byte ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) One can argue this could differ by one byte depending on which register is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) updated first, so the implementation below allows for that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) static snd_pcm_uframes_t snd_es1938_capture_pointer(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) struct es1938 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) size_t ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) size_t old, new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) /* This stuff is *needed*, don't ask why - AB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) old = inw(SLDM_REG(chip, DMACOUNT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) while ((new = inw(SLDM_REG(chip, DMACOUNT))) != old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) old = new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) ptr = chip->dma1_size - 1 - new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) size_t count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) unsigned int diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) ptr = inl(SLDM_REG(chip, DMAADDR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) count = inw(SLDM_REG(chip, DMACOUNT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) diff = chip->dma1_start + chip->dma1_size - ptr - count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (diff > 3 || ptr < chip->dma1_start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) || ptr >= chip->dma1_start+chip->dma1_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) ptr = chip->last_capture_dmaaddr; /* bad, use last saved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) chip->last_capture_dmaaddr = ptr; /* good, remember it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) ptr -= chip->dma1_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return ptr >> chip->dma1_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) static snd_pcm_uframes_t snd_es1938_playback1_pointer(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) struct es1938 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) size_t ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) #if 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) ptr = chip->dma2_size - inw(SLIO_REG(chip, AUDIO2DMACOUNT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) ptr = inl(SLIO_REG(chip, AUDIO2DMAADDR)) - chip->dma2_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) return ptr >> chip->dma2_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) static snd_pcm_uframes_t snd_es1938_playback2_pointer(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) struct es1938 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) size_t ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) size_t old, new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) #if 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) /* This stuff is *needed*, don't ask why - AB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) old = inw(SLDM_REG(chip, DMACOUNT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) while ((new = inw(SLDM_REG(chip, DMACOUNT))) != old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) old = new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) ptr = chip->dma1_size - 1 - new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) ptr = inl(SLDM_REG(chip, DMAADDR)) - chip->dma1_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) return ptr >> chip->dma1_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) static snd_pcm_uframes_t snd_es1938_playback_pointer(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) switch (substream->number) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) return snd_es1938_playback1_pointer(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) return snd_es1938_playback2_pointer(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) snd_BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) return -EINVAL;
^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 int snd_es1938_capture_copy(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) int channel, unsigned long pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) void __user *dst, unsigned long count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) struct es1938 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (snd_BUG_ON(pos + count > chip->dma1_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if (pos + count < chip->dma1_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (copy_to_user(dst, runtime->dma_area + pos + 1, count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) if (copy_to_user(dst, runtime->dma_area + pos + 1, count - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (put_user(runtime->dma_area[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) ((unsigned char __user *)dst) + count - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) static int snd_es1938_capture_copy_kernel(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) int channel, unsigned long pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) void *dst, unsigned long count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) struct es1938 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (snd_BUG_ON(pos + count > chip->dma1_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (pos + count < chip->dma1_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) memcpy(dst, runtime->dma_area + pos + 1, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) memcpy(dst, runtime->dma_area + pos + 1, count - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) runtime->dma_area[0] = *((unsigned char *)dst + count - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) /* ----------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) * Audio1 Capture (ADC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) * ----------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) static const struct snd_pcm_hardware snd_es1938_capture =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) .info = (SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) SNDRV_PCM_INFO_BLOCK_TRANSFER),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) .rate_min = 6000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) .rate_max = 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) .buffer_bytes_max = 0x8000, /* DMA controller screws on higher values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) .period_bytes_min = 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) .period_bytes_max = 0x8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) .periods_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) .periods_max = 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) .fifo_size = 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) /* -----------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * Audio2 Playback (DAC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) * -----------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) static const struct snd_pcm_hardware snd_es1938_playback =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) SNDRV_PCM_INFO_BLOCK_TRANSFER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) SNDRV_PCM_INFO_MMAP_VALID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) .rate_min = 6000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) .rate_max = 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) .buffer_bytes_max = 0x8000, /* DMA controller screws on higher values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) .period_bytes_min = 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) .period_bytes_max = 0x8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) .periods_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) .periods_max = 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) .fifo_size = 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) static int snd_es1938_capture_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) struct es1938 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) if (chip->playback2_substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) chip->capture_substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) runtime->hw = snd_es1938_capture;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) &hw_constraints_clocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 0, 0xff00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) return 0;
^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) static int snd_es1938_playback_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) struct es1938 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) switch (substream->number) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) chip->playback1_substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (chip->capture_substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) chip->playback2_substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) snd_BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) runtime->hw = snd_es1938_playback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) &hw_constraints_clocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 0, 0xff00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) static int snd_es1938_capture_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) struct es1938 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) chip->capture_substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) static int snd_es1938_playback_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) struct es1938 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) switch (substream->number) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) chip->playback1_substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) chip->playback2_substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) snd_BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) static const struct snd_pcm_ops snd_es1938_playback_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) .open = snd_es1938_playback_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) .close = snd_es1938_playback_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) .prepare = snd_es1938_playback_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) .trigger = snd_es1938_playback_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) .pointer = snd_es1938_playback_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) static const struct snd_pcm_ops snd_es1938_capture_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) .open = snd_es1938_capture_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) .close = snd_es1938_capture_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) .prepare = snd_es1938_capture_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) .trigger = snd_es1938_capture_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) .pointer = snd_es1938_capture_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) .copy_user = snd_es1938_capture_copy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) .copy_kernel = snd_es1938_capture_copy_kernel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) static int snd_es1938_new_pcm(struct es1938 *chip, int device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) if ((err = snd_pcm_new(chip->card, "es-1938-1946", device, 2, 1, &pcm)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_es1938_playback_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_es1938_capture_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) pcm->private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) pcm->info_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) strcpy(pcm->name, "ESS Solo-1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) &chip->pci->dev, 64*1024, 64*1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) chip->pcm = pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) /* -------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) * *** Mixer part ***
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) static int snd_es1938_info_mux(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) static const char * const texts[8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) "Mic", "Mic Master", "CD", "AOUT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) "Mic1", "Mix", "Line", "Master"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) return snd_ctl_enum_info(uinfo, 1, 8, texts);
^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 int snd_es1938_get_mux(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) struct es1938 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) ucontrol->value.enumerated.item[0] = snd_es1938_mixer_read(chip, 0x1c) & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) static int snd_es1938_put_mux(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) struct es1938 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) unsigned char val = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) if (val > 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) return snd_es1938_mixer_bits(chip, 0x1c, 0x07, val) != val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) #define snd_es1938_info_spatializer_enable snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) static int snd_es1938_get_spatializer_enable(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) struct es1938 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) unsigned char val = snd_es1938_mixer_read(chip, 0x50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) ucontrol->value.integer.value[0] = !!(val & 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) static int snd_es1938_put_spatializer_enable(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) struct es1938 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) unsigned char oval, nval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) nval = ucontrol->value.integer.value[0] ? 0x0c : 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) oval = snd_es1938_mixer_read(chip, 0x50) & 0x0c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) change = nval != oval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) if (change) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) snd_es1938_mixer_write(chip, 0x50, nval & ~0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) snd_es1938_mixer_write(chip, 0x50, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) static int snd_es1938_info_hw_volume(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) uinfo->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) uinfo->value.integer.max = 63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) static int snd_es1938_get_hw_volume(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) struct es1938 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) ucontrol->value.integer.value[0] = snd_es1938_mixer_read(chip, 0x61) & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) ucontrol->value.integer.value[1] = snd_es1938_mixer_read(chip, 0x63) & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) #define snd_es1938_info_hw_switch snd_ctl_boolean_stereo_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) static int snd_es1938_get_hw_switch(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) struct es1938 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) ucontrol->value.integer.value[0] = !(snd_es1938_mixer_read(chip, 0x61) & 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) ucontrol->value.integer.value[1] = !(snd_es1938_mixer_read(chip, 0x63) & 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) static void snd_es1938_hwv_free(struct snd_kcontrol *kcontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) struct es1938 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) chip->master_volume = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) chip->master_switch = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) chip->hw_volume = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) chip->hw_switch = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) static int snd_es1938_reg_bits(struct es1938 *chip, unsigned char reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) unsigned char mask, unsigned char val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) if (reg < 0xa0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) return snd_es1938_mixer_bits(chip, reg, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) return snd_es1938_bits(chip, reg, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) static int snd_es1938_reg_read(struct es1938 *chip, unsigned char reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) if (reg < 0xa0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) return snd_es1938_mixer_read(chip, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) return snd_es1938_read(chip, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) #define ES1938_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) .name = xname, .index = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) .info = snd_es1938_info_single, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) .get = snd_es1938_get_single, .put = snd_es1938_put_single, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) .tlv = { .p = xtlv } }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) #define ES1938_SINGLE(xname, xindex, reg, shift, mask, invert) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) .info = snd_es1938_info_single, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) .get = snd_es1938_get_single, .put = snd_es1938_put_single, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) static int snd_es1938_info_single(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) uinfo->value.integer.max = mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) static int snd_es1938_get_single(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) struct es1938 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) int reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) int shift = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) int invert = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) val = snd_es1938_reg_read(chip, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) ucontrol->value.integer.value[0] = (val >> shift) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) if (invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) static int snd_es1938_put_single(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) struct es1938 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) int reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) int shift = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) int invert = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) unsigned char val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) val = (ucontrol->value.integer.value[0] & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) if (invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) val = mask - val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) mask <<= shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) val <<= shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) return snd_es1938_reg_bits(chip, reg, mask, val) != val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) #define ES1938_DOUBLE_TLV(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert, xtlv) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) .name = xname, .index = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) .info = snd_es1938_info_double, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) .get = snd_es1938_get_double, .put = snd_es1938_put_double, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) .tlv = { .p = xtlv } }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) #define ES1938_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) .info = snd_es1938_info_double, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) .get = snd_es1938_get_double, .put = snd_es1938_put_double, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) static int snd_es1938_info_double(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) int mask = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) uinfo->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) uinfo->value.integer.max = mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) static int snd_es1938_get_double(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) struct es1938 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) int left_reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) int right_reg = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) int shift_left = (kcontrol->private_value >> 16) & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) int shift_right = (kcontrol->private_value >> 19) & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) int mask = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) int invert = (kcontrol->private_value >> 22) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) unsigned char left, right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) left = snd_es1938_reg_read(chip, left_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (left_reg != right_reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) right = snd_es1938_reg_read(chip, right_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) right = left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) ucontrol->value.integer.value[0] = (left >> shift_left) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) ucontrol->value.integer.value[1] = (right >> shift_right) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) if (invert) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) static int snd_es1938_put_double(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) struct es1938 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) int left_reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) int right_reg = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) int shift_left = (kcontrol->private_value >> 16) & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) int shift_right = (kcontrol->private_value >> 19) & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) int mask = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) int invert = (kcontrol->private_value >> 22) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) unsigned char val1, val2, mask1, mask2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) val1 = ucontrol->value.integer.value[0] & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) val2 = ucontrol->value.integer.value[1] & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) if (invert) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) val1 = mask - val1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) val2 = mask - val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) val1 <<= shift_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) val2 <<= shift_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) mask1 = mask << shift_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) mask2 = mask << shift_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) if (left_reg != right_reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) if (snd_es1938_reg_bits(chip, left_reg, mask1, val1) != val1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) change = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) if (snd_es1938_reg_bits(chip, right_reg, mask2, val2) != val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) change = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) change = (snd_es1938_reg_bits(chip, left_reg, mask1 | mask2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) val1 | val2) != (val1 | val2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) static const DECLARE_TLV_DB_RANGE(db_scale_master,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 0, 54, TLV_DB_SCALE_ITEM(-3600, 50, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 54, 63, TLV_DB_SCALE_ITEM(-900, 100, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) static const DECLARE_TLV_DB_RANGE(db_scale_audio1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 0, 8, TLV_DB_SCALE_ITEM(-3300, 300, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 8, 15, TLV_DB_SCALE_ITEM(-900, 150, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) static const DECLARE_TLV_DB_RANGE(db_scale_audio2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 0, 8, TLV_DB_SCALE_ITEM(-3450, 300, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 8, 15, TLV_DB_SCALE_ITEM(-1050, 150, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) static const DECLARE_TLV_DB_RANGE(db_scale_mic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 0, 8, TLV_DB_SCALE_ITEM(-2400, 300, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 8, 15, TLV_DB_SCALE_ITEM(0, 150, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) static const DECLARE_TLV_DB_RANGE(db_scale_line,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 0, 8, TLV_DB_SCALE_ITEM(-3150, 300, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 8, 15, TLV_DB_SCALE_ITEM(-750, 150, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) static const DECLARE_TLV_DB_SCALE(db_scale_capture, 0, 150, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) static const struct snd_kcontrol_new snd_es1938_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) ES1938_DOUBLE_TLV("Master Playback Volume", 0, 0x60, 0x62, 0, 0, 63, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) db_scale_master),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) ES1938_DOUBLE("Master Playback Switch", 0, 0x60, 0x62, 6, 6, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) .name = "Hardware Master Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) .access = SNDRV_CTL_ELEM_ACCESS_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) .info = snd_es1938_info_hw_volume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) .get = snd_es1938_get_hw_volume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) .access = (SNDRV_CTL_ELEM_ACCESS_READ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) .name = "Hardware Master Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) .info = snd_es1938_info_hw_switch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) .get = snd_es1938_get_hw_switch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) .tlv = { .p = db_scale_master },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) ES1938_SINGLE("Hardware Volume Split", 0, 0x64, 7, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) ES1938_DOUBLE_TLV("Line Playback Volume", 0, 0x3e, 0x3e, 4, 0, 15, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) db_scale_line),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) ES1938_DOUBLE("CD Playback Volume", 0, 0x38, 0x38, 4, 0, 15, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) ES1938_DOUBLE_TLV("FM Playback Volume", 0, 0x36, 0x36, 4, 0, 15, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) db_scale_mic),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) ES1938_DOUBLE_TLV("Mono Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) db_scale_line),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) ES1938_DOUBLE_TLV("Mic Playback Volume", 0, 0x1a, 0x1a, 4, 0, 15, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) db_scale_mic),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) ES1938_DOUBLE_TLV("Aux Playback Volume", 0, 0x3a, 0x3a, 4, 0, 15, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) db_scale_line),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) ES1938_DOUBLE_TLV("Capture Volume", 0, 0xb4, 0xb4, 4, 0, 15, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) db_scale_capture),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) ES1938_SINGLE("Beep Volume", 0, 0x3c, 0, 7, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) ES1938_SINGLE("Record Monitor", 0, 0xa8, 3, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) ES1938_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) .name = "Capture Source",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) .info = snd_es1938_info_mux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) .get = snd_es1938_get_mux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) .put = snd_es1938_put_mux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) ES1938_DOUBLE_TLV("Mono Input Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) db_scale_line),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) ES1938_DOUBLE_TLV("PCM Capture Volume", 0, 0x69, 0x69, 4, 0, 15, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) db_scale_audio2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) ES1938_DOUBLE_TLV("Mic Capture Volume", 0, 0x68, 0x68, 4, 0, 15, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) db_scale_mic),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) ES1938_DOUBLE_TLV("Line Capture Volume", 0, 0x6e, 0x6e, 4, 0, 15, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) db_scale_line),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) ES1938_DOUBLE_TLV("FM Capture Volume", 0, 0x6b, 0x6b, 4, 0, 15, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) db_scale_mic),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) ES1938_DOUBLE_TLV("Mono Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) db_scale_line),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) ES1938_DOUBLE_TLV("CD Capture Volume", 0, 0x6a, 0x6a, 4, 0, 15, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) db_scale_line),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) ES1938_DOUBLE_TLV("Aux Capture Volume", 0, 0x6c, 0x6c, 4, 0, 15, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) db_scale_line),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) ES1938_DOUBLE_TLV("PCM Playback Volume", 0, 0x7c, 0x7c, 4, 0, 15, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) db_scale_audio2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) ES1938_DOUBLE_TLV("PCM Playback Volume", 1, 0x14, 0x14, 4, 0, 15, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) db_scale_audio1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) ES1938_SINGLE("3D Control - Level", 0, 0x52, 0, 63, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) .name = "3D Control - Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) .info = snd_es1938_info_spatializer_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) .get = snd_es1938_get_spatializer_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) .put = snd_es1938_put_spatializer_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) ES1938_SINGLE("Mic Boost (+26dB)", 0, 0x7d, 3, 1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) };
^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) /* ---------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) /* ---------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) * initialize the chip - used by resume callback, too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) static void snd_es1938_chip_init(struct es1938 *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) /* reset chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) snd_es1938_reset(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) /* configure native mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) /* enable bus master */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) pci_set_master(chip->pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) /* disable legacy audio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) pci_write_config_word(chip->pci, SL_PCI_LEGACYCONTROL, 0x805f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) /* set DDMA base */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) pci_write_config_word(chip->pci, SL_PCI_DDMACONTROL, chip->ddma_port | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) /* set DMA/IRQ policy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) pci_write_config_dword(chip->pci, SL_PCI_CONFIG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) /* enable Audio 1, Audio 2, MPU401 IRQ and HW volume IRQ*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) outb(0xf0, SLIO_REG(chip, IRQCONTROL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) /* reset DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) outb(0, SLDM_REG(chip, DMACLEAR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) * PM support
^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 const unsigned char saved_regs[SAVED_REG_SIZE+1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 0x14, 0x1a, 0x1c, 0x3a, 0x3c, 0x3e, 0x36, 0x38,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 0x50, 0x52, 0x60, 0x61, 0x62, 0x63, 0x64, 0x68,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 0x69, 0x6a, 0x6b, 0x6d, 0x6e, 0x6f, 0x7c, 0x7d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 0xa8, 0xb4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) static int es1938_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) struct snd_card *card = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) struct es1938 *chip = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) const unsigned char *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) unsigned char *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) /* save mixer-related registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) for (s = saved_regs, d = chip->saved_regs; *s; s++, d++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) *d = snd_es1938_reg_read(chip, *s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) outb(0x00, SLIO_REG(chip, IRQCONTROL)); /* disable irqs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) if (chip->irq >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) free_irq(chip->irq, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) chip->irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) card->sync_irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) return 0;
^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) static int es1938_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) struct pci_dev *pci = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) struct snd_card *card = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) struct es1938 *chip = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) const unsigned char *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) unsigned char *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) if (request_irq(pci->irq, snd_es1938_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) IRQF_SHARED, KBUILD_MODNAME, chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) dev_err(dev, "unable to grab IRQ %d, disabling device\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) pci->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) snd_card_disconnect(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) chip->irq = pci->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) card->sync_irq = chip->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) snd_es1938_chip_init(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) /* restore mixer-related registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) for (s = saved_regs, d = chip->saved_regs; *s; s++, d++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) if (*s < 0xa0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) snd_es1938_mixer_write(chip, *s, *d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) snd_es1938_write(chip, *s, *d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) snd_power_change_state(card, SNDRV_CTL_POWER_D0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) static SIMPLE_DEV_PM_OPS(es1938_pm, es1938_suspend, es1938_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) #define ES1938_PM_OPS &es1938_pm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) #define ES1938_PM_OPS NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) #endif /* CONFIG_PM_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) #ifdef SUPPORT_JOYSTICK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) static int snd_es1938_create_gameport(struct es1938 *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) struct gameport *gp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) chip->gameport = gp = gameport_allocate_port();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) if (!gp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) dev_err(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) "cannot allocate memory for gameport\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) gameport_set_name(gp, "ES1938");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) gameport_set_dev_parent(gp, &chip->pci->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) gp->io = chip->game_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) gameport_register_port(gp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) static void snd_es1938_free_gameport(struct es1938 *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) if (chip->gameport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) gameport_unregister_port(chip->gameport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) chip->gameport = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) static inline int snd_es1938_create_gameport(struct es1938 *chip) { return -ENOSYS; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) static inline void snd_es1938_free_gameport(struct es1938 *chip) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) #endif /* SUPPORT_JOYSTICK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) static int snd_es1938_free(struct es1938 *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) /* disable irqs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) outb(0x00, SLIO_REG(chip, IRQCONTROL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) if (chip->rmidi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) snd_es1938_free_gameport(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) if (chip->irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) free_irq(chip->irq, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) pci_release_regions(chip->pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) pci_disable_device(chip->pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) kfree(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) static int snd_es1938_dev_free(struct snd_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) struct es1938 *chip = device->device_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) return snd_es1938_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) static int snd_es1938_create(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) struct pci_dev *pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) struct es1938 **rchip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) struct es1938 *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) static const struct snd_device_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) .dev_free = snd_es1938_dev_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) *rchip = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) /* enable PCI device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) if ((err = pci_enable_device(pci)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) /* check, if we can restrict PCI DMA transfers to 24 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) if (dma_set_mask(&pci->dev, DMA_BIT_MASK(24)) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(24)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) dev_err(card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) "architecture does not support 24bit PCI busmaster DMA\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) pci_disable_device(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) chip = kzalloc(sizeof(*chip), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) if (chip == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) pci_disable_device(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) spin_lock_init(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) spin_lock_init(&chip->mixer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) chip->card = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) chip->pci = pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) chip->irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) if ((err = pci_request_regions(pci, "ESS Solo-1")) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) kfree(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) pci_disable_device(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) chip->io_port = pci_resource_start(pci, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) chip->sb_port = pci_resource_start(pci, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) chip->vc_port = pci_resource_start(pci, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) chip->mpu_port = pci_resource_start(pci, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) chip->game_port = pci_resource_start(pci, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) if (request_irq(pci->irq, snd_es1938_interrupt, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) KBUILD_MODNAME, chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) snd_es1938_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) chip->irq = pci->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) card->sync_irq = chip->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) dev_dbg(card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) "create: io: 0x%lx, sb: 0x%lx, vc: 0x%lx, mpu: 0x%lx, game: 0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) chip->io_port, chip->sb_port, chip->vc_port, chip->mpu_port, chip->game_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) chip->ddma_port = chip->vc_port + 0x00; /* fix from Thomas Sailer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) snd_es1938_chip_init(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) snd_es1938_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) *rchip = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) }
^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) * Interrupt handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) * -------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) struct es1938 *chip = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) unsigned char status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) __always_unused unsigned char audiostatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) int handled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) status = inb(SLIO_REG(chip, IRQCONTROL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) dev_dbg(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) "Es1938debug - interrupt status: =0x%x\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) /* AUDIO 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) if (status & 0x10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) dev_dbg(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) "Es1938debug - AUDIO channel 1 interrupt\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) dev_dbg(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) "Es1938debug - AUDIO channel 1 DMAC DMA count: %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) inw(SLDM_REG(chip, DMACOUNT)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) dev_dbg(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) "Es1938debug - AUDIO channel 1 DMAC DMA base: %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) inl(SLDM_REG(chip, DMAADDR)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) dev_dbg(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) "Es1938debug - AUDIO channel 1 DMAC DMA status: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) inl(SLDM_REG(chip, DMASTATUS)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) /* clear irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) audiostatus = inb(SLSB_REG(chip, STATUS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) if (chip->active & ADC1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) snd_pcm_period_elapsed(chip->capture_substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) else if (chip->active & DAC1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) snd_pcm_period_elapsed(chip->playback2_substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) /* AUDIO 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) if (status & 0x20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) dev_dbg(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) "Es1938debug - AUDIO channel 2 interrupt\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) dev_dbg(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) "Es1938debug - AUDIO channel 2 DMAC DMA count: %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) inw(SLIO_REG(chip, AUDIO2DMACOUNT)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) dev_dbg(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) "Es1938debug - AUDIO channel 2 DMAC DMA base: %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) inl(SLIO_REG(chip, AUDIO2DMAADDR)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) /* clear irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) snd_es1938_mixer_bits(chip, ESSSB_IREG_AUDIO2CONTROL2, 0x80, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) if (chip->active & DAC2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) snd_pcm_period_elapsed(chip->playback1_substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) /* Hardware volume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) if (status & 0x40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) int split = snd_es1938_mixer_read(chip, 0x64) & 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_switch->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_volume->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) if (!split) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) &chip->master_switch->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) &chip->master_volume->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) /* ack interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) snd_es1938_mixer_write(chip, 0x66, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) /* MPU401 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) if (status & 0x80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) // the following line is evil! It switches off MIDI interrupt handling after the first interrupt received.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) // replacing the last 0 by 0x40 works for ESS-Solo1, but just doing nothing works as well!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) // andreas@flying-snail.de
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) // snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0); /* ack? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) if (chip->rmidi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) return IRQ_RETVAL(handled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) #define ES1938_DMA_SIZE 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) static int snd_es1938_mixer(struct es1938 *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) unsigned int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) card = chip->card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) strcpy(card->mixername, "ESS Solo-1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) for (idx = 0; idx < ARRAY_SIZE(snd_es1938_controls); idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) struct snd_kcontrol *kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) kctl = snd_ctl_new1(&snd_es1938_controls[idx], chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) switch (idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) chip->master_volume = kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) kctl->private_free = snd_es1938_hwv_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) chip->master_switch = kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) kctl->private_free = snd_es1938_hwv_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) chip->hw_volume = kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) kctl->private_free = snd_es1938_hwv_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) chip->hw_switch = kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) kctl->private_free = snd_es1938_hwv_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) if ((err = snd_ctl_add(card, kctl)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) static int snd_es1938_probe(struct pci_dev *pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) const struct pci_device_id *pci_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) static int dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) struct es1938 *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) struct snd_opl3 *opl3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) int idx, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) if (dev >= SNDRV_CARDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) if (!enable[dev]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) dev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 0, &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) for (idx = 0; idx < 5; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) if (pci_resource_start(pci, idx) == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) !(pci_resource_flags(pci, idx) & IORESOURCE_IO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) if ((err = snd_es1938_create(card, pci, &chip)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) card->private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) strcpy(card->driver, "ES1938");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) strcpy(card->shortname, "ESS ES1938 (Solo-1)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) sprintf(card->longname, "%s rev %i, irq %i",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) card->shortname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) chip->revision,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) chip->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) if ((err = snd_es1938_new_pcm(chip, 0)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) if ((err = snd_es1938_mixer(chip)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) if (snd_opl3_create(card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) SLSB_REG(chip, FMLOWADDR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) SLSB_REG(chip, FMHIGHADDR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) OPL3_HW_OPL3, 1, &opl3) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) dev_err(card->dev, "OPL3 not detected at 0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) SLSB_REG(chip, FMLOWADDR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) if ((err = snd_opl3_timer_new(opl3, 0, 1)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) chip->mpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) -1, &chip->rmidi) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) dev_err(card->dev, "unable to initialize MPU-401\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) // this line is vital for MIDI interrupt handling on ess-solo1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) // andreas@flying-snail.de
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) snd_es1938_create_gameport(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) if ((err = snd_card_register(card)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) pci_set_drvdata(pci, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) dev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) static void snd_es1938_remove(struct pci_dev *pci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) snd_card_free(pci_get_drvdata(pci));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) static struct pci_driver es1938_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) .name = KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) .id_table = snd_es1938_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) .probe = snd_es1938_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) .remove = snd_es1938_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) .pm = ES1938_PM_OPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) module_pci_driver(es1938_driver);