^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * ALSA driver for Echoaudio soundcards.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2020 Mark Hills <mark@xwax.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) MODULE_AUTHOR("Giuliano Pochini <pochini@shiny.it>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) MODULE_DESCRIPTION("Echoaudio " ECHOCARD_NAME " soundcards driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) MODULE_SUPPORTED_DEVICE("{{Echoaudio," ECHOCARD_NAME "}}");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) MODULE_DEVICE_TABLE(pci, snd_echo_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) module_param_array(index, int, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) MODULE_PARM_DESC(index, "Index value for " ECHOCARD_NAME " soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) module_param_array(id, charp, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) MODULE_PARM_DESC(id, "ID string for " ECHOCARD_NAME " soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) module_param_array(enable, bool, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) MODULE_PARM_DESC(enable, "Enable " ECHOCARD_NAME " soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static const unsigned int channels_list[10] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 999999};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static const DECLARE_TLV_DB_SCALE(db_scale_output_gain, -12800, 100, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static int get_firmware(const struct firmware **fw_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct echoaudio *chip, const short fw_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) char name[30];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (chip->fw_cache[fw_index]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) dev_dbg(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) "firmware requested: %s is cached\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) card_fw[fw_index].data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) *fw_entry = chip->fw_cache[fw_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) dev_dbg(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) "firmware requested: %s\n", card_fw[fw_index].data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) snprintf(name, sizeof(name), "ea/%s", card_fw[fw_index].data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) err = request_firmware(fw_entry, name, &chip->pci->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) dev_err(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) "get_firmware(): Firmware not available (%d)\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) chip->fw_cache[fw_index] = *fw_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static void free_firmware(const struct firmware *fw_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct echoaudio *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) dev_dbg(chip->card->dev, "firmware not released (kept in cache)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) release_firmware(fw_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static void free_firmware_cache(struct echoaudio *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) for (i = 0; i < 8 ; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (chip->fw_cache[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) release_firmware(chip->fw_cache[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) dev_dbg(chip->card->dev, "release_firmware(%d)\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) PCM interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static void audiopipe_free(struct snd_pcm_runtime *runtime)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct audiopipe *pipe = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (pipe->sgpage.area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) snd_dma_free_pages(&pipe->sgpage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) kfree(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static int hw_rule_capture_format_by_channels(struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct snd_pcm_hw_rule *rule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct snd_interval *c = hw_param_interval(params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) SNDRV_PCM_HW_PARAM_CHANNELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct snd_mask fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) snd_mask_any(&fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #ifndef ECHOCARD_HAS_STEREO_BIG_ENDIAN32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* >=2 channels cannot be S32_BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (c->min == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) fmt.bits[0] &= ~SNDRV_PCM_FMTBIT_S32_BE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return snd_mask_refine(f, &fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* > 2 channels cannot be U8 and S32_BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (c->min > 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) fmt.bits[0] &= ~(SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_BE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return snd_mask_refine(f, &fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* Mono is ok with any format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static int hw_rule_capture_channels_by_format(struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct snd_pcm_hw_rule *rule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct snd_interval *c = hw_param_interval(params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) SNDRV_PCM_HW_PARAM_CHANNELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct snd_interval ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) snd_interval_any(&ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /* S32_BE is mono (and stereo) only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (f->bits[0] == SNDRV_PCM_FMTBIT_S32_BE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ch.min = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #ifdef ECHOCARD_HAS_STEREO_BIG_ENDIAN32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) ch.max = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) ch.max = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) ch.integer = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return snd_interval_refine(c, &ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /* U8 can be only mono or stereo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (f->bits[0] == SNDRV_PCM_FMTBIT_U8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) ch.min = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ch.max = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) ch.integer = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return snd_interval_refine(c, &ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* S16_LE, S24_3LE and S32_LE support any number of channels. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static int hw_rule_playback_format_by_channels(struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct snd_pcm_hw_rule *rule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct snd_interval *c = hw_param_interval(params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) SNDRV_PCM_HW_PARAM_CHANNELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct snd_mask fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) u64 fmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) snd_mask_any(&fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) fmask = fmt.bits[0] + ((u64)fmt.bits[1] << 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /* >2 channels must be S16_LE, S24_3LE or S32_LE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (c->min > 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) fmask &= SNDRV_PCM_FMTBIT_S16_LE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) SNDRV_PCM_FMTBIT_S24_3LE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) SNDRV_PCM_FMTBIT_S32_LE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /* 1 channel must be S32_BE or S32_LE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) } else if (c->max == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) fmask &= SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #ifndef ECHOCARD_HAS_STEREO_BIG_ENDIAN32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /* 2 channels cannot be S32_BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) else if (c->min == 2 && c->max == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) fmask &= ~SNDRV_PCM_FMTBIT_S32_BE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) fmt.bits[0] &= (u32)fmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) fmt.bits[1] &= (u32)(fmask >> 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return snd_mask_refine(f, &fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static int hw_rule_playback_channels_by_format(struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct snd_pcm_hw_rule *rule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct snd_interval *c = hw_param_interval(params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) SNDRV_PCM_HW_PARAM_CHANNELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct snd_interval ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) u64 fmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) snd_interval_any(&ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) ch.integer = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) fmask = f->bits[0] + ((u64)f->bits[1] << 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* S32_BE is mono (and stereo) only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (fmask == SNDRV_PCM_FMTBIT_S32_BE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ch.min = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #ifdef ECHOCARD_HAS_STEREO_BIG_ENDIAN32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) ch.max = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ch.max = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /* U8 is stereo only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) } else if (fmask == SNDRV_PCM_FMTBIT_U8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) ch.min = ch.max = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) /* S16_LE and S24_3LE must be at least stereo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) else if (!(fmask & ~(SNDRV_PCM_FMTBIT_S16_LE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) SNDRV_PCM_FMTBIT_S24_3LE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) ch.min = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return snd_interval_refine(c, &ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /* Since the sample rate is a global setting, do allow the user to change the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) sample rate only if there is only one pcm device open. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static int hw_rule_sample_rate(struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct snd_pcm_hw_rule *rule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct snd_interval *rate = hw_param_interval(params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) SNDRV_PCM_HW_PARAM_RATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct echoaudio *chip = rule->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct snd_interval fixed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) mutex_lock(&chip->mode_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (chip->can_set_rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) snd_interval_any(&fixed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) fixed.min = fixed.max = chip->sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) err = snd_interval_refine(rate, &fixed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) mutex_unlock(&chip->mode_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static int pcm_open(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) signed char max_channels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) struct snd_pcm_runtime *runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct audiopipe *pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (max_channels <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) pipe = kzalloc(sizeof(struct audiopipe), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (!pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) pipe->index = -1; /* Not configured yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /* Set up hw capabilities and contraints */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) memcpy(&pipe->hw, &pcm_hardware_skel, sizeof(struct snd_pcm_hardware));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) dev_dbg(chip->card->dev, "max_channels=%d\n", max_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) pipe->constr.list = channels_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) pipe->constr.mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) for (i = 0; channels_list[i] <= max_channels; i++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) pipe->constr.count = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (pipe->hw.channels_max > max_channels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) pipe->hw.channels_max = max_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (chip->digital_mode == DIGITAL_MODE_ADAT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) pipe->hw.rate_max = 48000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) pipe->hw.rates &= SNDRV_PCM_RATE_8000_48000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) runtime->hw = pipe->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) runtime->private_data = pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) runtime->private_free = audiopipe_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) snd_pcm_set_sync(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) /* Only mono and any even number of channels are allowed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if ((err = snd_pcm_hw_constraint_list(runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) SNDRV_PCM_HW_PARAM_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) &pipe->constr)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /* All periods should have the same size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if ((err = snd_pcm_hw_constraint_integer(runtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /* The hw accesses memory in chunks 32 frames long and they should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 32-bytes-aligned. It's not a requirement, but it seems that IRQs are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) generated with a resolution of 32 frames. Thus we need the following */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if ((err = snd_pcm_hw_constraint_step(runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 32)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if ((err = snd_pcm_hw_constraint_step(runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 32)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) SNDRV_PCM_HW_PARAM_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) hw_rule_sample_rate, chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) SNDRV_PCM_HW_PARAM_RATE, -1)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) /* Allocate a page for the scatter-gather list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) &chip->pci->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) PAGE_SIZE, &pipe->sgpage)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) dev_err(chip->card->dev, "s-g list allocation failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * Sole ownership required to set the rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) dev_dbg(chip->card->dev, "pcm_open opencount=%d can_set_rate=%d, rate_set=%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) chip->opencount, chip->can_set_rate, chip->rate_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) chip->opencount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (chip->opencount > 1 && chip->rate_set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) chip->can_set_rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) static int pcm_analog_in_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) struct echoaudio *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if ((err = pcm_open(substream, num_analog_busses_in(chip) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) substream->number)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) SNDRV_PCM_HW_PARAM_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) hw_rule_capture_channels_by_format, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) SNDRV_PCM_HW_PARAM_FORMAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) hw_rule_capture_format_by_channels, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static int pcm_analog_out_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) struct echoaudio *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) int max_channels, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) #ifdef ECHOCARD_HAS_VMIXER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) max_channels = num_pipes_out(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) max_channels = num_analog_busses_out(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if ((err = pcm_open(substream, max_channels - substream->number)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) SNDRV_PCM_HW_PARAM_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) hw_rule_playback_channels_by_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) SNDRV_PCM_HW_PARAM_FORMAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) hw_rule_playback_format_by_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) #ifdef ECHOCARD_HAS_DIGITAL_IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) static int pcm_digital_in_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) struct echoaudio *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) int err, max_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) max_channels = num_digital_busses_in(chip) - substream->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) mutex_lock(&chip->mode_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (chip->digital_mode == DIGITAL_MODE_ADAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) err = pcm_open(substream, max_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) else /* If the card has ADAT, subtract the 6 channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * that S/PDIF doesn't have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) err = pcm_open(substream, max_channels - ECHOCARD_HAS_ADAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) goto din_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) SNDRV_PCM_HW_PARAM_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) hw_rule_capture_channels_by_format, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) goto din_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) SNDRV_PCM_HW_PARAM_FORMAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) hw_rule_capture_format_by_channels, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) goto din_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) din_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) mutex_unlock(&chip->mode_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) #ifndef ECHOCARD_HAS_VMIXER /* See the note in snd_echo_new_pcm() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) static int pcm_digital_out_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) struct echoaudio *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) int err, max_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) max_channels = num_digital_busses_out(chip) - substream->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) mutex_lock(&chip->mode_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (chip->digital_mode == DIGITAL_MODE_ADAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) err = pcm_open(substream, max_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) else /* If the card has ADAT, subtract the 6 channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * that S/PDIF doesn't have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) err = pcm_open(substream, max_channels - ECHOCARD_HAS_ADAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) goto dout_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) SNDRV_PCM_HW_PARAM_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) hw_rule_playback_channels_by_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) NULL, SNDRV_PCM_HW_PARAM_FORMAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) -1)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) goto dout_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) SNDRV_PCM_HW_PARAM_FORMAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) hw_rule_playback_format_by_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) NULL, SNDRV_PCM_HW_PARAM_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) -1)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) goto dout_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) dout_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) mutex_unlock(&chip->mode_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) #endif /* !ECHOCARD_HAS_VMIXER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) #endif /* ECHOCARD_HAS_DIGITAL_IO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) static int pcm_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) struct echoaudio *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) /* Nothing to do here. Audio is already off and pipe will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) * freed by its callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) mutex_lock(&chip->mode_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) dev_dbg(chip->card->dev, "pcm_open opencount=%d can_set_rate=%d, rate_set=%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) chip->opencount, chip->can_set_rate, chip->rate_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) chip->opencount--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) switch (chip->opencount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) chip->can_set_rate = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) chip->rate_set = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) break;
^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) mutex_unlock(&chip->mode_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) /* Channel allocation and scatter-gather list setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) static int init_engine(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct snd_pcm_hw_params *hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) int pipe_index, int interleave)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) int err, per, rest, page, edge, offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) struct audiopipe *pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) pipe = (struct audiopipe *) substream->runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) /* Sets up che hardware. If it's already initialized, reset and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * redo with the new parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) spin_lock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (pipe->index >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) dev_dbg(chip->card->dev, "hwp_ie free(%d)\n", pipe->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) err = free_pipes(chip, pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) snd_BUG_ON(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) chip->substream[pipe->index] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) err = allocate_pipes(chip, pipe, pipe_index, interleave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) spin_unlock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) dev_err(chip->card->dev, "allocate_pipes(%d) err=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) pipe_index, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) spin_unlock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) dev_dbg(chip->card->dev, "allocate_pipes()=%d\n", pipe_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) dev_dbg(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) "pcm_hw_params (bufsize=%dB periods=%d persize=%dB)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) params_buffer_bytes(hw_params), params_periods(hw_params),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) params_period_bytes(hw_params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) sglist_init(chip, pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) edge = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) for (offs = page = per = 0; offs < params_buffer_bytes(hw_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) per++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) rest = params_period_bytes(hw_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if (offs + rest > params_buffer_bytes(hw_params))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) rest = params_buffer_bytes(hw_params) - offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) while (rest) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) dma_addr_t addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) addr = snd_pcm_sgbuf_get_addr(substream, offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (rest <= edge - offs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) sglist_add_mapping(chip, pipe, addr, rest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) sglist_add_irq(chip, pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) offs += rest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) rest = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) sglist_add_mapping(chip, pipe, addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) edge - offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) rest -= edge - offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) offs = edge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (offs == edge) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) edge += PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) page++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) /* Close the ring buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) sglist_wrap(chip, pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) /* This stuff is used by the irq handler, so it must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) * initialized before chip->substream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) pipe->last_period = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) pipe->last_counter = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) pipe->position = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) smp_wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) chip->substream[pipe_index] = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) chip->rate_set = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) spin_lock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) set_sample_rate(chip, hw_params->rate_num / hw_params->rate_den);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) spin_unlock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) return 0;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static int pcm_analog_in_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) struct snd_pcm_hw_params *hw_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) struct echoaudio *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return init_engine(substream, hw_params, px_analog_in(chip) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) substream->number, params_channels(hw_params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) static int pcm_analog_out_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) struct snd_pcm_hw_params *hw_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) return init_engine(substream, hw_params, substream->number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) params_channels(hw_params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) #ifdef ECHOCARD_HAS_DIGITAL_IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) static int pcm_digital_in_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) struct snd_pcm_hw_params *hw_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) struct echoaudio *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) return init_engine(substream, hw_params, px_digital_in(chip) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) substream->number, params_channels(hw_params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) #ifndef ECHOCARD_HAS_VMIXER /* See the note in snd_echo_new_pcm() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) static int pcm_digital_out_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) struct snd_pcm_hw_params *hw_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) struct echoaudio *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) return init_engine(substream, hw_params, px_digital_out(chip) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) substream->number, params_channels(hw_params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) #endif /* !ECHOCARD_HAS_VMIXER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) #endif /* ECHOCARD_HAS_DIGITAL_IO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) static int pcm_hw_free(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 echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) struct audiopipe *pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) pipe = (struct audiopipe *) substream->runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) spin_lock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) if (pipe->index >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) dev_dbg(chip->card->dev, "pcm_hw_free(%d)\n", pipe->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) free_pipes(chip, pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) chip->substream[pipe->index] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) pipe->index = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) spin_unlock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) static int pcm_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) struct echoaudio *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) struct audioformat format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) int pipe_index = ((struct audiopipe *)runtime->private_data)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) dev_dbg(chip->card->dev, "Prepare rate=%d format=%d channels=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) runtime->rate, runtime->format, runtime->channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) format.interleave = runtime->channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) format.data_are_bigendian = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) format.mono_to_stereo = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) switch (runtime->format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) case SNDRV_PCM_FORMAT_U8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) format.bits_per_sample = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) case SNDRV_PCM_FORMAT_S16_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) format.bits_per_sample = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) case SNDRV_PCM_FORMAT_S24_3LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) format.bits_per_sample = 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) case SNDRV_PCM_FORMAT_S32_BE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) format.data_are_bigendian = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) case SNDRV_PCM_FORMAT_S32_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) format.bits_per_sample = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) dev_err(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) "Prepare error: unsupported format %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) runtime->format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) if (snd_BUG_ON(pipe_index >= px_num(chip)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) * We passed checks we can do independently; now take
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) * exclusive control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) spin_lock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (snd_BUG_ON(!is_pipe_allocated(chip, pipe_index))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) spin_unlock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) set_audio_format(chip, pipe_index, &format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) spin_unlock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) struct echoaudio *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) struct audiopipe *pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) u32 channelmask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) struct snd_pcm_substream *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) snd_pcm_group_for_each_entry(s, substream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) for (i = 0; i < DSP_MAXPIPES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (s == chip->substream[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) channelmask |= 1 << i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) snd_pcm_trigger_done(s, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) spin_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) for (i = 0; i < DSP_MAXPIPES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (channelmask & (1 << i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) pipe = chip->substream[i]->runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) switch (pipe->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) case PIPE_STATE_STOPPED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) pipe->last_period = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) pipe->last_counter = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) pipe->position = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) *pipe->dma_counter = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) case PIPE_STATE_PAUSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) pipe->state = PIPE_STATE_STARTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) case PIPE_STATE_STARTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) err = start_transport(chip, channelmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) chip->pipe_cyclic_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) for (i = 0; i < DSP_MAXPIPES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (channelmask & (1 << i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) pipe = chip->substream[i]->runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) pipe->state = PIPE_STATE_STOPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) err = stop_transport(chip, channelmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) for (i = 0; i < DSP_MAXPIPES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) if (channelmask & (1 << i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) pipe = chip->substream[i]->runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) pipe->state = PIPE_STATE_PAUSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) err = pause_transport(chip, channelmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) spin_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) static snd_pcm_uframes_t pcm_pointer(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) struct audiopipe *pipe = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) u32 counter, step;
^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) * IRQ handling runs concurrently. Do not share tracking of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) * counter with it, which would race or require locking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) counter = le32_to_cpu(*pipe->dma_counter); /* presumed atomic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) step = counter - pipe->last_counter; /* handles wrapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) pipe->last_counter = counter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) /* counter doesn't neccessarily wrap on a multiple of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) * buffer_size, so can't derive the position; must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) * accumulate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) pipe->position += step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) pipe->position %= frames_to_bytes(runtime, runtime->buffer_size); /* wrap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) return bytes_to_frames(runtime, pipe->position);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) /* pcm *_ops structures */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) static const struct snd_pcm_ops analog_playback_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) .open = pcm_analog_out_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) .close = pcm_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) .hw_params = pcm_analog_out_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) .hw_free = pcm_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) .prepare = pcm_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) .trigger = pcm_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) .pointer = pcm_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) static const struct snd_pcm_ops analog_capture_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) .open = pcm_analog_in_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) .close = pcm_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) .hw_params = pcm_analog_in_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) .hw_free = pcm_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) .prepare = pcm_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) .trigger = pcm_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) .pointer = pcm_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) #ifdef ECHOCARD_HAS_DIGITAL_IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) #ifndef ECHOCARD_HAS_VMIXER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) static const struct snd_pcm_ops digital_playback_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) .open = pcm_digital_out_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) .close = pcm_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) .hw_params = pcm_digital_out_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) .hw_free = pcm_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) .prepare = pcm_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) .trigger = pcm_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) .pointer = pcm_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) #endif /* !ECHOCARD_HAS_VMIXER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) static const struct snd_pcm_ops digital_capture_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) .open = pcm_digital_in_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) .close = pcm_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) .hw_params = pcm_digital_in_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) .hw_free = pcm_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) .prepare = pcm_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) .trigger = pcm_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) .pointer = pcm_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) #endif /* ECHOCARD_HAS_DIGITAL_IO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) /* Preallocate memory only for the first substream because it's the most
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) * used one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) static void snd_echo_preallocate_pages(struct snd_pcm *pcm, struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) struct snd_pcm_substream *ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) int stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) for (stream = 0; stream < 2; stream++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) for (ss = pcm->streams[stream].substream; ss; ss = ss->next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) snd_pcm_set_managed_buffer(ss, SNDRV_DMA_TYPE_DEV_SG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) ss->number ? 0 : 128<<10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) 256<<10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) /*<--snd_echo_probe() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) static int snd_echo_new_pcm(struct echoaudio *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) #ifdef ECHOCARD_HAS_VMIXER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) /* This card has a Vmixer, that is there is no direct mapping from PCM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) streams to physical outputs. The user can mix the streams as he wishes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) via control interface and it's possible to send any stream to any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) output, thus it makes no sense to keep analog and digital outputs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) separated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) /* PCM#0 Virtual outputs and analog inputs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if ((err = snd_pcm_new(chip->card, "PCM", 0, num_pipes_out(chip),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) num_analog_busses_in(chip), &pcm)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) pcm->private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) chip->analog_pcm = pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) strcpy(pcm->name, chip->card->shortname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &analog_playback_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) snd_echo_preallocate_pages(pcm, &chip->pci->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) #ifdef ECHOCARD_HAS_DIGITAL_IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) /* PCM#1 Digital inputs, no outputs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if ((err = snd_pcm_new(chip->card, "Digital PCM", 1, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) num_digital_busses_in(chip), &pcm)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) pcm->private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) chip->digital_pcm = pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) strcpy(pcm->name, chip->card->shortname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) snd_echo_preallocate_pages(pcm, &chip->pci->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) #endif /* ECHOCARD_HAS_DIGITAL_IO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) #else /* ECHOCARD_HAS_VMIXER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) /* The card can manage substreams formed by analog and digital channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) at the same time, but I prefer to keep analog and digital channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) separated, because that mixed thing is confusing and useless. So we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) register two PCM devices: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) /* PCM#0 Analog i/o */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if ((err = snd_pcm_new(chip->card, "Analog PCM", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) num_analog_busses_out(chip),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) num_analog_busses_in(chip), &pcm)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) pcm->private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) chip->analog_pcm = pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) strcpy(pcm->name, chip->card->shortname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &analog_playback_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) snd_echo_preallocate_pages(pcm, &chip->pci->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) #ifdef ECHOCARD_HAS_DIGITAL_IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) /* PCM#1 Digital i/o */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if ((err = snd_pcm_new(chip->card, "Digital PCM", 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) num_digital_busses_out(chip),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) num_digital_busses_in(chip), &pcm)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) pcm->private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) chip->digital_pcm = pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) strcpy(pcm->name, chip->card->shortname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &digital_playback_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) snd_echo_preallocate_pages(pcm, &chip->pci->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) #endif /* ECHOCARD_HAS_DIGITAL_IO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) #endif /* ECHOCARD_HAS_VMIXER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) Control interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) #if !defined(ECHOCARD_HAS_VMIXER) || defined(ECHOCARD_HAS_LINE_OUT_GAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) /******************* PCM output volume *******************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) static int snd_echo_output_gain_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) uinfo->count = num_busses_out(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) uinfo->value.integer.min = ECHOGAIN_MINOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) uinfo->value.integer.max = ECHOGAIN_MAXOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) static int snd_echo_output_gain_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) int c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) for (c = 0; c < num_busses_out(chip); c++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) ucontrol->value.integer.value[c] = chip->output_gain[c];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) static int snd_echo_output_gain_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) int c, changed, gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) spin_lock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) for (c = 0; c < num_busses_out(chip); c++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) gain = ucontrol->value.integer.value[c];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) /* Ignore out of range values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) if (chip->output_gain[c] != gain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) set_output_gain(chip, c, gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) if (changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) update_output_line_level(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) spin_unlock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) #ifdef ECHOCARD_HAS_LINE_OUT_GAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) /* On the Mia this one controls the line-out volume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) static const struct snd_kcontrol_new snd_echo_line_output_gain = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) .name = "Line Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) SNDRV_CTL_ELEM_ACCESS_TLV_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) .info = snd_echo_output_gain_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) .get = snd_echo_output_gain_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) .put = snd_echo_output_gain_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) .tlv = {.p = db_scale_output_gain},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) static const struct snd_kcontrol_new snd_echo_pcm_output_gain = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) .name = "PCM Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) .info = snd_echo_output_gain_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) .get = snd_echo_output_gain_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) .put = snd_echo_output_gain_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) .tlv = {.p = db_scale_output_gain},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) #endif /* !ECHOCARD_HAS_VMIXER || ECHOCARD_HAS_LINE_OUT_GAIN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) #ifdef ECHOCARD_HAS_INPUT_GAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) /******************* Analog input volume *******************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) static int snd_echo_input_gain_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) uinfo->count = num_analog_busses_in(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) uinfo->value.integer.min = ECHOGAIN_MININP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) uinfo->value.integer.max = ECHOGAIN_MAXINP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) static int snd_echo_input_gain_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) int c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) for (c = 0; c < num_analog_busses_in(chip); c++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) ucontrol->value.integer.value[c] = chip->input_gain[c];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) static int snd_echo_input_gain_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) int c, gain, changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) spin_lock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) for (c = 0; c < num_analog_busses_in(chip); c++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) gain = ucontrol->value.integer.value[c];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) /* Ignore out of range values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) if (gain < ECHOGAIN_MININP || gain > ECHOGAIN_MAXINP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) if (chip->input_gain[c] != gain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) set_input_gain(chip, c, gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) update_input_line_level(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) spin_unlock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) static const DECLARE_TLV_DB_SCALE(db_scale_input_gain, -2500, 50, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) static const struct snd_kcontrol_new snd_echo_line_input_gain = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) .name = "Line Capture Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) .info = snd_echo_input_gain_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) .get = snd_echo_input_gain_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) .put = snd_echo_input_gain_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) .tlv = {.p = db_scale_input_gain},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) #endif /* ECHOCARD_HAS_INPUT_GAIN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) #ifdef ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) /************ Analog output nominal level (+4dBu / -10dBV) ***************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) static int snd_echo_output_nominal_info (struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) uinfo->count = num_analog_busses_out(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) uinfo->value.integer.max = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) static int snd_echo_output_nominal_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) int c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) for (c = 0; c < num_analog_busses_out(chip); c++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) ucontrol->value.integer.value[c] = chip->nominal_level[c];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) static int snd_echo_output_nominal_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) int c, changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) spin_lock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) for (c = 0; c < num_analog_busses_out(chip); c++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) if (chip->nominal_level[c] != ucontrol->value.integer.value[c]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) set_nominal_level(chip, c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) ucontrol->value.integer.value[c]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) if (changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) update_output_line_level(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) spin_unlock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) static const struct snd_kcontrol_new snd_echo_output_nominal_level = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) .name = "Line Playback Switch (-10dBV)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) .info = snd_echo_output_nominal_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) .get = snd_echo_output_nominal_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) .put = snd_echo_output_nominal_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) #endif /* ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) #ifdef ECHOCARD_HAS_INPUT_NOMINAL_LEVEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) /*************** Analog input nominal level (+4dBu / -10dBV) ***************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) static int snd_echo_input_nominal_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) uinfo->count = num_analog_busses_in(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) uinfo->value.integer.max = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) static int snd_echo_input_nominal_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) int c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) for (c = 0; c < num_analog_busses_in(chip); c++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) ucontrol->value.integer.value[c] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) chip->nominal_level[bx_analog_in(chip) + c];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) static int snd_echo_input_nominal_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) int c, changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) spin_lock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) for (c = 0; c < num_analog_busses_in(chip); c++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) if (chip->nominal_level[bx_analog_in(chip) + c] !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) ucontrol->value.integer.value[c]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) set_nominal_level(chip, bx_analog_in(chip) + c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) ucontrol->value.integer.value[c]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) if (changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) update_output_line_level(chip); /* "Output" is not a mistake
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) * here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) spin_unlock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) static const struct snd_kcontrol_new snd_echo_intput_nominal_level = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) .name = "Line Capture Switch (-10dBV)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) .info = snd_echo_input_nominal_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) .get = snd_echo_input_nominal_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) .put = snd_echo_input_nominal_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) #endif /* ECHOCARD_HAS_INPUT_NOMINAL_LEVEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) #ifdef ECHOCARD_HAS_MONITOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) /******************* Monitor mixer *******************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) static int snd_echo_mixer_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) uinfo->value.integer.min = ECHOGAIN_MINOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) uinfo->value.integer.max = ECHOGAIN_MAXOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) static int snd_echo_mixer_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) struct echoaudio *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) unsigned int out = ucontrol->id.index / num_busses_in(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) unsigned int in = ucontrol->id.index % num_busses_in(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) if (out >= ECHO_MAXAUDIOOUTPUTS || in >= ECHO_MAXAUDIOINPUTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) ucontrol->value.integer.value[0] = chip->monitor_gain[out][in];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) return 0;
^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 int snd_echo_mixer_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) int changed, gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) unsigned int out, in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) out = ucontrol->id.index / num_busses_in(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) in = ucontrol->id.index % num_busses_in(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) if (out >= ECHO_MAXAUDIOOUTPUTS || in >= ECHO_MAXAUDIOINPUTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) gain = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) if (chip->monitor_gain[out][in] != gain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) spin_lock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) set_monitor_gain(chip, out, in, gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) update_output_line_level(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) spin_unlock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) static struct snd_kcontrol_new snd_echo_monitor_mixer = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) .name = "Monitor Mixer Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) .info = snd_echo_mixer_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) .get = snd_echo_mixer_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) .put = snd_echo_mixer_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) .tlv = {.p = db_scale_output_gain},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) #endif /* ECHOCARD_HAS_MONITOR */
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) #ifdef ECHOCARD_HAS_VMIXER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) /******************* Vmixer *******************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) static int snd_echo_vmixer_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) uinfo->value.integer.min = ECHOGAIN_MINOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) uinfo->value.integer.max = ECHOGAIN_MAXOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) static int snd_echo_vmixer_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) ucontrol->value.integer.value[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) chip->vmixer_gain[ucontrol->id.index / num_pipes_out(chip)]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) [ucontrol->id.index % num_pipes_out(chip)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) static int snd_echo_vmixer_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) int gain, changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) short vch, out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) out = ucontrol->id.index / num_pipes_out(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) vch = ucontrol->id.index % num_pipes_out(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) gain = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) if (chip->vmixer_gain[out][vch] != ucontrol->value.integer.value[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) spin_lock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) set_vmixer_gain(chip, out, vch, ucontrol->value.integer.value[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) update_vmixer_level(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) spin_unlock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) static struct snd_kcontrol_new snd_echo_vmixer = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) .name = "VMixer Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) .info = snd_echo_vmixer_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) .get = snd_echo_vmixer_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) .put = snd_echo_vmixer_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) .tlv = {.p = db_scale_output_gain},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) #endif /* ECHOCARD_HAS_VMIXER */
^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) #ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) /******************* Digital mode switch *******************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) static int snd_echo_digital_mode_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) static const char * const names[4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) "S/PDIF Coaxial", "S/PDIF Optical", "ADAT Optical",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) "S/PDIF Cdrom"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) return snd_ctl_enum_info(uinfo, 1, chip->num_digital_modes, names);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) static int snd_echo_digital_mode_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) int i, mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) mode = chip->digital_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) for (i = chip->num_digital_modes - 1; i >= 0; i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) if (mode == chip->digital_mode_list[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) ucontrol->value.enumerated.item[0] = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) return 0;
^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) static int snd_echo_digital_mode_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) int changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) unsigned short emode, dmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) emode = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) if (emode >= chip->num_digital_modes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) dmode = chip->digital_mode_list[emode];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) if (dmode != chip->digital_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) /* mode_mutex is required to make this operation atomic wrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) pcm_digital_*_open() and set_input_clock() functions. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) mutex_lock(&chip->mode_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) /* Do not allow the user to change the digital mode when a pcm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) device is open because it also changes the number of channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) and the allowed sample rates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) if (chip->opencount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) changed = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) changed = set_digital_mode(chip, dmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) /* If we had to change the clock source, report it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) if (changed > 0 && chip->clock_src_ctl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) snd_ctl_notify(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) SNDRV_CTL_EVENT_MASK_VALUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) &chip->clock_src_ctl->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) dev_dbg(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) "SDM() =%d\n", changed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) if (changed >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) changed = 1; /* No errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) mutex_unlock(&chip->mode_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) static const struct snd_kcontrol_new snd_echo_digital_mode_switch = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) .name = "Digital mode Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) .iface = SNDRV_CTL_ELEM_IFACE_CARD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) .info = snd_echo_digital_mode_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) .get = snd_echo_digital_mode_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) .put = snd_echo_digital_mode_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) #endif /* ECHOCARD_HAS_DIGITAL_MODE_SWITCH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) #ifdef ECHOCARD_HAS_DIGITAL_IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) /******************* S/PDIF mode switch *******************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) static int snd_echo_spdif_mode_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) static const char * const names[2] = {"Consumer", "Professional"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) return snd_ctl_enum_info(uinfo, 1, 2, names);
^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 int snd_echo_spdif_mode_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) ucontrol->value.enumerated.item[0] = !!chip->professional_spdif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) static int snd_echo_spdif_mode_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) int mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) mode = !!ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) if (mode != chip->professional_spdif) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) spin_lock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) set_professional_spdif(chip, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) spin_unlock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) static const struct snd_kcontrol_new snd_echo_spdif_mode_switch = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) .name = "S/PDIF mode Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) .iface = SNDRV_CTL_ELEM_IFACE_CARD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) .info = snd_echo_spdif_mode_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) .get = snd_echo_spdif_mode_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) .put = snd_echo_spdif_mode_put,
^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) #endif /* ECHOCARD_HAS_DIGITAL_IO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) #ifdef ECHOCARD_HAS_EXTERNAL_CLOCK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) /******************* Select input clock source *******************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) static int snd_echo_clock_source_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) static const char * const names[8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) "Internal", "Word", "Super", "S/PDIF", "ADAT", "ESync",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) "ESync96", "MTC"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) return snd_ctl_enum_info(uinfo, 1, chip->num_clock_sources, names);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) static int snd_echo_clock_source_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) int i, clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) clock = chip->input_clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) for (i = 0; i < chip->num_clock_sources; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) if (clock == chip->clock_source_list[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) ucontrol->value.enumerated.item[0] = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) static int snd_echo_clock_source_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) int changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) unsigned int eclock, dclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) eclock = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) if (eclock >= chip->input_clock_types)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) dclock = chip->clock_source_list[eclock];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) if (chip->input_clock != dclock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) mutex_lock(&chip->mode_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) spin_lock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) if ((changed = set_input_clock(chip, dclock)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) changed = 1; /* no errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) spin_unlock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) mutex_unlock(&chip->mode_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) if (changed < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) dev_dbg(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) "seticlk val%d err 0x%x\n", dclock, changed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) static const struct snd_kcontrol_new snd_echo_clock_source_switch = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) .name = "Sample Clock Source",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) .iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) .info = snd_echo_clock_source_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) .get = snd_echo_clock_source_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) .put = snd_echo_clock_source_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) #endif /* ECHOCARD_HAS_EXTERNAL_CLOCK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) #ifdef ECHOCARD_HAS_PHANTOM_POWER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) /******************* Phantom power switch *******************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) #define snd_echo_phantom_power_info snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) static int snd_echo_phantom_power_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) struct echoaudio *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) ucontrol->value.integer.value[0] = chip->phantom_power;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) static int snd_echo_phantom_power_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) struct echoaudio *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) int power, changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) power = !!ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) if (chip->phantom_power != power) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) spin_lock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) changed = set_phantom_power(chip, power);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) spin_unlock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) if (changed == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) changed = 1; /* no errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) static const struct snd_kcontrol_new snd_echo_phantom_power_switch = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) .name = "Phantom power Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) .iface = SNDRV_CTL_ELEM_IFACE_CARD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) .info = snd_echo_phantom_power_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) .get = snd_echo_phantom_power_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) .put = snd_echo_phantom_power_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) #endif /* ECHOCARD_HAS_PHANTOM_POWER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) #ifdef ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) /******************* Digital input automute switch *******************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) #define snd_echo_automute_info snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) static int snd_echo_automute_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) struct echoaudio *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) ucontrol->value.integer.value[0] = chip->digital_in_automute;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) static int snd_echo_automute_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) struct echoaudio *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) int automute, changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) automute = !!ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) if (chip->digital_in_automute != automute) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) spin_lock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) changed = set_input_auto_mute(chip, automute);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) spin_unlock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) if (changed == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) changed = 1; /* no errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) static const struct snd_kcontrol_new snd_echo_automute_switch = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) .name = "Digital Capture Switch (automute)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) .iface = SNDRV_CTL_ELEM_IFACE_CARD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) .info = snd_echo_automute_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) .get = snd_echo_automute_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) .put = snd_echo_automute_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) #endif /* ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) /******************* VU-meters switch *******************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) #define snd_echo_vumeters_switch_info snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) static int snd_echo_vumeters_switch_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) spin_lock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) set_meters_on(chip, ucontrol->value.integer.value[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) spin_unlock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) static const struct snd_kcontrol_new snd_echo_vumeters_switch = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) .name = "VU-meters Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) .iface = SNDRV_CTL_ELEM_IFACE_CARD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) .access = SNDRV_CTL_ELEM_ACCESS_WRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) .info = snd_echo_vumeters_switch_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) .put = snd_echo_vumeters_switch_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) };
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) /***** Read VU-meters (input, output, analog and digital together) *****/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) static int snd_echo_vumeters_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) uinfo->count = 96;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) uinfo->value.integer.min = ECHOGAIN_MINOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) uinfo->value.integer.max = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) static int snd_echo_vumeters_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) get_audio_meters(chip, ucontrol->value.integer.value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) static const struct snd_kcontrol_new snd_echo_vumeters = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) .name = "VU-meters",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) .access = SNDRV_CTL_ELEM_ACCESS_READ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) SNDRV_CTL_ELEM_ACCESS_VOLATILE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) SNDRV_CTL_ELEM_ACCESS_TLV_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) .info = snd_echo_vumeters_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) .get = snd_echo_vumeters_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) .tlv = {.p = db_scale_output_gain},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) /*** Channels info - it exports informations about the number of channels ***/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) static int snd_echo_channels_info_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) uinfo->count = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) uinfo->value.integer.max = 1 << ECHO_CLOCK_NUMBER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) static int snd_echo_channels_info_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) int detected, clocks, bit, src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) ucontrol->value.integer.value[0] = num_busses_in(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) ucontrol->value.integer.value[1] = num_analog_busses_in(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) ucontrol->value.integer.value[2] = num_busses_out(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) ucontrol->value.integer.value[3] = num_analog_busses_out(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) ucontrol->value.integer.value[4] = num_pipes_out(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) /* Compute the bitmask of the currently valid input clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) detected = detect_input_clocks(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) clocks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) src = chip->num_clock_sources - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) for (bit = ECHO_CLOCK_NUMBER - 1; bit >= 0; bit--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) if (detected & (1 << bit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) for (; src >= 0; src--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) if (bit == chip->clock_source_list[src]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) clocks |= 1 << src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) ucontrol->value.integer.value[5] = clocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) static const struct snd_kcontrol_new snd_echo_channels_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) .name = "Channels info",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) .iface = SNDRV_CTL_ELEM_IFACE_HWDEP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) .info = snd_echo_channels_info_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) .get = snd_echo_channels_info_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) IRQ Handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) /* Check if a period has elapsed since last interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) * Don't make any updates to state; PCM core handles this with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) * correct locks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) * \return true if a period has elapsed, otherwise false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) static bool period_has_elapsed(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) struct audiopipe *pipe = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) u32 counter, step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) size_t period_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) if (pipe->state != PIPE_STATE_STARTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) period_bytes = frames_to_bytes(runtime, runtime->period_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) counter = le32_to_cpu(*pipe->dma_counter); /* presumed atomic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) step = counter - pipe->last_period; /* handles wrapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) step -= step % period_bytes; /* acknowledge whole periods only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) if (step == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) return false; /* haven't advanced a whole period yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) pipe->last_period += step; /* used exclusively by us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) static irqreturn_t snd_echo_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) struct echoaudio *chip = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) int ss, st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) spin_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) st = service_irq(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) if (st < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) spin_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) /* The hardware doesn't tell us which substream caused the irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) thus we have to check all running substreams. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) for (ss = 0; ss < DSP_MAXPIPES; ss++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) struct snd_pcm_substream *substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) substream = chip->substream[ss];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) if (substream && period_has_elapsed(substream)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) spin_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) snd_pcm_period_elapsed(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) spin_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) spin_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) #ifdef ECHOCARD_HAS_MIDI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) if (st > 0 && chip->midi_in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) snd_rawmidi_receive(chip->midi_in, chip->midi_buffer, st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) dev_dbg(chip->card->dev, "rawmidi_iread=%d\n", st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) Module construction / destruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) static int snd_echo_free(struct echoaudio *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) if (chip->comm_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) rest_in_peace(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) if (chip->irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) free_irq(chip->irq, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) if (chip->comm_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) snd_dma_free_pages(&chip->commpage_dma_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) iounmap(chip->dsp_registers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) release_and_free_resource(chip->iores);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) pci_disable_device(chip->pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) /* release chip data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) free_firmware_cache(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) kfree(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) static int snd_echo_dev_free(struct snd_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) struct echoaudio *chip = device->device_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) return snd_echo_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) /* <--snd_echo_probe() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) static int snd_echo_create(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) struct pci_dev *pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) struct echoaudio **rchip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) size_t sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) static const struct snd_device_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) .dev_free = snd_echo_dev_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) *rchip = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) pci_write_config_byte(pci, PCI_LATENCY_TIMER, 0xC0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) if ((err = pci_enable_device(pci)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) pci_set_master(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) /* Allocate chip if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) if (!*rchip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) chip = kzalloc(sizeof(*chip), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) if (!chip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) pci_disable_device(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) dev_dbg(card->dev, "chip=%p\n", chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) spin_lock_init(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) chip->card = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) chip->pci = pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) chip->irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) chip->opencount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) mutex_init(&chip->mode_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) chip->can_set_rate = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) /* If this was called from the resume function, chip is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) * already allocated and it contains current card settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) chip = *rchip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) /* PCI resource allocation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) chip->dsp_registers_phys = pci_resource_start(pci, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) sz = pci_resource_len(pci, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) if (sz > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) sz = PAGE_SIZE; /* We map only the required part */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) if ((chip->iores = request_mem_region(chip->dsp_registers_phys, sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) ECHOCARD_NAME)) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) dev_err(chip->card->dev, "cannot get memory region\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) snd_echo_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) chip->dsp_registers = ioremap(chip->dsp_registers_phys, sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) if (!chip->dsp_registers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) dev_err(chip->card->dev, "ioremap failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) snd_echo_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) KBUILD_MODNAME, chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) dev_err(chip->card->dev, "cannot grab irq\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) snd_echo_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) chip->irq = pci->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) card->sync_irq = chip->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) dev_dbg(card->dev, "pci=%p irq=%d subdev=%04x Init hardware...\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) chip->pci, chip->irq, chip->pci->subsystem_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) /* Create the DSP comm page - this is the area of memory used for most
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) of the communication with the DSP, which accesses it via bus mastering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &chip->pci->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) sizeof(struct comm_page),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) &chip->commpage_dma_buf) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) dev_err(chip->card->dev, "cannot allocate the comm page\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) snd_echo_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) chip->comm_page_phys = chip->commpage_dma_buf.addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) chip->comm_page = (struct comm_page *)chip->commpage_dma_buf.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) if (err >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) err = set_mixer_defaults(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) dev_err(card->dev, "init_hw err=%d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) snd_echo_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) snd_echo_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) *rchip = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) /* Init done ! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) /* constructor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) static int snd_echo_probe(struct pci_dev *pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) const struct pci_device_id *pci_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) static int dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) char *dsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) __maybe_unused int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) if (dev >= SNDRV_CARDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) if (!enable[dev]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) dev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 0, &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) chip = NULL; /* Tells snd_echo_create to allocate chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) if ((err = snd_echo_create(card, pci, &chip)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) strcpy(card->driver, "Echo_" ECHOCARD_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) strcpy(card->shortname, chip->card_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) dsp = "56301";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) if (pci_id->device == 0x3410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) dsp = "56361";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) sprintf(card->longname, "%s rev.%d (DSP%s) at 0x%lx irq %i",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) card->shortname, pci_id->subdevice & 0x000f, dsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) chip->dsp_registers_phys, chip->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) if ((err = snd_echo_new_pcm(chip)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) dev_err(chip->card->dev, "new pcm error %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) #ifdef ECHOCARD_HAS_MIDI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) if (chip->has_midi) { /* Some Mia's do not have midi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) if ((err = snd_echo_midi_create(card, chip)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) dev_err(chip->card->dev, "new midi error %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) #ifdef ECHOCARD_HAS_VMIXER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) snd_echo_vmixer.count = num_pipes_out(chip) * num_busses_out(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vmixer, chip))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) goto ctl_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) #ifdef ECHOCARD_HAS_LINE_OUT_GAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) err = snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) snd_ctl_new1(&snd_echo_line_output_gain, chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) goto ctl_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) #else /* ECHOCARD_HAS_VMIXER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) err = snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) snd_ctl_new1(&snd_echo_pcm_output_gain, chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) goto ctl_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) #endif /* ECHOCARD_HAS_VMIXER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) #ifdef ECHOCARD_HAS_INPUT_GAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_input_gain, chip))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) goto ctl_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) #ifdef ECHOCARD_HAS_INPUT_NOMINAL_LEVEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) if (!chip->hasnt_input_nominal_level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_intput_nominal_level, chip))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) goto ctl_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) #ifdef ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_output_nominal_level, chip))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) goto ctl_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vumeters_switch, chip))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) goto ctl_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vumeters, chip))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) goto ctl_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) #ifdef ECHOCARD_HAS_MONITOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) snd_echo_monitor_mixer.count = num_busses_in(chip) * num_busses_out(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_monitor_mixer, chip))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) goto ctl_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) #ifdef ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_automute_switch, chip))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) goto ctl_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_channels_info, chip))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) goto ctl_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) #ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) /* Creates a list of available digital modes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) chip->num_digital_modes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) for (i = 0; i < 6; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) if (chip->digital_modes & (1 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) chip->digital_mode_list[chip->num_digital_modes++] = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_digital_mode_switch, chip))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) goto ctl_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) #endif /* ECHOCARD_HAS_DIGITAL_MODE_SWITCH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) #ifdef ECHOCARD_HAS_EXTERNAL_CLOCK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) /* Creates a list of available clock sources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) chip->num_clock_sources = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) for (i = 0; i < 10; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) if (chip->input_clock_types & (1 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) chip->clock_source_list[chip->num_clock_sources++] = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) if (chip->num_clock_sources > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) chip->clock_src_ctl = snd_ctl_new1(&snd_echo_clock_source_switch, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) if ((err = snd_ctl_add(chip->card, chip->clock_src_ctl)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) goto ctl_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) #endif /* ECHOCARD_HAS_EXTERNAL_CLOCK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) #ifdef ECHOCARD_HAS_DIGITAL_IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_spdif_mode_switch, chip))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) goto ctl_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) #ifdef ECHOCARD_HAS_PHANTOM_POWER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) if (chip->has_phantom_power)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_phantom_power_switch, chip))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) goto ctl_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) err = snd_card_register(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) goto ctl_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) dev_info(card->dev, "Card registered: %s\n", card->longname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) pci_set_drvdata(pci, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) dev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) ctl_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) dev_err(card->dev, "new control error %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) #if defined(CONFIG_PM_SLEEP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) static int snd_echo_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) struct echoaudio *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) #ifdef ECHOCARD_HAS_MIDI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) /* This call can sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) if (chip->midi_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) snd_echo_midi_output_trigger(chip->midi_out, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) spin_lock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) if (wait_handshake(chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) spin_unlock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) clear_handshake(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) if (send_vector(chip, DSP_VC_GO_COMATOSE) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) spin_unlock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) spin_unlock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) chip->dsp_code = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) free_irq(chip->irq, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) chip->irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) chip->card->sync_irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) static int snd_echo_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) struct pci_dev *pci = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) struct echoaudio *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) struct comm_page *commpage, *commpage_bak;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) u32 pipe_alloc_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) commpage = chip->comm_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) commpage_bak = kmemdup(commpage, sizeof(*commpage), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) if (commpage_bak == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) kfree(commpage_bak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) dev_err(dev, "resume init_hw err=%d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) /* Temporarily set chip->pipe_alloc_mask=0 otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) * restore_dsp_settings() fails.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) pipe_alloc_mask = chip->pipe_alloc_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) chip->pipe_alloc_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) err = restore_dsp_rettings(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) chip->pipe_alloc_mask = pipe_alloc_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) kfree(commpage_bak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) memcpy(&commpage->audio_format, &commpage_bak->audio_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) sizeof(commpage->audio_format));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) memcpy(&commpage->sglist_addr, &commpage_bak->sglist_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) sizeof(commpage->sglist_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) memcpy(&commpage->midi_output, &commpage_bak->midi_output,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) sizeof(commpage->midi_output));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) kfree(commpage_bak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) KBUILD_MODNAME, chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) dev_err(chip->card->dev, "cannot grab irq\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) chip->irq = pci->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) chip->card->sync_irq = chip->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) dev_dbg(dev, "resume irq=%d\n", chip->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) #ifdef ECHOCARD_HAS_MIDI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) if (chip->midi_input_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) enable_midi_input(chip, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) if (chip->midi_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) snd_echo_midi_output_trigger(chip->midi_out, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) static SIMPLE_DEV_PM_OPS(snd_echo_pm, snd_echo_suspend, snd_echo_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) #define SND_ECHO_PM_OPS &snd_echo_pm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) #define SND_ECHO_PM_OPS NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) #endif /* CONFIG_PM_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) static void snd_echo_remove(struct pci_dev *pci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) struct echoaudio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) chip = pci_get_drvdata(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) if (chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) snd_card_free(chip->card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) Everything starts and ends here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) /* pci_driver definition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) static struct pci_driver echo_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) .name = KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) .id_table = snd_echo_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) .probe = snd_echo_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) .remove = snd_echo_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) .pm = SND_ECHO_PM_OPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) module_pci_driver(echo_driver);