Lines Matching +full:int +full:- +full:clock +full:- +full:stable +full:- +full:broken
1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Abramo Bagnara <abramo@alsa-project.org>
9 * - Sometimes the SPDIF input DSP tasks get's unsynchronized
13 * - On the Hercules Game Theater XP the amplifier are sometimes turned
17 * - Secondary CODEC on some soundcards
18 * - SPDIF input support for other sample rates then 48khz
19 * - Posibility to mix the SPDIF output with analog sources.
20 * - PCM channels for Center and LFE on secondary codec
58 static void amp_voyetra(struct snd_cs46xx *chip, int change);
76 int codec_index) in snd_cs46xx_codec_read()
78 int count; in snd_cs46xx_codec_read()
86 chip->active_ctrl(chip, 1); in snd_cs46xx_codec_read()
94 * 3. Write ACCTL = Control Register = 460h for initiating the write7---55 in snd_cs46xx_codec_read()
104 dev_warn(chip->card->dev, "ACCTL_VFRM not set 0x%x\n", tmp); in snd_cs46xx_codec_read()
118 * set DCV - will clear when process completed in snd_cs46xx_codec_read()
119 * set CRW - Read command in snd_cs46xx_codec_read()
120 * set VFRM - valid frame enabled in snd_cs46xx_codec_read()
121 * set ESYN - ASYNC generation enabled in snd_cs46xx_codec_read()
122 * set RSTN - ARST# inactive, AC97 codec not reset in snd_cs46xx_codec_read()
156 dev_err(chip->card->dev, in snd_cs46xx_codec_read()
169 * VSTS - Valid Status in snd_cs46xx_codec_read()
176 dev_err(chip->card->dev, in snd_cs46xx_codec_read()
188 dev_dbg(chip->card->dev, in snd_cs46xx_codec_read()
197 chip->active_ctrl(chip, -1); in snd_cs46xx_codec_read()
204 struct snd_cs46xx *chip = ac97->private_data; in snd_cs46xx_ac97_read()
206 int codec_index = ac97->num; in snd_cs46xx_ac97_read()
221 int codec_index) in snd_cs46xx_codec_write()
223 int count; in snd_cs46xx_codec_write()
229 chip->active_ctrl(chip, 1); in snd_cs46xx_codec_write()
245 * set DCV - will clear when process completed in snd_cs46xx_codec_write()
246 * reset CRW - Write command in snd_cs46xx_codec_write()
247 * set VFRM - valid frame enabled in snd_cs46xx_codec_write()
248 * set ESYN - ASYNC generation enabled in snd_cs46xx_codec_write()
249 * set RSTN - ARST# inactive, AC97 codec not reset in snd_cs46xx_codec_write()
278 dev_err(chip->card->dev, in snd_cs46xx_codec_write()
282 chip->active_ctrl(chip, -1); in snd_cs46xx_codec_write()
289 struct snd_cs46xx *chip = ac97->private_data; in snd_cs46xx_ac97_write()
290 int codec_index = ac97->num; in snd_cs46xx_ac97_write()
304 int snd_cs46xx_download(struct snd_cs46xx *chip, in snd_cs46xx_download()
310 unsigned int bank = offset >> 16; in snd_cs46xx_download()
314 return -EINVAL; in snd_cs46xx_download()
315 dst = chip->region.idx[bank+1].remap_addr + offset; in snd_cs46xx_download()
318 /* writel already converts 32-bit value to right endianess */ in snd_cs46xx_download()
319 while (len-- > 0) { in snd_cs46xx_download()
326 static inline void memcpy_le32(void *dst, const void *src, unsigned int len) in memcpy_le32()
334 while (len-- > 0) in memcpy_le32()
355 kfree(module->module_name); in free_module_desc()
356 kfree(module->symbol_table.symbols); in free_module_desc()
357 if (module->segments) { in free_module_desc()
358 int i; in free_module_desc()
359 for (i = 0; i < module->nsegments; i++) in free_module_desc()
360 kfree(module->segments[i].data); in free_module_desc()
361 kfree(module->segments); in free_module_desc()
382 static int load_firmware(struct snd_cs46xx *chip, in load_firmware()
386 int i, err; in load_firmware()
387 unsigned int nums, fwlen, fwsize; in load_firmware()
394 err = request_firmware(&fw, fw_path, &chip->pci->dev); in load_firmware()
397 fwsize = fw->size / 4; in load_firmware()
399 err = -EINVAL; in load_firmware()
403 err = -ENOMEM; in load_firmware()
407 module->module_name = kstrdup(fw_name, GFP_KERNEL); in load_firmware()
408 if (!module->module_name) in load_firmware()
412 fwdat = (const __le32 *)fw->data; in load_firmware()
413 nums = module->symbol_table.nsymbols = le32_to_cpu(fwdat[fwlen++]); in load_firmware()
416 module->symbol_table.symbols = in load_firmware()
418 if (!module->symbol_table.symbols) in load_firmware()
422 &module->symbol_table.symbols[i]; in load_firmware()
425 entry->address = le32_to_cpu(fwdat[fwlen++]); in load_firmware()
426 memcpy(entry->symbol_name, &fwdat[fwlen], DSP_MAX_SYMBOL_NAME - 1); in load_firmware()
428 entry->symbol_type = le32_to_cpu(fwdat[fwlen++]); in load_firmware()
433 nums = module->nsegments = le32_to_cpu(fwdat[fwlen++]); in load_firmware()
436 module->segments = in load_firmware()
438 if (!module->segments) in load_firmware()
441 struct dsp_segment_desc *entry = &module->segments[i]; in load_firmware()
444 entry->segment_type = le32_to_cpu(fwdat[fwlen++]); in load_firmware()
445 entry->offset = le32_to_cpu(fwdat[fwlen++]); in load_firmware()
446 entry->size = le32_to_cpu(fwdat[fwlen++]); in load_firmware()
447 if (fwlen + entry->size > fwsize) in load_firmware()
449 entry->data = kmalloc_array(entry->size, 4, GFP_KERNEL); in load_firmware()
450 if (!entry->data) in load_firmware()
452 memcpy_le32(entry->data, &fwdat[fwlen], entry->size * 4); in load_firmware()
453 fwlen += entry->size; in load_firmware()
461 err = -EINVAL; in load_firmware()
468 int snd_cs46xx_clear_BA1(struct snd_cs46xx *chip, in snd_cs46xx_clear_BA1()
473 unsigned int bank = offset >> 16; in snd_cs46xx_clear_BA1()
477 return -EINVAL; in snd_cs46xx_clear_BA1()
478 dst = chip->region.idx[bank+1].remap_addr + offset; in snd_cs46xx_clear_BA1()
481 /* writel already converts 32-bit value to right endianess */ in snd_cs46xx_clear_BA1()
482 while (len-- > 0) { in snd_cs46xx_clear_BA1()
501 static int load_firmware(struct snd_cs46xx *chip) in load_firmware()
504 int i, size, err; in load_firmware()
506 err = request_firmware(&fw, "cs46xx/ba1", &chip->pci->dev); in load_firmware()
509 if (fw->size != sizeof(*chip->ba1)) { in load_firmware()
510 err = -EINVAL; in load_firmware()
514 chip->ba1 = vmalloc(sizeof(*chip->ba1)); in load_firmware()
515 if (!chip->ba1) { in load_firmware()
516 err = -ENOMEM; in load_firmware()
520 memcpy_le32(chip->ba1, fw->data, sizeof(*chip->ba1)); in load_firmware()
525 size += chip->ba1->memory[i].size; in load_firmware()
527 err = -EINVAL; in load_firmware()
534 int snd_cs46xx_download_image(struct snd_cs46xx *chip) in snd_cs46xx_download_image()
536 int idx, err; in snd_cs46xx_download_image()
537 unsigned int offset = 0; in snd_cs46xx_download_image()
538 struct ba1_struct *ba1 = chip->ba1; in snd_cs46xx_download_image()
542 &ba1->map[offset], in snd_cs46xx_download_image()
543 ba1->memory[idx].offset, in snd_cs46xx_download_image()
544 ba1->memory[idx].size); in snd_cs46xx_download_image()
547 offset += ba1->memory[idx].size >> 2; in snd_cs46xx_download_image()
559 int idx; in snd_cs46xx_reset()
586 static int cs46xx_wait_for_fifo(struct snd_cs46xx * chip,int retry_timeout) in cs46xx_wait_for_fifo()
602 dev_err(chip->card->dev, in cs46xx_wait_for_fifo()
604 return -EINVAL; in cs46xx_wait_for_fifo()
612 int idx, powerdown = 0; in snd_cs46xx_clear_serial_FIFOs()
613 unsigned int tmp; in snd_cs46xx_clear_serial_FIFOs()
640 dev_dbg(chip->card->dev, in snd_cs46xx_clear_serial_FIFOs()
668 int cnt; in snd_cs46xx_proc_start()
690 dev_err(chip->card->dev, "SPCR_RUNFR never reset\n"); in snd_cs46xx_proc_start()
708 static void snd_cs46xx_set_play_sample_rate(struct snd_cs46xx *chip, unsigned int rate) in snd_cs46xx_set_play_sample_rate()
711 unsigned int tmp1, tmp2; in snd_cs46xx_set_play_sample_rate()
712 unsigned int phiIncr; in snd_cs46xx_set_play_sample_rate()
713 unsigned int correctionPerGOF, correctionPerSec; in snd_cs46xx_set_play_sample_rate()
721 * correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) / in snd_cs46xx_set_play_sample_rate()
723 * ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -M in snd_cs46xx_set_play_sample_rate()
734 tmp1 -= phiIncr * 48000; in snd_cs46xx_set_play_sample_rate()
739 tmp1 -= tmp2 * 48000; in snd_cs46xx_set_play_sample_rate()
741 tmp1 -= correctionPerGOF * GOF_PER_SEC; in snd_cs46xx_set_play_sample_rate()
747 spin_lock_irqsave(&chip->reg_lock, flags); in snd_cs46xx_set_play_sample_rate()
751 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_cs46xx_set_play_sample_rate()
754 static void snd_cs46xx_set_capture_sample_rate(struct snd_cs46xx *chip, unsigned int rate) in snd_cs46xx_set_capture_sample_rate()
757 unsigned int phiIncr, coeffIncr, tmp1, tmp2; in snd_cs46xx_set_capture_sample_rate()
758 unsigned int correctionPerGOF, correctionPerSec, initialDelay; in snd_cs46xx_set_capture_sample_rate()
759 unsigned int frameGroupLength, cnt; in snd_cs46xx_set_capture_sample_rate()
780 * coeffIncr = -floor((Fs,out * 2^23) / Fs,in) in snd_cs46xx_set_capture_sample_rate()
782 * correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) / in snd_cs46xx_set_capture_sample_rate()
784 * correctionPerSec = Fs,in * 2^26 - Fs,out * phiIncr - in snd_cs46xx_set_capture_sample_rate()
794 * initialDelay = dividend(((24 * Fs,in) + Fs,out - 1) / Fs,out) in snd_cs46xx_set_capture_sample_rate()
799 tmp1 -= coeffIncr * 48000; in snd_cs46xx_set_capture_sample_rate()
807 tmp1 -= phiIncr * rate; in snd_cs46xx_set_capture_sample_rate()
812 tmp1 -= tmp2 * rate; in snd_cs46xx_set_capture_sample_rate()
814 tmp1 -= correctionPerGOF * GOF_PER_SEC; in snd_cs46xx_set_capture_sample_rate()
816 initialDelay = ((48000 * 24) + rate - 1) / rate; in snd_cs46xx_set_capture_sample_rate()
821 spin_lock_irqsave(&chip->reg_lock, flags); in snd_cs46xx_set_capture_sample_rate()
828 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_cs46xx_set_capture_sample_rate()
851 spin_lock_irqsave(&chip->reg_lock, flags); in snd_cs46xx_set_capture_sample_rate()
857 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_cs46xx_set_capture_sample_rate()
867 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_pb_trans_copy()
868 struct snd_cs46xx_pcm * cpcm = runtime->private_data; in snd_cs46xx_pb_trans_copy()
869 memcpy(cpcm->hw_buf.area + rec->hw_data, runtime->dma_area + rec->sw_data, bytes); in snd_cs46xx_pb_trans_copy()
872 static int snd_cs46xx_playback_transfer(struct snd_pcm_substream *substream) in snd_cs46xx_playback_transfer()
874 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_playback_transfer()
875 struct snd_cs46xx_pcm * cpcm = runtime->private_data; in snd_cs46xx_playback_transfer()
876 return snd_pcm_indirect_playback_transfer(substream, &cpcm->pcm_rec, in snd_cs46xx_playback_transfer()
884 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_cp_trans_copy()
885 memcpy(runtime->dma_area + rec->sw_data, in snd_cs46xx_cp_trans_copy()
886 chip->capt.hw_buf.area + rec->hw_data, bytes); in snd_cs46xx_cp_trans_copy()
889 static int snd_cs46xx_capture_transfer(struct snd_pcm_substream *substream) in snd_cs46xx_capture_transfer()
892 return snd_pcm_indirect_capture_transfer(substream, &chip->capt.pcm_rec, in snd_cs46xx_capture_transfer()
900 struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data; in snd_cs46xx_playback_direct_pointer()
902 if (snd_BUG_ON(!cpcm->pcm_channel)) in snd_cs46xx_playback_direct_pointer()
903 return -ENXIO; in snd_cs46xx_playback_direct_pointer()
906 ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2); in snd_cs46xx_playback_direct_pointer()
910 ptr -= cpcm->hw_buf.addr; in snd_cs46xx_playback_direct_pointer()
911 return ptr >> cpcm->shift; in snd_cs46xx_playback_direct_pointer()
918 struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data; in snd_cs46xx_playback_indirect_pointer()
921 if (snd_BUG_ON(!cpcm->pcm_channel)) in snd_cs46xx_playback_indirect_pointer()
922 return -ENXIO; in snd_cs46xx_playback_indirect_pointer()
923 ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2); in snd_cs46xx_playback_indirect_pointer()
927 ptr -= cpcm->hw_buf.addr; in snd_cs46xx_playback_indirect_pointer()
928 return snd_pcm_indirect_playback_pointer(substream, &cpcm->pcm_rec, ptr); in snd_cs46xx_playback_indirect_pointer()
934 size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_buf.addr; in snd_cs46xx_capture_direct_pointer()
935 return ptr >> chip->capt.shift; in snd_cs46xx_capture_direct_pointer()
941 size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_buf.addr; in snd_cs46xx_capture_indirect_pointer()
942 return snd_pcm_indirect_capture_pointer(substream, &chip->capt.pcm_rec, ptr); in snd_cs46xx_capture_indirect_pointer()
945 static int snd_cs46xx_playback_trigger(struct snd_pcm_substream *substream, in snd_cs46xx_playback_trigger()
946 int cmd) in snd_cs46xx_playback_trigger()
949 /*struct snd_pcm_runtime *runtime = substream->runtime;*/ in snd_cs46xx_playback_trigger()
950 int result = 0; in snd_cs46xx_playback_trigger()
953 struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data; in snd_cs46xx_playback_trigger()
954 if (! cpcm->pcm_channel) { in snd_cs46xx_playback_trigger()
955 return -ENXIO; in snd_cs46xx_playback_trigger()
963 snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + in snd_cs46xx_playback_trigger()
966 if (cpcm->pcm_channel->unlinked) in snd_cs46xx_playback_trigger()
967 cs46xx_dsp_pcm_link(chip,cpcm->pcm_channel); in snd_cs46xx_playback_trigger()
969 if (substream->runtime->periods != CS46XX_FRAGS) in snd_cs46xx_playback_trigger()
972 spin_lock(&chip->reg_lock); in snd_cs46xx_playback_trigger()
973 if (substream->runtime->periods != CS46XX_FRAGS) in snd_cs46xx_playback_trigger()
975 { unsigned int tmp; in snd_cs46xx_playback_trigger()
978 snd_cs46xx_poke(chip, BA1_PCTL, chip->play_ctl | tmp); in snd_cs46xx_playback_trigger()
980 spin_unlock(&chip->reg_lock); in snd_cs46xx_playback_trigger()
987 snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + in snd_cs46xx_playback_trigger()
990 if (!cpcm->pcm_channel->unlinked) in snd_cs46xx_playback_trigger()
991 cs46xx_dsp_pcm_unlink(chip,cpcm->pcm_channel); in snd_cs46xx_playback_trigger()
993 spin_lock(&chip->reg_lock); in snd_cs46xx_playback_trigger()
994 { unsigned int tmp; in snd_cs46xx_playback_trigger()
999 spin_unlock(&chip->reg_lock); in snd_cs46xx_playback_trigger()
1003 result = -EINVAL; in snd_cs46xx_playback_trigger()
1010 static int snd_cs46xx_capture_trigger(struct snd_pcm_substream *substream, in snd_cs46xx_capture_trigger()
1011 int cmd) in snd_cs46xx_capture_trigger()
1014 unsigned int tmp; in snd_cs46xx_capture_trigger()
1015 int result = 0; in snd_cs46xx_capture_trigger()
1017 spin_lock(&chip->reg_lock); in snd_cs46xx_capture_trigger()
1023 snd_cs46xx_poke(chip, BA1_CCTL, chip->capt.ctl | tmp); in snd_cs46xx_capture_trigger()
1032 result = -EINVAL; in snd_cs46xx_capture_trigger()
1035 spin_unlock(&chip->reg_lock); in snd_cs46xx_capture_trigger()
1041 static int _cs46xx_adjust_sample_rate (struct snd_cs46xx *chip, struct snd_cs46xx_pcm *cpcm, in _cs46xx_adjust_sample_rate()
1042 int sample_rate) in _cs46xx_adjust_sample_rate()
1046 if ( cpcm->pcm_channel == NULL) { in _cs46xx_adjust_sample_rate()
1047 cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip, sample_rate, in _cs46xx_adjust_sample_rate()
1048 cpcm, cpcm->hw_buf.addr,cpcm->pcm_channel_id); in _cs46xx_adjust_sample_rate()
1049 if (cpcm->pcm_channel == NULL) { in _cs46xx_adjust_sample_rate()
1050 dev_err(chip->card->dev, in _cs46xx_adjust_sample_rate()
1052 return -ENOMEM; in _cs46xx_adjust_sample_rate()
1054 cpcm->pcm_channel->sample_rate = sample_rate; in _cs46xx_adjust_sample_rate()
1057 if ((int)cpcm->pcm_channel->sample_rate != sample_rate) { in _cs46xx_adjust_sample_rate()
1058 int unlinked = cpcm->pcm_channel->unlinked; in _cs46xx_adjust_sample_rate()
1059 cs46xx_dsp_destroy_pcm_channel (chip,cpcm->pcm_channel); in _cs46xx_adjust_sample_rate()
1061 if ( (cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip, sample_rate, cpcm, in _cs46xx_adjust_sample_rate()
1062 cpcm->hw_buf.addr, in _cs46xx_adjust_sample_rate()
1063 cpcm->pcm_channel_id)) == NULL) { in _cs46xx_adjust_sample_rate()
1064 dev_err(chip->card->dev, in _cs46xx_adjust_sample_rate()
1065 "failed to re-create virtual PCM channel\n"); in _cs46xx_adjust_sample_rate()
1066 return -ENOMEM; in _cs46xx_adjust_sample_rate()
1069 if (!unlinked) cs46xx_dsp_pcm_link (chip,cpcm->pcm_channel); in _cs46xx_adjust_sample_rate()
1070 cpcm->pcm_channel->sample_rate = sample_rate; in _cs46xx_adjust_sample_rate()
1078 static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream, in snd_cs46xx_playback_hw_params()
1081 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_playback_hw_params()
1083 int err; in snd_cs46xx_playback_hw_params()
1086 int sample_rate = params_rate(hw_params); in snd_cs46xx_playback_hw_params()
1087 int period_size = params_period_bytes(hw_params); in snd_cs46xx_playback_hw_params()
1089 cpcm = runtime->private_data; in snd_cs46xx_playback_hw_params()
1093 return -ENXIO; in snd_cs46xx_playback_hw_params()
1095 mutex_lock(&chip->spos_mutex); in snd_cs46xx_playback_hw_params()
1098 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_hw_params()
1099 return -ENXIO; in snd_cs46xx_playback_hw_params()
1102 snd_BUG_ON(!cpcm->pcm_channel); in snd_cs46xx_playback_hw_params()
1103 if (!cpcm->pcm_channel) { in snd_cs46xx_playback_hw_params()
1104 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_hw_params()
1105 return -ENXIO; in snd_cs46xx_playback_hw_params()
1109 if (cs46xx_dsp_pcm_channel_set_period (chip,cpcm->pcm_channel,period_size)) { in snd_cs46xx_playback_hw_params()
1110 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_hw_params()
1111 return -EINVAL; in snd_cs46xx_playback_hw_params()
1114 dev_dbg(chip->card->dev, in snd_cs46xx_playback_hw_params()
1121 if (runtime->dma_area != cpcm->hw_buf.area) in snd_cs46xx_playback_hw_params()
1123 runtime->dma_area = cpcm->hw_buf.area; in snd_cs46xx_playback_hw_params()
1124 runtime->dma_addr = cpcm->hw_buf.addr; in snd_cs46xx_playback_hw_params()
1125 runtime->dma_bytes = cpcm->hw_buf.bytes; in snd_cs46xx_playback_hw_params()
1129 if (cpcm->pcm_channel_id == DSP_PCM_MAIN_CHANNEL) { in snd_cs46xx_playback_hw_params()
1130 substream->ops = &snd_cs46xx_playback_ops; in snd_cs46xx_playback_hw_params()
1131 } else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) { in snd_cs46xx_playback_hw_params()
1132 substream->ops = &snd_cs46xx_playback_rear_ops; in snd_cs46xx_playback_hw_params()
1133 } else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) { in snd_cs46xx_playback_hw_params()
1134 substream->ops = &snd_cs46xx_playback_clfe_ops; in snd_cs46xx_playback_hw_params()
1135 } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) { in snd_cs46xx_playback_hw_params()
1136 substream->ops = &snd_cs46xx_playback_iec958_ops; in snd_cs46xx_playback_hw_params()
1141 substream->ops = &snd_cs46xx_playback_ops; in snd_cs46xx_playback_hw_params()
1145 if (runtime->dma_area == cpcm->hw_buf.area) { in snd_cs46xx_playback_hw_params()
1146 runtime->dma_area = NULL; in snd_cs46xx_playback_hw_params()
1147 runtime->dma_addr = 0; in snd_cs46xx_playback_hw_params()
1148 runtime->dma_bytes = 0; in snd_cs46xx_playback_hw_params()
1152 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_hw_params()
1158 if (cpcm->pcm_channel_id == DSP_PCM_MAIN_CHANNEL) { in snd_cs46xx_playback_hw_params()
1159 substream->ops = &snd_cs46xx_playback_indirect_ops; in snd_cs46xx_playback_hw_params()
1160 } else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) { in snd_cs46xx_playback_hw_params()
1161 substream->ops = &snd_cs46xx_playback_indirect_rear_ops; in snd_cs46xx_playback_hw_params()
1162 } else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) { in snd_cs46xx_playback_hw_params()
1163 substream->ops = &snd_cs46xx_playback_indirect_clfe_ops; in snd_cs46xx_playback_hw_params()
1164 } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) { in snd_cs46xx_playback_hw_params()
1165 substream->ops = &snd_cs46xx_playback_indirect_iec958_ops; in snd_cs46xx_playback_hw_params()
1170 substream->ops = &snd_cs46xx_playback_indirect_ops; in snd_cs46xx_playback_hw_params()
1176 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_hw_params()
1182 static int snd_cs46xx_playback_hw_free(struct snd_pcm_substream *substream) in snd_cs46xx_playback_hw_free()
1185 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_playback_hw_free()
1188 cpcm = runtime->private_data; in snd_cs46xx_playback_hw_free()
1192 if (!cpcm) return -ENXIO; in snd_cs46xx_playback_hw_free()
1194 if (runtime->dma_area != cpcm->hw_buf.area) in snd_cs46xx_playback_hw_free()
1197 runtime->dma_area = NULL; in snd_cs46xx_playback_hw_free()
1198 runtime->dma_addr = 0; in snd_cs46xx_playback_hw_free()
1199 runtime->dma_bytes = 0; in snd_cs46xx_playback_hw_free()
1204 static int snd_cs46xx_playback_prepare(struct snd_pcm_substream *substream) in snd_cs46xx_playback_prepare()
1206 unsigned int tmp; in snd_cs46xx_playback_prepare()
1207 unsigned int pfie; in snd_cs46xx_playback_prepare()
1209 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_playback_prepare()
1212 cpcm = runtime->private_data; in snd_cs46xx_playback_prepare()
1215 if (snd_BUG_ON(!cpcm->pcm_channel)) in snd_cs46xx_playback_prepare()
1216 return -ENXIO; in snd_cs46xx_playback_prepare()
1218 pfie = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2 ); in snd_cs46xx_playback_prepare()
1226 cpcm->shift = 2; in snd_cs46xx_playback_prepare()
1228 if (runtime->channels == 1) { in snd_cs46xx_playback_prepare()
1229 cpcm->shift--; in snd_cs46xx_playback_prepare()
1233 if (snd_pcm_format_width(runtime->format) == 8) { in snd_cs46xx_playback_prepare()
1234 cpcm->shift--; in snd_cs46xx_playback_prepare()
1238 if (snd_pcm_format_unsigned(runtime->format)) in snd_cs46xx_playback_prepare()
1242 if (snd_pcm_format_width(runtime->format) != 8) { in snd_cs46xx_playback_prepare()
1244 if (snd_pcm_format_big_endian(runtime->format)) in snd_cs46xx_playback_prepare()
1248 memset(&cpcm->pcm_rec, 0, sizeof(cpcm->pcm_rec)); in snd_cs46xx_playback_prepare()
1249 cpcm->pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); in snd_cs46xx_playback_prepare()
1250 cpcm->pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << cpcm->shift; in snd_cs46xx_playback_prepare()
1254 tmp = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address) << 2); in snd_cs46xx_playback_prepare()
1256 tmp |= (4 << cpcm->shift) - 1; in snd_cs46xx_playback_prepare()
1258 snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address) << 2, tmp); in snd_cs46xx_playback_prepare()
1261 …snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2, pfie | cpcm->pcm_chan… in snd_cs46xx_playback_prepare()
1263 snd_cs46xx_poke(chip, BA1_PBA, cpcm->hw_buf.addr); in snd_cs46xx_playback_prepare()
1266 tmp |= (4 << cpcm->shift) - 1; in snd_cs46xx_playback_prepare()
1269 snd_cs46xx_set_play_sample_rate(chip, runtime->rate); in snd_cs46xx_playback_prepare()
1275 static int snd_cs46xx_capture_hw_params(struct snd_pcm_substream *substream, in snd_cs46xx_capture_hw_params()
1279 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_capture_hw_params()
1280 int err; in snd_cs46xx_capture_hw_params()
1285 if (runtime->periods == CS46XX_FRAGS) { in snd_cs46xx_capture_hw_params()
1286 if (runtime->dma_area != chip->capt.hw_buf.area) in snd_cs46xx_capture_hw_params()
1288 runtime->dma_area = chip->capt.hw_buf.area; in snd_cs46xx_capture_hw_params()
1289 runtime->dma_addr = chip->capt.hw_buf.addr; in snd_cs46xx_capture_hw_params()
1290 runtime->dma_bytes = chip->capt.hw_buf.bytes; in snd_cs46xx_capture_hw_params()
1291 substream->ops = &snd_cs46xx_capture_ops; in snd_cs46xx_capture_hw_params()
1293 if (runtime->dma_area == chip->capt.hw_buf.area) { in snd_cs46xx_capture_hw_params()
1294 runtime->dma_area = NULL; in snd_cs46xx_capture_hw_params()
1295 runtime->dma_addr = 0; in snd_cs46xx_capture_hw_params()
1296 runtime->dma_bytes = 0; in snd_cs46xx_capture_hw_params()
1300 substream->ops = &snd_cs46xx_capture_indirect_ops; in snd_cs46xx_capture_hw_params()
1306 static int snd_cs46xx_capture_hw_free(struct snd_pcm_substream *substream) in snd_cs46xx_capture_hw_free()
1309 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_capture_hw_free()
1311 if (runtime->dma_area != chip->capt.hw_buf.area) in snd_cs46xx_capture_hw_free()
1313 runtime->dma_area = NULL; in snd_cs46xx_capture_hw_free()
1314 runtime->dma_addr = 0; in snd_cs46xx_capture_hw_free()
1315 runtime->dma_bytes = 0; in snd_cs46xx_capture_hw_free()
1320 static int snd_cs46xx_capture_prepare(struct snd_pcm_substream *substream) in snd_cs46xx_capture_prepare()
1323 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_capture_prepare()
1325 snd_cs46xx_poke(chip, BA1_CBA, chip->capt.hw_buf.addr); in snd_cs46xx_capture_prepare()
1326 chip->capt.shift = 2; in snd_cs46xx_capture_prepare()
1327 memset(&chip->capt.pcm_rec, 0, sizeof(chip->capt.pcm_rec)); in snd_cs46xx_capture_prepare()
1328 chip->capt.pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); in snd_cs46xx_capture_prepare()
1329 chip->capt.pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << 2; in snd_cs46xx_capture_prepare()
1330 snd_cs46xx_set_capture_sample_rate(chip, runtime->rate); in snd_cs46xx_capture_prepare()
1335 static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id) in snd_cs46xx_interrupt()
1340 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_interrupt()
1342 int i; in snd_cs46xx_interrupt()
1362 if (chip->capt.substream) in snd_cs46xx_interrupt()
1363 snd_pcm_period_elapsed(chip->capt.substream); in snd_cs46xx_interrupt()
1365 if (ins->pcm_channels[i].active && in snd_cs46xx_interrupt()
1366 ins->pcm_channels[i].private_data && in snd_cs46xx_interrupt()
1367 !ins->pcm_channels[i].unlinked) { in snd_cs46xx_interrupt()
1368 cpcm = ins->pcm_channels[i].private_data; in snd_cs46xx_interrupt()
1369 snd_pcm_period_elapsed(cpcm->substream); in snd_cs46xx_interrupt()
1374 if ( status2 & (1 << (i - 16))) { in snd_cs46xx_interrupt()
1375 if (ins->pcm_channels[i].active && in snd_cs46xx_interrupt()
1376 ins->pcm_channels[i].private_data && in snd_cs46xx_interrupt()
1377 !ins->pcm_channels[i].unlinked) { in snd_cs46xx_interrupt()
1378 cpcm = ins->pcm_channels[i].private_data; in snd_cs46xx_interrupt()
1379 snd_pcm_period_elapsed(cpcm->substream); in snd_cs46xx_interrupt()
1387 if ((status1 & HISR_VC0) && chip->playback_pcm) { in snd_cs46xx_interrupt()
1388 if (chip->playback_pcm->substream) in snd_cs46xx_interrupt()
1389 snd_pcm_period_elapsed(chip->playback_pcm->substream); in snd_cs46xx_interrupt()
1391 if ((status1 & HISR_VC1) && chip->pcm) { in snd_cs46xx_interrupt()
1392 if (chip->capt.substream) in snd_cs46xx_interrupt()
1393 snd_pcm_period_elapsed(chip->capt.substream); in snd_cs46xx_interrupt()
1397 if ((status1 & HISR_MIDI) && chip->rmidi) { in snd_cs46xx_interrupt()
1400 spin_lock(&chip->reg_lock); in snd_cs46xx_interrupt()
1403 if ((chip->midcr & MIDCR_RIE) == 0) in snd_cs46xx_interrupt()
1405 snd_rawmidi_receive(chip->midi_input, &c, 1); in snd_cs46xx_interrupt()
1408 if ((chip->midcr & MIDCR_TIE) == 0) in snd_cs46xx_interrupt()
1410 if (snd_rawmidi_transmit(chip->midi_output, &c, 1) != 1) { in snd_cs46xx_interrupt()
1411 chip->midcr &= ~MIDCR_TIE; in snd_cs46xx_interrupt()
1412 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_interrupt()
1417 spin_unlock(&chip->reg_lock); in snd_cs46xx_interrupt()
1473 static const unsigned int period_sizes[] = { 32, 64, 128, 256, 512, 1024, 2048 };
1485 kfree(runtime->private_data); in snd_cs46xx_pcm_free_substream()
1488 static int _cs46xx_playback_open_channel (struct snd_pcm_substream *substream,int pcm_channel_id) in _cs46xx_playback_open_channel()
1492 struct snd_pcm_runtime *runtime = substream->runtime; in _cs46xx_playback_open_channel()
1496 return -ENOMEM; in _cs46xx_playback_open_channel()
1497 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &chip->pci->dev, in _cs46xx_playback_open_channel()
1498 PAGE_SIZE, &cpcm->hw_buf) < 0) { in _cs46xx_playback_open_channel()
1500 return -ENOMEM; in _cs46xx_playback_open_channel()
1503 runtime->hw = snd_cs46xx_playback; in _cs46xx_playback_open_channel()
1504 runtime->private_data = cpcm; in _cs46xx_playback_open_channel()
1505 runtime->private_free = snd_cs46xx_pcm_free_substream; in _cs46xx_playback_open_channel()
1507 cpcm->substream = substream; in _cs46xx_playback_open_channel()
1509 mutex_lock(&chip->spos_mutex); in _cs46xx_playback_open_channel()
1510 cpcm->pcm_channel = NULL; in _cs46xx_playback_open_channel()
1511 cpcm->pcm_channel_id = pcm_channel_id; in _cs46xx_playback_open_channel()
1518 mutex_unlock(&chip->spos_mutex); in _cs46xx_playback_open_channel()
1520 chip->playback_pcm = cpcm; /* HACK */ in _cs46xx_playback_open_channel()
1523 if (chip->accept_valid) in _cs46xx_playback_open_channel()
1524 substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID; in _cs46xx_playback_open_channel()
1525 chip->active_ctrl(chip, 1); in _cs46xx_playback_open_channel()
1530 static int snd_cs46xx_playback_open(struct snd_pcm_substream *substream) in snd_cs46xx_playback_open()
1532 dev_dbg(substream->pcm->card->dev, "open front channel\n"); in snd_cs46xx_playback_open()
1537 static int snd_cs46xx_playback_open_rear(struct snd_pcm_substream *substream) in snd_cs46xx_playback_open_rear()
1539 dev_dbg(substream->pcm->card->dev, "open rear channel\n"); in snd_cs46xx_playback_open_rear()
1543 static int snd_cs46xx_playback_open_clfe(struct snd_pcm_substream *substream) in snd_cs46xx_playback_open_clfe()
1545 dev_dbg(substream->pcm->card->dev, "open center - LFE channel\n"); in snd_cs46xx_playback_open_clfe()
1549 static int snd_cs46xx_playback_open_iec958(struct snd_pcm_substream *substream) in snd_cs46xx_playback_open_iec958()
1553 dev_dbg(chip->card->dev, "open raw iec958 channel\n"); in snd_cs46xx_playback_open_iec958()
1555 mutex_lock(&chip->spos_mutex); in snd_cs46xx_playback_open_iec958()
1557 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_open_iec958()
1562 static int snd_cs46xx_playback_close(struct snd_pcm_substream *substream);
1564 static int snd_cs46xx_playback_close_iec958(struct snd_pcm_substream *substream) in snd_cs46xx_playback_close_iec958()
1566 int err; in snd_cs46xx_playback_close_iec958()
1569 dev_dbg(chip->card->dev, "close raw iec958 channel\n"); in snd_cs46xx_playback_close_iec958()
1573 mutex_lock(&chip->spos_mutex); in snd_cs46xx_playback_close_iec958()
1575 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_close_iec958()
1581 static int snd_cs46xx_capture_open(struct snd_pcm_substream *substream) in snd_cs46xx_capture_open()
1585 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &chip->pci->dev, in snd_cs46xx_capture_open()
1586 PAGE_SIZE, &chip->capt.hw_buf) < 0) in snd_cs46xx_capture_open()
1587 return -ENOMEM; in snd_cs46xx_capture_open()
1588 chip->capt.substream = substream; in snd_cs46xx_capture_open()
1589 substream->runtime->hw = snd_cs46xx_capture; in snd_cs46xx_capture_open()
1591 if (chip->accept_valid) in snd_cs46xx_capture_open()
1592 substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID; in snd_cs46xx_capture_open()
1594 chip->active_ctrl(chip, 1); in snd_cs46xx_capture_open()
1597 snd_pcm_hw_constraint_list(substream->runtime, 0, in snd_cs46xx_capture_open()
1604 static int snd_cs46xx_playback_close(struct snd_pcm_substream *substream) in snd_cs46xx_playback_close()
1607 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_playback_close()
1610 cpcm = runtime->private_data; in snd_cs46xx_playback_close()
1613 if (!cpcm) return -ENXIO; in snd_cs46xx_playback_close()
1616 mutex_lock(&chip->spos_mutex); in snd_cs46xx_playback_close()
1617 if (cpcm->pcm_channel) { in snd_cs46xx_playback_close()
1618 cs46xx_dsp_destroy_pcm_channel(chip,cpcm->pcm_channel); in snd_cs46xx_playback_close()
1619 cpcm->pcm_channel = NULL; in snd_cs46xx_playback_close()
1621 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_close()
1623 chip->playback_pcm = NULL; in snd_cs46xx_playback_close()
1626 cpcm->substream = NULL; in snd_cs46xx_playback_close()
1627 snd_dma_free_pages(&cpcm->hw_buf); in snd_cs46xx_playback_close()
1628 chip->active_ctrl(chip, -1); in snd_cs46xx_playback_close()
1633 static int snd_cs46xx_capture_close(struct snd_pcm_substream *substream) in snd_cs46xx_capture_close()
1637 chip->capt.substream = NULL; in snd_cs46xx_capture_close()
1638 snd_dma_free_pages(&chip->capt.hw_buf); in snd_cs46xx_capture_close()
1639 chip->active_ctrl(chip, -1); in snd_cs46xx_capture_close()
1753 #define MAX_PLAYBACK_CHANNELS (DSP_MAX_PCM_CHANNELS - 1)
1758 int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device) in snd_cs46xx_pcm()
1761 int err; in snd_cs46xx_pcm()
1763 if ((err = snd_pcm_new(chip->card, "CS46xx", device, MAX_PLAYBACK_CHANNELS, 1, &pcm)) < 0) in snd_cs46xx_pcm()
1766 pcm->private_data = chip; in snd_cs46xx_pcm()
1772 pcm->info_flags = 0; in snd_cs46xx_pcm()
1773 strcpy(pcm->name, "CS46xx"); in snd_cs46xx_pcm()
1774 chip->pcm = pcm; in snd_cs46xx_pcm()
1777 &chip->pci->dev, in snd_cs46xx_pcm()
1785 int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device) in snd_cs46xx_pcm_rear()
1788 int err; in snd_cs46xx_pcm_rear()
1790 if ((err = snd_pcm_new(chip->card, "CS46xx - Rear", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0) in snd_cs46xx_pcm_rear()
1793 pcm->private_data = chip; in snd_cs46xx_pcm_rear()
1798 pcm->info_flags = 0; in snd_cs46xx_pcm_rear()
1799 strcpy(pcm->name, "CS46xx - Rear"); in snd_cs46xx_pcm_rear()
1800 chip->pcm_rear = pcm; in snd_cs46xx_pcm_rear()
1803 &chip->pci->dev, in snd_cs46xx_pcm_rear()
1809 int snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device) in snd_cs46xx_pcm_center_lfe()
1812 int err; in snd_cs46xx_pcm_center_lfe()
1814 …if ((err = snd_pcm_new(chip->card, "CS46xx - Center LFE", device, MAX_PLAYBACK_CHANNELS, 0, &pcm))… in snd_cs46xx_pcm_center_lfe()
1817 pcm->private_data = chip; in snd_cs46xx_pcm_center_lfe()
1822 pcm->info_flags = 0; in snd_cs46xx_pcm_center_lfe()
1823 strcpy(pcm->name, "CS46xx - Center LFE"); in snd_cs46xx_pcm_center_lfe()
1824 chip->pcm_center_lfe = pcm; in snd_cs46xx_pcm_center_lfe()
1827 &chip->pci->dev, in snd_cs46xx_pcm_center_lfe()
1833 int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device) in snd_cs46xx_pcm_iec958()
1836 int err; in snd_cs46xx_pcm_iec958()
1838 if ((err = snd_pcm_new(chip->card, "CS46xx - IEC958", device, 1, 0, &pcm)) < 0) in snd_cs46xx_pcm_iec958()
1841 pcm->private_data = chip; in snd_cs46xx_pcm_iec958()
1846 pcm->info_flags = 0; in snd_cs46xx_pcm_iec958()
1847 strcpy(pcm->name, "CS46xx - IEC958"); in snd_cs46xx_pcm_iec958()
1848 chip->pcm_iec958 = pcm; in snd_cs46xx_pcm_iec958()
1851 &chip->pci->dev, in snd_cs46xx_pcm_iec958()
1863 struct snd_cs46xx *chip = bus->private_data; in snd_cs46xx_mixer_free_ac97_bus()
1865 chip->ac97_bus = NULL; in snd_cs46xx_mixer_free_ac97_bus()
1870 struct snd_cs46xx *chip = ac97->private_data; in snd_cs46xx_mixer_free_ac97()
1872 if (snd_BUG_ON(ac97 != chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] && in snd_cs46xx_mixer_free_ac97()
1873 ac97 != chip->ac97[CS46XX_SECONDARY_CODEC_INDEX])) in snd_cs46xx_mixer_free_ac97()
1876 if (ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) { in snd_cs46xx_mixer_free_ac97()
1877 chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] = NULL; in snd_cs46xx_mixer_free_ac97()
1878 chip->eapd_switch = NULL; in snd_cs46xx_mixer_free_ac97()
1881 chip->ac97[CS46XX_SECONDARY_CODEC_INDEX] = NULL; in snd_cs46xx_mixer_free_ac97()
1884 static int snd_cs46xx_vol_info(struct snd_kcontrol *kcontrol, in snd_cs46xx_vol_info()
1887 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_cs46xx_vol_info()
1888 uinfo->count = 2; in snd_cs46xx_vol_info()
1889 uinfo->value.integer.min = 0; in snd_cs46xx_vol_info()
1890 uinfo->value.integer.max = 0x7fff; in snd_cs46xx_vol_info()
1894 static int snd_cs46xx_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) in snd_cs46xx_vol_get()
1897 int reg = kcontrol->private_value; in snd_cs46xx_vol_get()
1898 unsigned int val = snd_cs46xx_peek(chip, reg); in snd_cs46xx_vol_get()
1899 ucontrol->value.integer.value[0] = 0xffff - (val >> 16); in snd_cs46xx_vol_get()
1900 ucontrol->value.integer.value[1] = 0xffff - (val & 0xffff); in snd_cs46xx_vol_get()
1904 static int snd_cs46xx_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) in snd_cs46xx_vol_put()
1907 int reg = kcontrol->private_value; in snd_cs46xx_vol_put()
1908 unsigned int val = ((0xffff - ucontrol->value.integer.value[0]) << 16 | in snd_cs46xx_vol_put()
1909 (0xffff - ucontrol->value.integer.value[1])); in snd_cs46xx_vol_put()
1910 unsigned int old = snd_cs46xx_peek(chip, reg); in snd_cs46xx_vol_put()
1911 int change = (old != val); in snd_cs46xx_vol_put()
1922 static int snd_cs46xx_vol_dac_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontro… in snd_cs46xx_vol_dac_get()
1926 ucontrol->value.integer.value[0] = chip->dsp_spos_instance->dac_volume_left; in snd_cs46xx_vol_dac_get()
1927 ucontrol->value.integer.value[1] = chip->dsp_spos_instance->dac_volume_right; in snd_cs46xx_vol_dac_get()
1932 static int snd_cs46xx_vol_dac_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontro… in snd_cs46xx_vol_dac_put()
1935 int change = 0; in snd_cs46xx_vol_dac_put()
1937 if (chip->dsp_spos_instance->dac_volume_right != ucontrol->value.integer.value[0] || in snd_cs46xx_vol_dac_put()
1938 chip->dsp_spos_instance->dac_volume_left != ucontrol->value.integer.value[1]) { in snd_cs46xx_vol_dac_put()
1940 ucontrol->value.integer.value[0], in snd_cs46xx_vol_dac_put()
1941 ucontrol->value.integer.value[1]); in snd_cs46xx_vol_dac_put()
1949 static int snd_cs46xx_vol_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucon…
1953 ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_input_volume_left;
1954 ucontrol->value.integer.value[1] = chip->dsp_spos_instance->spdif_input_volume_right;
1958 static int snd_cs46xx_vol_iec958_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucon…
1961 int change = 0;
1963 if (chip->dsp_spos_instance->spdif_input_volume_left != ucontrol->value.integer.value[0] ||
1964 chip->dsp_spos_instance->spdif_input_volume_right!= ucontrol->value.integer.value[1]) {
1966 ucontrol->value.integer.value[0],
1967 ucontrol->value.integer.value[1]);
1977 static int snd_cs46xx_iec958_get(struct snd_kcontrol *kcontrol, in snd_cs46xx_iec958_get()
1981 int reg = kcontrol->private_value; in snd_cs46xx_iec958_get()
1984 …ucontrol->value.integer.value[0] = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_O… in snd_cs46xx_iec958_get()
1986 ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_status_in; in snd_cs46xx_iec958_get()
1991 static int snd_cs46xx_iec958_put(struct snd_kcontrol *kcontrol, in snd_cs46xx_iec958_put()
1995 int change, res; in snd_cs46xx_iec958_put()
1997 switch (kcontrol->private_value) { in snd_cs46xx_iec958_put()
1999 mutex_lock(&chip->spos_mutex); in snd_cs46xx_iec958_put()
2000 change = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED); in snd_cs46xx_iec958_put()
2001 if (ucontrol->value.integer.value[0] && !change) in snd_cs46xx_iec958_put()
2003 else if (change && !ucontrol->value.integer.value[0]) in snd_cs46xx_iec958_put()
2006 res = (change != (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED)); in snd_cs46xx_iec958_put()
2007 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_iec958_put()
2010 change = chip->dsp_spos_instance->spdif_status_in; in snd_cs46xx_iec958_put()
2011 if (ucontrol->value.integer.value[0] && !change) { in snd_cs46xx_iec958_put()
2015 else if (change && !ucontrol->value.integer.value[0]) in snd_cs46xx_iec958_put()
2018 res = (change != chip->dsp_spos_instance->spdif_status_in); in snd_cs46xx_iec958_put()
2021 res = -EINVAL; in snd_cs46xx_iec958_put()
2028 static int snd_cs46xx_adc_capture_get(struct snd_kcontrol *kcontrol, in snd_cs46xx_adc_capture_get()
2032 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_adc_capture_get()
2034 if (ins->adc_input != NULL) in snd_cs46xx_adc_capture_get()
2035 ucontrol->value.integer.value[0] = 1; in snd_cs46xx_adc_capture_get()
2037 ucontrol->value.integer.value[0] = 0; in snd_cs46xx_adc_capture_get()
2042 static int snd_cs46xx_adc_capture_put(struct snd_kcontrol *kcontrol, in snd_cs46xx_adc_capture_put()
2046 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_adc_capture_put()
2047 int change = 0; in snd_cs46xx_adc_capture_put()
2049 if (ucontrol->value.integer.value[0] && !ins->adc_input) { in snd_cs46xx_adc_capture_put()
2052 } else if (!ucontrol->value.integer.value[0] && ins->adc_input) { in snd_cs46xx_adc_capture_put()
2059 static int snd_cs46xx_pcm_capture_get(struct snd_kcontrol *kcontrol, in snd_cs46xx_pcm_capture_get()
2063 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_pcm_capture_get()
2065 if (ins->pcm_input != NULL) in snd_cs46xx_pcm_capture_get()
2066 ucontrol->value.integer.value[0] = 1; in snd_cs46xx_pcm_capture_get()
2068 ucontrol->value.integer.value[0] = 0; in snd_cs46xx_pcm_capture_get()
2074 static int snd_cs46xx_pcm_capture_put(struct snd_kcontrol *kcontrol, in snd_cs46xx_pcm_capture_put()
2078 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_pcm_capture_put()
2079 int change = 0; in snd_cs46xx_pcm_capture_put()
2081 if (ucontrol->value.integer.value[0] && !ins->pcm_input) { in snd_cs46xx_pcm_capture_put()
2084 } else if (!ucontrol->value.integer.value[0] && ins->pcm_input) { in snd_cs46xx_pcm_capture_put()
2092 static int snd_herc_spdif_select_get(struct snd_kcontrol *kcontrol, in snd_herc_spdif_select_get()
2097 int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR); in snd_herc_spdif_select_get()
2100 ucontrol->value.integer.value[0] = 1; in snd_herc_spdif_select_get()
2102 ucontrol->value.integer.value[0] = 0; in snd_herc_spdif_select_get()
2108 * Game Theatre XP card - EGPIO[0] is used to select SPDIF input optical or coaxial.
2110 static int snd_herc_spdif_select_put(struct snd_kcontrol *kcontrol, in snd_herc_spdif_select_put()
2114 int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR); in snd_herc_spdif_select_put()
2115 int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR); in snd_herc_spdif_select_put()
2117 if (ucontrol->value.integer.value[0]) { in snd_herc_spdif_select_put()
2122 EGPIOPTR_GPPT0 | val2); /* open-drain on output */ in snd_herc_spdif_select_put()
2131 return (val1 != (int)snd_cs46xx_peekBA0(chip, BA0_EGPIODR)); in snd_herc_spdif_select_put()
2135 static int snd_cs46xx_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) in snd_cs46xx_spdif_info()
2137 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; in snd_cs46xx_spdif_info()
2138 uinfo->count = 1; in snd_cs46xx_spdif_info()
2142 static int snd_cs46xx_spdif_default_get(struct snd_kcontrol *kcontrol, in snd_cs46xx_spdif_default_get()
2146 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_spdif_default_get()
2148 mutex_lock(&chip->spos_mutex); in snd_cs46xx_spdif_default_get()
2149 ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_default >> 24) & 0xff); in snd_cs46xx_spdif_default_get()
2150 ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_default >> 16) & 0xff); in snd_cs46xx_spdif_default_get()
2151 ucontrol->value.iec958.status[2] = 0; in snd_cs46xx_spdif_default_get()
2152 ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_default) & 0xff); in snd_cs46xx_spdif_default_get()
2153 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_spdif_default_get()
2158 static int snd_cs46xx_spdif_default_put(struct snd_kcontrol *kcontrol, in snd_cs46xx_spdif_default_put()
2162 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_spdif_default_put()
2163 unsigned int val; in snd_cs46xx_spdif_default_put()
2164 int change; in snd_cs46xx_spdif_default_put()
2166 mutex_lock(&chip->spos_mutex); in snd_cs46xx_spdif_default_put()
2167 val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) | in snd_cs46xx_spdif_default_put()
2168 ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[2]) << 16) | in snd_cs46xx_spdif_default_put()
2169 ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) | in snd_cs46xx_spdif_default_put()
2174 change = (unsigned int)ins->spdif_csuv_default != val; in snd_cs46xx_spdif_default_put()
2175 ins->spdif_csuv_default = val; in snd_cs46xx_spdif_default_put()
2177 if ( !(ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) ) in snd_cs46xx_spdif_default_put()
2180 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_spdif_default_put()
2185 static int snd_cs46xx_spdif_mask_get(struct snd_kcontrol *kcontrol, in snd_cs46xx_spdif_mask_get()
2188 ucontrol->value.iec958.status[0] = 0xff; in snd_cs46xx_spdif_mask_get()
2189 ucontrol->value.iec958.status[1] = 0xff; in snd_cs46xx_spdif_mask_get()
2190 ucontrol->value.iec958.status[2] = 0x00; in snd_cs46xx_spdif_mask_get()
2191 ucontrol->value.iec958.status[3] = 0xff; in snd_cs46xx_spdif_mask_get()
2195 static int snd_cs46xx_spdif_stream_get(struct snd_kcontrol *kcontrol, in snd_cs46xx_spdif_stream_get()
2199 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_spdif_stream_get()
2201 mutex_lock(&chip->spos_mutex); in snd_cs46xx_spdif_stream_get()
2202 ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_stream >> 24) & 0xff); in snd_cs46xx_spdif_stream_get()
2203 ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_stream >> 16) & 0xff); in snd_cs46xx_spdif_stream_get()
2204 ucontrol->value.iec958.status[2] = 0; in snd_cs46xx_spdif_stream_get()
2205 ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_stream) & 0xff); in snd_cs46xx_spdif_stream_get()
2206 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_spdif_stream_get()
2211 static int snd_cs46xx_spdif_stream_put(struct snd_kcontrol *kcontrol, in snd_cs46xx_spdif_stream_put()
2215 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_spdif_stream_put()
2216 unsigned int val; in snd_cs46xx_spdif_stream_put()
2217 int change; in snd_cs46xx_spdif_stream_put()
2219 mutex_lock(&chip->spos_mutex); in snd_cs46xx_spdif_stream_put()
2220 val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) | in snd_cs46xx_spdif_stream_put()
2221 ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[1]) << 16) | in snd_cs46xx_spdif_stream_put()
2222 ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) | in snd_cs46xx_spdif_stream_put()
2227 change = ins->spdif_csuv_stream != val; in snd_cs46xx_spdif_stream_put()
2228 ins->spdif_csuv_stream = val; in snd_cs46xx_spdif_stream_put()
2230 if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN ) in snd_cs46xx_spdif_stream_put()
2233 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_spdif_stream_put()
2337 static int snd_cs46xx_front_dup_get(struct snd_kcontrol *kcontrol, in snd_cs46xx_front_dup_get()
2342 val = snd_ac97_read(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], AC97_CSR_ACMODE); in snd_cs46xx_front_dup_get()
2343 ucontrol->value.integer.value[0] = (val & 0x200) ? 0 : 1; in snd_cs46xx_front_dup_get()
2347 static int snd_cs46xx_front_dup_put(struct snd_kcontrol *kcontrol, in snd_cs46xx_front_dup_put()
2351 return snd_ac97_update_bits(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], in snd_cs46xx_front_dup_put()
2353 ucontrol->value.integer.value[0] ? 0 : 0x200); in snd_cs46xx_front_dup_put()
2381 int err; in snd_cs46xx_codec_reset()
2387 if (ac97->num == CS46XX_PRIMARY_CODEC_INDEX) { in snd_cs46xx_codec_reset()
2388 dev_dbg(ac97->bus->card->dev, "CODEC1 mode %04x\n", 0x0); in snd_cs46xx_codec_reset()
2390 } else if (ac97->num == CS46XX_SECONDARY_CODEC_INDEX) { in snd_cs46xx_codec_reset()
2391 dev_dbg(ac97->bus->card->dev, "CODEC2 mode %04x\n", 0x3); in snd_cs46xx_codec_reset()
2423 dev_err(ac97->bus->card->dev, in snd_cs46xx_codec_reset()
2428 static int cs46xx_detect_codec(struct snd_cs46xx *chip, int codec) in cs46xx_detect_codec()
2430 int idx, err; in cs46xx_detect_codec()
2437 if (chip->amplifier_ctrl == amp_voyetra) in cs46xx_detect_codec()
2444 dev_dbg(chip->card->dev, in cs46xx_detect_codec()
2446 return -ENXIO; in cs46xx_detect_codec()
2453 err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97[codec]); in cs46xx_detect_codec()
2458 dev_dbg(chip->card->dev, "codec %d detection timeout\n", codec); in cs46xx_detect_codec()
2459 return -ENXIO; in cs46xx_detect_codec()
2462 int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device) in snd_cs46xx_mixer()
2464 struct snd_card *card = chip->card; in snd_cs46xx_mixer()
2466 int err; in snd_cs46xx_mixer()
2467 unsigned int idx; in snd_cs46xx_mixer()
2477 chip->nr_ac97_codecs = 0; in snd_cs46xx_mixer()
2478 dev_dbg(chip->card->dev, "detecting primary codec\n"); in snd_cs46xx_mixer()
2479 if ((err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus)) < 0) in snd_cs46xx_mixer()
2481 chip->ac97_bus->private_free = snd_cs46xx_mixer_free_ac97_bus; in snd_cs46xx_mixer()
2484 return -ENXIO; in snd_cs46xx_mixer()
2485 chip->nr_ac97_codecs = 1; in snd_cs46xx_mixer()
2488 dev_dbg(chip->card->dev, "detecting secondary codec\n"); in snd_cs46xx_mixer()
2491 chip->nr_ac97_codecs = 2; in snd_cs46xx_mixer()
2498 if (kctl && kctl->id.iface == SNDRV_CTL_ELEM_IFACE_PCM) in snd_cs46xx_mixer()
2499 kctl->id.device = spdif_device; in snd_cs46xx_mixer()
2508 chip->eapd_switch = snd_ctl_find_id(chip->card, &id); in snd_cs46xx_mixer()
2511 if (chip->nr_ac97_codecs == 1) { in snd_cs46xx_mixer()
2512 unsigned int id2 = chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]->id & 0xffff; in snd_cs46xx_mixer()
2517 snd_ac97_write_cache(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], in snd_cs46xx_mixer()
2522 if (chip->mixer_init) { in snd_cs46xx_mixer()
2523 dev_dbg(chip->card->dev, "calling chip->mixer_init(chip);\n"); in snd_cs46xx_mixer()
2524 chip->mixer_init(chip); in snd_cs46xx_mixer()
2529 chip->amplifier_ctrl(chip, 1); in snd_cs46xx_mixer()
2542 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_reset()
2545 static int snd_cs46xx_midi_input_open(struct snd_rawmidi_substream *substream) in snd_cs46xx_midi_input_open()
2547 struct snd_cs46xx *chip = substream->rmidi->private_data; in snd_cs46xx_midi_input_open()
2549 chip->active_ctrl(chip, 1); in snd_cs46xx_midi_input_open()
2550 spin_lock_irq(&chip->reg_lock); in snd_cs46xx_midi_input_open()
2551 chip->uartm |= CS46XX_MODE_INPUT; in snd_cs46xx_midi_input_open()
2552 chip->midcr |= MIDCR_RXE; in snd_cs46xx_midi_input_open()
2553 chip->midi_input = substream; in snd_cs46xx_midi_input_open()
2554 if (!(chip->uartm & CS46XX_MODE_OUTPUT)) { in snd_cs46xx_midi_input_open()
2557 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_input_open()
2559 spin_unlock_irq(&chip->reg_lock); in snd_cs46xx_midi_input_open()
2563 static int snd_cs46xx_midi_input_close(struct snd_rawmidi_substream *substream) in snd_cs46xx_midi_input_close()
2565 struct snd_cs46xx *chip = substream->rmidi->private_data; in snd_cs46xx_midi_input_close()
2567 spin_lock_irq(&chip->reg_lock); in snd_cs46xx_midi_input_close()
2568 chip->midcr &= ~(MIDCR_RXE | MIDCR_RIE); in snd_cs46xx_midi_input_close()
2569 chip->midi_input = NULL; in snd_cs46xx_midi_input_close()
2570 if (!(chip->uartm & CS46XX_MODE_OUTPUT)) { in snd_cs46xx_midi_input_close()
2573 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_input_close()
2575 chip->uartm &= ~CS46XX_MODE_INPUT; in snd_cs46xx_midi_input_close()
2576 spin_unlock_irq(&chip->reg_lock); in snd_cs46xx_midi_input_close()
2577 chip->active_ctrl(chip, -1); in snd_cs46xx_midi_input_close()
2581 static int snd_cs46xx_midi_output_open(struct snd_rawmidi_substream *substream) in snd_cs46xx_midi_output_open()
2583 struct snd_cs46xx *chip = substream->rmidi->private_data; in snd_cs46xx_midi_output_open()
2585 chip->active_ctrl(chip, 1); in snd_cs46xx_midi_output_open()
2587 spin_lock_irq(&chip->reg_lock); in snd_cs46xx_midi_output_open()
2588 chip->uartm |= CS46XX_MODE_OUTPUT; in snd_cs46xx_midi_output_open()
2589 chip->midcr |= MIDCR_TXE; in snd_cs46xx_midi_output_open()
2590 chip->midi_output = substream; in snd_cs46xx_midi_output_open()
2591 if (!(chip->uartm & CS46XX_MODE_INPUT)) { in snd_cs46xx_midi_output_open()
2594 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_output_open()
2596 spin_unlock_irq(&chip->reg_lock); in snd_cs46xx_midi_output_open()
2600 static int snd_cs46xx_midi_output_close(struct snd_rawmidi_substream *substream) in snd_cs46xx_midi_output_close()
2602 struct snd_cs46xx *chip = substream->rmidi->private_data; in snd_cs46xx_midi_output_close()
2604 spin_lock_irq(&chip->reg_lock); in snd_cs46xx_midi_output_close()
2605 chip->midcr &= ~(MIDCR_TXE | MIDCR_TIE); in snd_cs46xx_midi_output_close()
2606 chip->midi_output = NULL; in snd_cs46xx_midi_output_close()
2607 if (!(chip->uartm & CS46XX_MODE_INPUT)) { in snd_cs46xx_midi_output_close()
2610 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_output_close()
2612 chip->uartm &= ~CS46XX_MODE_OUTPUT; in snd_cs46xx_midi_output_close()
2613 spin_unlock_irq(&chip->reg_lock); in snd_cs46xx_midi_output_close()
2614 chip->active_ctrl(chip, -1); in snd_cs46xx_midi_output_close()
2618 static void snd_cs46xx_midi_input_trigger(struct snd_rawmidi_substream *substream, int up) in snd_cs46xx_midi_input_trigger()
2621 struct snd_cs46xx *chip = substream->rmidi->private_data; in snd_cs46xx_midi_input_trigger()
2623 spin_lock_irqsave(&chip->reg_lock, flags); in snd_cs46xx_midi_input_trigger()
2625 if ((chip->midcr & MIDCR_RIE) == 0) { in snd_cs46xx_midi_input_trigger()
2626 chip->midcr |= MIDCR_RIE; in snd_cs46xx_midi_input_trigger()
2627 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_input_trigger()
2630 if (chip->midcr & MIDCR_RIE) { in snd_cs46xx_midi_input_trigger()
2631 chip->midcr &= ~MIDCR_RIE; in snd_cs46xx_midi_input_trigger()
2632 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_input_trigger()
2635 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_cs46xx_midi_input_trigger()
2638 static void snd_cs46xx_midi_output_trigger(struct snd_rawmidi_substream *substream, int up) in snd_cs46xx_midi_output_trigger()
2641 struct snd_cs46xx *chip = substream->rmidi->private_data; in snd_cs46xx_midi_output_trigger()
2644 spin_lock_irqsave(&chip->reg_lock, flags); in snd_cs46xx_midi_output_trigger()
2646 if ((chip->midcr & MIDCR_TIE) == 0) { in snd_cs46xx_midi_output_trigger()
2647 chip->midcr |= MIDCR_TIE; in snd_cs46xx_midi_output_trigger()
2649 while ((chip->midcr & MIDCR_TIE) && in snd_cs46xx_midi_output_trigger()
2652 chip->midcr &= ~MIDCR_TIE; in snd_cs46xx_midi_output_trigger()
2657 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_output_trigger()
2660 if (chip->midcr & MIDCR_TIE) { in snd_cs46xx_midi_output_trigger()
2661 chip->midcr &= ~MIDCR_TIE; in snd_cs46xx_midi_output_trigger()
2662 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_output_trigger()
2665 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_cs46xx_midi_output_trigger()
2682 int snd_cs46xx_midi(struct snd_cs46xx *chip, int device) in snd_cs46xx_midi()
2685 int err; in snd_cs46xx_midi()
2687 if ((err = snd_rawmidi_new(chip->card, "CS46XX", device, 1, 1, &rmidi)) < 0) in snd_cs46xx_midi()
2689 strcpy(rmidi->name, "CS46XX"); in snd_cs46xx_midi()
2692 …rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUP… in snd_cs46xx_midi()
2693 rmidi->private_data = chip; in snd_cs46xx_midi()
2694 chip->rmidi = rmidi; in snd_cs46xx_midi()
2711 snd_cs46xx_pokeBA0(chip, BA0_JSPT, 0xFF); //outb(gameport->io, 0xFF); in snd_cs46xx_gameport_trigger()
2720 return snd_cs46xx_peekBA0(chip, BA0_JSPT); //inb(gameport->io); in snd_cs46xx_gameport_read()
2723 static int snd_cs46xx_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons) in snd_cs46xx_gameport_cooked_read()
2743 if(axes[jst]==0xFFFF) axes[jst] = -1; in snd_cs46xx_gameport_cooked_read()
2747 static int snd_cs46xx_gameport_open(struct gameport *gameport, int mode) in snd_cs46xx_gameport_open()
2755 return -1; in snd_cs46xx_gameport_open()
2760 int snd_cs46xx_gameport(struct snd_cs46xx *chip) in snd_cs46xx_gameport()
2764 chip->gameport = gp = gameport_allocate_port(); in snd_cs46xx_gameport()
2766 dev_err(chip->card->dev, in snd_cs46xx_gameport()
2768 return -ENOMEM; in snd_cs46xx_gameport()
2772 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci)); in snd_cs46xx_gameport()
2773 gameport_set_dev_parent(gp, &chip->pci->dev); in snd_cs46xx_gameport()
2776 gp->open = snd_cs46xx_gameport_open; in snd_cs46xx_gameport()
2777 gp->read = snd_cs46xx_gameport_read; in snd_cs46xx_gameport()
2778 gp->trigger = snd_cs46xx_gameport_trigger; in snd_cs46xx_gameport()
2779 gp->cooked_read = snd_cs46xx_gameport_cooked_read; in snd_cs46xx_gameport()
2791 if (chip->gameport) { in snd_cs46xx_remove_gameport()
2792 gameport_unregister_port(chip->gameport); in snd_cs46xx_remove_gameport()
2793 chip->gameport = NULL; in snd_cs46xx_remove_gameport()
2797 int snd_cs46xx_gameport(struct snd_cs46xx *chip) { return -ENOSYS; } in snd_cs46xx_gameport()
2811 struct snd_cs46xx_region *region = entry->private_data; in snd_cs46xx_io_read()
2813 if (copy_to_user_fromio(buf, region->remap_addr + pos, count)) in snd_cs46xx_io_read()
2814 return -EFAULT; in snd_cs46xx_io_read()
2822 static int snd_cs46xx_proc_init(struct snd_card *card, struct snd_cs46xx *chip) in snd_cs46xx_proc_init()
2825 int idx; in snd_cs46xx_proc_init()
2828 struct snd_cs46xx_region *region = &chip->region.idx[idx]; in snd_cs46xx_proc_init()
2829 if (! snd_card_proc_new(card, region->name, &entry)) { in snd_cs46xx_proc_init()
2830 entry->content = SNDRV_INFO_CONTENT_DATA; in snd_cs46xx_proc_init()
2831 entry->private_data = chip; in snd_cs46xx_proc_init()
2832 entry->c.ops = &snd_cs46xx_proc_io_ops; in snd_cs46xx_proc_init()
2833 entry->size = region->size; in snd_cs46xx_proc_init()
2834 entry->mode = S_IFREG | 0400; in snd_cs46xx_proc_init()
2843 static int snd_cs46xx_proc_done(struct snd_cs46xx *chip) in snd_cs46xx_proc_done()
2860 unsigned int tmp; in snd_cs46xx_hw_stop()
2897 * Turn off the Processor by turning off the software clock enable flag in in snd_cs46xx_hw_stop()
2898 * the clock control register. in snd_cs46xx_hw_stop()
2905 static int snd_cs46xx_free(struct snd_cs46xx *chip) in snd_cs46xx_free()
2907 int idx; in snd_cs46xx_free()
2910 return -EINVAL; in snd_cs46xx_free()
2912 if (chip->active_ctrl) in snd_cs46xx_free()
2913 chip->active_ctrl(chip, 1); in snd_cs46xx_free()
2917 if (chip->amplifier_ctrl) in snd_cs46xx_free()
2918 chip->amplifier_ctrl(chip, -chip->amplifier); /* force to off */ in snd_cs46xx_free()
2922 if (chip->region.idx[0].resource) in snd_cs46xx_free()
2925 if (chip->irq >= 0) in snd_cs46xx_free()
2926 free_irq(chip->irq, chip); in snd_cs46xx_free()
2928 if (chip->active_ctrl) in snd_cs46xx_free()
2929 chip->active_ctrl(chip, -chip->amplifier); in snd_cs46xx_free()
2932 struct snd_cs46xx_region *region = &chip->region.idx[idx]; in snd_cs46xx_free()
2934 iounmap(region->remap_addr); in snd_cs46xx_free()
2935 release_and_free_resource(region->resource); in snd_cs46xx_free()
2939 if (chip->dsp_spos_instance) { in snd_cs46xx_free()
2941 chip->dsp_spos_instance = NULL; in snd_cs46xx_free()
2944 free_module_desc(chip->modules[idx]); in snd_cs46xx_free()
2946 vfree(chip->ba1); in snd_cs46xx_free()
2950 kfree(chip->saved_regs); in snd_cs46xx_free()
2953 pci_disable_device(chip->pci); in snd_cs46xx_free()
2958 static int snd_cs46xx_dev_free(struct snd_device *device) in snd_cs46xx_dev_free()
2960 struct snd_cs46xx *chip = device->device_data; in snd_cs46xx_dev_free()
2967 static int snd_cs46xx_chip_init(struct snd_cs46xx *chip) in snd_cs46xx_chip_init()
2969 int timeout; in snd_cs46xx_chip_init()
2972 * First, blast the clock control register to zero so that the PLL starts in snd_cs46xx_chip_init()
2981 * AC-link. Otherwise, we won't be able to bring up the link. in snd_cs46xx_chip_init()
3009 * as we start receiving bit clock, we'll start producing the SYNC in snd_cs46xx_chip_init()
3019 * generating bit clock (so we don't try to start the PLL without an in snd_cs46xx_chip_init()
3020 * input clock). in snd_cs46xx_chip_init()
3026 * the clock control circuit gets its clock from the correct place. in snd_cs46xx_chip_init()
3031 * Write the selected clock control setup to the hardware. Do not turn on in snd_cs46xx_chip_init()
3033 * PLL are not clocked until the PLL is stable. in snd_cs46xx_chip_init()
3093 while (timeout-- > 0) { in snd_cs46xx_chip_init()
3104 dev_err(chip->card->dev, in snd_cs46xx_chip_init()
3105 "create - never read codec ready from AC'97\n"); in snd_cs46xx_chip_init()
3106 dev_err(chip->card->dev, in snd_cs46xx_chip_init()
3108 return -EIO; in snd_cs46xx_chip_init()
3112 int count; in snd_cs46xx_chip_init()
3125 dev_dbg(chip->card->dev, in snd_cs46xx_chip_init()
3142 * the codec is pumping ADC data across the AC-link. in snd_cs46xx_chip_init()
3145 while (timeout-- > 0) { in snd_cs46xx_chip_init()
3156 dev_err(chip->card->dev, in snd_cs46xx_chip_init()
3157 "create - never read ISV3 & ISV4 from AC'97\n"); in snd_cs46xx_chip_init()
3158 return -EIO; in snd_cs46xx_chip_init()
3164 dev_err(chip->card->dev, "never read ISV3 & ISV4 from AC'97\n"); in snd_cs46xx_chip_init()
3165 dev_err(chip->card->dev, in snd_cs46xx_chip_init()
3167 dev_err(chip->card->dev, in snd_cs46xx_chip_init()
3168 "broken or not working on your soundcard upon\n"); in snd_cs46xx_chip_init()
3169 dev_err(chip->card->dev, in snd_cs46xx_chip_init()
3170 "this message please report to alsa-devel@alsa-project.org\n"); in snd_cs46xx_chip_init()
3172 return -EIO; in snd_cs46xx_chip_init()
3191 * Turn off the Processor by turning off the software clock enable flag in in snd_cs46xx_chip_init()
3192 * the clock control register. in snd_cs46xx_chip_init()
3206 unsigned int tmp; in cs46xx_enable_stream_irqs()
3220 int snd_cs46xx_start_dsp(struct snd_cs46xx *chip) in snd_cs46xx_start_dsp()
3222 unsigned int tmp; in snd_cs46xx_start_dsp()
3224 int i; in snd_cs46xx_start_dsp()
3226 int err; in snd_cs46xx_start_dsp()
3237 err = load_firmware(chip, &chip->modules[i], module_names[i]); in snd_cs46xx_start_dsp()
3239 dev_err(chip->card->dev, "firmware load error [%s]\n", in snd_cs46xx_start_dsp()
3243 err = cs46xx_dsp_load_module(chip, chip->modules[i]); in snd_cs46xx_start_dsp()
3245 dev_err(chip->card->dev, "image download error [%s]\n", in snd_cs46xx_start_dsp()
3252 return -EIO; in snd_cs46xx_start_dsp()
3261 dev_err(chip->card->dev, "image download error\n"); in snd_cs46xx_start_dsp()
3269 chip->play_ctl = tmp & 0xffff0000; in snd_cs46xx_start_dsp()
3277 chip->capt.ctl = tmp & 0x0000ffff; in snd_cs46xx_start_dsp()
3300 * AMP control - null AMP
3303 static void amp_none(struct snd_cs46xx *chip, int change) in amp_none()
3308 static int voyetra_setup_eapd_slot(struct snd_cs46xx *chip) in voyetra_setup_eapd_slot()
3314 dev_dbg(chip->card->dev, "cs46xx_setup_eapd_slot()+\n"); in voyetra_setup_eapd_slot()
3331 if(chip->nr_ac97_codecs != 2) { in voyetra_setup_eapd_slot()
3332 dev_err(chip->card->dev, in voyetra_setup_eapd_slot()
3333 "cs46xx_setup_eapd_slot() - no secondary codec configured\n"); in voyetra_setup_eapd_slot()
3334 return -EINVAL; in voyetra_setup_eapd_slot()
3374 dev_dbg(chip->card->dev, "FIFO is busy\n"); in voyetra_setup_eapd_slot()
3376 return -EINVAL; in voyetra_setup_eapd_slot()
3395 dev_dbg(chip->card->dev, in voyetra_setup_eapd_slot()
3399 return -EINVAL; in voyetra_setup_eapd_slot()
3431 static void amp_voyetra(struct snd_cs46xx *chip, int change) in amp_voyetra()
3437 int old = chip->amplifier; in amp_voyetra()
3439 int oval, val; in amp_voyetra()
3441 chip->amplifier += change; in amp_voyetra()
3445 if (chip->amplifier) { in amp_voyetra()
3455 if (chip->eapd_switch) in amp_voyetra()
3456 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, in amp_voyetra()
3457 &chip->eapd_switch->id); in amp_voyetra()
3461 if (chip->amplifier && !old) { in amp_voyetra()
3476 * Game Theatre XP card - EGPIO[2] is used to enable the external amp.
3478 static void amp_hercules(struct snd_cs46xx *chip, int change) in amp_hercules()
3480 int old = chip->amplifier; in amp_hercules()
3481 int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR); in amp_hercules()
3482 int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR); in amp_hercules()
3484 chip->amplifier += change; in amp_hercules()
3485 if (chip->amplifier && !old) { in amp_hercules()
3486 dev_dbg(chip->card->dev, "Hercules amplifier ON\n"); in amp_hercules()
3491 EGPIOPTR_GPPT2 | val2); /* open-drain on output */ in amp_hercules()
3492 } else if (old && !chip->amplifier) { in amp_hercules()
3493 dev_dbg(chip->card->dev, "Hercules amplifier OFF\n"); in amp_hercules()
3501 dev_dbg(chip->card->dev, "initializing Voyetra mixer\n"); in voyetra_mixer_init()
3511 unsigned int idx; in hercules_mixer_init()
3512 int err; in hercules_mixer_init()
3513 struct snd_card *card = chip->card; in hercules_mixer_init()
3519 dev_dbg(chip->card->dev, "initializing Hercules mixer\n"); in hercules_mixer_init()
3522 if (chip->in_suspend) in hercules_mixer_init()
3530 dev_err(card->dev, in hercules_mixer_init()
3545 static void amp_voyetra_4294(struct snd_cs46xx *chip, int change)
3547 chip->amplifier += change;
3549 if (chip->amplifier) {
3575 static void clkrun_hack(struct snd_cs46xx *chip, int change) in clkrun_hack()
3579 if (!chip->acpi_port) in clkrun_hack()
3582 chip->amplifier += change; in clkrun_hack()
3585 nval = control = inw(chip->acpi_port + 0x10); in clkrun_hack()
3588 if (! chip->amplifier) in clkrun_hack()
3593 outw(nval, chip->acpi_port + 0x10); in clkrun_hack()
3605 chip->acpi_port = 0; in clkrun_init()
3614 chip->acpi_port = pp << 8; in clkrun_init()
3629 void (*amp)(struct snd_cs46xx *, int);
3630 void (*active)(struct snd_cs46xx *, int);
3748 static const unsigned int saved_regs[] = {
3756 static int snd_cs46xx_suspend(struct device *dev) in snd_cs46xx_suspend()
3759 struct snd_cs46xx *chip = card->private_data; in snd_cs46xx_suspend()
3760 int i, amp_saved; in snd_cs46xx_suspend()
3763 chip->in_suspend = 1; in snd_cs46xx_suspend()
3764 // chip->ac97_powerdown = snd_cs46xx_codec_read(chip, AC97_POWER_CONTROL); in snd_cs46xx_suspend()
3765 // chip->ac97_general_purpose = snd_cs46xx_codec_read(chip, BA0_AC97_GENERAL_PURPOSE); in snd_cs46xx_suspend()
3767 snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); in snd_cs46xx_suspend()
3768 snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); in snd_cs46xx_suspend()
3772 chip->saved_regs[i] = snd_cs46xx_peekBA0(chip, saved_regs[i]); in snd_cs46xx_suspend()
3774 amp_saved = chip->amplifier; in snd_cs46xx_suspend()
3776 chip->amplifier_ctrl(chip, -chip->amplifier); in snd_cs46xx_suspend()
3779 chip->active_ctrl(chip, -chip->amplifier); in snd_cs46xx_suspend()
3780 chip->amplifier = amp_saved; /* restore the status */ in snd_cs46xx_suspend()
3784 static int snd_cs46xx_resume(struct device *dev) in snd_cs46xx_resume()
3787 struct snd_cs46xx *chip = card->private_data; in snd_cs46xx_resume()
3788 int amp_saved; in snd_cs46xx_resume()
3790 int i; in snd_cs46xx_resume()
3792 unsigned int tmp; in snd_cs46xx_resume()
3794 amp_saved = chip->amplifier; in snd_cs46xx_resume()
3795 chip->amplifier = 0; in snd_cs46xx_resume()
3796 chip->active_ctrl(chip, 1); /* force to on */ in snd_cs46xx_resume()
3805 snd_cs46xx_pokeBA0(chip, saved_regs[i], chip->saved_regs[i]); in snd_cs46xx_resume()
3812 chip->ac97_general_purpose); in snd_cs46xx_resume()
3814 chip->ac97_powerdown); in snd_cs46xx_resume()
3817 chip->ac97_powerdown); in snd_cs46xx_resume()
3821 snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); in snd_cs46xx_resume()
3822 snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); in snd_cs46xx_resume()
3828 chip->capt.ctl = tmp & 0x0000ffff; in snd_cs46xx_resume()
3841 chip->amplifier_ctrl(chip, 1); /* turn amp on */ in snd_cs46xx_resume()
3843 chip->active_ctrl(chip, -1); /* disable CLKRUN */ in snd_cs46xx_resume()
3844 chip->amplifier = amp_saved; in snd_cs46xx_resume()
3845 chip->in_suspend = 0; in snd_cs46xx_resume()
3857 int snd_cs46xx_create(struct snd_card *card, in snd_cs46xx_create()
3859 int external_amp, int thinkpad, in snd_cs46xx_create()
3863 int err, idx; in snd_cs46xx_create()
3880 return -ENOMEM; in snd_cs46xx_create()
3882 spin_lock_init(&chip->reg_lock); in snd_cs46xx_create()
3884 mutex_init(&chip->spos_mutex); in snd_cs46xx_create()
3886 chip->card = card; in snd_cs46xx_create()
3887 chip->pci = pci; in snd_cs46xx_create()
3888 chip->irq = -1; in snd_cs46xx_create()
3889 chip->ba0_addr = pci_resource_start(pci, 0); in snd_cs46xx_create()
3890 chip->ba1_addr = pci_resource_start(pci, 1); in snd_cs46xx_create()
3891 if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 || in snd_cs46xx_create()
3892 chip->ba1_addr == 0 || chip->ba1_addr == (unsigned long)~0) { in snd_cs46xx_create()
3893 dev_err(chip->card->dev, in snd_cs46xx_create()
3894 "wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n", in snd_cs46xx_create()
3895 chip->ba0_addr, chip->ba1_addr); in snd_cs46xx_create()
3897 return -ENOMEM; in snd_cs46xx_create()
3900 region = &chip->region.name.ba0; in snd_cs46xx_create()
3901 strcpy(region->name, "CS46xx_BA0"); in snd_cs46xx_create()
3902 region->base = chip->ba0_addr; in snd_cs46xx_create()
3903 region->size = CS46XX_BA0_SIZE; in snd_cs46xx_create()
3905 region = &chip->region.name.data0; in snd_cs46xx_create()
3906 strcpy(region->name, "CS46xx_BA1_data0"); in snd_cs46xx_create()
3907 region->base = chip->ba1_addr + BA1_SP_DMEM0; in snd_cs46xx_create()
3908 region->size = CS46XX_BA1_DATA0_SIZE; in snd_cs46xx_create()
3910 region = &chip->region.name.data1; in snd_cs46xx_create()
3911 strcpy(region->name, "CS46xx_BA1_data1"); in snd_cs46xx_create()
3912 region->base = chip->ba1_addr + BA1_SP_DMEM1; in snd_cs46xx_create()
3913 region->size = CS46XX_BA1_DATA1_SIZE; in snd_cs46xx_create()
3915 region = &chip->region.name.pmem; in snd_cs46xx_create()
3916 strcpy(region->name, "CS46xx_BA1_pmem"); in snd_cs46xx_create()
3917 region->base = chip->ba1_addr + BA1_SP_PMEM; in snd_cs46xx_create()
3918 region->size = CS46XX_BA1_PRG_SIZE; in snd_cs46xx_create()
3920 region = &chip->region.name.reg; in snd_cs46xx_create()
3921 strcpy(region->name, "CS46xx_BA1_reg"); in snd_cs46xx_create()
3922 region->base = chip->ba1_addr + BA1_SP_REG; in snd_cs46xx_create()
3923 region->size = CS46XX_BA1_REG_SIZE; in snd_cs46xx_create()
3929 for (cp = &cards[0]; cp->name; cp++) { in snd_cs46xx_create()
3930 if (cp->vendor == ss_vendor && cp->id == ss_card) { in snd_cs46xx_create()
3931 dev_dbg(chip->card->dev, "hack for %s enabled\n", in snd_cs46xx_create()
3932 cp->name); in snd_cs46xx_create()
3934 chip->amplifier_ctrl = cp->amp; in snd_cs46xx_create()
3935 chip->active_ctrl = cp->active; in snd_cs46xx_create()
3936 chip->mixer_init = cp->mixer_init; in snd_cs46xx_create()
3938 if (cp->init) in snd_cs46xx_create()
3939 cp->init(chip); in snd_cs46xx_create()
3945 dev_info(chip->card->dev, in snd_cs46xx_create()
3947 chip->amplifier_ctrl = amp_voyetra; in snd_cs46xx_create()
3951 dev_info(chip->card->dev, in snd_cs46xx_create()
3953 chip->active_ctrl = clkrun_hack; in snd_cs46xx_create()
3957 if (chip->amplifier_ctrl == NULL) in snd_cs46xx_create()
3958 chip->amplifier_ctrl = amp_none; in snd_cs46xx_create()
3959 if (chip->active_ctrl == NULL) in snd_cs46xx_create()
3960 chip->active_ctrl = amp_none; in snd_cs46xx_create()
3962 chip->active_ctrl(chip, 1); /* enable CLKRUN */ in snd_cs46xx_create()
3967 region = &chip->region.idx[idx]; in snd_cs46xx_create()
3968 if ((region->resource = request_mem_region(region->base, region->size, in snd_cs46xx_create()
3969 region->name)) == NULL) { in snd_cs46xx_create()
3970 dev_err(chip->card->dev, in snd_cs46xx_create()
3971 "unable to request memory region 0x%lx-0x%lx\n", in snd_cs46xx_create()
3972 region->base, region->base + region->size - 1); in snd_cs46xx_create()
3974 return -EBUSY; in snd_cs46xx_create()
3976 region->remap_addr = ioremap(region->base, region->size); in snd_cs46xx_create()
3977 if (region->remap_addr == NULL) { in snd_cs46xx_create()
3978 dev_err(chip->card->dev, in snd_cs46xx_create()
3979 "%s ioremap problem\n", region->name); in snd_cs46xx_create()
3981 return -ENOMEM; in snd_cs46xx_create()
3985 if (request_irq(pci->irq, snd_cs46xx_interrupt, IRQF_SHARED, in snd_cs46xx_create()
3987 dev_err(chip->card->dev, "unable to grab IRQ %d\n", pci->irq); in snd_cs46xx_create()
3989 return -EBUSY; in snd_cs46xx_create()
3991 chip->irq = pci->irq; in snd_cs46xx_create()
3992 card->sync_irq = chip->irq; in snd_cs46xx_create()
3995 chip->dsp_spos_instance = cs46xx_dsp_spos_create(chip); in snd_cs46xx_create()
3996 if (chip->dsp_spos_instance == NULL) { in snd_cs46xx_create()
3998 return -ENOMEM; in snd_cs46xx_create()
4016 chip->saved_regs = kmalloc_array(ARRAY_SIZE(saved_regs), in snd_cs46xx_create()
4017 sizeof(*chip->saved_regs), in snd_cs46xx_create()
4019 if (!chip->saved_regs) { in snd_cs46xx_create()
4021 return -ENOMEM; in snd_cs46xx_create()
4025 chip->active_ctrl(chip, -1); /* disable CLKRUN */ in snd_cs46xx_create()