1dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/* 2dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini * ALSA driver for Echoaudio soundcards. 3dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> 4dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini * 5dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini * This program is free software; you can redistribute it and/or modify 6dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini * it under the terms of the GNU General Public License as published by 7dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini * the Free Software Foundation; version 2 of the License. 8dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini * 9dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini * This program is distributed in the hope that it will be useful, 10dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini * but WITHOUT ANY WARRANTY; without even the implied warranty of 11dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini * GNU General Public License for more details. 13dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini * 14dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini * You should have received a copy of the GNU General Public License 15dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini * along with this program; if not, write to the Free Software 16dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini */ 18dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 19dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano PochiniMODULE_AUTHOR("Giuliano Pochini <pochini@shiny.it>"); 20dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano PochiniMODULE_LICENSE("GPL v2"); 21dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano PochiniMODULE_DESCRIPTION("Echoaudio " ECHOCARD_NAME " soundcards driver"); 22dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano PochiniMODULE_SUPPORTED_DEVICE("{{Echoaudio," ECHOCARD_NAME "}}"); 23dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano PochiniMODULE_DEVICE_TABLE(pci, snd_echo_ids); 24dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 25dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 26dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 27dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; 28dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 29dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinimodule_param_array(index, int, NULL, 0444); 30dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano PochiniMODULE_PARM_DESC(index, "Index value for " ECHOCARD_NAME " soundcard."); 31dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinimodule_param_array(id, charp, NULL, 0444); 32dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano PochiniMODULE_PARM_DESC(id, "ID string for " ECHOCARD_NAME " soundcard."); 33dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinimodule_param_array(enable, bool, NULL, 0444); 34dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano PochiniMODULE_PARM_DESC(enable, "Enable " ECHOCARD_NAME " soundcard."); 35dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 36dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic unsigned int channels_list[10] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 999999}; 370cb29ea0d449d7c0ecc9649a08ab63476389701dTakashi Iwaistatic const DECLARE_TLV_DB_SCALE(db_scale_output_gain, -12800, 100, 1); 38dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 3919b50063780953563e3c3a2867c39aad7b9e64cfGiuliano Pochini 4019b50063780953563e3c3a2867c39aad7b9e64cfGiuliano Pochini 41dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int get_firmware(const struct firmware **fw_entry, 4219b50063780953563e3c3a2867c39aad7b9e64cfGiuliano Pochini struct echoaudio *chip, const short fw_index) 43dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 44dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int err; 45dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini char name[30]; 4619b50063780953563e3c3a2867c39aad7b9e64cfGiuliano Pochini 474f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini#ifdef CONFIG_PM 484f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini if (chip->fw_cache[fw_index]) { 494f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini DE_ACT(("firmware requested: %s is cached\n", card_fw[fw_index].data)); 504f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini *fw_entry = chip->fw_cache[fw_index]; 514f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini return 0; 524f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini } 534f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini#endif 544f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini 554f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini DE_ACT(("firmware requested: %s\n", card_fw[fw_index].data)); 564f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini snprintf(name, sizeof(name), "ea/%s", card_fw[fw_index].data); 574f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini err = request_firmware(fw_entry, name, pci_device(chip)); 584f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini if (err < 0) 59dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_printk(KERN_ERR "get_firmware(): Firmware not available (%d)\n", err); 604f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini#ifdef CONFIG_PM 614f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini else 624f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini chip->fw_cache[fw_index] = *fw_entry; 634f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini#endif 64dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 65dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 66dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 6719b50063780953563e3c3a2867c39aad7b9e64cfGiuliano Pochini 6819b50063780953563e3c3a2867c39aad7b9e64cfGiuliano Pochini 69dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic void free_firmware(const struct firmware *fw_entry) 70dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 714f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini#ifdef CONFIG_PM 724f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini DE_ACT(("firmware not released (kept in cache)\n")); 734f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini#else 74dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini release_firmware(fw_entry); 75dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_ACT(("firmware released\n")); 764f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini#endif 774f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini} 784f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini 794f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini 804f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini 814f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochinistatic void free_firmware_cache(struct echoaudio *chip) 824f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini{ 834f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini#ifdef CONFIG_PM 844f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini int i; 854f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini 864f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini for (i = 0; i < 8 ; i++) 874f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini if (chip->fw_cache[i]) { 884f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini release_firmware(chip->fw_cache[i]); 894f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini DE_ACT(("release_firmware(%d)\n", i)); 904f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini } 914f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini 924f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini DE_ACT(("firmware_cache released\n")); 934f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini#endif 94dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 95dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 96dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 97dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 98dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/****************************************************************************** 99dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini PCM interface 100dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini******************************************************************************/ 101dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 102dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic void audiopipe_free(struct snd_pcm_runtime *runtime) 103dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 104dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct audiopipe *pipe = runtime->private_data; 105dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 106dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (pipe->sgpage.area) 107dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_dma_free_pages(&pipe->sgpage); 108dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini kfree(pipe); 109dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 110dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 111dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 112dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 113dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int hw_rule_capture_format_by_channels(struct snd_pcm_hw_params *params, 114dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_pcm_hw_rule *rule) 115dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 116dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_interval *c = hw_param_interval(params, 117dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_CHANNELS); 118dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 119dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_mask fmt; 120dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 121dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_mask_any(&fmt); 122dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 123dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifndef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 124dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* >=2 channels cannot be S32_BE */ 125dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (c->min == 2) { 126dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini fmt.bits[0] &= ~SNDRV_PCM_FMTBIT_S32_BE; 127dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return snd_mask_refine(f, &fmt); 128dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 129dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif 130dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* > 2 channels cannot be U8 and S32_BE */ 131dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (c->min > 2) { 132dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini fmt.bits[0] &= ~(SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_BE); 133dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return snd_mask_refine(f, &fmt); 134dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 135dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* Mono is ok with any format */ 136dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 137dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 138dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 139dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 140dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 141dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int hw_rule_capture_channels_by_format(struct snd_pcm_hw_params *params, 142dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_pcm_hw_rule *rule) 143dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 144dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_interval *c = hw_param_interval(params, 145dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_CHANNELS); 146dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 147dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_interval ch; 148dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 149dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_interval_any(&ch); 150dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 151dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* S32_BE is mono (and stereo) only */ 152dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (f->bits[0] == SNDRV_PCM_FMTBIT_S32_BE) { 153dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ch.min = 1; 154dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 155dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ch.max = 2; 156dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#else 157dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ch.max = 1; 158dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif 159dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ch.integer = 1; 160dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return snd_interval_refine(c, &ch); 161dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 162dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* U8 can be only mono or stereo */ 163dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (f->bits[0] == SNDRV_PCM_FMTBIT_U8) { 164dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ch.min = 1; 165dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ch.max = 2; 166dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ch.integer = 1; 167dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return snd_interval_refine(c, &ch); 168dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 169dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* S16_LE, S24_3LE and S32_LE support any number of channels. */ 170dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 171dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 172dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 173dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 174dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 175dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int hw_rule_playback_format_by_channels(struct snd_pcm_hw_params *params, 176dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_pcm_hw_rule *rule) 177dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 178dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_interval *c = hw_param_interval(params, 179dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_CHANNELS); 180dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 181dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_mask fmt; 182dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini u64 fmask; 183dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_mask_any(&fmt); 184dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 185dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini fmask = fmt.bits[0] + ((u64)fmt.bits[1] << 32); 186dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 187dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* >2 channels must be S16_LE, S24_3LE or S32_LE */ 188dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (c->min > 2) { 189dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini fmask &= SNDRV_PCM_FMTBIT_S16_LE | 190dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_FMTBIT_S24_3LE | 191dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_FMTBIT_S32_LE; 192dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* 1 channel must be S32_BE or S32_LE */ 193dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } else if (c->max == 1) 194dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini fmask &= SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE; 195dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifndef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 196dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* 2 channels cannot be S32_BE */ 197dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini else if (c->min == 2 && c->max == 2) 198dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini fmask &= ~SNDRV_PCM_FMTBIT_S32_BE; 199dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif 200dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini else 201dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 202dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 203dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini fmt.bits[0] &= (u32)fmask; 204dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini fmt.bits[1] &= (u32)(fmask >> 32); 205dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return snd_mask_refine(f, &fmt); 206dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 207dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 208dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 209dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 210dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int hw_rule_playback_channels_by_format(struct snd_pcm_hw_params *params, 211dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_pcm_hw_rule *rule) 212dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 213dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_interval *c = hw_param_interval(params, 214dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_CHANNELS); 215dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 216dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_interval ch; 217dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini u64 fmask; 218dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 219dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_interval_any(&ch); 220dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ch.integer = 1; 221dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini fmask = f->bits[0] + ((u64)f->bits[1] << 32); 222dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 223dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* S32_BE is mono (and stereo) only */ 224dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (fmask == SNDRV_PCM_FMTBIT_S32_BE) { 225dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ch.min = 1; 226dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 227dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ch.max = 2; 228dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#else 229dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ch.max = 1; 230dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif 231dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* U8 is stereo only */ 232dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } else if (fmask == SNDRV_PCM_FMTBIT_U8) 233dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ch.min = ch.max = 2; 234dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* S16_LE and S24_3LE must be at least stereo */ 235dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini else if (!(fmask & ~(SNDRV_PCM_FMTBIT_S16_LE | 236dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_FMTBIT_S24_3LE))) 237dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ch.min = 2; 238dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini else 239dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 240dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 241dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return snd_interval_refine(c, &ch); 242dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 243dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 244dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 245dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 246dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/* Since the sample rate is a global setting, do allow the user to change the 247dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinisample rate only if there is only one pcm device open. */ 248dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int hw_rule_sample_rate(struct snd_pcm_hw_params *params, 249dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_pcm_hw_rule *rule) 250dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 251dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_interval *rate = hw_param_interval(params, 252dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_RATE); 253dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip = rule->private; 254dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_interval fixed; 255dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 256dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (!chip->can_set_rate) { 257dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_interval_any(&fixed); 258dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini fixed.min = fixed.max = chip->sample_rate; 259dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return snd_interval_refine(rate, &fixed); 260dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 261dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 262dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 263dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 264dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 265dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int pcm_open(struct snd_pcm_substream *substream, 266dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini signed char max_channels) 267dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 268dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 269dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_pcm_runtime *runtime; 270dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct audiopipe *pipe; 271dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int err, i; 272dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 273dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (max_channels <= 0) 274dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return -EAGAIN; 275dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 276dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_pcm_substream_chip(substream); 277dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini runtime = substream->runtime; 278dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 27959feddb25f9d925e86ee22596802405788bc050fPanagiotis Issaris pipe = kzalloc(sizeof(struct audiopipe), GFP_KERNEL); 28059feddb25f9d925e86ee22596802405788bc050fPanagiotis Issaris if (!pipe) 281dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return -ENOMEM; 282dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe->index = -1; /* Not configured yet */ 283dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 284dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* Set up hw capabilities and contraints */ 285dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini memcpy(&pipe->hw, &pcm_hardware_skel, sizeof(struct snd_pcm_hardware)); 286dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_HWP(("max_channels=%d\n", max_channels)); 287dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe->constr.list = channels_list; 288dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe->constr.mask = 0; 289dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini for (i = 0; channels_list[i] <= max_channels; i++); 290dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe->constr.count = i; 291dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (pipe->hw.channels_max > max_channels) 292dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe->hw.channels_max = max_channels; 293dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (chip->digital_mode == DIGITAL_MODE_ADAT) { 294dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe->hw.rate_max = 48000; 295dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe->hw.rates &= SNDRV_PCM_RATE_8000_48000; 296dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 297dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 298dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini runtime->hw = pipe->hw; 299dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini runtime->private_data = pipe; 300dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini runtime->private_free = audiopipe_free; 301dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_pcm_set_sync(substream); 302dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 303dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* Only mono and any even number of channels are allowed */ 304dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_pcm_hw_constraint_list(runtime, 0, 305dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_CHANNELS, 306dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini &pipe->constr)) < 0) 307dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 308dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 309dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* All periods should have the same size */ 310dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_pcm_hw_constraint_integer(runtime, 311dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_PERIODS)) < 0) 312dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 313dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 314dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* The hw accesses memory in chunks 32 frames long and they should be 315dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 32-bytes-aligned. It's not a requirement, but it seems that IRQs are 316dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini generated with a resolution of 32 frames. Thus we need the following */ 317dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_pcm_hw_constraint_step(runtime, 0, 318dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 319dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 32)) < 0) 320dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 321dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_pcm_hw_constraint_step(runtime, 0, 322dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 323dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 32)) < 0) 324dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 325dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 326dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, 327dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_RATE, 328dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini hw_rule_sample_rate, chip, 329dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_RATE, -1)) < 0) 330dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 331dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 332dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* Finally allocate a page for the scatter-gather list */ 333dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, 334dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_dma_pci_data(chip->pci), 335dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini PAGE_SIZE, &pipe->sgpage)) < 0) { 336dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_HWP(("s-g list allocation failed\n")); 337dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 338dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 339dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 340dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 341dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 342dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 343dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 344dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 345dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int pcm_analog_in_open(struct snd_pcm_substream *substream) 346dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 347dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip = snd_pcm_substream_chip(substream); 348dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int err; 349dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 350dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_ACT(("pcm_analog_in_open\n")); 351dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = pcm_open(substream, num_analog_busses_in(chip) - 352dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini substream->number)) < 0) 353dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 354dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, 355dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_CHANNELS, 356dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini hw_rule_capture_channels_by_format, NULL, 357dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0) 358dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 359dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, 360dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_FORMAT, 361dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini hw_rule_capture_format_by_channels, NULL, 362dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0) 363dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 364dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini atomic_inc(&chip->opencount); 365dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (atomic_read(&chip->opencount) > 1 && chip->rate_set) 366dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->can_set_rate=0; 367dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_HWP(("pcm_analog_in_open cs=%d oc=%d r=%d\n", 368dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->can_set_rate, atomic_read(&chip->opencount), 369dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->sample_rate)); 370dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 371dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 372dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 373dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 374dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 375dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int pcm_analog_out_open(struct snd_pcm_substream *substream) 376dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 377dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip = snd_pcm_substream_chip(substream); 378dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int max_channels, err; 379dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 380dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_VMIXER 381dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini max_channels = num_pipes_out(chip); 382dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#else 383dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini max_channels = num_analog_busses_out(chip); 384dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif 385dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_ACT(("pcm_analog_out_open\n")); 386dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = pcm_open(substream, max_channels - substream->number)) < 0) 387dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 388dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, 389dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_CHANNELS, 390dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini hw_rule_playback_channels_by_format, 391dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini NULL, 392dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0) 393dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 394dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, 395dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_FORMAT, 396dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini hw_rule_playback_format_by_channels, 397dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini NULL, 398dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0) 399dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 400dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini atomic_inc(&chip->opencount); 401dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (atomic_read(&chip->opencount) > 1 && chip->rate_set) 402dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->can_set_rate=0; 403dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_HWP(("pcm_analog_out_open cs=%d oc=%d r=%d\n", 404dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->can_set_rate, atomic_read(&chip->opencount), 405dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->sample_rate)); 406dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 407dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 408dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 409dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 410dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 411dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_DIGITAL_IO 412dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 413dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int pcm_digital_in_open(struct snd_pcm_substream *substream) 414dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 415dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip = snd_pcm_substream_chip(substream); 416dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int err, max_channels; 417dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 418dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_ACT(("pcm_digital_in_open\n")); 419dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini max_channels = num_digital_busses_in(chip) - substream->number; 420befceea90b17792cb03cc4e22f3329c89621bba3Takashi Iwai mutex_lock(&chip->mode_mutex); 421dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (chip->digital_mode == DIGITAL_MODE_ADAT) 422dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini err = pcm_open(substream, max_channels); 423dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini else /* If the card has ADAT, subtract the 6 channels 424dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini * that S/PDIF doesn't have 425dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini */ 426dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini err = pcm_open(substream, max_channels - ECHOCARD_HAS_ADAT); 427dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 428dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (err < 0) 429dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini goto din_exit; 430dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 431dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, 432dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_CHANNELS, 433dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini hw_rule_capture_channels_by_format, NULL, 434dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0) 435dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini goto din_exit; 436dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, 437dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_FORMAT, 438dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini hw_rule_capture_format_by_channels, NULL, 439dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0) 440dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini goto din_exit; 441dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 442dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini atomic_inc(&chip->opencount); 443dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (atomic_read(&chip->opencount) > 1 && chip->rate_set) 444dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->can_set_rate=0; 445dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 446dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinidin_exit: 447befceea90b17792cb03cc4e22f3329c89621bba3Takashi Iwai mutex_unlock(&chip->mode_mutex); 448dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 449dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 450dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 451dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 452dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 453dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifndef ECHOCARD_HAS_VMIXER /* See the note in snd_echo_new_pcm() */ 454dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 455dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int pcm_digital_out_open(struct snd_pcm_substream *substream) 456dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 457dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip = snd_pcm_substream_chip(substream); 458dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int err, max_channels; 459dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 460dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_ACT(("pcm_digital_out_open\n")); 461dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini max_channels = num_digital_busses_out(chip) - substream->number; 462befceea90b17792cb03cc4e22f3329c89621bba3Takashi Iwai mutex_lock(&chip->mode_mutex); 463dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (chip->digital_mode == DIGITAL_MODE_ADAT) 464dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini err = pcm_open(substream, max_channels); 465dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini else /* If the card has ADAT, subtract the 6 channels 466dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini * that S/PDIF doesn't have 467dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini */ 468dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini err = pcm_open(substream, max_channels - ECHOCARD_HAS_ADAT); 469dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 470dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (err < 0) 471dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini goto dout_exit; 472dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 473dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, 474dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_CHANNELS, 475dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini hw_rule_playback_channels_by_format, 476dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini NULL, SNDRV_PCM_HW_PARAM_FORMAT, 477dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini -1)) < 0) 478dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini goto dout_exit; 479dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, 480dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_PCM_HW_PARAM_FORMAT, 481dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini hw_rule_playback_format_by_channels, 482dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini NULL, SNDRV_PCM_HW_PARAM_CHANNELS, 483dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini -1)) < 0) 484dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini goto dout_exit; 485dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini atomic_inc(&chip->opencount); 486dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (atomic_read(&chip->opencount) > 1 && chip->rate_set) 487dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->can_set_rate=0; 488dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinidout_exit: 489befceea90b17792cb03cc4e22f3329c89621bba3Takashi Iwai mutex_unlock(&chip->mode_mutex); 490dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 491dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 492dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 493dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif /* !ECHOCARD_HAS_VMIXER */ 494dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 495dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif /* ECHOCARD_HAS_DIGITAL_IO */ 496dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 497dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 498dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 499dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int pcm_close(struct snd_pcm_substream *substream) 500dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 501dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip = snd_pcm_substream_chip(substream); 502dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int oc; 503dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 504dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* Nothing to do here. Audio is already off and pipe will be 505dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini * freed by its callback 506dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini */ 507dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_ACT(("pcm_close\n")); 508dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 509dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini atomic_dec(&chip->opencount); 510dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini oc = atomic_read(&chip->opencount); 511dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_ACT(("pcm_close oc=%d cs=%d rs=%d\n", oc, 512dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->can_set_rate, chip->rate_set)); 513dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (oc < 2) 514dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->can_set_rate = 1; 515dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (oc == 0) 516dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->rate_set = 0; 517dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_ACT(("pcm_close2 oc=%d cs=%d rs=%d\n", oc, 518dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->can_set_rate,chip->rate_set)); 519dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 520dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 521dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 522dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 523dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 524dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 525dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/* Channel allocation and scatter-gather list setup */ 526dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int init_engine(struct snd_pcm_substream *substream, 527dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_pcm_hw_params *hw_params, 528dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int pipe_index, int interleave) 529dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 530dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 531dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int err, per, rest, page, edge, offs; 532dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct audiopipe *pipe; 533dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 534dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_pcm_substream_chip(substream); 535dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe = (struct audiopipe *) substream->runtime->private_data; 536dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 537dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* Sets up che hardware. If it's already initialized, reset and 538dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini * redo with the new parameters 539dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini */ 540dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_lock_irq(&chip->lock); 541dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (pipe->index >= 0) { 542dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_HWP(("hwp_ie free(%d)\n", pipe->index)); 543dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini err = free_pipes(chip, pipe); 544da3cec35dd3c31d8706db4bf379372ce70d92118Takashi Iwai snd_BUG_ON(err); 545dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->substream[pipe->index] = NULL; 546dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 547dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 548dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini err = allocate_pipes(chip, pipe, pipe_index, interleave); 549dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (err < 0) { 550dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_unlock_irq(&chip->lock); 551dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_ACT((KERN_NOTICE "allocate_pipes(%d) err=%d\n", 552dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe_index, err)); 553dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 554dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 555dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_unlock_irq(&chip->lock); 556dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_ACT((KERN_NOTICE "allocate_pipes()=%d\n", pipe_index)); 557dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 558dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_HWP(("pcm_hw_params (bufsize=%dB periods=%d persize=%dB)\n", 559dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini params_buffer_bytes(hw_params), params_periods(hw_params), 560dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini params_period_bytes(hw_params))); 561dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini err = snd_pcm_lib_malloc_pages(substream, 562dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini params_buffer_bytes(hw_params)); 563dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (err < 0) { 564dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_printk(KERN_ERR "malloc_pages err=%d\n", err); 565dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_lock_irq(&chip->lock); 566dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini free_pipes(chip, pipe); 567dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_unlock_irq(&chip->lock); 568dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe->index = -1; 569dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 570dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 571dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 572dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini sglist_init(chip, pipe); 573dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini edge = PAGE_SIZE; 574dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini for (offs = page = per = 0; offs < params_buffer_bytes(hw_params); 575dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini per++) { 576dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini rest = params_period_bytes(hw_params); 577dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (offs + rest > params_buffer_bytes(hw_params)) 578dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini rest = params_buffer_bytes(hw_params) - offs; 579dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini while (rest) { 58077a23f2695bb2de0cd74599400dc55109c531b72Takashi Iwai dma_addr_t addr; 58177a23f2695bb2de0cd74599400dc55109c531b72Takashi Iwai addr = snd_pcm_sgbuf_get_addr(substream, offs); 582dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (rest <= edge - offs) { 58377a23f2695bb2de0cd74599400dc55109c531b72Takashi Iwai sglist_add_mapping(chip, pipe, addr, rest); 584dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini sglist_add_irq(chip, pipe); 585dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini offs += rest; 586dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini rest = 0; 587dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } else { 58877a23f2695bb2de0cd74599400dc55109c531b72Takashi Iwai sglist_add_mapping(chip, pipe, addr, 589dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini edge - offs); 590dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini rest -= edge - offs; 591dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini offs = edge; 592dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 593dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (offs == edge) { 594dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini edge += PAGE_SIZE; 595dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini page++; 596dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 597dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 598dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 599dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 600dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* Close the ring buffer */ 601dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini sglist_wrap(chip, pipe); 602dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 603dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* This stuff is used by the irq handler, so it must be 604dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini * initialized before chip->substream 605dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini */ 606dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->last_period[pipe_index] = 0; 607dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe->last_counter = 0; 608dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe->position = 0; 609dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini smp_wmb(); 610dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->substream[pipe_index] = substream; 611dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->rate_set = 1; 612dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_lock_irq(&chip->lock); 613dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini set_sample_rate(chip, hw_params->rate_num / hw_params->rate_den); 614dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_unlock_irq(&chip->lock); 615dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_HWP(("pcm_hw_params ok\n")); 616dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 617dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 618dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 619dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 620dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 621dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int pcm_analog_in_hw_params(struct snd_pcm_substream *substream, 622dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_pcm_hw_params *hw_params) 623dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 624dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip = snd_pcm_substream_chip(substream); 625dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 626dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return init_engine(substream, hw_params, px_analog_in(chip) + 627dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini substream->number, params_channels(hw_params)); 628dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 629dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 630dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 631dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 632dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int pcm_analog_out_hw_params(struct snd_pcm_substream *substream, 633dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_pcm_hw_params *hw_params) 634dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 635dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return init_engine(substream, hw_params, substream->number, 636dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini params_channels(hw_params)); 637dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 638dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 639dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 640dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 641dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_DIGITAL_IO 642dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 643dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int pcm_digital_in_hw_params(struct snd_pcm_substream *substream, 644dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_pcm_hw_params *hw_params) 645dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 646dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip = snd_pcm_substream_chip(substream); 647dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 648dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return init_engine(substream, hw_params, px_digital_in(chip) + 649dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini substream->number, params_channels(hw_params)); 650dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 651dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 652dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 653dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 654dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifndef ECHOCARD_HAS_VMIXER /* See the note in snd_echo_new_pcm() */ 655dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int pcm_digital_out_hw_params(struct snd_pcm_substream *substream, 656dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_pcm_hw_params *hw_params) 657dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 658dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip = snd_pcm_substream_chip(substream); 659dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 660dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return init_engine(substream, hw_params, px_digital_out(chip) + 661dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini substream->number, params_channels(hw_params)); 662dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 663dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif /* !ECHOCARD_HAS_VMIXER */ 664dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 665dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif /* ECHOCARD_HAS_DIGITAL_IO */ 666dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 667dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 668dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 669dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int pcm_hw_free(struct snd_pcm_substream *substream) 670dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 671dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 672dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct audiopipe *pipe; 673dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 674dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_pcm_substream_chip(substream); 675dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe = (struct audiopipe *) substream->runtime->private_data; 676dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 677dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_lock_irq(&chip->lock); 678dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (pipe->index >= 0) { 679dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_HWP(("pcm_hw_free(%d)\n", pipe->index)); 680dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini free_pipes(chip, pipe); 681dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->substream[pipe->index] = NULL; 682dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe->index = -1; 683dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 684dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_unlock_irq(&chip->lock); 685dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 686dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_HWP(("pcm_hw_freed\n")); 687dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_pcm_lib_free_pages(substream); 688dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 689dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 690dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 691dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 692dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 693dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int pcm_prepare(struct snd_pcm_substream *substream) 694dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 695dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip = snd_pcm_substream_chip(substream); 696dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_pcm_runtime *runtime = substream->runtime; 697dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct audioformat format; 698dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int pipe_index = ((struct audiopipe *)runtime->private_data)->index; 699dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 700dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_HWP(("Prepare rate=%d format=%d channels=%d\n", 701dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini runtime->rate, runtime->format, runtime->channels)); 702dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini format.interleave = runtime->channels; 703dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini format.data_are_bigendian = 0; 704dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini format.mono_to_stereo = 0; 705dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini switch (runtime->format) { 706dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini case SNDRV_PCM_FORMAT_U8: 707dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini format.bits_per_sample = 8; 708dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini break; 709dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini case SNDRV_PCM_FORMAT_S16_LE: 710dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini format.bits_per_sample = 16; 711dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini break; 712dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini case SNDRV_PCM_FORMAT_S24_3LE: 713dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini format.bits_per_sample = 24; 714dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini break; 715dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini case SNDRV_PCM_FORMAT_S32_BE: 716dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini format.data_are_bigendian = 1; 717dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini case SNDRV_PCM_FORMAT_S32_LE: 718dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini format.bits_per_sample = 32; 719dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini break; 720dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini default: 721dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_HWP(("Prepare error: unsupported format %d\n", 722dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini runtime->format)); 723dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return -EINVAL; 724dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 725dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 726da3cec35dd3c31d8706db4bf379372ce70d92118Takashi Iwai if (snd_BUG_ON(pipe_index >= px_num(chip))) 727da3cec35dd3c31d8706db4bf379372ce70d92118Takashi Iwai return -EINVAL; 728da3cec35dd3c31d8706db4bf379372ce70d92118Takashi Iwai if (snd_BUG_ON(!is_pipe_allocated(chip, pipe_index))) 729da3cec35dd3c31d8706db4bf379372ce70d92118Takashi Iwai return -EINVAL; 730dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini set_audio_format(chip, pipe_index, &format); 731dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 732dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 733dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 734dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 735dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 736dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int pcm_trigger(struct snd_pcm_substream *substream, int cmd) 737dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 738dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip = snd_pcm_substream_chip(substream); 739dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_pcm_runtime *runtime = substream->runtime; 740dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct audiopipe *pipe = runtime->private_data; 741dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int i, err; 742dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini u32 channelmask = 0; 743dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_pcm_substream *s; 744dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 745ef991b95aa1351a5782cfaccb9aefba76ca8b990Takashi Iwai snd_pcm_group_for_each_entry(s, substream) { 746dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini for (i = 0; i < DSP_MAXPIPES; i++) { 747dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (s == chip->substream[i]) { 748dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini channelmask |= 1 << i; 749dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_pcm_trigger_done(s, substream); 750dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 751dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 752dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 753dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 754dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_lock(&chip->lock); 755dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini switch (cmd) { 75647b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini case SNDRV_PCM_TRIGGER_RESUME: 75747b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini DE_ACT(("pcm_trigger resume\n")); 758dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini case SNDRV_PCM_TRIGGER_START: 759dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 760dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_ACT(("pcm_trigger start\n")); 761dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini for (i = 0; i < DSP_MAXPIPES; i++) { 762dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (channelmask & (1 << i)) { 763dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe = chip->substream[i]->runtime->private_data; 764dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini switch (pipe->state) { 765dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini case PIPE_STATE_STOPPED: 766dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->last_period[i] = 0; 767dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe->last_counter = 0; 768dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe->position = 0; 769dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini *pipe->dma_counter = 0; 770dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini case PIPE_STATE_PAUSED: 771dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe->state = PIPE_STATE_STARTED; 772dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini break; 773dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini case PIPE_STATE_STARTED: 774dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini break; 775dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 776dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 777dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 778dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini err = start_transport(chip, channelmask, 779dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->pipe_cyclic_mask); 780dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini break; 78147b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini case SNDRV_PCM_TRIGGER_SUSPEND: 78247b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini DE_ACT(("pcm_trigger suspend\n")); 783dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini case SNDRV_PCM_TRIGGER_STOP: 784dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_ACT(("pcm_trigger stop\n")); 785dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini for (i = 0; i < DSP_MAXPIPES; i++) { 786dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (channelmask & (1 << i)) { 787dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe = chip->substream[i]->runtime->private_data; 788dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe->state = PIPE_STATE_STOPPED; 789dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 790dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 791dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini err = stop_transport(chip, channelmask); 792dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini break; 793dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 794dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_ACT(("pcm_trigger pause\n")); 795dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini for (i = 0; i < DSP_MAXPIPES; i++) { 796dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (channelmask & (1 << i)) { 797dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe = chip->substream[i]->runtime->private_data; 798dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe->state = PIPE_STATE_PAUSED; 799dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 800dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 801dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini err = pause_transport(chip, channelmask); 802dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini break; 803dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini default: 804dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini err = -EINVAL; 805dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 806dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_unlock(&chip->lock); 807dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 808dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 809dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 810dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 811dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 812dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic snd_pcm_uframes_t pcm_pointer(struct snd_pcm_substream *substream) 813dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 814dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_pcm_runtime *runtime = substream->runtime; 815dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct audiopipe *pipe = runtime->private_data; 816dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini size_t cnt, bufsize, pos; 817dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 818dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini cnt = le32_to_cpu(*pipe->dma_counter); 819dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe->position += cnt - pipe->last_counter; 820dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe->last_counter = cnt; 821dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini bufsize = substream->runtime->buffer_size; 822dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pos = bytes_to_frames(substream->runtime, pipe->position); 823dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 824dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini while (pos >= bufsize) { 825dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pipe->position -= frames_to_bytes(substream->runtime, bufsize); 826dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pos -= bufsize; 827dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 828dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return pos; 829dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 830dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 831dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 832dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 833dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/* pcm *_ops structures */ 834dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic struct snd_pcm_ops analog_playback_ops = { 835dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .open = pcm_analog_out_open, 836dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .close = pcm_close, 837dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .ioctl = snd_pcm_lib_ioctl, 838dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .hw_params = pcm_analog_out_hw_params, 839dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .hw_free = pcm_hw_free, 840dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .prepare = pcm_prepare, 841dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .trigger = pcm_trigger, 842dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .pointer = pcm_pointer, 843dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .page = snd_pcm_sgbuf_ops_page, 844dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini}; 845dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic struct snd_pcm_ops analog_capture_ops = { 846dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .open = pcm_analog_in_open, 847dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .close = pcm_close, 848dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .ioctl = snd_pcm_lib_ioctl, 849dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .hw_params = pcm_analog_in_hw_params, 850dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .hw_free = pcm_hw_free, 851dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .prepare = pcm_prepare, 852dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .trigger = pcm_trigger, 853dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .pointer = pcm_pointer, 854dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .page = snd_pcm_sgbuf_ops_page, 855dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini}; 856dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_DIGITAL_IO 857dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifndef ECHOCARD_HAS_VMIXER 858dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic struct snd_pcm_ops digital_playback_ops = { 859dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .open = pcm_digital_out_open, 860dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .close = pcm_close, 861dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .ioctl = snd_pcm_lib_ioctl, 862dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .hw_params = pcm_digital_out_hw_params, 863dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .hw_free = pcm_hw_free, 864dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .prepare = pcm_prepare, 865dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .trigger = pcm_trigger, 866dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .pointer = pcm_pointer, 867dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .page = snd_pcm_sgbuf_ops_page, 868dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini}; 869dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif /* !ECHOCARD_HAS_VMIXER */ 870dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic struct snd_pcm_ops digital_capture_ops = { 871dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .open = pcm_digital_in_open, 872dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .close = pcm_close, 873dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .ioctl = snd_pcm_lib_ioctl, 874dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .hw_params = pcm_digital_in_hw_params, 875dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .hw_free = pcm_hw_free, 876dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .prepare = pcm_prepare, 877dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .trigger = pcm_trigger, 878dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .pointer = pcm_pointer, 879dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .page = snd_pcm_sgbuf_ops_page, 880dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini}; 881dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif /* ECHOCARD_HAS_DIGITAL_IO */ 882dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 883dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 884dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 885dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/* Preallocate memory only for the first substream because it's the most 886dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini * used one 887dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini */ 888dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_preallocate_pages(struct snd_pcm *pcm, struct device *dev) 889dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 890dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_pcm_substream *ss; 891dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int stream, err; 892dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 893dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini for (stream = 0; stream < 2; stream++) 894dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini for (ss = pcm->streams[stream].substream; ss; ss = ss->next) { 895dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini err = snd_pcm_lib_preallocate_pages(ss, SNDRV_DMA_TYPE_DEV_SG, 896dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini dev, 897dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ss->number ? 0 : 128<<10, 898dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 256<<10); 899dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (err < 0) 900dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 901dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 902dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 903dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 904dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 905dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 906dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 907dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/*<--snd_echo_probe() */ 908dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int __devinit snd_echo_new_pcm(struct echoaudio *chip) 909dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 910dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_pcm *pcm; 911dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int err; 912dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 913dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_VMIXER 914dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* This card has a Vmixer, that is there is no direct mapping from PCM 915dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini streams to physical outputs. The user can mix the streams as he wishes 916dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini via control interface and it's possible to send any stream to any 917dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini output, thus it makes no sense to keep analog and digital outputs 918dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini separated */ 919dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 920dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* PCM#0 Virtual outputs and analog inputs */ 921dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_pcm_new(chip->card, "PCM", 0, num_pipes_out(chip), 922dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini num_analog_busses_in(chip), &pcm)) < 0) 923dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 924dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pcm->private_data = chip; 925dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->analog_pcm = pcm; 926dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini strcpy(pcm->name, chip->card->shortname); 927dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &analog_playback_ops); 928dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops); 929dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) 930dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 931dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_INIT(("Analog PCM ok\n")); 932dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 933dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_DIGITAL_IO 934dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* PCM#1 Digital inputs, no outputs */ 935dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_pcm_new(chip->card, "Digital PCM", 1, 0, 936dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini num_digital_busses_in(chip), &pcm)) < 0) 937dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 938dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pcm->private_data = chip; 939dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->digital_pcm = pcm; 940dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini strcpy(pcm->name, chip->card->shortname); 941dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops); 942dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) 943dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 944dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_INIT(("Digital PCM ok\n")); 945dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif /* ECHOCARD_HAS_DIGITAL_IO */ 946dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 947dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#else /* ECHOCARD_HAS_VMIXER */ 948dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 949dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* The card can manage substreams formed by analog and digital channels 950dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini at the same time, but I prefer to keep analog and digital channels 951dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini separated, because that mixed thing is confusing and useless. So we 952dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini register two PCM devices: */ 953dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 954dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* PCM#0 Analog i/o */ 955dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_pcm_new(chip->card, "Analog PCM", 0, 956dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini num_analog_busses_out(chip), 957dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini num_analog_busses_in(chip), &pcm)) < 0) 958dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 959dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pcm->private_data = chip; 960dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->analog_pcm = pcm; 961dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini strcpy(pcm->name, chip->card->shortname); 962dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &analog_playback_ops); 963dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops); 964dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) 965dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 966dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_INIT(("Analog PCM ok\n")); 967dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 968dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_DIGITAL_IO 969dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* PCM#1 Digital i/o */ 970dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_pcm_new(chip->card, "Digital PCM", 1, 971dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini num_digital_busses_out(chip), 972dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini num_digital_busses_in(chip), &pcm)) < 0) 973dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 974dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pcm->private_data = chip; 975dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->digital_pcm = pcm; 976dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini strcpy(pcm->name, chip->card->shortname); 977dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &digital_playback_ops); 978dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops); 979dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) 980dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 981dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_INIT(("Digital PCM ok\n")); 982dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif /* ECHOCARD_HAS_DIGITAL_IO */ 983dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 984dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif /* ECHOCARD_HAS_VMIXER */ 985dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 986dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 987dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 988dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 989dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 990dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 991dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 992dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/****************************************************************************** 993dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini Control interface 994dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini******************************************************************************/ 995dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 996392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini#if !defined(ECHOCARD_HAS_VMIXER) || defined(ECHOCARD_HAS_LINE_OUT_GAIN) 9979f5d790d1b0af8e3705df12fd5d49a1df2a45c47Giuliano Pochini 998dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/******************* PCM output volume *******************/ 999dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_output_gain_info(struct snd_kcontrol *kcontrol, 1000dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_info *uinfo) 1001dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1002dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1003dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1004dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1005dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 1006dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->count = num_busses_out(chip); 1007dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->value.integer.min = ECHOGAIN_MINOUT; 1008dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->value.integer.max = ECHOGAIN_MAXOUT; 1009dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1010dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1011dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1012dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_output_gain_get(struct snd_kcontrol *kcontrol, 1013dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1014dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1015dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1016dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int c; 1017dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1018dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1019dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini for (c = 0; c < num_busses_out(chip); c++) 1020dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ucontrol->value.integer.value[c] = chip->output_gain[c]; 1021dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1022dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1023dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1024dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_output_gain_put(struct snd_kcontrol *kcontrol, 1025dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1026dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1027dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1028dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int c, changed, gain; 1029dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1030dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini changed = 0; 1031dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1032dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_lock_irq(&chip->lock); 1033dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini for (c = 0; c < num_busses_out(chip); c++) { 1034dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini gain = ucontrol->value.integer.value[c]; 1035dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* Ignore out of range values */ 1036dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT) 1037dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini continue; 1038dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (chip->output_gain[c] != gain) { 1039dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini set_output_gain(chip, c, gain); 1040dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini changed = 1; 1041dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1042dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1043dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (changed) 1044dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini update_output_line_level(chip); 1045dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_unlock_irq(&chip->lock); 1046dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return changed; 1047dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1048dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1049392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini#ifdef ECHOCARD_HAS_LINE_OUT_GAIN 1050392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini/* On the Mia this one controls the line-out volume */ 1051392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochinistatic struct snd_kcontrol_new snd_echo_line_output_gain __devinitdata = { 1052392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini .name = "Line Playback Volume", 1053392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1054392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 1055392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini SNDRV_CTL_ELEM_ACCESS_TLV_READ, 1056392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini .info = snd_echo_output_gain_info, 1057392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini .get = snd_echo_output_gain_get, 1058392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini .put = snd_echo_output_gain_put, 1059392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini .tlv = {.p = db_scale_output_gain}, 1060392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini}; 1061392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini#else 1062dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = { 1063dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .name = "PCM Playback Volume", 1064dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1065048b945077bdc7e8dff5d5810ff2a0ced3590ca9Giuliano Pochini .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, 1066dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .info = snd_echo_output_gain_info, 1067dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .get = snd_echo_output_gain_get, 1068dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .put = snd_echo_output_gain_put, 1069048b945077bdc7e8dff5d5810ff2a0ced3590ca9Giuliano Pochini .tlv = {.p = db_scale_output_gain}, 1070dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini}; 1071dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif 1072dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1073392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini#endif /* !ECHOCARD_HAS_VMIXER || ECHOCARD_HAS_LINE_OUT_GAIN */ 1074392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini 1075dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1076dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1077dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_INPUT_GAIN 1078dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1079dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/******************* Analog input volume *******************/ 1080dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_input_gain_info(struct snd_kcontrol *kcontrol, 1081dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_info *uinfo) 1082dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1083dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1084dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1085dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1086dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 1087dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->count = num_analog_busses_in(chip); 1088dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->value.integer.min = ECHOGAIN_MININP; 1089dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->value.integer.max = ECHOGAIN_MAXINP; 1090dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1091dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1092dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1093dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_input_gain_get(struct snd_kcontrol *kcontrol, 1094dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1095dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1096dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1097dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int c; 1098dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1099dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1100dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini for (c = 0; c < num_analog_busses_in(chip); c++) 1101dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ucontrol->value.integer.value[c] = chip->input_gain[c]; 1102dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1103dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1104dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1105dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_input_gain_put(struct snd_kcontrol *kcontrol, 1106dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1107dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1108dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1109dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int c, gain, changed; 1110dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1111dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini changed = 0; 1112dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1113dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_lock_irq(&chip->lock); 1114dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini for (c = 0; c < num_analog_busses_in(chip); c++) { 1115dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini gain = ucontrol->value.integer.value[c]; 1116dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* Ignore out of range values */ 1117dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (gain < ECHOGAIN_MININP || gain > ECHOGAIN_MAXINP) 1118dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini continue; 1119dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (chip->input_gain[c] != gain) { 1120dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini set_input_gain(chip, c, gain); 1121dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini changed = 1; 1122dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1123dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1124dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (changed) 1125dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini update_input_line_level(chip); 1126dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_unlock_irq(&chip->lock); 1127dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return changed; 1128dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1129dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 11300cb29ea0d449d7c0ecc9649a08ab63476389701dTakashi Iwaistatic const DECLARE_TLV_DB_SCALE(db_scale_input_gain, -2500, 50, 0); 1131048b945077bdc7e8dff5d5810ff2a0ced3590ca9Giuliano Pochini 1132dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic struct snd_kcontrol_new snd_echo_line_input_gain __devinitdata = { 1133dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .name = "Line Capture Volume", 1134dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1135048b945077bdc7e8dff5d5810ff2a0ced3590ca9Giuliano Pochini .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, 1136dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .info = snd_echo_input_gain_info, 1137dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .get = snd_echo_input_gain_get, 1138dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .put = snd_echo_input_gain_put, 1139048b945077bdc7e8dff5d5810ff2a0ced3590ca9Giuliano Pochini .tlv = {.p = db_scale_input_gain}, 1140dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini}; 1141dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1142dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif /* ECHOCARD_HAS_INPUT_GAIN */ 1143dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1144dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1145dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1146dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL 1147dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1148dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/************ Analog output nominal level (+4dBu / -10dBV) ***************/ 1149dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_output_nominal_info (struct snd_kcontrol *kcontrol, 1150dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_info *uinfo) 1151dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1152dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1153dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1154dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1155dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 1156dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->count = num_analog_busses_out(chip); 1157dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->value.integer.min = 0; 1158dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->value.integer.max = 1; 1159dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1160dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1161dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1162dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_output_nominal_get(struct snd_kcontrol *kcontrol, 1163dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1164dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1165dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1166dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int c; 1167dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1168dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1169dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini for (c = 0; c < num_analog_busses_out(chip); c++) 1170dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ucontrol->value.integer.value[c] = chip->nominal_level[c]; 1171dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1172dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1173dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1174dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_output_nominal_put(struct snd_kcontrol *kcontrol, 1175dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1176dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1177dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1178dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int c, changed; 1179dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1180dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini changed = 0; 1181dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1182dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_lock_irq(&chip->lock); 1183dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini for (c = 0; c < num_analog_busses_out(chip); c++) { 1184dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (chip->nominal_level[c] != ucontrol->value.integer.value[c]) { 1185dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini set_nominal_level(chip, c, 1186dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ucontrol->value.integer.value[c]); 1187dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini changed = 1; 1188dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1189dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1190dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (changed) 1191dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini update_output_line_level(chip); 1192dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_unlock_irq(&chip->lock); 1193dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return changed; 1194dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1195dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1196dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic struct snd_kcontrol_new snd_echo_output_nominal_level __devinitdata = { 1197dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .name = "Line Playback Switch (-10dBV)", 1198dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1199dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .info = snd_echo_output_nominal_info, 1200dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .get = snd_echo_output_nominal_get, 1201dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .put = snd_echo_output_nominal_put, 1202dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini}; 1203dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1204dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif /* ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL */ 1205dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1206dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1207dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1208dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_INPUT_NOMINAL_LEVEL 1209dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1210dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/*************** Analog input nominal level (+4dBu / -10dBV) ***************/ 1211dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_input_nominal_info(struct snd_kcontrol *kcontrol, 1212dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_info *uinfo) 1213dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1214dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1215dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1216dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1217dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 1218dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->count = num_analog_busses_in(chip); 1219dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->value.integer.min = 0; 1220dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->value.integer.max = 1; 1221dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1222dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1223dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1224dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_input_nominal_get(struct snd_kcontrol *kcontrol, 1225dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1226dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1227dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1228dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int c; 1229dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1230dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1231dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini for (c = 0; c < num_analog_busses_in(chip); c++) 1232dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ucontrol->value.integer.value[c] = 1233dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->nominal_level[bx_analog_in(chip) + c]; 1234dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1235dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1236dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1237dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_input_nominal_put(struct snd_kcontrol *kcontrol, 1238dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1239dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1240dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1241dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int c, changed; 1242dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1243dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini changed = 0; 1244dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1245dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_lock_irq(&chip->lock); 1246dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini for (c = 0; c < num_analog_busses_in(chip); c++) { 1247dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (chip->nominal_level[bx_analog_in(chip) + c] != 1248dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ucontrol->value.integer.value[c]) { 1249dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini set_nominal_level(chip, bx_analog_in(chip) + c, 1250dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ucontrol->value.integer.value[c]); 1251dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini changed = 1; 1252dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1253dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1254dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (changed) 1255dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini update_output_line_level(chip); /* "Output" is not a mistake 1256dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini * here. 1257dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini */ 1258dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_unlock_irq(&chip->lock); 1259dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return changed; 1260dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1261dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1262dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic struct snd_kcontrol_new snd_echo_intput_nominal_level __devinitdata = { 1263dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .name = "Line Capture Switch (-10dBV)", 1264dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1265dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .info = snd_echo_input_nominal_info, 1266dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .get = snd_echo_input_nominal_get, 1267dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .put = snd_echo_input_nominal_put, 1268dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini}; 1269dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1270dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif /* ECHOCARD_HAS_INPUT_NOMINAL_LEVEL */ 1271dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1272dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1273dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1274dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_MONITOR 1275dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1276dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/******************* Monitor mixer *******************/ 1277dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_mixer_info(struct snd_kcontrol *kcontrol, 1278dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_info *uinfo) 1279dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1280dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1281dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1282dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1283dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 1284dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->count = 1; 1285dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->value.integer.min = ECHOGAIN_MINOUT; 1286dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->value.integer.max = ECHOGAIN_MAXOUT; 1287dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->dimen.d[0] = num_busses_out(chip); 1288dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->dimen.d[1] = num_busses_in(chip); 1289dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1290dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1291dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1292dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_mixer_get(struct snd_kcontrol *kcontrol, 1293dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1294dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1295dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1296dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1297dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1298dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ucontrol->value.integer.value[0] = 1299dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->monitor_gain[ucontrol->id.index / num_busses_in(chip)] 1300dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini [ucontrol->id.index % num_busses_in(chip)]; 1301dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1302dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1303dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1304dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_mixer_put(struct snd_kcontrol *kcontrol, 1305dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1306dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1307dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1308dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int changed, gain; 1309dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini short out, in; 1310dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1311dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini changed = 0; 1312dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1313dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini out = ucontrol->id.index / num_busses_in(chip); 1314dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini in = ucontrol->id.index % num_busses_in(chip); 1315dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini gain = ucontrol->value.integer.value[0]; 1316dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT) 1317dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return -EINVAL; 1318dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (chip->monitor_gain[out][in] != gain) { 1319dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_lock_irq(&chip->lock); 1320dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini set_monitor_gain(chip, out, in, gain); 1321dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini update_output_line_level(chip); 1322dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_unlock_irq(&chip->lock); 1323dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini changed = 1; 1324dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1325dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return changed; 1326dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1327dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1328dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic struct snd_kcontrol_new snd_echo_monitor_mixer __devinitdata = { 1329dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .name = "Monitor Mixer Volume", 1330dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1331048b945077bdc7e8dff5d5810ff2a0ced3590ca9Giuliano Pochini .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, 1332dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .info = snd_echo_mixer_info, 1333dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .get = snd_echo_mixer_get, 1334dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .put = snd_echo_mixer_put, 1335048b945077bdc7e8dff5d5810ff2a0ced3590ca9Giuliano Pochini .tlv = {.p = db_scale_output_gain}, 1336dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini}; 1337dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1338dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif /* ECHOCARD_HAS_MONITOR */ 1339dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1340dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1341dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1342dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_VMIXER 1343dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1344dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/******************* Vmixer *******************/ 1345dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_vmixer_info(struct snd_kcontrol *kcontrol, 1346dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_info *uinfo) 1347dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1348dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1349dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1350dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1351dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 1352dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->count = 1; 1353dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->value.integer.min = ECHOGAIN_MINOUT; 1354dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->value.integer.max = ECHOGAIN_MAXOUT; 1355dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->dimen.d[0] = num_busses_out(chip); 1356dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->dimen.d[1] = num_pipes_out(chip); 1357dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1358dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1359dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1360dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_vmixer_get(struct snd_kcontrol *kcontrol, 1361dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1362dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1363dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1364dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1365dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1366dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ucontrol->value.integer.value[0] = 1367dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->vmixer_gain[ucontrol->id.index / num_pipes_out(chip)] 1368dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini [ucontrol->id.index % num_pipes_out(chip)]; 1369dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1370dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1371dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1372dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_vmixer_put(struct snd_kcontrol *kcontrol, 1373dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1374dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1375dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1376dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int gain, changed; 1377dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini short vch, out; 1378dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1379dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini changed = 0; 1380dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1381dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini out = ucontrol->id.index / num_pipes_out(chip); 1382dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini vch = ucontrol->id.index % num_pipes_out(chip); 1383dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini gain = ucontrol->value.integer.value[0]; 1384dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT) 1385dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return -EINVAL; 1386dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (chip->vmixer_gain[out][vch] != ucontrol->value.integer.value[0]) { 1387dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_lock_irq(&chip->lock); 1388dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini set_vmixer_gain(chip, out, vch, ucontrol->value.integer.value[0]); 1389dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini update_vmixer_level(chip); 1390dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_unlock_irq(&chip->lock); 1391dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini changed = 1; 1392dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1393dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return changed; 1394dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1395dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1396dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic struct snd_kcontrol_new snd_echo_vmixer __devinitdata = { 1397dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .name = "VMixer Volume", 1398dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1399048b945077bdc7e8dff5d5810ff2a0ced3590ca9Giuliano Pochini .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, 1400dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .info = snd_echo_vmixer_info, 1401dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .get = snd_echo_vmixer_get, 1402dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .put = snd_echo_vmixer_put, 1403048b945077bdc7e8dff5d5810ff2a0ced3590ca9Giuliano Pochini .tlv = {.p = db_scale_output_gain}, 1404dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini}; 1405dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1406dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif /* ECHOCARD_HAS_VMIXER */ 1407dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1408dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1409dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1410dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH 1411dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1412dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/******************* Digital mode switch *******************/ 1413dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_digital_mode_info(struct snd_kcontrol *kcontrol, 1414dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_info *uinfo) 1415dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1416dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini static char *names[4] = { 1417dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini "S/PDIF Coaxial", "S/PDIF Optical", "ADAT Optical", 1418dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini "S/PDIF Cdrom" 1419dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini }; 1420dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1421dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1422dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1423dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1424dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->value.enumerated.items = chip->num_digital_modes; 1425dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->count = 1; 1426dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (uinfo->value.enumerated.item >= chip->num_digital_modes) 1427dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->value.enumerated.item = chip->num_digital_modes - 1; 1428dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini strcpy(uinfo->value.enumerated.name, names[ 1429dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->digital_mode_list[uinfo->value.enumerated.item]]); 1430dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1431dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1432dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1433dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_digital_mode_get(struct snd_kcontrol *kcontrol, 1434dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1435dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1436dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1437dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int i, mode; 1438dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1439dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1440dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini mode = chip->digital_mode; 1441dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini for (i = chip->num_digital_modes - 1; i >= 0; i--) 1442dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (mode == chip->digital_mode_list[i]) { 1443dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ucontrol->value.enumerated.item[0] = i; 1444dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini break; 1445dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1446dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1447dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1448dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1449dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_digital_mode_put(struct snd_kcontrol *kcontrol, 1450dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1451dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1452dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1453dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int changed; 1454dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini unsigned short emode, dmode; 1455dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1456dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini changed = 0; 1457dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1458dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1459dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini emode = ucontrol->value.enumerated.item[0]; 1460dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (emode >= chip->num_digital_modes) 1461dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return -EINVAL; 1462dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini dmode = chip->digital_mode_list[emode]; 1463dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1464dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (dmode != chip->digital_mode) { 1465dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* mode_mutex is required to make this operation atomic wrt 1466dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pcm_digital_*_open() and set_input_clock() functions. */ 1467befceea90b17792cb03cc4e22f3329c89621bba3Takashi Iwai mutex_lock(&chip->mode_mutex); 1468dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1469dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* Do not allow the user to change the digital mode when a pcm 1470dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini device is open because it also changes the number of channels 1471dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini and the allowed sample rates */ 1472dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (atomic_read(&chip->opencount)) { 1473dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini changed = -EAGAIN; 1474dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } else { 1475dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini changed = set_digital_mode(chip, dmode); 1476dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* If we had to change the clock source, report it */ 1477dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (changed > 0 && chip->clock_src_ctl) { 1478dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_ctl_notify(chip->card, 1479dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini SNDRV_CTL_EVENT_MASK_VALUE, 1480dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini &chip->clock_src_ctl->id); 1481dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_ACT(("SDM() =%d\n", changed)); 1482dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1483dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (changed >= 0) 1484dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini changed = 1; /* No errors */ 1485dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1486befceea90b17792cb03cc4e22f3329c89621bba3Takashi Iwai mutex_unlock(&chip->mode_mutex); 1487dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1488dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return changed; 1489dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1490dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1491dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic struct snd_kcontrol_new snd_echo_digital_mode_switch __devinitdata = { 1492dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .name = "Digital mode Switch", 1493dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1494dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .info = snd_echo_digital_mode_info, 1495dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .get = snd_echo_digital_mode_get, 1496dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .put = snd_echo_digital_mode_put, 1497dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini}; 1498dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1499dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif /* ECHOCARD_HAS_DIGITAL_MODE_SWITCH */ 1500dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1501dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1502dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1503dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_DIGITAL_IO 1504dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1505dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/******************* S/PDIF mode switch *******************/ 1506dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_spdif_mode_info(struct snd_kcontrol *kcontrol, 1507dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_info *uinfo) 1508dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1509dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini static char *names[2] = {"Consumer", "Professional"}; 1510dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1511dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1512dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->value.enumerated.items = 2; 1513dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->count = 1; 1514dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (uinfo->value.enumerated.item) 1515dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->value.enumerated.item = 1; 1516dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini strcpy(uinfo->value.enumerated.name, 1517dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini names[uinfo->value.enumerated.item]); 1518dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1519dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1520dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1521dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_spdif_mode_get(struct snd_kcontrol *kcontrol, 1522dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1523dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1524dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1525dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1526dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1527dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ucontrol->value.enumerated.item[0] = !!chip->professional_spdif; 1528dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1529dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1530dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1531dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_spdif_mode_put(struct snd_kcontrol *kcontrol, 1532dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1533dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1534dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1535dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int mode; 1536dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1537dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1538dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini mode = !!ucontrol->value.enumerated.item[0]; 1539dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (mode != chip->professional_spdif) { 1540dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_lock_irq(&chip->lock); 1541dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini set_professional_spdif(chip, mode); 1542dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_unlock_irq(&chip->lock); 1543dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 1; 1544dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1545dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1546dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1547dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1548dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic struct snd_kcontrol_new snd_echo_spdif_mode_switch __devinitdata = { 1549dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .name = "S/PDIF mode Switch", 1550dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1551dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .info = snd_echo_spdif_mode_info, 1552dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .get = snd_echo_spdif_mode_get, 1553dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .put = snd_echo_spdif_mode_put, 1554dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini}; 1555dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1556dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif /* ECHOCARD_HAS_DIGITAL_IO */ 1557dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1558dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1559dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1560dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_EXTERNAL_CLOCK 1561dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1562dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/******************* Select input clock source *******************/ 1563dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_clock_source_info(struct snd_kcontrol *kcontrol, 1564dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_info *uinfo) 1565dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1566dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini static char *names[8] = { 1567dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini "Internal", "Word", "Super", "S/PDIF", "ADAT", "ESync", 1568dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini "ESync96", "MTC" 1569dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini }; 1570dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1571dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1572dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1573dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1574dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->value.enumerated.items = chip->num_clock_sources; 1575dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->count = 1; 1576dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (uinfo->value.enumerated.item >= chip->num_clock_sources) 1577dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->value.enumerated.item = chip->num_clock_sources - 1; 1578dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini strcpy(uinfo->value.enumerated.name, names[ 1579dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->clock_source_list[uinfo->value.enumerated.item]]); 1580dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1581dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1582dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1583dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_clock_source_get(struct snd_kcontrol *kcontrol, 1584dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1585dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1586dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1587dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int i, clock; 1588dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1589dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1590dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini clock = chip->input_clock; 1591dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1592dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini for (i = 0; i < chip->num_clock_sources; i++) 1593dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (clock == chip->clock_source_list[i]) 1594dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ucontrol->value.enumerated.item[0] = i; 1595dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1596dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1597dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1598dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1599dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_clock_source_put(struct snd_kcontrol *kcontrol, 1600dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1601dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1602dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1603dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int changed; 1604dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini unsigned int eclock, dclock; 1605dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1606dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini changed = 0; 1607dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1608dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini eclock = ucontrol->value.enumerated.item[0]; 1609dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (eclock >= chip->input_clock_types) 1610dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return -EINVAL; 1611dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini dclock = chip->clock_source_list[eclock]; 1612dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (chip->input_clock != dclock) { 1613befceea90b17792cb03cc4e22f3329c89621bba3Takashi Iwai mutex_lock(&chip->mode_mutex); 1614dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_lock_irq(&chip->lock); 1615dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((changed = set_input_clock(chip, dclock)) == 0) 1616dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini changed = 1; /* no errors */ 1617dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_unlock_irq(&chip->lock); 1618befceea90b17792cb03cc4e22f3329c89621bba3Takashi Iwai mutex_unlock(&chip->mode_mutex); 1619dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1620dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1621dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (changed < 0) 1622dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_ACT(("seticlk val%d err 0x%x\n", dclock, changed)); 1623dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1624dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return changed; 1625dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1626dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1627dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic struct snd_kcontrol_new snd_echo_clock_source_switch __devinitdata = { 1628dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .name = "Sample Clock Source", 1629dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1630dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .info = snd_echo_clock_source_info, 1631dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .get = snd_echo_clock_source_get, 1632dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .put = snd_echo_clock_source_put, 1633dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini}; 1634dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1635dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif /* ECHOCARD_HAS_EXTERNAL_CLOCK */ 1636dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1637dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1638dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1639dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_PHANTOM_POWER 1640dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1641dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/******************* Phantom power switch *******************/ 1642a5ce88909d3007caa7b65996a8f6784350beb2a6Takashi Iwai#define snd_echo_phantom_power_info snd_ctl_boolean_mono_info 1643dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1644dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_phantom_power_get(struct snd_kcontrol *kcontrol, 1645dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1646dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1647dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip = snd_kcontrol_chip(kcontrol); 1648dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1649dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ucontrol->value.integer.value[0] = chip->phantom_power; 1650dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1651dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1652dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1653dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_phantom_power_put(struct snd_kcontrol *kcontrol, 1654dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1655dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1656dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip = snd_kcontrol_chip(kcontrol); 1657dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int power, changed = 0; 1658dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1659dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini power = !!ucontrol->value.integer.value[0]; 1660dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (chip->phantom_power != power) { 1661dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_lock_irq(&chip->lock); 1662dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini changed = set_phantom_power(chip, power); 1663dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_unlock_irq(&chip->lock); 1664dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (changed == 0) 1665dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini changed = 1; /* no errors */ 1666dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1667dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return changed; 1668dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1669dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1670dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic struct snd_kcontrol_new snd_echo_phantom_power_switch __devinitdata = { 1671dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .name = "Phantom power Switch", 1672dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1673dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .info = snd_echo_phantom_power_info, 1674dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .get = snd_echo_phantom_power_get, 1675dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .put = snd_echo_phantom_power_put, 1676dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini}; 1677dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1678dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif /* ECHOCARD_HAS_PHANTOM_POWER */ 1679dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1680dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1681dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1682dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE 1683dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1684dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/******************* Digital input automute switch *******************/ 1685a5ce88909d3007caa7b65996a8f6784350beb2a6Takashi Iwai#define snd_echo_automute_info snd_ctl_boolean_mono_info 1686dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1687dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_automute_get(struct snd_kcontrol *kcontrol, 1688dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1689dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1690dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip = snd_kcontrol_chip(kcontrol); 1691dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1692dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ucontrol->value.integer.value[0] = chip->digital_in_automute; 1693dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1694dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1695dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1696dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_automute_put(struct snd_kcontrol *kcontrol, 1697dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1698dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1699dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip = snd_kcontrol_chip(kcontrol); 1700dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int automute, changed = 0; 1701dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1702dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini automute = !!ucontrol->value.integer.value[0]; 1703dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (chip->digital_in_automute != automute) { 1704dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_lock_irq(&chip->lock); 1705dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini changed = set_input_auto_mute(chip, automute); 1706dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_unlock_irq(&chip->lock); 1707dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (changed == 0) 1708dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini changed = 1; /* no errors */ 1709dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1710dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return changed; 1711dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1712dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1713dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic struct snd_kcontrol_new snd_echo_automute_switch __devinitdata = { 1714dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .name = "Digital Capture Switch (automute)", 1715dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1716dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .info = snd_echo_automute_info, 1717dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .get = snd_echo_automute_get, 1718dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .put = snd_echo_automute_put, 1719dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini}; 1720dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1721dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif /* ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE */ 1722dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1723dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1724dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1725dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/******************* VU-meters switch *******************/ 1726a5ce88909d3007caa7b65996a8f6784350beb2a6Takashi Iwai#define snd_echo_vumeters_switch_info snd_ctl_boolean_mono_info 1727dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1728dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_vumeters_switch_put(struct snd_kcontrol *kcontrol, 1729dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1730dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1731dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1732dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1733dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1734dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_lock_irq(&chip->lock); 1735dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini set_meters_on(chip, ucontrol->value.integer.value[0]); 1736dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_unlock_irq(&chip->lock); 1737dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 1; 1738dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1739dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1740dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic struct snd_kcontrol_new snd_echo_vumeters_switch __devinitdata = { 1741dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .name = "VU-meters Switch", 1742dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1743dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .access = SNDRV_CTL_ELEM_ACCESS_WRITE, 1744dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .info = snd_echo_vumeters_switch_info, 1745dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .put = snd_echo_vumeters_switch_put, 1746dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini}; 1747dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1748dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1749dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1750dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/***** Read VU-meters (input, output, analog and digital together) *****/ 1751dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_vumeters_info(struct snd_kcontrol *kcontrol, 1752dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_info *uinfo) 1753dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1754dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1755dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1756dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1757dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 1758dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->count = 96; 1759dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->value.integer.min = ECHOGAIN_MINOUT; 1760dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->value.integer.max = 0; 1761dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_VMIXER 1762dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->dimen.d[0] = 3; /* Out, In, Virt */ 1763dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#else 1764dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->dimen.d[0] = 2; /* Out, In */ 1765dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif 1766dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->dimen.d[1] = 16; /* 16 channels */ 1767dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->dimen.d[2] = 2; /* 0=level, 1=peak */ 1768dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1769dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1770dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1771dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_vumeters_get(struct snd_kcontrol *kcontrol, 1772dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1773dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1774dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1775dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1776dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1777dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini get_audio_meters(chip, ucontrol->value.integer.value); 1778dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1779dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1780dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1781dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic struct snd_kcontrol_new snd_echo_vumeters __devinitdata = { 1782dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .name = "VU-meters", 1783dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1784048b945077bdc7e8dff5d5810ff2a0ced3590ca9Giuliano Pochini .access = SNDRV_CTL_ELEM_ACCESS_READ | 1785048b945077bdc7e8dff5d5810ff2a0ced3590ca9Giuliano Pochini SNDRV_CTL_ELEM_ACCESS_VOLATILE | 1786048b945077bdc7e8dff5d5810ff2a0ced3590ca9Giuliano Pochini SNDRV_CTL_ELEM_ACCESS_TLV_READ, 1787dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .info = snd_echo_vumeters_info, 1788dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .get = snd_echo_vumeters_get, 1789048b945077bdc7e8dff5d5810ff2a0ced3590ca9Giuliano Pochini .tlv = {.p = db_scale_output_gain}, 1790dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini}; 1791dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1792dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1793dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1794dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/*** Channels info - it exports informations about the number of channels ***/ 1795dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_channels_info_info(struct snd_kcontrol *kcontrol, 1796dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_info *uinfo) 1797dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1798dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1799dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1800dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1801dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 1802dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->count = 6; 1803dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->value.integer.min = 0; 1804dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini uinfo->value.integer.max = 1 << ECHO_CLOCK_NUMBER; 1805dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1806dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1807dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1808dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_channels_info_get(struct snd_kcontrol *kcontrol, 1809dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_ctl_elem_value *ucontrol) 1810dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1811dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1812dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int detected, clocks, bit, src; 1813dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1814dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = snd_kcontrol_chip(kcontrol); 1815dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ucontrol->value.integer.value[0] = num_busses_in(chip); 1816dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ucontrol->value.integer.value[1] = num_analog_busses_in(chip); 1817dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ucontrol->value.integer.value[2] = num_busses_out(chip); 1818dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ucontrol->value.integer.value[3] = num_analog_busses_out(chip); 1819dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ucontrol->value.integer.value[4] = num_pipes_out(chip); 1820dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1821dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* Compute the bitmask of the currently valid input clocks */ 1822dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini detected = detect_input_clocks(chip); 1823dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini clocks = 0; 1824dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini src = chip->num_clock_sources - 1; 1825dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini for (bit = ECHO_CLOCK_NUMBER - 1; bit >= 0; bit--) 1826dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (detected & (1 << bit)) 1827dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini for (; src >= 0; src--) 1828dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (bit == chip->clock_source_list[src]) { 1829dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini clocks |= 1 << src; 1830dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini break; 1831dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1832dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ucontrol->value.integer.value[5] = clocks; 1833dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1834dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1835dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1836dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1837dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic struct snd_kcontrol_new snd_echo_channels_info __devinitdata = { 1838dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .name = "Channels info", 1839dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, 1840dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 1841dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .info = snd_echo_channels_info_info, 1842dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .get = snd_echo_channels_info_get, 1843dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini}; 1844dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1845dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1846dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1847dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1848dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/****************************************************************************** 1849dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini IRQ Handler 1850dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini******************************************************************************/ 1851dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 18527d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsstatic irqreturn_t snd_echo_interrupt(int irq, void *dev_id) 1853dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1854dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip = dev_id; 1855dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_pcm_substream *substream; 1856dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int period, ss, st; 1857dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1858dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_lock(&chip->lock); 1859dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini st = service_irq(chip); 1860dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (st < 0) { 1861dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_unlock(&chip->lock); 1862dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return IRQ_NONE; 1863dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1864dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* The hardware doesn't tell us which substream caused the irq, 1865dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini thus we have to check all running substreams. */ 1866dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini for (ss = 0; ss < DSP_MAXPIPES; ss++) { 1867b721e68bdc5b39c51bf6a1469f8d3663fbe03243Giuliano Pochini substream = chip->substream[ss]; 1868b721e68bdc5b39c51bf6a1469f8d3663fbe03243Giuliano Pochini if (substream && ((struct audiopipe *)substream->runtime-> 1869b721e68bdc5b39c51bf6a1469f8d3663fbe03243Giuliano Pochini private_data)->state == PIPE_STATE_STARTED) { 1870dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini period = pcm_pointer(substream) / 1871dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini substream->runtime->period_size; 1872dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (period != chip->last_period[ss]) { 1873dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->last_period[ss] = period; 1874dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_unlock(&chip->lock); 1875dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_pcm_period_elapsed(substream); 1876dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_lock(&chip->lock); 1877dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1878dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1879dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1880dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini spin_unlock(&chip->lock); 1881dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1882dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_MIDI 1883dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (st > 0 && chip->midi_in) { 1884dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_rawmidi_receive(chip->midi_in, chip->midi_buffer, st); 1885dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_MID(("rawmidi_iread=%d\n", st)); 1886dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1887dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif 1888dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return IRQ_HANDLED; 1889dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1890dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1891dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1892dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1893dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1894dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/****************************************************************************** 1895dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini Module construction / destruction 1896dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini******************************************************************************/ 1897dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1898dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_free(struct echoaudio *chip) 1899dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1900dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_INIT(("Stop DSP...\n")); 1901ebf029da38829ede6b53ac8a5ad45b149064ea16Takashi Iwai if (chip->comm_page) 1902dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini rest_in_peace(chip); 1903dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_INIT(("Stopped.\n")); 1904dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1905dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (chip->irq >= 0) 1906437a5a4606c12ab904793a7cad5b2062fc76c04eTakashi Iwai free_irq(chip->irq, chip); 1907dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1908ebf029da38829ede6b53ac8a5ad45b149064ea16Takashi Iwai if (chip->comm_page) 1909ebf029da38829ede6b53ac8a5ad45b149064ea16Takashi Iwai snd_dma_free_pages(&chip->commpage_dma_buf); 1910ebf029da38829ede6b53ac8a5ad45b149064ea16Takashi Iwai 1911dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (chip->dsp_registers) 1912dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini iounmap(chip->dsp_registers); 1913dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 19148caf7aa26e0797e5706043f94c491acd1a08636aTakashi Iwai if (chip->iores) 19158caf7aa26e0797e5706043f94c491acd1a08636aTakashi Iwai release_and_free_resource(chip->iores); 19168caf7aa26e0797e5706043f94c491acd1a08636aTakashi Iwai 1917dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_INIT(("MMIO freed.\n")); 1918dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1919dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pci_disable_device(chip->pci); 1920dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1921dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* release chip data */ 19224f8ada444cc7a7ea70cdc81f098b34c5f1f2df41Giuliano Pochini free_firmware_cache(chip); 1923dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini kfree(chip); 1924dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_INIT(("Chip freed.\n")); 1925dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 1926dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1927dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1928dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1929dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1930dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int snd_echo_dev_free(struct snd_device *device) 1931dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1932dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip = device->device_data; 1933dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1934dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_INIT(("snd_echo_dev_free()...\n")); 1935dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return snd_echo_free(chip); 1936dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 1937dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1938dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1939dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1940dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/* <--snd_echo_probe() */ 1941dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic __devinit int snd_echo_create(struct snd_card *card, 1942dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct pci_dev *pci, 1943dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio **rchip) 1944dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 1945dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 1946dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int err; 1947dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini size_t sz; 1948dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini static struct snd_device_ops ops = { 1949dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .dev_free = snd_echo_dev_free, 1950dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini }; 1951dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1952dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini *rchip = NULL; 1953dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1954dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pci_write_config_byte(pci, PCI_LATENCY_TIMER, 0xC0); 1955dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1956dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = pci_enable_device(pci)) < 0) 1957dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 1958dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pci_set_master(pci); 1959dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 196047b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini /* Allocate chip if needed */ 196147b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini if (!*rchip) { 196247b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini chip = kzalloc(sizeof(*chip), GFP_KERNEL); 196347b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini if (!chip) { 196447b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini pci_disable_device(pci); 196547b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini return -ENOMEM; 196647b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini } 196747b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini DE_INIT(("chip=%p\n", chip)); 196847b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini spin_lock_init(&chip->lock); 196947b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini chip->card = card; 197047b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini chip->pci = pci; 197147b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini chip->irq = -1; 197247b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini atomic_set(&chip->opencount, 0); 197347b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini mutex_init(&chip->mode_mutex); 197447b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini chip->can_set_rate = 1; 197547b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini } else { 197647b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini /* If this was called from the resume function, chip is 197747b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini * already allocated and it contains current card settings. 197847b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini */ 197947b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini chip = *rchip; 1980dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1981dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1982dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* PCI resource allocation */ 1983dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->dsp_registers_phys = pci_resource_start(pci, 0); 1984dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini sz = pci_resource_len(pci, 0); 1985dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (sz > PAGE_SIZE) 1986dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini sz = PAGE_SIZE; /* We map only the required part */ 1987dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1988dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((chip->iores = request_mem_region(chip->dsp_registers_phys, sz, 1989dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ECHOCARD_NAME)) == NULL) { 1990dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_echo_free(chip); 1991dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_printk(KERN_ERR "cannot get memory region\n"); 1992dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return -EBUSY; 1993dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 1994dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->dsp_registers = (volatile u32 __iomem *) 1995dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini ioremap_nocache(chip->dsp_registers_phys, sz); 1996dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 1997437a5a4606c12ab904793a7cad5b2062fc76c04eTakashi Iwai if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED, 1998437a5a4606c12ab904793a7cad5b2062fc76c04eTakashi Iwai ECHOCARD_NAME, chip)) { 1999dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_echo_free(chip); 2000dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_printk(KERN_ERR "cannot grab irq\n"); 2001dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return -EBUSY; 2002dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 2003dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->irq = pci->irq; 2004dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_INIT(("pci=%p irq=%d subdev=%04x Init hardware...\n", 2005dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->pci, chip->irq, chip->pci->subsystem_device)); 2006dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2007dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* Create the DSP comm page - this is the area of memory used for most 2008dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini of the communication with the DSP, which accesses it via bus mastering */ 2009dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), 2010dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini sizeof(struct comm_page), 2011dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini &chip->commpage_dma_buf) < 0) { 2012dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_echo_free(chip); 2013dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_printk(KERN_ERR "cannot allocate the comm page\n"); 2014dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return -ENOMEM; 2015dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 2016dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->comm_page_phys = chip->commpage_dma_buf.addr; 2017dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->comm_page = (struct comm_page *)chip->commpage_dma_buf.area; 2018dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2019dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device); 202047b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini if (err >= 0) 202147b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini err = set_mixer_defaults(chip); 202247b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini if (err < 0) { 2023dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_INIT(("init_hw err=%d\n", err)); 2024dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_echo_free(chip); 2025dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 2026dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 2027dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_INIT(("Card init OK\n")); 2028dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2029dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { 2030dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_echo_free(chip); 2031dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 2032dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 2033dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini *rchip = chip; 2034dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* Init done ! */ 2035dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 2036dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 2037dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2038dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2039dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2040dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/* constructor */ 2041dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int __devinit snd_echo_probe(struct pci_dev *pci, 2042dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini const struct pci_device_id *pci_id) 2043dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 2044dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini static int dev; 2045dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct snd_card *card; 2046dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 2047dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini char *dsp; 2048dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini int i, err; 2049dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2050dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (dev >= SNDRV_CARDS) 2051dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return -ENODEV; 2052dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (!enable[dev]) { 2053dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini dev++; 2054dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return -ENOENT; 2055dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 2056dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2057dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini DE_INIT(("Echoaudio driver starting...\n")); 2058dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini i = 0; 2059e58de7baf7de11f01a675cbbf6ecc8a2758b9ca5Takashi Iwai err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); 2060e58de7baf7de11f01a675cbbf6ecc8a2758b9ca5Takashi Iwai if (err < 0) 2061e58de7baf7de11f01a675cbbf6ecc8a2758b9ca5Takashi Iwai return err; 2062dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2063c187c041c6552339e4d8883a1a00c3c489354ecaTakashi Iwai snd_card_set_dev(card, &pci->dev); 2064c187c041c6552339e4d8883a1a00c3c489354ecaTakashi Iwai 206547b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini chip = NULL; /* Tells snd_echo_create to allocate chip */ 2066dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_echo_create(card, pci, &chip)) < 0) { 2067dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_card_free(card); 2068dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 2069dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 2070dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2071dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini strcpy(card->driver, "Echo_" ECHOCARD_NAME); 2072dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini strcpy(card->shortname, chip->card_name); 2073dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2074dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini dsp = "56301"; 2075dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (pci_id->device == 0x3410) 2076dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini dsp = "56361"; 2077dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2078dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini sprintf(card->longname, "%s rev.%d (DSP%s) at 0x%lx irq %i", 2079dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini card->shortname, pci_id->subdevice & 0x000f, dsp, 2080dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->dsp_registers_phys, chip->irq); 2081dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2082dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_echo_new_pcm(chip)) < 0) { 2083dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_printk(KERN_ERR "new pcm error %d\n", err); 2084dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_card_free(card); 2085dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 2086dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 2087dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2088dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_MIDI 2089dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (chip->has_midi) { /* Some Mia's do not have midi */ 2090dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_echo_midi_create(card, chip)) < 0) { 2091dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_printk(KERN_ERR "new midi error %d\n", err); 2092dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_card_free(card); 2093dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 2094dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 2095dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 2096dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif 2097dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2098dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_VMIXER 2099dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_echo_vmixer.count = num_pipes_out(chip) * num_busses_out(chip); 2100dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vmixer, chip))) < 0) 2101dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini goto ctl_error; 2102392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini#ifdef ECHOCARD_HAS_LINE_OUT_GAIN 2103392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini err = snd_ctl_add(chip->card, 2104392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini snd_ctl_new1(&snd_echo_line_output_gain, chip)); 2105392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini if (err < 0) 2106dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini goto ctl_error; 2107dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif 2108392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini#else /* ECHOCARD_HAS_VMIXER */ 2109392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini err = snd_ctl_add(chip->card, 2110392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini snd_ctl_new1(&snd_echo_pcm_output_gain, chip)); 2111392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini if (err < 0) 2112392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini goto ctl_error; 2113392bf2f1ba03b690f0ee71a185d4a5720a82bb25Giuliano Pochini#endif /* ECHOCARD_HAS_VMIXER */ 2114dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2115dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_INPUT_GAIN 2116dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_input_gain, chip))) < 0) 2117dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini goto ctl_error; 2118dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif 2119dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2120dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_INPUT_NOMINAL_LEVEL 2121dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (!chip->hasnt_input_nominal_level) 2122dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_intput_nominal_level, chip))) < 0) 2123dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini goto ctl_error; 2124dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif 2125dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2126dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL 2127dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_output_nominal_level, chip))) < 0) 2128dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini goto ctl_error; 2129dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif 2130dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2131dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vumeters_switch, chip))) < 0) 2132dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini goto ctl_error; 2133dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2134dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vumeters, chip))) < 0) 2135dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini goto ctl_error; 2136dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2137dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_MONITOR 2138dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_echo_monitor_mixer.count = num_busses_in(chip) * num_busses_out(chip); 2139dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_monitor_mixer, chip))) < 0) 2140dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini goto ctl_error; 2141dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif 2142dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2143dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE 2144dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_automute_switch, chip))) < 0) 2145dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini goto ctl_error; 2146dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif 2147dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2148dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_channels_info, chip))) < 0) 2149dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini goto ctl_error; 2150dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2151dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH 2152dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* Creates a list of available digital modes */ 2153dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->num_digital_modes = 0; 2154dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini for (i = 0; i < 6; i++) 2155dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (chip->digital_modes & (1 << i)) 2156dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->digital_mode_list[chip->num_digital_modes++] = i; 2157dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2158dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_digital_mode_switch, chip))) < 0) 2159dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini goto ctl_error; 2160dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif /* ECHOCARD_HAS_DIGITAL_MODE_SWITCH */ 2161dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2162dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_EXTERNAL_CLOCK 2163dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini /* Creates a list of available clock sources */ 2164dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->num_clock_sources = 0; 2165dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini for (i = 0; i < 10; i++) 2166dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (chip->input_clock_types & (1 << i)) 2167dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->clock_source_list[chip->num_clock_sources++] = i; 2168dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2169dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (chip->num_clock_sources > 1) { 2170dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip->clock_src_ctl = snd_ctl_new1(&snd_echo_clock_source_switch, chip); 2171dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_ctl_add(chip->card, chip->clock_src_ctl)) < 0) 2172dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini goto ctl_error; 2173dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini } 2174dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif /* ECHOCARD_HAS_EXTERNAL_CLOCK */ 2175dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2176dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_DIGITAL_IO 2177dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_spdif_mode_switch, chip))) < 0) 2178dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini goto ctl_error; 2179dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif 2180dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2181dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#ifdef ECHOCARD_HAS_PHANTOM_POWER 2182dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (chip->has_phantom_power) 2183dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_phantom_power_switch, chip))) < 0) 2184dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini goto ctl_error; 2185dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini#endif 2186dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2187a0fd4345f928d72a56e27b23e4cd28c94bf36be5Julia Lawall err = snd_card_register(card); 2188a0fd4345f928d72a56e27b23e4cd28c94bf36be5Julia Lawall if (err < 0) 2189dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini goto ctl_error; 2190dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_printk(KERN_INFO "Card registered: %s\n", card->longname); 2191dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2192dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pci_set_drvdata(pci, chip); 2193dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini dev++; 2194dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return 0; 2195dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2196dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinictl_error: 2197dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_printk(KERN_ERR "new control error %d\n", err); 2198dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_card_free(card); 2199dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return err; 2200dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 2201dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2202dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2203dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 220447b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini#if defined(CONFIG_PM) 220547b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini 220647b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochinistatic int snd_echo_suspend(struct pci_dev *pci, pm_message_t state) 220747b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini{ 220847b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini struct echoaudio *chip = pci_get_drvdata(pci); 220947b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini 221047b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini DE_INIT(("suspend start\n")); 221147b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini snd_pcm_suspend_all(chip->analog_pcm); 221247b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini snd_pcm_suspend_all(chip->digital_pcm); 221347b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini 221447b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini#ifdef ECHOCARD_HAS_MIDI 221547b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini /* This call can sleep */ 221647b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini if (chip->midi_out) 221747b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini snd_echo_midi_output_trigger(chip->midi_out, 0); 221847b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini#endif 221947b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini spin_lock_irq(&chip->lock); 222047b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini if (wait_handshake(chip)) { 222147b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini spin_unlock_irq(&chip->lock); 222247b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini return -EIO; 222347b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini } 222447b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini clear_handshake(chip); 222547b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini if (send_vector(chip, DSP_VC_GO_COMATOSE) < 0) { 222647b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini spin_unlock_irq(&chip->lock); 222747b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini return -EIO; 222847b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini } 222947b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini spin_unlock_irq(&chip->lock); 223047b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini 223147b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini chip->dsp_code = NULL; 223247b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini free_irq(chip->irq, chip); 223347b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini chip->irq = -1; 223447b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini pci_save_state(pci); 223547b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini pci_disable_device(pci); 223647b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini 223747b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini DE_INIT(("suspend done\n")); 223847b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini return 0; 223947b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini} 224047b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini 224147b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini 224247b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini 224347b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochinistatic int snd_echo_resume(struct pci_dev *pci) 224447b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini{ 224547b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini struct echoaudio *chip = pci_get_drvdata(pci); 224647b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini struct comm_page *commpage, *commpage_bak; 224747b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini u32 pipe_alloc_mask; 224847b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini int err; 224947b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini 225047b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini DE_INIT(("resume start\n")); 225147b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini pci_restore_state(pci); 225247b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL); 22530b6d092c8eeeb43893503afd2f6c1c67ceafc863Kulikov Vasiliy if (commpage_bak == NULL) 22540b6d092c8eeeb43893503afd2f6c1c67ceafc863Kulikov Vasiliy return -ENOMEM; 225547b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini commpage = chip->comm_page; 225647b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini memcpy(commpage_bak, commpage, sizeof(struct comm_page)); 225747b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini 225847b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device); 225947b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini if (err < 0) { 226047b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini kfree(commpage_bak); 226147b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini DE_INIT(("resume init_hw err=%d\n", err)); 226247b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini snd_echo_free(chip); 226347b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini return err; 226447b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini } 226547b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini DE_INIT(("resume init OK\n")); 226647b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini 226747b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini /* Temporarily set chip->pipe_alloc_mask=0 otherwise 226847b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini * restore_dsp_settings() fails. 226947b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini */ 227047b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini pipe_alloc_mask = chip->pipe_alloc_mask; 227147b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini chip->pipe_alloc_mask = 0; 227247b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini err = restore_dsp_rettings(chip); 227347b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini chip->pipe_alloc_mask = pipe_alloc_mask; 227447b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini if (err < 0) { 227547b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini kfree(commpage_bak); 227647b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini return err; 227747b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini } 227847b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini DE_INIT(("resume restore OK\n")); 227947b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini 228047b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini memcpy(&commpage->audio_format, &commpage_bak->audio_format, 228147b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini sizeof(commpage->audio_format)); 228247b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini memcpy(&commpage->sglist_addr, &commpage_bak->sglist_addr, 228347b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini sizeof(commpage->sglist_addr)); 228447b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini memcpy(&commpage->midi_output, &commpage_bak->midi_output, 228547b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini sizeof(commpage->midi_output)); 228647b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini kfree(commpage_bak); 228747b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini 228847b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED, 228947b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini ECHOCARD_NAME, chip)) { 229047b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini snd_echo_free(chip); 229147b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini snd_printk(KERN_ERR "cannot grab irq\n"); 229247b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini return -EBUSY; 229347b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini } 229447b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini chip->irq = pci->irq; 229547b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini DE_INIT(("resume irq=%d\n", chip->irq)); 229647b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini 229747b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini#ifdef ECHOCARD_HAS_MIDI 229847b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini if (chip->midi_input_enabled) 229947b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini enable_midi_input(chip, TRUE); 230047b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini if (chip->midi_out) 230147b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini snd_echo_midi_output_trigger(chip->midi_out, 1); 230247b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini#endif 230347b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini 230447b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini DE_INIT(("resume done\n")); 230547b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini return 0; 230647b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini} 230747b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini 230847b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini#endif /* CONFIG_PM */ 230947b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini 231047b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini 231147b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini 2312dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic void __devexit snd_echo_remove(struct pci_dev *pci) 2313dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 2314dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini struct echoaudio *chip; 2315dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2316dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini chip = pci_get_drvdata(pci); 2317dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini if (chip) 2318dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini snd_card_free(chip->card); 2319dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pci_set_drvdata(pci, NULL); 2320dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 2321dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2322dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2323dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2324dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/****************************************************************************** 2325dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini Everything starts and ends here 2326dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini******************************************************************************/ 2327dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2328dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/* pci_driver definition */ 2329dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic struct pci_driver driver = { 2330dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .name = "Echoaudio " ECHOCARD_NAME, 2331dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .id_table = snd_echo_ids, 2332dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .probe = snd_echo_probe, 2333dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini .remove = __devexit_p(snd_echo_remove), 233447b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini#ifdef CONFIG_PM 233547b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini .suspend = snd_echo_suspend, 233647b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini .resume = snd_echo_resume, 233747b5d028fdce8f809bf22852ac900338fb90e8aaGiuliano Pochini#endif /* CONFIG_PM */ 2338dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini}; 2339dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2340dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2341dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2342dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/* initialization of the module */ 2343dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic int __init alsa_card_echo_init(void) 2344dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 2345dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini return pci_register_driver(&driver); 2346dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 2347dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2348dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2349dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2350dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini/* clean up the module */ 2351dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinistatic void __exit alsa_card_echo_exit(void) 2352dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini{ 2353dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini pci_unregister_driver(&driver); 2354dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini} 2355dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2356dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochini 2357dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinimodule_init(alsa_card_echo_init) 2358dd7b254d8dd3a9528f423ac3bf875e6f0c8da561Giuliano Pochinimodule_exit(alsa_card_echo_exit) 2359