Lines Matching +full:chip +full:- +full:to +full:- +full:chip
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
11 * are swapped. To get around this problem when it happens, mute and unmute
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
24 * multi channel PCM. But known to work.
26 * FINALLY: A credit to the developers Tom and Jordan
29 * references to be able to implement all fancy feutures
58 static void amp_voyetra(struct snd_cs46xx *chip, int change);
74 static unsigned short snd_cs46xx_codec_read(struct snd_cs46xx *chip, in snd_cs46xx_codec_read() argument
86 chip->active_ctrl(chip, 1); in snd_cs46xx_codec_read()
93 * 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 in snd_cs46xx_codec_read()
94 * 3. Write ACCTL = Control Register = 460h for initiating the write7---55 in snd_cs46xx_codec_read()
100 snd_cs46xx_peekBA0(chip, BA0_ACSDA + offset); in snd_cs46xx_codec_read()
102 tmp = snd_cs46xx_peekBA0(chip, BA0_ACCTL); in snd_cs46xx_codec_read()
104 dev_warn(chip->card->dev, "ACCTL_VFRM not set 0x%x\n", tmp); in snd_cs46xx_codec_read()
105 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, (tmp & (~ACCTL_ESYN)) | ACCTL_VFRM ); in snd_cs46xx_codec_read()
107 tmp = snd_cs46xx_peekBA0(chip, BA0_ACCTL + offset); in snd_cs46xx_codec_read()
108 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, tmp | ACCTL_ESYN | ACCTL_VFRM ); in snd_cs46xx_codec_read()
113 * Setup the AC97 control registers on the CS461x to send the in snd_cs46xx_codec_read()
114 * appropriate command to the AC97 to perform the read. 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()
125 snd_cs46xx_pokeBA0(chip, BA0_ACCAD, reg); in snd_cs46xx_codec_read()
126 snd_cs46xx_pokeBA0(chip, BA0_ACCDA, 0); in snd_cs46xx_codec_read()
128 snd_cs46xx_pokeBA0(chip, BA0_ACCTL,/* clear ACCTL_DCV */ ACCTL_CRW | in snd_cs46xx_codec_read()
131 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_CRW | in snd_cs46xx_codec_read()
135 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_TC | in snd_cs46xx_codec_read()
141 * Wait for the read to occur. in snd_cs46xx_codec_read()
145 * First, we want to wait for a short time. in snd_cs46xx_codec_read()
149 * Now, check to see if the read has completed. in snd_cs46xx_codec_read()
152 if (!(snd_cs46xx_peekBA0(chip, BA0_ACCTL) & ACCTL_DCV)) in snd_cs46xx_codec_read()
156 dev_err(chip->card->dev, in snd_cs46xx_codec_read()
163 * Wait for the valid status bit to go active. in snd_cs46xx_codec_read()
169 * VSTS - Valid Status in snd_cs46xx_codec_read()
171 if (snd_cs46xx_peekBA0(chip, BA0_ACSTS + offset) & ACSTS_VSTS) 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()
190 snd_cs46xx_peekBA0(chip, BA0_ACSDA), in snd_cs46xx_codec_read()
191 snd_cs46xx_peekBA0(chip, BA0_ACCAD)); in snd_cs46xx_codec_read()
194 //snd_cs46xx_peekBA0(chip, BA0_ACCAD); in snd_cs46xx_codec_read()
195 result = snd_cs46xx_peekBA0(chip, BA0_ACSDA + offset); 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() local
206 int codec_index = ac97->num; in snd_cs46xx_ac97_read()
212 val = snd_cs46xx_codec_read(chip, reg, codec_index); in snd_cs46xx_ac97_read()
218 static void snd_cs46xx_codec_write(struct snd_cs46xx *chip, in snd_cs46xx_codec_write() argument
229 chip->active_ctrl(chip, 1); in snd_cs46xx_codec_write()
233 * 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 in snd_cs46xx_codec_write()
240 * Setup the AC97 control registers on the CS461x to send the in snd_cs46xx_codec_write()
241 * appropriate command to the AC97 to perform the read. 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()
251 snd_cs46xx_pokeBA0(chip, BA0_ACCAD , reg); in snd_cs46xx_codec_write()
252 snd_cs46xx_pokeBA0(chip, BA0_ACCDA , val); in snd_cs46xx_codec_write()
253 snd_cs46xx_peekBA0(chip, BA0_ACCTL); in snd_cs46xx_codec_write()
256 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, /* clear ACCTL_DCV */ ACCTL_VFRM | in snd_cs46xx_codec_write()
258 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_VFRM | in snd_cs46xx_codec_write()
261 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_TC | in snd_cs46xx_codec_write()
267 * First, we want to wait for a short time. in snd_cs46xx_codec_write()
271 * Now, check to see if the write has completed. in snd_cs46xx_codec_write()
274 if (!(snd_cs46xx_peekBA0(chip, BA0_ACCTL) & ACCTL_DCV)) { 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() local
290 int codec_index = ac97->num; in snd_cs46xx_ac97_write()
296 snd_cs46xx_codec_write(chip, reg, val, codec_index); in snd_cs46xx_ac97_write()
301 * Chip initialization
304 int snd_cs46xx_download(struct snd_cs46xx *chip, in snd_cs46xx_download() argument
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()
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()
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() argument
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() argument
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() argument
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 static __maybe_unused int snd_cs46xx_download_image(struct snd_cs46xx *chip) in snd_cs46xx_download_image() argument
538 struct ba1_struct *ba1 = chip->ba1; in snd_cs46xx_download_image()
541 err = snd_cs46xx_download(chip, 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()
554 * Chip reset
557 static void snd_cs46xx_reset(struct snd_cs46xx *chip) in snd_cs46xx_reset() argument
564 snd_cs46xx_poke(chip, BA1_SPCR, SPCR_RSTSP); in snd_cs46xx_reset()
569 snd_cs46xx_poke(chip, BA1_SPCR, SPCR_DRQEN); in snd_cs46xx_reset()
575 snd_cs46xx_poke(chip, BA1_DREG, DREG_REGID_TRAP_SELECT + idx); in snd_cs46xx_reset()
576 snd_cs46xx_poke(chip, BA1_TWPR, 0xFFFF); in snd_cs46xx_reset()
578 snd_cs46xx_poke(chip, BA1_DREG, 0); in snd_cs46xx_reset()
581 * Set the frame timer to reflect the number of cycles per frame. in snd_cs46xx_reset()
583 snd_cs46xx_poke(chip, BA1_FRMT, 0xadf); in snd_cs46xx_reset()
586 static int cs46xx_wait_for_fifo(struct snd_cs46xx * chip,int retry_timeout) in cs46xx_wait_for_fifo() argument
593 status = snd_cs46xx_peekBA0(chip, BA0_SERBST); in cs46xx_wait_for_fifo()
602 dev_err(chip->card->dev, in cs46xx_wait_for_fifo()
603 "failure waiting for FIFO command to complete\n"); in cs46xx_wait_for_fifo()
604 return -EINVAL; in cs46xx_wait_for_fifo()
610 static void snd_cs46xx_clear_serial_FIFOs(struct snd_cs46xx *chip) in snd_cs46xx_clear_serial_FIFOs() argument
619 tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1); in snd_cs46xx_clear_serial_FIFOs()
621 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp | CLKCR1_SWCE); in snd_cs46xx_clear_serial_FIFOs()
626 * We want to clear out the serial port FIFOs so we don't end up playing in snd_cs46xx_clear_serial_FIFOs()
627 * whatever random garbage happens to be in them. We fill the sample FIFOS in snd_cs46xx_clear_serial_FIFOs()
630 snd_cs46xx_pokeBA0(chip, BA0_SERBWP, 0); in snd_cs46xx_clear_serial_FIFOs()
639 if (cs46xx_wait_for_fifo(chip,1)) { in snd_cs46xx_clear_serial_FIFOs()
640 dev_dbg(chip->card->dev, in snd_cs46xx_clear_serial_FIFOs()
645 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); in snd_cs46xx_clear_serial_FIFOs()
652 snd_cs46xx_pokeBA0(chip, BA0_SERBAD, idx); in snd_cs46xx_clear_serial_FIFOs()
654 * Tell the serial port to load the new value into the FIFO location. in snd_cs46xx_clear_serial_FIFOs()
656 snd_cs46xx_pokeBA0(chip, BA0_SERBCM, SERBCM_WRC); in snd_cs46xx_clear_serial_FIFOs()
663 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); in snd_cs46xx_clear_serial_FIFOs()
666 static void snd_cs46xx_proc_start(struct snd_cs46xx *chip) in snd_cs46xx_proc_start() argument
671 * Set the frame timer to reflect the number of cycles per frame. in snd_cs46xx_proc_start()
673 snd_cs46xx_poke(chip, BA1_FRMT, 0xadf); in snd_cs46xx_proc_start()
678 snd_cs46xx_poke(chip, BA1_SPCR, SPCR_RUN | SPCR_RUNFR | SPCR_DRQEN); in snd_cs46xx_proc_start()
685 if (!(snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR)) in snd_cs46xx_proc_start()
689 if (snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR) in snd_cs46xx_proc_start()
690 dev_err(chip->card->dev, "SPCR_RUNFR never reset\n"); in snd_cs46xx_proc_start()
693 static void snd_cs46xx_proc_stop(struct snd_cs46xx *chip) in snd_cs46xx_proc_stop() argument
699 snd_cs46xx_poke(chip, BA1_SPCR, 0); in snd_cs46xx_proc_stop()
708 static void snd_cs46xx_set_play_sample_rate(struct snd_cs46xx *chip, unsigned int rate) in snd_cs46xx_set_play_sample_rate() argument
716 * Compute the values used to drive the actual sample rate conversion. in snd_cs46xx_set_play_sample_rate()
718 * since we need to use 64 bit arithmetic to compute the values: 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()
748 snd_cs46xx_poke(chip, BA1_PSRC, in snd_cs46xx_set_play_sample_rate()
750 snd_cs46xx_poke(chip, BA1_PPI, phiIncr); 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() argument
762 * We can only decimate by up to a factor of 1/9th the hardware rate. in snd_cs46xx_set_capture_sample_rate()
763 * Correct the value if an attempt is made to stray outside that limit. in snd_cs46xx_set_capture_sample_rate()
770 * Return an error if an attempt is made to stray outside that limit. in snd_cs46xx_set_capture_sample_rate()
776 * Compute the values used to drive the actual sample rate conversion. in snd_cs46xx_set_capture_sample_rate()
778 * since we need to use 64 bit arithmetic to compute the values: 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()
821 spin_lock_irqsave(&chip->reg_lock, flags); in snd_cs46xx_set_capture_sample_rate()
822 snd_cs46xx_poke(chip, BA1_CSRC, in snd_cs46xx_set_capture_sample_rate()
824 snd_cs46xx_poke(chip, BA1_CCI, coeffIncr); in snd_cs46xx_set_capture_sample_rate()
825 snd_cs46xx_poke(chip, BA1_CD, in snd_cs46xx_set_capture_sample_rate()
827 snd_cs46xx_poke(chip, BA1_CPI, phiIncr); 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()
852 snd_cs46xx_poke(chip, BA1_CFG1, frameGroupLength); in snd_cs46xx_set_capture_sample_rate()
853 snd_cs46xx_poke(chip, BA1_CFG2, (0x00800000 | frameGroupLength)); in snd_cs46xx_set_capture_sample_rate()
854 snd_cs46xx_poke(chip, BA1_CCST, 0x0000FFFF); in snd_cs46xx_set_capture_sample_rate()
855 snd_cs46xx_poke(chip, BA1_CSPB, ((65536 * rate) / 24000)); in snd_cs46xx_set_capture_sample_rate()
856 snd_cs46xx_poke(chip, (BA1_CSPB + 4), 0x0000FFFF); 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()
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()
883 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_cp_trans_copy() local
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()
891 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_capture_transfer() local
892 return snd_pcm_indirect_capture_transfer(substream, &chip->capt.pcm_rec, in snd_cs46xx_capture_transfer()
898 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_playback_direct_pointer() local
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()
908 ptr = snd_cs46xx_peek(chip, BA1_PBA); 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()
916 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_playback_indirect_pointer() local
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()
925 ptr = snd_cs46xx_peek(chip, BA1_PBA); 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()
933 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_capture_direct_pointer() local
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()
940 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_capture_indirect_pointer() local
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()
948 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_playback_trigger() local
949 /*struct snd_pcm_runtime *runtime = substream->runtime;*/ 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()
962 /* magic value to unmute PCM stream playback volume */ 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()
976 tmp = snd_cs46xx_peek(chip, BA1_PCTL); 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()
995 tmp = snd_cs46xx_peek(chip, BA1_PCTL); in snd_cs46xx_playback_trigger()
997 snd_cs46xx_poke(chip, BA1_PCTL, 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()
1013 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_capture_trigger() local
1017 spin_lock(&chip->reg_lock); in snd_cs46xx_capture_trigger()
1021 tmp = snd_cs46xx_peek(chip, BA1_CCTL); in snd_cs46xx_capture_trigger()
1023 snd_cs46xx_poke(chip, BA1_CCTL, chip->capt.ctl | tmp); in snd_cs46xx_capture_trigger()
1027 tmp = snd_cs46xx_peek(chip, BA1_CCTL); in snd_cs46xx_capture_trigger()
1029 snd_cs46xx_poke(chip, BA1_CCTL, 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() argument
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()
1051 "failed to create virtual PCM channel\n"); 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 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); in _cs46xx_adjust_sample_rate()
1064 if (!cpcm->pcm_channel) { in _cs46xx_adjust_sample_rate()
1065 dev_err(chip->card->dev, in _cs46xx_adjust_sample_rate()
1066 "failed to re-create virtual PCM channel\n"); in _cs46xx_adjust_sample_rate()
1067 return -ENOMEM; in _cs46xx_adjust_sample_rate()
1070 if (!unlinked) cs46xx_dsp_pcm_link (chip,cpcm->pcm_channel); in _cs46xx_adjust_sample_rate()
1071 cpcm->pcm_channel->sample_rate = sample_rate; in _cs46xx_adjust_sample_rate()
1082 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_playback_hw_params()
1086 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_playback_hw_params() local
1090 cpcm = runtime->private_data; in snd_cs46xx_playback_hw_params()
1094 return -ENXIO; in snd_cs46xx_playback_hw_params()
1096 mutex_lock(&chip->spos_mutex); in snd_cs46xx_playback_hw_params()
1098 if (_cs46xx_adjust_sample_rate (chip,cpcm,sample_rate)) { in snd_cs46xx_playback_hw_params()
1099 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_hw_params()
1100 return -ENXIO; in snd_cs46xx_playback_hw_params()
1103 snd_BUG_ON(!cpcm->pcm_channel); in snd_cs46xx_playback_hw_params()
1104 if (!cpcm->pcm_channel) { in snd_cs46xx_playback_hw_params()
1105 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_hw_params()
1106 return -ENXIO; in snd_cs46xx_playback_hw_params()
1110 if (cs46xx_dsp_pcm_channel_set_period (chip,cpcm->pcm_channel,period_size)) { in snd_cs46xx_playback_hw_params()
1111 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_hw_params()
1112 return -EINVAL; in snd_cs46xx_playback_hw_params()
1115 dev_dbg(chip->card->dev, in snd_cs46xx_playback_hw_params()
1122 if (runtime->dma_area != cpcm->hw_buf.area) in snd_cs46xx_playback_hw_params()
1124 snd_pcm_set_runtime_buffer(substream, &cpcm->hw_buf); in snd_cs46xx_playback_hw_params()
1128 if (cpcm->pcm_channel_id == DSP_PCM_MAIN_CHANNEL) { in snd_cs46xx_playback_hw_params()
1129 substream->ops = &snd_cs46xx_playback_ops; in snd_cs46xx_playback_hw_params()
1130 } else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) { in snd_cs46xx_playback_hw_params()
1131 substream->ops = &snd_cs46xx_playback_rear_ops; in snd_cs46xx_playback_hw_params()
1132 } else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) { in snd_cs46xx_playback_hw_params()
1133 substream->ops = &snd_cs46xx_playback_clfe_ops; in snd_cs46xx_playback_hw_params()
1134 } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) { in snd_cs46xx_playback_hw_params()
1135 substream->ops = &snd_cs46xx_playback_iec958_ops; in snd_cs46xx_playback_hw_params()
1140 substream->ops = &snd_cs46xx_playback_ops; in snd_cs46xx_playback_hw_params()
1144 if (runtime->dma_area == cpcm->hw_buf.area) in snd_cs46xx_playback_hw_params()
1149 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_hw_params()
1155 if (cpcm->pcm_channel_id == DSP_PCM_MAIN_CHANNEL) { in snd_cs46xx_playback_hw_params()
1156 substream->ops = &snd_cs46xx_playback_indirect_ops; in snd_cs46xx_playback_hw_params()
1157 } else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) { in snd_cs46xx_playback_hw_params()
1158 substream->ops = &snd_cs46xx_playback_indirect_rear_ops; in snd_cs46xx_playback_hw_params()
1159 } else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) { in snd_cs46xx_playback_hw_params()
1160 substream->ops = &snd_cs46xx_playback_indirect_clfe_ops; in snd_cs46xx_playback_hw_params()
1161 } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) { in snd_cs46xx_playback_hw_params()
1162 substream->ops = &snd_cs46xx_playback_indirect_iec958_ops; in snd_cs46xx_playback_hw_params()
1167 substream->ops = &snd_cs46xx_playback_indirect_ops; in snd_cs46xx_playback_hw_params()
1173 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_hw_params()
1181 /*struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);*/ in snd_cs46xx_playback_hw_free()
1182 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_playback_hw_free()
1185 cpcm = runtime->private_data; in snd_cs46xx_playback_hw_free()
1189 if (!cpcm) return -ENXIO; in snd_cs46xx_playback_hw_free()
1191 if (runtime->dma_area != cpcm->hw_buf.area) in snd_cs46xx_playback_hw_free()
1203 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_playback_prepare() local
1204 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_playback_prepare()
1207 cpcm = runtime->private_data; in snd_cs46xx_playback_prepare()
1210 if (snd_BUG_ON(!cpcm->pcm_channel)) in snd_cs46xx_playback_prepare()
1211 return -ENXIO; in snd_cs46xx_playback_prepare()
1213 pfie = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2 ); in snd_cs46xx_playback_prepare()
1217 pfie = snd_cs46xx_peek(chip, BA1_PFIE); in snd_cs46xx_playback_prepare()
1221 cpcm->shift = 2; in snd_cs46xx_playback_prepare()
1222 /* if to convert from stereo to mono */ in snd_cs46xx_playback_prepare()
1223 if (runtime->channels == 1) { in snd_cs46xx_playback_prepare()
1224 cpcm->shift--; in snd_cs46xx_playback_prepare()
1227 /* if to convert from 8 bit to 16 bit */ in snd_cs46xx_playback_prepare()
1228 if (snd_pcm_format_width(runtime->format) == 8) { in snd_cs46xx_playback_prepare()
1229 cpcm->shift--; in snd_cs46xx_playback_prepare()
1232 /* if to convert to unsigned */ in snd_cs46xx_playback_prepare()
1233 if (snd_pcm_format_unsigned(runtime->format)) in snd_cs46xx_playback_prepare()
1237 if (snd_pcm_format_width(runtime->format) != 8) { in snd_cs46xx_playback_prepare()
1238 /* convert from big endian to little endian */ in snd_cs46xx_playback_prepare()
1239 if (snd_pcm_format_big_endian(runtime->format)) in snd_cs46xx_playback_prepare()
1243 memset(&cpcm->pcm_rec, 0, sizeof(cpcm->pcm_rec)); in snd_cs46xx_playback_prepare()
1244 cpcm->pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); in snd_cs46xx_playback_prepare()
1245 cpcm->pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << cpcm->shift; in snd_cs46xx_playback_prepare()
1249 tmp = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address) << 2); in snd_cs46xx_playback_prepare()
1251 tmp |= (4 << cpcm->shift) - 1; in snd_cs46xx_playback_prepare()
1253 snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address) << 2, tmp); in snd_cs46xx_playback_prepare()
1256 …snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2, pfie | cpcm->pcm_chan… in snd_cs46xx_playback_prepare()
1258 snd_cs46xx_poke(chip, BA1_PBA, cpcm->hw_buf.addr); in snd_cs46xx_playback_prepare()
1259 tmp = snd_cs46xx_peek(chip, BA1_PDTC); in snd_cs46xx_playback_prepare()
1261 tmp |= (4 << cpcm->shift) - 1; in snd_cs46xx_playback_prepare()
1262 snd_cs46xx_poke(chip, BA1_PDTC, tmp); in snd_cs46xx_playback_prepare()
1263 snd_cs46xx_poke(chip, BA1_PFIE, pfie); in snd_cs46xx_playback_prepare()
1264 snd_cs46xx_set_play_sample_rate(chip, runtime->rate); in snd_cs46xx_playback_prepare()
1273 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_capture_hw_params() local
1274 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_capture_hw_params()
1278 cs46xx_dsp_pcm_ostream_set_period (chip, params_period_bytes(hw_params)); in snd_cs46xx_capture_hw_params()
1280 if (runtime->periods == CS46XX_FRAGS) { in snd_cs46xx_capture_hw_params()
1281 if (runtime->dma_area != chip->capt.hw_buf.area) in snd_cs46xx_capture_hw_params()
1283 snd_pcm_set_runtime_buffer(substream, &chip->capt.hw_buf); in snd_cs46xx_capture_hw_params()
1284 substream->ops = &snd_cs46xx_capture_ops; in snd_cs46xx_capture_hw_params()
1286 if (runtime->dma_area == chip->capt.hw_buf.area) in snd_cs46xx_capture_hw_params()
1291 substream->ops = &snd_cs46xx_capture_indirect_ops; in snd_cs46xx_capture_hw_params()
1299 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_capture_hw_free() local
1300 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_capture_hw_free()
1302 if (runtime->dma_area != chip->capt.hw_buf.area) in snd_cs46xx_capture_hw_free()
1311 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_capture_prepare() local
1312 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_capture_prepare()
1314 snd_cs46xx_poke(chip, BA1_CBA, chip->capt.hw_buf.addr); in snd_cs46xx_capture_prepare()
1315 chip->capt.shift = 2; in snd_cs46xx_capture_prepare()
1316 memset(&chip->capt.pcm_rec, 0, sizeof(chip->capt.pcm_rec)); in snd_cs46xx_capture_prepare()
1317 chip->capt.pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); in snd_cs46xx_capture_prepare()
1318 chip->capt.pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << 2; in snd_cs46xx_capture_prepare()
1319 snd_cs46xx_set_capture_sample_rate(chip, runtime->rate); in snd_cs46xx_capture_prepare()
1326 struct snd_cs46xx *chip = dev_id; in snd_cs46xx_interrupt() local
1329 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_interrupt()
1336 * Read the Interrupt Status Register to clear the interrupt in snd_cs46xx_interrupt()
1338 status1 = snd_cs46xx_peekBA0(chip, BA0_HISR); in snd_cs46xx_interrupt()
1340 snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_CHGM | HICR_IEV); in snd_cs46xx_interrupt()
1345 status2 = snd_cs46xx_peekBA0(chip, BA0_HSR0); in snd_cs46xx_interrupt()
1351 if (chip->capt.substream) in snd_cs46xx_interrupt()
1352 snd_pcm_period_elapsed(chip->capt.substream); in snd_cs46xx_interrupt()
1354 if (ins->pcm_channels[i].active && in snd_cs46xx_interrupt()
1355 ins->pcm_channels[i].private_data && in snd_cs46xx_interrupt()
1356 !ins->pcm_channels[i].unlinked) { in snd_cs46xx_interrupt()
1357 cpcm = ins->pcm_channels[i].private_data; in snd_cs46xx_interrupt()
1358 snd_pcm_period_elapsed(cpcm->substream); in snd_cs46xx_interrupt()
1363 if ( status2 & (1 << (i - 16))) { in snd_cs46xx_interrupt()
1364 if (ins->pcm_channels[i].active && in snd_cs46xx_interrupt()
1365 ins->pcm_channels[i].private_data && in snd_cs46xx_interrupt()
1366 !ins->pcm_channels[i].unlinked) { in snd_cs46xx_interrupt()
1367 cpcm = ins->pcm_channels[i].private_data; in snd_cs46xx_interrupt()
1368 snd_pcm_period_elapsed(cpcm->substream); in snd_cs46xx_interrupt()
1376 if ((status1 & HISR_VC0) && chip->playback_pcm) { in snd_cs46xx_interrupt()
1377 if (chip->playback_pcm->substream) in snd_cs46xx_interrupt()
1378 snd_pcm_period_elapsed(chip->playback_pcm->substream); in snd_cs46xx_interrupt()
1380 if ((status1 & HISR_VC1) && chip->pcm) { in snd_cs46xx_interrupt()
1381 if (chip->capt.substream) in snd_cs46xx_interrupt()
1382 snd_pcm_period_elapsed(chip->capt.substream); in snd_cs46xx_interrupt()
1386 if ((status1 & HISR_MIDI) && chip->rmidi) { in snd_cs46xx_interrupt()
1389 spin_lock(&chip->reg_lock); in snd_cs46xx_interrupt()
1390 while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_RBE) == 0) { in snd_cs46xx_interrupt()
1391 c = snd_cs46xx_peekBA0(chip, BA0_MIDRP); in snd_cs46xx_interrupt()
1392 if ((chip->midcr & MIDCR_RIE) == 0) in snd_cs46xx_interrupt()
1394 snd_rawmidi_receive(chip->midi_input, &c, 1); in snd_cs46xx_interrupt()
1396 while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_TBF) == 0) { in snd_cs46xx_interrupt()
1397 if ((chip->midcr & MIDCR_TIE) == 0) in snd_cs46xx_interrupt()
1399 if (snd_rawmidi_transmit(chip->midi_output, &c, 1) != 1) { in snd_cs46xx_interrupt()
1400 chip->midcr &= ~MIDCR_TIE; in snd_cs46xx_interrupt()
1401 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_interrupt()
1404 snd_cs46xx_pokeBA0(chip, BA0_MIDWP, c); in snd_cs46xx_interrupt()
1406 spin_unlock(&chip->reg_lock); in snd_cs46xx_interrupt()
1409 * EOI to the PCI part....reenables interrupts in snd_cs46xx_interrupt()
1411 snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_CHGM | HICR_IEV); in snd_cs46xx_interrupt()
1474 kfree(runtime->private_data); in snd_cs46xx_pcm_free_substream()
1479 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in _cs46xx_playback_open_channel() local
1481 struct snd_pcm_runtime *runtime = substream->runtime; in _cs46xx_playback_open_channel()
1485 return -ENOMEM; in _cs46xx_playback_open_channel()
1486 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &chip->pci->dev, in _cs46xx_playback_open_channel()
1487 PAGE_SIZE, &cpcm->hw_buf) < 0) { in _cs46xx_playback_open_channel()
1489 return -ENOMEM; in _cs46xx_playback_open_channel()
1492 runtime->hw = snd_cs46xx_playback; in _cs46xx_playback_open_channel()
1493 runtime->private_data = cpcm; in _cs46xx_playback_open_channel()
1494 runtime->private_free = snd_cs46xx_pcm_free_substream; in _cs46xx_playback_open_channel()
1496 cpcm->substream = substream; in _cs46xx_playback_open_channel()
1498 mutex_lock(&chip->spos_mutex); in _cs46xx_playback_open_channel()
1499 cpcm->pcm_channel = NULL; in _cs46xx_playback_open_channel()
1500 cpcm->pcm_channel_id = pcm_channel_id; in _cs46xx_playback_open_channel()
1507 mutex_unlock(&chip->spos_mutex); in _cs46xx_playback_open_channel()
1509 chip->playback_pcm = cpcm; /* HACK */ in _cs46xx_playback_open_channel()
1512 if (chip->accept_valid) in _cs46xx_playback_open_channel()
1513 substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID; in _cs46xx_playback_open_channel()
1514 chip->active_ctrl(chip, 1); in _cs46xx_playback_open_channel()
1521 dev_dbg(substream->pcm->card->dev, "open front channel\n"); in snd_cs46xx_playback_open()
1528 dev_dbg(substream->pcm->card->dev, "open rear channel\n"); in snd_cs46xx_playback_open_rear()
1534 dev_dbg(substream->pcm->card->dev, "open center - LFE channel\n"); in snd_cs46xx_playback_open_clfe()
1540 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_playback_open_iec958() local
1542 dev_dbg(chip->card->dev, "open raw iec958 channel\n"); in snd_cs46xx_playback_open_iec958()
1544 mutex_lock(&chip->spos_mutex); in snd_cs46xx_playback_open_iec958()
1545 cs46xx_iec958_pre_open (chip); in snd_cs46xx_playback_open_iec958()
1546 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_open_iec958()
1556 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_playback_close_iec958() local
1558 dev_dbg(chip->card->dev, "close raw iec958 channel\n"); in snd_cs46xx_playback_close_iec958()
1562 mutex_lock(&chip->spos_mutex); in snd_cs46xx_playback_close_iec958()
1563 cs46xx_iec958_post_close (chip); in snd_cs46xx_playback_close_iec958()
1564 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_close_iec958()
1572 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_capture_open() local
1574 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &chip->pci->dev, in snd_cs46xx_capture_open()
1575 PAGE_SIZE, &chip->capt.hw_buf) < 0) in snd_cs46xx_capture_open()
1576 return -ENOMEM; in snd_cs46xx_capture_open()
1577 chip->capt.substream = substream; in snd_cs46xx_capture_open()
1578 substream->runtime->hw = snd_cs46xx_capture; in snd_cs46xx_capture_open()
1580 if (chip->accept_valid) in snd_cs46xx_capture_open()
1581 substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID; in snd_cs46xx_capture_open()
1583 chip->active_ctrl(chip, 1); in snd_cs46xx_capture_open()
1586 snd_pcm_hw_constraint_list(substream->runtime, 0, in snd_cs46xx_capture_open()
1595 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_playback_close() local
1596 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_playback_close()
1599 cpcm = runtime->private_data; in snd_cs46xx_playback_close()
1602 if (!cpcm) return -ENXIO; in snd_cs46xx_playback_close()
1605 mutex_lock(&chip->spos_mutex); in snd_cs46xx_playback_close()
1606 if (cpcm->pcm_channel) { in snd_cs46xx_playback_close()
1607 cs46xx_dsp_destroy_pcm_channel(chip,cpcm->pcm_channel); in snd_cs46xx_playback_close()
1608 cpcm->pcm_channel = NULL; in snd_cs46xx_playback_close()
1610 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_close()
1612 chip->playback_pcm = NULL; in snd_cs46xx_playback_close()
1615 cpcm->substream = NULL; in snd_cs46xx_playback_close()
1616 snd_dma_free_pages(&cpcm->hw_buf); in snd_cs46xx_playback_close()
1617 chip->active_ctrl(chip, -1); in snd_cs46xx_playback_close()
1624 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_capture_close() local
1626 chip->capt.substream = NULL; in snd_cs46xx_capture_close()
1627 snd_dma_free_pages(&chip->capt.hw_buf); in snd_cs46xx_capture_close()
1628 chip->active_ctrl(chip, -1); in snd_cs46xx_capture_close()
1742 #define MAX_PLAYBACK_CHANNELS (DSP_MAX_PCM_CHANNELS - 1)
1747 int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device) in snd_cs46xx_pcm() argument
1752 err = snd_pcm_new(chip->card, "CS46xx", device, MAX_PLAYBACK_CHANNELS, 1, &pcm); in snd_cs46xx_pcm()
1756 pcm->private_data = chip; in snd_cs46xx_pcm()
1762 pcm->info_flags = 0; in snd_cs46xx_pcm()
1763 strcpy(pcm->name, "CS46xx"); in snd_cs46xx_pcm()
1764 chip->pcm = pcm; in snd_cs46xx_pcm()
1767 &chip->pci->dev, in snd_cs46xx_pcm()
1775 int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device) in snd_cs46xx_pcm_rear() argument
1780 err = snd_pcm_new(chip->card, "CS46xx - Rear", device, MAX_PLAYBACK_CHANNELS, 0, &pcm); in snd_cs46xx_pcm_rear()
1784 pcm->private_data = chip; in snd_cs46xx_pcm_rear()
1789 pcm->info_flags = 0; in snd_cs46xx_pcm_rear()
1790 strcpy(pcm->name, "CS46xx - Rear"); in snd_cs46xx_pcm_rear()
1791 chip->pcm_rear = pcm; in snd_cs46xx_pcm_rear()
1794 &chip->pci->dev, in snd_cs46xx_pcm_rear()
1800 int snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device) in snd_cs46xx_pcm_center_lfe() argument
1805 err = snd_pcm_new(chip->card, "CS46xx - Center LFE", device, MAX_PLAYBACK_CHANNELS, 0, &pcm); in snd_cs46xx_pcm_center_lfe()
1809 pcm->private_data = chip; in snd_cs46xx_pcm_center_lfe()
1814 pcm->info_flags = 0; in snd_cs46xx_pcm_center_lfe()
1815 strcpy(pcm->name, "CS46xx - Center LFE"); in snd_cs46xx_pcm_center_lfe()
1816 chip->pcm_center_lfe = pcm; in snd_cs46xx_pcm_center_lfe()
1819 &chip->pci->dev, in snd_cs46xx_pcm_center_lfe()
1825 int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device) in snd_cs46xx_pcm_iec958() argument
1830 err = snd_pcm_new(chip->card, "CS46xx - IEC958", device, 1, 0, &pcm); in snd_cs46xx_pcm_iec958()
1834 pcm->private_data = chip; in snd_cs46xx_pcm_iec958()
1839 pcm->info_flags = 0; in snd_cs46xx_pcm_iec958()
1840 strcpy(pcm->name, "CS46xx - IEC958"); in snd_cs46xx_pcm_iec958()
1841 chip->pcm_iec958 = pcm; in snd_cs46xx_pcm_iec958()
1844 &chip->pci->dev, in snd_cs46xx_pcm_iec958()
1856 struct snd_cs46xx *chip = ac97->private_data; in snd_cs46xx_mixer_free_ac97() local
1858 if (snd_BUG_ON(ac97 != chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] && in snd_cs46xx_mixer_free_ac97()
1859 ac97 != chip->ac97[CS46XX_SECONDARY_CODEC_INDEX])) in snd_cs46xx_mixer_free_ac97()
1862 if (ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) { in snd_cs46xx_mixer_free_ac97()
1863 chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] = NULL; in snd_cs46xx_mixer_free_ac97()
1864 chip->eapd_switch = NULL; in snd_cs46xx_mixer_free_ac97()
1867 chip->ac97[CS46XX_SECONDARY_CODEC_INDEX] = NULL; in snd_cs46xx_mixer_free_ac97()
1873 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_cs46xx_vol_info()
1874 uinfo->count = 2; in snd_cs46xx_vol_info()
1875 uinfo->value.integer.min = 0; in snd_cs46xx_vol_info()
1876 uinfo->value.integer.max = 0x7fff; in snd_cs46xx_vol_info()
1882 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_vol_get() local
1883 int reg = kcontrol->private_value; in snd_cs46xx_vol_get()
1884 unsigned int val = snd_cs46xx_peek(chip, reg); in snd_cs46xx_vol_get()
1885 ucontrol->value.integer.value[0] = 0xffff - (val >> 16); in snd_cs46xx_vol_get()
1886 ucontrol->value.integer.value[1] = 0xffff - (val & 0xffff); in snd_cs46xx_vol_get()
1892 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_vol_put() local
1893 int reg = kcontrol->private_value; in snd_cs46xx_vol_put()
1894 unsigned int val = ((0xffff - ucontrol->value.integer.value[0]) << 16 | in snd_cs46xx_vol_put()
1895 (0xffff - ucontrol->value.integer.value[1])); in snd_cs46xx_vol_put()
1896 unsigned int old = snd_cs46xx_peek(chip, reg); in snd_cs46xx_vol_put()
1900 snd_cs46xx_poke(chip, reg, val); in snd_cs46xx_vol_put()
1910 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_vol_dac_get() local
1912 ucontrol->value.integer.value[0] = chip->dsp_spos_instance->dac_volume_left; in snd_cs46xx_vol_dac_get()
1913 ucontrol->value.integer.value[1] = chip->dsp_spos_instance->dac_volume_right; in snd_cs46xx_vol_dac_get()
1920 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_vol_dac_put() local
1923 if (chip->dsp_spos_instance->dac_volume_right != ucontrol->value.integer.value[0] || in snd_cs46xx_vol_dac_put()
1924 chip->dsp_spos_instance->dac_volume_left != ucontrol->value.integer.value[1]) { in snd_cs46xx_vol_dac_put()
1925 cs46xx_dsp_set_dac_volume(chip, in snd_cs46xx_vol_dac_put()
1926 ucontrol->value.integer.value[0], in snd_cs46xx_vol_dac_put()
1927 ucontrol->value.integer.value[1]); in snd_cs46xx_vol_dac_put()
1937 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1939 ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_input_volume_left;
1940 ucontrol->value.integer.value[1] = chip->dsp_spos_instance->spdif_input_volume_right;
1946 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1949 if (chip->dsp_spos_instance->spdif_input_volume_left != ucontrol->value.integer.value[0] ||
1950 chip->dsp_spos_instance->spdif_input_volume_right!= ucontrol->value.integer.value[1]) {
1951 cs46xx_dsp_set_iec958_volume (chip,
1952 ucontrol->value.integer.value[0],
1953 ucontrol->value.integer.value[1]);
1966 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_iec958_get() local
1967 int reg = kcontrol->private_value; in snd_cs46xx_iec958_get()
1970 …ucontrol->value.integer.value[0] = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_O… in snd_cs46xx_iec958_get()
1972 ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_status_in; in snd_cs46xx_iec958_get()
1980 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_iec958_put() local
1983 switch (kcontrol->private_value) { in snd_cs46xx_iec958_put()
1985 mutex_lock(&chip->spos_mutex); in snd_cs46xx_iec958_put()
1986 change = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED); in snd_cs46xx_iec958_put()
1987 if (ucontrol->value.integer.value[0] && !change) in snd_cs46xx_iec958_put()
1988 cs46xx_dsp_enable_spdif_out(chip); in snd_cs46xx_iec958_put()
1989 else if (change && !ucontrol->value.integer.value[0]) in snd_cs46xx_iec958_put()
1990 cs46xx_dsp_disable_spdif_out(chip); in snd_cs46xx_iec958_put()
1992 res = (change != (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED)); in snd_cs46xx_iec958_put()
1993 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_iec958_put()
1996 change = chip->dsp_spos_instance->spdif_status_in; in snd_cs46xx_iec958_put()
1997 if (ucontrol->value.integer.value[0] && !change) { in snd_cs46xx_iec958_put()
1998 cs46xx_dsp_enable_spdif_in(chip); in snd_cs46xx_iec958_put()
2001 else if (change && !ucontrol->value.integer.value[0]) in snd_cs46xx_iec958_put()
2002 cs46xx_dsp_disable_spdif_in(chip); in snd_cs46xx_iec958_put()
2004 res = (change != chip->dsp_spos_instance->spdif_status_in); in snd_cs46xx_iec958_put()
2007 res = -EINVAL; in snd_cs46xx_iec958_put()
2017 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_adc_capture_get() local
2018 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_adc_capture_get()
2020 if (ins->adc_input != NULL) in snd_cs46xx_adc_capture_get()
2021 ucontrol->value.integer.value[0] = 1; in snd_cs46xx_adc_capture_get()
2023 ucontrol->value.integer.value[0] = 0; in snd_cs46xx_adc_capture_get()
2031 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_adc_capture_put() local
2032 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_adc_capture_put()
2035 if (ucontrol->value.integer.value[0] && !ins->adc_input) { in snd_cs46xx_adc_capture_put()
2036 cs46xx_dsp_enable_adc_capture(chip); in snd_cs46xx_adc_capture_put()
2038 } else if (!ucontrol->value.integer.value[0] && ins->adc_input) { in snd_cs46xx_adc_capture_put()
2039 cs46xx_dsp_disable_adc_capture(chip); in snd_cs46xx_adc_capture_put()
2048 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_pcm_capture_get() local
2049 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_pcm_capture_get()
2051 if (ins->pcm_input != NULL) in snd_cs46xx_pcm_capture_get()
2052 ucontrol->value.integer.value[0] = 1; in snd_cs46xx_pcm_capture_get()
2054 ucontrol->value.integer.value[0] = 0; in snd_cs46xx_pcm_capture_get()
2063 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_pcm_capture_put() local
2064 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_pcm_capture_put()
2067 if (ucontrol->value.integer.value[0] && !ins->pcm_input) { in snd_cs46xx_pcm_capture_put()
2068 cs46xx_dsp_enable_pcm_capture(chip); in snd_cs46xx_pcm_capture_put()
2070 } else if (!ucontrol->value.integer.value[0] && ins->pcm_input) { in snd_cs46xx_pcm_capture_put()
2071 cs46xx_dsp_disable_pcm_capture(chip); in snd_cs46xx_pcm_capture_put()
2081 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_herc_spdif_select_get() local
2083 int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR); in snd_herc_spdif_select_get()
2086 ucontrol->value.integer.value[0] = 1; in snd_herc_spdif_select_get()
2088 ucontrol->value.integer.value[0] = 0; in snd_herc_spdif_select_get()
2094 * Game Theatre XP card - EGPIO[0] is used to select SPDIF input optical or coaxial.
2099 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_herc_spdif_select_put() local
2100 int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR); in snd_herc_spdif_select_put()
2101 int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR); in snd_herc_spdif_select_put()
2103 if (ucontrol->value.integer.value[0]) { in snd_herc_spdif_select_put()
2105 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, in snd_herc_spdif_select_put()
2107 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, in snd_herc_spdif_select_put()
2108 EGPIOPTR_GPPT0 | val2); /* open-drain on output */ in snd_herc_spdif_select_put()
2111 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, val1 & ~EGPIODR_GPOE0); /* disable */ in snd_herc_spdif_select_put()
2112 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT0); /* disable */ in snd_herc_spdif_select_put()
2117 return (val1 != (int)snd_cs46xx_peekBA0(chip, BA0_EGPIODR)); in snd_herc_spdif_select_put()
2123 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; in snd_cs46xx_spdif_info()
2124 uinfo->count = 1; in snd_cs46xx_spdif_info()
2131 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_spdif_default_get() local
2132 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_spdif_default_get()
2134 mutex_lock(&chip->spos_mutex); in snd_cs46xx_spdif_default_get()
2135 ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_default >> 24) & 0xff); in snd_cs46xx_spdif_default_get()
2136 ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_default >> 16) & 0xff); in snd_cs46xx_spdif_default_get()
2137 ucontrol->value.iec958.status[2] = 0; in snd_cs46xx_spdif_default_get()
2138 ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_default) & 0xff); in snd_cs46xx_spdif_default_get()
2139 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_spdif_default_get()
2147 struct snd_cs46xx * chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_spdif_default_put() local
2148 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_spdif_default_put()
2152 mutex_lock(&chip->spos_mutex); in snd_cs46xx_spdif_default_put()
2153 val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) | in snd_cs46xx_spdif_default_put()
2154 ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[2]) << 16) | in snd_cs46xx_spdif_default_put()
2155 ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) | in snd_cs46xx_spdif_default_put()
2160 change = (unsigned int)ins->spdif_csuv_default != val; in snd_cs46xx_spdif_default_put()
2161 ins->spdif_csuv_default = val; in snd_cs46xx_spdif_default_put()
2163 if ( !(ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) ) in snd_cs46xx_spdif_default_put()
2164 cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val); in snd_cs46xx_spdif_default_put()
2166 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_spdif_default_put()
2174 ucontrol->value.iec958.status[0] = 0xff; in snd_cs46xx_spdif_mask_get()
2175 ucontrol->value.iec958.status[1] = 0xff; in snd_cs46xx_spdif_mask_get()
2176 ucontrol->value.iec958.status[2] = 0x00; in snd_cs46xx_spdif_mask_get()
2177 ucontrol->value.iec958.status[3] = 0xff; in snd_cs46xx_spdif_mask_get()
2184 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_spdif_stream_get() local
2185 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_spdif_stream_get()
2187 mutex_lock(&chip->spos_mutex); in snd_cs46xx_spdif_stream_get()
2188 ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_stream >> 24) & 0xff); in snd_cs46xx_spdif_stream_get()
2189 ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_stream >> 16) & 0xff); in snd_cs46xx_spdif_stream_get()
2190 ucontrol->value.iec958.status[2] = 0; in snd_cs46xx_spdif_stream_get()
2191 ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_stream) & 0xff); in snd_cs46xx_spdif_stream_get()
2192 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_spdif_stream_get()
2200 struct snd_cs46xx * chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_spdif_stream_put() local
2201 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_spdif_stream_put()
2205 mutex_lock(&chip->spos_mutex); in snd_cs46xx_spdif_stream_put()
2206 val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) | in snd_cs46xx_spdif_stream_put()
2207 ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[1]) << 16) | in snd_cs46xx_spdif_stream_put()
2208 ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) | in snd_cs46xx_spdif_stream_put()
2213 change = ins->spdif_csuv_stream != val; in snd_cs46xx_spdif_stream_put()
2214 ins->spdif_csuv_stream = val; in snd_cs46xx_spdif_stream_put()
2216 if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN ) in snd_cs46xx_spdif_stream_put()
2217 cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val); in snd_cs46xx_spdif_stream_put()
2219 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_spdif_stream_put()
2326 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_front_dup_get() local
2328 val = snd_ac97_read(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], AC97_CSR_ACMODE); in snd_cs46xx_front_dup_get()
2329 ucontrol->value.integer.value[0] = (val & 0x200) ? 0 : 1; in snd_cs46xx_front_dup_get()
2336 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_front_dup_put() local
2337 return snd_ac97_update_bits(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], in snd_cs46xx_front_dup_put()
2339 ucontrol->value.integer.value[0] ? 0 : 0x200); in snd_cs46xx_front_dup_put()
2369 /* reset to defaults */ in snd_cs46xx_codec_reset()
2373 if (ac97->num == CS46XX_PRIMARY_CODEC_INDEX) { in snd_cs46xx_codec_reset()
2374 dev_dbg(ac97->bus->card->dev, "CODEC1 mode %04x\n", 0x0); in snd_cs46xx_codec_reset()
2376 } else if (ac97->num == CS46XX_SECONDARY_CODEC_INDEX) { in snd_cs46xx_codec_reset()
2377 dev_dbg(ac97->bus->card->dev, "CODEC2 mode %04x\n", 0x3); in snd_cs46xx_codec_reset()
2385 /* it's necessary to wait awhile until registers are accessible after RESET */ in snd_cs46xx_codec_reset()
2392 /* use preliminary reads to settle the communication */ in snd_cs46xx_codec_reset()
2401 /* test if we can write to the record gain volume register */ in snd_cs46xx_codec_reset()
2410 dev_err(ac97->bus->card->dev, in snd_cs46xx_codec_reset()
2415 static int cs46xx_detect_codec(struct snd_cs46xx *chip, int codec) in cs46xx_detect_codec() argument
2421 ac97.private_data = chip; in cs46xx_detect_codec()
2424 if (chip->amplifier_ctrl == amp_voyetra) in cs46xx_detect_codec()
2428 snd_cs46xx_codec_write(chip, AC97_RESET, 0, codec); in cs46xx_detect_codec()
2430 if (snd_cs46xx_codec_read(chip, AC97_RESET, codec) & 0x8000) { in cs46xx_detect_codec()
2431 dev_dbg(chip->card->dev, in cs46xx_detect_codec()
2433 return -ENXIO; in cs46xx_detect_codec()
2437 snd_cs46xx_codec_write(chip, AC97_MASTER, 0x8000, codec); in cs46xx_detect_codec()
2439 if (snd_cs46xx_codec_read(chip, AC97_MASTER, codec) == 0x8000) { in cs46xx_detect_codec()
2440 err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97[codec]); in cs46xx_detect_codec()
2445 dev_dbg(chip->card->dev, "codec %d detection timeout\n", codec); in cs46xx_detect_codec()
2446 return -ENXIO; in cs46xx_detect_codec()
2449 int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device) in snd_cs46xx_mixer() argument
2451 struct snd_card *card = chip->card; in snd_cs46xx_mixer()
2463 chip->nr_ac97_codecs = 0; in snd_cs46xx_mixer()
2464 dev_dbg(chip->card->dev, "detecting primary codec\n"); in snd_cs46xx_mixer()
2465 err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus); in snd_cs46xx_mixer()
2469 if (cs46xx_detect_codec(chip, CS46XX_PRIMARY_CODEC_INDEX) < 0) in snd_cs46xx_mixer()
2470 return -ENXIO; in snd_cs46xx_mixer()
2471 chip->nr_ac97_codecs = 1; in snd_cs46xx_mixer()
2474 dev_dbg(chip->card->dev, "detecting secondary codec\n"); in snd_cs46xx_mixer()
2476 if (! cs46xx_detect_codec(chip, CS46XX_SECONDARY_CODEC_INDEX)) in snd_cs46xx_mixer()
2477 chip->nr_ac97_codecs = 2; in snd_cs46xx_mixer()
2483 kctl = snd_ctl_new1(&snd_cs46xx_controls[idx], chip); in snd_cs46xx_mixer()
2484 if (kctl && kctl->id.iface == SNDRV_CTL_ELEM_IFACE_PCM) in snd_cs46xx_mixer()
2485 kctl->id.device = spdif_device; in snd_cs46xx_mixer()
2492 chip->eapd_switch = snd_ctl_find_id_mixer(chip->card, in snd_cs46xx_mixer()
2496 if (chip->nr_ac97_codecs == 1) { in snd_cs46xx_mixer()
2497 unsigned int id2 = chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]->id & 0xffff; in snd_cs46xx_mixer()
2499 err = snd_ctl_add(card, snd_ctl_new1(&snd_cs46xx_front_dup_ctl, chip)); in snd_cs46xx_mixer()
2502 snd_ac97_write_cache(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], in snd_cs46xx_mixer()
2507 if (chip->mixer_init) { in snd_cs46xx_mixer()
2508 dev_dbg(chip->card->dev, "calling chip->mixer_init(chip);\n"); in snd_cs46xx_mixer()
2509 chip->mixer_init(chip); in snd_cs46xx_mixer()
2514 chip->amplifier_ctrl(chip, 1); in snd_cs46xx_mixer()
2523 static void snd_cs46xx_midi_reset(struct snd_cs46xx *chip) in snd_cs46xx_midi_reset() argument
2525 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, MIDCR_MRST); in snd_cs46xx_midi_reset()
2527 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_reset()
2532 struct snd_cs46xx *chip = substream->rmidi->private_data; in snd_cs46xx_midi_input_open() local
2534 chip->active_ctrl(chip, 1); in snd_cs46xx_midi_input_open()
2535 spin_lock_irq(&chip->reg_lock); in snd_cs46xx_midi_input_open()
2536 chip->uartm |= CS46XX_MODE_INPUT; in snd_cs46xx_midi_input_open()
2537 chip->midcr |= MIDCR_RXE; in snd_cs46xx_midi_input_open()
2538 chip->midi_input = substream; in snd_cs46xx_midi_input_open()
2539 if (!(chip->uartm & CS46XX_MODE_OUTPUT)) { in snd_cs46xx_midi_input_open()
2540 snd_cs46xx_midi_reset(chip); in snd_cs46xx_midi_input_open()
2542 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_input_open()
2544 spin_unlock_irq(&chip->reg_lock); in snd_cs46xx_midi_input_open()
2550 struct snd_cs46xx *chip = substream->rmidi->private_data; in snd_cs46xx_midi_input_close() local
2552 spin_lock_irq(&chip->reg_lock); in snd_cs46xx_midi_input_close()
2553 chip->midcr &= ~(MIDCR_RXE | MIDCR_RIE); in snd_cs46xx_midi_input_close()
2554 chip->midi_input = NULL; in snd_cs46xx_midi_input_close()
2555 if (!(chip->uartm & CS46XX_MODE_OUTPUT)) { in snd_cs46xx_midi_input_close()
2556 snd_cs46xx_midi_reset(chip); in snd_cs46xx_midi_input_close()
2558 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_input_close()
2560 chip->uartm &= ~CS46XX_MODE_INPUT; in snd_cs46xx_midi_input_close()
2561 spin_unlock_irq(&chip->reg_lock); in snd_cs46xx_midi_input_close()
2562 chip->active_ctrl(chip, -1); in snd_cs46xx_midi_input_close()
2568 struct snd_cs46xx *chip = substream->rmidi->private_data; in snd_cs46xx_midi_output_open() local
2570 chip->active_ctrl(chip, 1); in snd_cs46xx_midi_output_open()
2572 spin_lock_irq(&chip->reg_lock); in snd_cs46xx_midi_output_open()
2573 chip->uartm |= CS46XX_MODE_OUTPUT; in snd_cs46xx_midi_output_open()
2574 chip->midcr |= MIDCR_TXE; in snd_cs46xx_midi_output_open()
2575 chip->midi_output = substream; in snd_cs46xx_midi_output_open()
2576 if (!(chip->uartm & CS46XX_MODE_INPUT)) { in snd_cs46xx_midi_output_open()
2577 snd_cs46xx_midi_reset(chip); in snd_cs46xx_midi_output_open()
2579 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_output_open()
2581 spin_unlock_irq(&chip->reg_lock); in snd_cs46xx_midi_output_open()
2587 struct snd_cs46xx *chip = substream->rmidi->private_data; in snd_cs46xx_midi_output_close() local
2589 spin_lock_irq(&chip->reg_lock); in snd_cs46xx_midi_output_close()
2590 chip->midcr &= ~(MIDCR_TXE | MIDCR_TIE); in snd_cs46xx_midi_output_close()
2591 chip->midi_output = NULL; in snd_cs46xx_midi_output_close()
2592 if (!(chip->uartm & CS46XX_MODE_INPUT)) { in snd_cs46xx_midi_output_close()
2593 snd_cs46xx_midi_reset(chip); in snd_cs46xx_midi_output_close()
2595 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_output_close()
2597 chip->uartm &= ~CS46XX_MODE_OUTPUT; in snd_cs46xx_midi_output_close()
2598 spin_unlock_irq(&chip->reg_lock); in snd_cs46xx_midi_output_close()
2599 chip->active_ctrl(chip, -1); in snd_cs46xx_midi_output_close()
2606 struct snd_cs46xx *chip = substream->rmidi->private_data; in snd_cs46xx_midi_input_trigger() local
2608 spin_lock_irqsave(&chip->reg_lock, flags); in snd_cs46xx_midi_input_trigger()
2610 if ((chip->midcr & MIDCR_RIE) == 0) { in snd_cs46xx_midi_input_trigger()
2611 chip->midcr |= MIDCR_RIE; in snd_cs46xx_midi_input_trigger()
2612 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_input_trigger()
2615 if (chip->midcr & MIDCR_RIE) { in snd_cs46xx_midi_input_trigger()
2616 chip->midcr &= ~MIDCR_RIE; in snd_cs46xx_midi_input_trigger()
2617 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_input_trigger()
2620 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_cs46xx_midi_input_trigger()
2626 struct snd_cs46xx *chip = substream->rmidi->private_data; in snd_cs46xx_midi_output_trigger() local
2629 spin_lock_irqsave(&chip->reg_lock, flags); in snd_cs46xx_midi_output_trigger()
2631 if ((chip->midcr & MIDCR_TIE) == 0) { in snd_cs46xx_midi_output_trigger()
2632 chip->midcr |= MIDCR_TIE; in snd_cs46xx_midi_output_trigger()
2634 while ((chip->midcr & MIDCR_TIE) && in snd_cs46xx_midi_output_trigger()
2635 (snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_TBF) == 0) { in snd_cs46xx_midi_output_trigger()
2637 chip->midcr &= ~MIDCR_TIE; in snd_cs46xx_midi_output_trigger()
2639 snd_cs46xx_pokeBA0(chip, BA0_MIDWP, byte); in snd_cs46xx_midi_output_trigger()
2642 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_output_trigger()
2645 if (chip->midcr & MIDCR_TIE) { in snd_cs46xx_midi_output_trigger()
2646 chip->midcr &= ~MIDCR_TIE; in snd_cs46xx_midi_output_trigger()
2647 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_output_trigger()
2650 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_cs46xx_midi_output_trigger()
2667 int snd_cs46xx_midi(struct snd_cs46xx *chip, int device) in snd_cs46xx_midi() argument
2672 err = snd_rawmidi_new(chip->card, "CS46XX", device, 1, 1, &rmidi); in snd_cs46xx_midi()
2675 strcpy(rmidi->name, "CS46XX"); in snd_cs46xx_midi()
2678 …rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUP… in snd_cs46xx_midi()
2679 rmidi->private_data = chip; in snd_cs46xx_midi()
2680 chip->rmidi = rmidi; in snd_cs46xx_midi()
2693 struct snd_cs46xx *chip = gameport_get_port_data(gameport); in snd_cs46xx_gameport_trigger() local
2695 if (snd_BUG_ON(!chip)) in snd_cs46xx_gameport_trigger()
2697 snd_cs46xx_pokeBA0(chip, BA0_JSPT, 0xFF); //outb(gameport->io, 0xFF); in snd_cs46xx_gameport_trigger()
2702 struct snd_cs46xx *chip = gameport_get_port_data(gameport); in snd_cs46xx_gameport_read() local
2704 if (snd_BUG_ON(!chip)) in snd_cs46xx_gameport_read()
2706 return snd_cs46xx_peekBA0(chip, BA0_JSPT); //inb(gameport->io); in snd_cs46xx_gameport_read()
2711 struct snd_cs46xx *chip = gameport_get_port_data(gameport); in snd_cs46xx_gameport_cooked_read() local
2714 if (snd_BUG_ON(!chip)) in snd_cs46xx_gameport_cooked_read()
2717 js1 = snd_cs46xx_peekBA0(chip, BA0_JSC1); in snd_cs46xx_gameport_cooked_read()
2718 js2 = snd_cs46xx_peekBA0(chip, BA0_JSC2); in snd_cs46xx_gameport_cooked_read()
2719 jst = snd_cs46xx_peekBA0(chip, BA0_JSPT); in snd_cs46xx_gameport_cooked_read()
2729 if(axes[jst]==0xFFFF) axes[jst] = -1; in snd_cs46xx_gameport_cooked_read()
2741 return -1; in snd_cs46xx_gameport_open()
2746 int snd_cs46xx_gameport(struct snd_cs46xx *chip) in snd_cs46xx_gameport() argument
2750 chip->gameport = gp = gameport_allocate_port(); in snd_cs46xx_gameport()
2752 dev_err(chip->card->dev, in snd_cs46xx_gameport()
2754 return -ENOMEM; in snd_cs46xx_gameport()
2758 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci)); in snd_cs46xx_gameport()
2759 gameport_set_dev_parent(gp, &chip->pci->dev); in snd_cs46xx_gameport()
2760 gameport_set_port_data(gp, chip); in snd_cs46xx_gameport()
2762 gp->open = snd_cs46xx_gameport_open; in snd_cs46xx_gameport()
2763 gp->read = snd_cs46xx_gameport_read; in snd_cs46xx_gameport()
2764 gp->trigger = snd_cs46xx_gameport_trigger; in snd_cs46xx_gameport()
2765 gp->cooked_read = snd_cs46xx_gameport_cooked_read; in snd_cs46xx_gameport()
2767 snd_cs46xx_pokeBA0(chip, BA0_JSIO, 0xFF); // ? in snd_cs46xx_gameport()
2768 snd_cs46xx_pokeBA0(chip, BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW); in snd_cs46xx_gameport()
2775 static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip) in snd_cs46xx_remove_gameport() argument
2777 if (chip->gameport) { in snd_cs46xx_remove_gameport()
2778 gameport_unregister_port(chip->gameport); in snd_cs46xx_remove_gameport()
2779 chip->gameport = NULL; in snd_cs46xx_remove_gameport()
2783 int snd_cs46xx_gameport(struct snd_cs46xx *chip) { return -ENOSYS; } in snd_cs46xx_gameport() argument
2784 static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip) { } in snd_cs46xx_remove_gameport() argument
2797 struct snd_cs46xx_region *region = entry->private_data; in snd_cs46xx_io_read()
2799 if (copy_to_user_fromio(buf, region->remap_addr + pos, count)) in snd_cs46xx_io_read()
2800 return -EFAULT; in snd_cs46xx_io_read()
2808 static int snd_cs46xx_proc_init(struct snd_card *card, struct snd_cs46xx *chip) in snd_cs46xx_proc_init() argument
2814 struct snd_cs46xx_region *region = &chip->region.idx[idx]; in snd_cs46xx_proc_init()
2815 if (! snd_card_proc_new(card, region->name, &entry)) { in snd_cs46xx_proc_init()
2816 entry->content = SNDRV_INFO_CONTENT_DATA; in snd_cs46xx_proc_init()
2817 entry->private_data = chip; in snd_cs46xx_proc_init()
2818 entry->c.ops = &snd_cs46xx_proc_io_ops; in snd_cs46xx_proc_init()
2819 entry->size = region->size; in snd_cs46xx_proc_init()
2820 entry->mode = S_IFREG | 0400; in snd_cs46xx_proc_init()
2824 cs46xx_dsp_proc_init(card, chip); in snd_cs46xx_proc_init()
2829 static int snd_cs46xx_proc_done(struct snd_cs46xx *chip) in snd_cs46xx_proc_done() argument
2832 cs46xx_dsp_proc_done(chip); in snd_cs46xx_proc_done()
2837 #define snd_cs46xx_proc_init(card, chip) argument
2838 #define snd_cs46xx_proc_done(chip) argument
2844 static void snd_cs46xx_hw_stop(struct snd_cs46xx *chip) in snd_cs46xx_hw_stop() argument
2848 tmp = snd_cs46xx_peek(chip, BA1_PFIE); in snd_cs46xx_hw_stop()
2851 snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt disable */ in snd_cs46xx_hw_stop()
2853 tmp = snd_cs46xx_peek(chip, BA1_CIE); in snd_cs46xx_hw_stop()
2856 snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt disable */ in snd_cs46xx_hw_stop()
2861 tmp = snd_cs46xx_peek(chip, BA1_PCTL); in snd_cs46xx_hw_stop()
2862 snd_cs46xx_poke(chip, BA1_PCTL, tmp & 0x0000ffff); in snd_cs46xx_hw_stop()
2867 tmp = snd_cs46xx_peek(chip, BA1_CCTL); in snd_cs46xx_hw_stop()
2868 snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000); in snd_cs46xx_hw_stop()
2873 snd_cs46xx_reset(chip); in snd_cs46xx_hw_stop()
2875 snd_cs46xx_proc_stop(chip); in snd_cs46xx_hw_stop()
2880 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, 0); in snd_cs46xx_hw_stop()
2886 tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE; in snd_cs46xx_hw_stop()
2887 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); in snd_cs46xx_hw_stop()
2893 struct snd_cs46xx *chip = card->private_data; in snd_cs46xx_free() local
2898 if (chip->active_ctrl) in snd_cs46xx_free()
2899 chip->active_ctrl(chip, 1); in snd_cs46xx_free()
2901 snd_cs46xx_remove_gameport(chip); in snd_cs46xx_free()
2903 if (chip->amplifier_ctrl) in snd_cs46xx_free()
2904 chip->amplifier_ctrl(chip, -chip->amplifier); /* force to off */ in snd_cs46xx_free()
2906 snd_cs46xx_proc_done(chip); in snd_cs46xx_free()
2908 snd_cs46xx_hw_stop(chip); in snd_cs46xx_free()
2910 if (chip->active_ctrl) in snd_cs46xx_free()
2911 chip->active_ctrl(chip, -chip->amplifier); in snd_cs46xx_free()
2914 if (chip->dsp_spos_instance) { in snd_cs46xx_free()
2915 cs46xx_dsp_spos_destroy(chip); in snd_cs46xx_free()
2916 chip->dsp_spos_instance = NULL; in snd_cs46xx_free()
2919 free_module_desc(chip->modules[idx]); in snd_cs46xx_free()
2921 vfree(chip->ba1); in snd_cs46xx_free()
2926 * initialize chip
2928 static int snd_cs46xx_chip_init(struct snd_cs46xx *chip) in snd_cs46xx_chip_init() argument
2933 * First, blast the clock control register to zero so that the PLL starts in snd_cs46xx_chip_init()
2935 * to zero so that the serial ports also start out in a known state. in snd_cs46xx_chip_init()
2937 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, 0); in snd_cs46xx_chip_init()
2938 snd_cs46xx_pokeBA0(chip, BA0_SERMC1, 0); in snd_cs46xx_chip_init()
2941 * If we are in AC97 mode, then we must set the part to a host controlled in snd_cs46xx_chip_init()
2942 * AC-link. Otherwise, we won't be able to bring up the link. in snd_cs46xx_chip_init()
2945 snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0 | in snd_cs46xx_chip_init()
2947 /* snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0); */ /* 2.00 codec */ in snd_cs46xx_chip_init()
2949 snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_1_03); /* 1.03 codec */ in snd_cs46xx_chip_init()
2955 * there might be logic external to the CS461x that uses the ARST# line in snd_cs46xx_chip_init()
2958 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, 0); in snd_cs46xx_chip_init()
2960 snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, 0); in snd_cs46xx_chip_init()
2963 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_RSTN); in snd_cs46xx_chip_init()
2965 snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_RSTN); in snd_cs46xx_chip_init()
2969 * The first thing we do here is to enable sync generation. As soon in snd_cs46xx_chip_init()
2973 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_ESYN | ACCTL_RSTN); in snd_cs46xx_chip_init()
2975 snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_ESYN | ACCTL_RSTN); in snd_cs46xx_chip_init()
2979 * Now wait for a short while to allow the AC97 part to start in snd_cs46xx_chip_init()
2980 * generating bit clock (so we don't try to start the PLL without an in snd_cs46xx_chip_init()
2989 snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97); in snd_cs46xx_chip_init()
2992 * Write the selected clock control setup to the hardware. Do not turn on in snd_cs46xx_chip_init()
2996 snd_cs46xx_pokeBA0(chip, BA0_PLLCC, PLLCC_LPF_1050_2780_KHZ | PLLCC_CDR_73_104_MHZ); in snd_cs46xx_chip_init()
2997 snd_cs46xx_pokeBA0(chip, BA0_PLLM, 0x3a); in snd_cs46xx_chip_init()
2998 snd_cs46xx_pokeBA0(chip, BA0_CLKCR2, CLKCR2_PDIVS_8); in snd_cs46xx_chip_init()
3003 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP); in snd_cs46xx_chip_init()
3013 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP | CLKCR1_SWCE); in snd_cs46xx_chip_init()
3018 snd_cs46xx_pokeBA0(chip, BA0_SERBCF, SERBCF_HBP); in snd_cs46xx_chip_init()
3023 snd_cs46xx_clear_serial_FIFOs(chip); in snd_cs46xx_chip_init()
3026 * Set the serial port FIFO pointer to the first sample in the FIFO. in snd_cs46xx_chip_init()
3028 /* snd_cs46xx_pokeBA0(chip, BA0_SERBSP, 0); */ in snd_cs46xx_chip_init()
3031 * Write the serial port configuration to the part. The master in snd_cs46xx_chip_init()
3034 snd_cs46xx_pokeBA0(chip, BA0_SERC1, SERC1_SO1F_AC97 | SERC1_SO1EN); in snd_cs46xx_chip_init()
3035 snd_cs46xx_pokeBA0(chip, BA0_SERC2, SERC2_SI1F_AC97 | SERC1_SO1EN); in snd_cs46xx_chip_init()
3036 snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97 | SERMC1_MSPE); in snd_cs46xx_chip_init()
3040 snd_cs46xx_pokeBA0(chip, BA0_SERC7, SERC7_ASDI2EN); in snd_cs46xx_chip_init()
3041 snd_cs46xx_pokeBA0(chip, BA0_SERC3, 0); in snd_cs46xx_chip_init()
3042 snd_cs46xx_pokeBA0(chip, BA0_SERC4, 0); in snd_cs46xx_chip_init()
3043 snd_cs46xx_pokeBA0(chip, BA0_SERC5, 0); in snd_cs46xx_chip_init()
3044 snd_cs46xx_pokeBA0(chip, BA0_SERC6, 1); in snd_cs46xx_chip_init()
3054 while (timeout-- > 0) { in snd_cs46xx_chip_init()
3056 * Read the AC97 status register to see if we've seen a CODEC READY in snd_cs46xx_chip_init()
3059 if (snd_cs46xx_peekBA0(chip, BA0_ACSTS) & ACSTS_CRDY) in snd_cs46xx_chip_init()
3065 dev_err(chip->card->dev, in snd_cs46xx_chip_init()
3066 "create - never read codec ready from AC'97\n"); in snd_cs46xx_chip_init()
3067 dev_err(chip->card->dev, in snd_cs46xx_chip_init()
3068 "it is not probably bug, try to use CS4236 driver\n"); in snd_cs46xx_chip_init()
3069 return -EIO; in snd_cs46xx_chip_init()
3075 /* First, we want to wait for a short time. */ in snd_cs46xx_chip_init()
3078 if (snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY) in snd_cs46xx_chip_init()
3085 if (!(snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY)) in snd_cs46xx_chip_init()
3086 dev_dbg(chip->card->dev, in snd_cs46xx_chip_init()
3093 * to the AC97 codec. in snd_cs46xx_chip_init()
3095 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN); in snd_cs46xx_chip_init()
3097 snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN); in snd_cs46xx_chip_init()
3103 * the codec is pumping ADC data across the AC-link. in snd_cs46xx_chip_init()
3106 while (timeout-- > 0) { in snd_cs46xx_chip_init()
3111 …if ((snd_cs46xx_peekBA0(chip, BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) == (ACISV_ISV3 | ACISV_ISV4)) in snd_cs46xx_chip_init()
3117 dev_err(chip->card->dev, in snd_cs46xx_chip_init()
3118 "create - never read ISV3 & ISV4 from AC'97\n"); in snd_cs46xx_chip_init()
3119 return -EIO; in snd_cs46xx_chip_init()
3123 with the same problem I would like to know. (Benny) */ in snd_cs46xx_chip_init()
3125 dev_err(chip->card->dev, "never read ISV3 & ISV4 from AC'97\n"); in snd_cs46xx_chip_init()
3126 dev_err(chip->card->dev, in snd_cs46xx_chip_init()
3128 dev_err(chip->card->dev, in snd_cs46xx_chip_init()
3130 dev_err(chip->card->dev, in snd_cs46xx_chip_init()
3131 "this message please report to alsa-devel@alsa-project.org\n"); in snd_cs46xx_chip_init()
3133 return -EIO; in snd_cs46xx_chip_init()
3139 * commense the transfer of digital audio data to the AC97 codec. in snd_cs46xx_chip_init()
3142 snd_cs46xx_pokeBA0(chip, BA0_ACOSV, ACOSV_SLV3 | ACOSV_SLV4); in snd_cs46xx_chip_init()
3149 /* snd_cs46xx_pokeBA0(chip, BA0_AC97_POWERDOWN, 0x300); */ in snd_cs46xx_chip_init()
3155 /* tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE; */ in snd_cs46xx_chip_init()
3156 /* snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); */ in snd_cs46xx_chip_init()
3165 static void cs46xx_enable_stream_irqs(struct snd_cs46xx *chip) in cs46xx_enable_stream_irqs() argument
3169 snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM); in cs46xx_enable_stream_irqs()
3171 tmp = snd_cs46xx_peek(chip, BA1_PFIE); in cs46xx_enable_stream_irqs()
3173 snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */ in cs46xx_enable_stream_irqs()
3175 tmp = snd_cs46xx_peek(chip, BA1_CIE); in cs46xx_enable_stream_irqs()
3178 snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */ in cs46xx_enable_stream_irqs()
3181 int snd_cs46xx_start_dsp(struct snd_cs46xx *chip) in snd_cs46xx_start_dsp() argument
3192 snd_cs46xx_reset(chip); in snd_cs46xx_start_dsp()
3194 * Download the image to the processor. in snd_cs46xx_start_dsp()
3198 err = load_firmware(chip, &chip->modules[i], module_names[i]); in snd_cs46xx_start_dsp()
3200 dev_err(chip->card->dev, "firmware load error [%s]\n", in snd_cs46xx_start_dsp()
3204 err = cs46xx_dsp_load_module(chip, chip->modules[i]); in snd_cs46xx_start_dsp()
3206 dev_err(chip->card->dev, "image download error [%s]\n", in snd_cs46xx_start_dsp()
3212 if (cs46xx_dsp_scb_and_task_init(chip) < 0) in snd_cs46xx_start_dsp()
3213 return -EIO; in snd_cs46xx_start_dsp()
3215 err = load_firmware(chip); in snd_cs46xx_start_dsp()
3220 err = snd_cs46xx_download_image(chip); in snd_cs46xx_start_dsp()
3222 dev_err(chip->card->dev, "image download error\n"); in snd_cs46xx_start_dsp()
3229 tmp = snd_cs46xx_peek(chip, BA1_PCTL); in snd_cs46xx_start_dsp()
3230 chip->play_ctl = tmp & 0xffff0000; in snd_cs46xx_start_dsp()
3231 snd_cs46xx_poke(chip, BA1_PCTL, tmp & 0x0000ffff); in snd_cs46xx_start_dsp()
3237 tmp = snd_cs46xx_peek(chip, BA1_CCTL); in snd_cs46xx_start_dsp()
3238 chip->capt.ctl = tmp & 0x0000ffff; in snd_cs46xx_start_dsp()
3239 snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000); in snd_cs46xx_start_dsp()
3243 snd_cs46xx_set_play_sample_rate(chip, 8000); in snd_cs46xx_start_dsp()
3244 snd_cs46xx_set_capture_sample_rate(chip, 8000); in snd_cs46xx_start_dsp()
3246 snd_cs46xx_proc_start(chip); in snd_cs46xx_start_dsp()
3248 cs46xx_enable_stream_irqs(chip); in snd_cs46xx_start_dsp()
3251 /* set the attenuation to 0dB */ in snd_cs46xx_start_dsp()
3252 snd_cs46xx_poke(chip, BA1_PVOL, 0x80008000); in snd_cs46xx_start_dsp()
3253 snd_cs46xx_poke(chip, BA1_CVOL, 0x80008000); in snd_cs46xx_start_dsp()
3261 * AMP control - null AMP
3264 static void amp_none(struct snd_cs46xx *chip, int change) in amp_none() argument
3269 static int voyetra_setup_eapd_slot(struct snd_cs46xx *chip) in voyetra_setup_eapd_slot() argument
3275 dev_dbg(chip->card->dev, "cs46xx_setup_eapd_slot()+\n"); in voyetra_setup_eapd_slot()
3281 tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1); in voyetra_setup_eapd_slot()
3284 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp | CLKCR1_SWCE); in voyetra_setup_eapd_slot()
3289 * Clear PRA. The Bonzo chip will be used for GPIO not for modem in voyetra_setup_eapd_slot()
3292 if(chip->nr_ac97_codecs != 2) { in voyetra_setup_eapd_slot()
3293 dev_err(chip->card->dev, in voyetra_setup_eapd_slot()
3294 "cs46xx_setup_eapd_slot() - no secondary codec configured\n"); in voyetra_setup_eapd_slot()
3295 return -EINVAL; in voyetra_setup_eapd_slot()
3298 modem_power = snd_cs46xx_codec_read (chip, in voyetra_setup_eapd_slot()
3303 snd_cs46xx_codec_write(chip, in voyetra_setup_eapd_slot()
3310 pin_config = snd_cs46xx_codec_read (chip, in voyetra_setup_eapd_slot()
3315 snd_cs46xx_codec_write(chip, in voyetra_setup_eapd_slot()
3323 logic_type = snd_cs46xx_codec_read(chip, AC97_GPIO_POLARITY, in voyetra_setup_eapd_slot()
3327 snd_cs46xx_codec_write (chip, AC97_GPIO_POLARITY, logic_type, in voyetra_setup_eapd_slot()
3330 valid_slots = snd_cs46xx_peekBA0(chip, BA0_ACOSV); in voyetra_setup_eapd_slot()
3332 snd_cs46xx_pokeBA0(chip, BA0_ACOSV, valid_slots); in voyetra_setup_eapd_slot()
3334 if ( cs46xx_wait_for_fifo(chip,1) ) { in voyetra_setup_eapd_slot()
3335 dev_dbg(chip->card->dev, "FIFO is busy\n"); in voyetra_setup_eapd_slot()
3337 return -EINVAL; in voyetra_setup_eapd_slot()
3347 * Remember that the GPIO pins in bonzo are shifted by 4 bits to in voyetra_setup_eapd_slot()
3348 * the left. 0x1800 corresponds to bits 7 and 8. in voyetra_setup_eapd_slot()
3350 snd_cs46xx_pokeBA0(chip, BA0_SERBWP, 0x1800); in voyetra_setup_eapd_slot()
3353 * Wait for command to complete in voyetra_setup_eapd_slot()
3355 if ( cs46xx_wait_for_fifo(chip,200) ) { in voyetra_setup_eapd_slot()
3356 dev_dbg(chip->card->dev, in voyetra_setup_eapd_slot()
3360 return -EINVAL; in voyetra_setup_eapd_slot()
3366 snd_cs46xx_pokeBA0(chip, BA0_SERBAD, idx); in voyetra_setup_eapd_slot()
3369 * Tell the serial port to load the new value into the FIFO location. in voyetra_setup_eapd_slot()
3371 snd_cs46xx_pokeBA0(chip, BA0_SERBCM, SERBCM_WRC); in voyetra_setup_eapd_slot()
3374 /* wait for last command to complete */ in voyetra_setup_eapd_slot()
3375 cs46xx_wait_for_fifo(chip,200); in voyetra_setup_eapd_slot()
3382 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); in voyetra_setup_eapd_slot()
3392 static void amp_voyetra(struct snd_cs46xx *chip, int change) in amp_voyetra() argument
3398 int old = chip->amplifier; in amp_voyetra()
3402 chip->amplifier += change; in amp_voyetra()
3403 oval = snd_cs46xx_codec_read(chip, AC97_POWERDOWN, in amp_voyetra()
3406 if (chip->amplifier) { in amp_voyetra()
3414 snd_cs46xx_codec_write(chip, AC97_POWERDOWN, val, in amp_voyetra()
3416 if (chip->eapd_switch) in amp_voyetra()
3417 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, in amp_voyetra()
3418 &chip->eapd_switch->id); in amp_voyetra()
3422 if (chip->amplifier && !old) { in amp_voyetra()
3423 voyetra_setup_eapd_slot(chip); in amp_voyetra()
3428 static void hercules_init(struct snd_cs46xx *chip) in hercules_init() argument
3431 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0); in hercules_init()
3432 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0); in hercules_init()
3437 * Game Theatre XP card - EGPIO[2] is used to enable the external amp.
3439 static void amp_hercules(struct snd_cs46xx *chip, int change) in amp_hercules() argument
3441 int old = chip->amplifier; in amp_hercules()
3442 int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR); in amp_hercules()
3443 int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR); in amp_hercules()
3445 chip->amplifier += change; in amp_hercules()
3446 if (chip->amplifier && !old) { in amp_hercules()
3447 dev_dbg(chip->card->dev, "Hercules amplifier ON\n"); in amp_hercules()
3449 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, in amp_hercules()
3451 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, in amp_hercules()
3452 EGPIOPTR_GPPT2 | val2); /* open-drain on output */ in amp_hercules()
3453 } else if (old && !chip->amplifier) { in amp_hercules()
3454 dev_dbg(chip->card->dev, "Hercules amplifier OFF\n"); in amp_hercules()
3455 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, val1 & ~EGPIODR_GPOE2); /* disable */ in amp_hercules()
3456 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT2); /* disable */ in amp_hercules()
3460 static void voyetra_mixer_init (struct snd_cs46xx *chip) in voyetra_mixer_init() argument
3462 dev_dbg(chip->card->dev, "initializing Voyetra mixer\n"); in voyetra_mixer_init()
3465 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0); in voyetra_mixer_init()
3466 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0); in voyetra_mixer_init()
3469 static void hercules_mixer_init (struct snd_cs46xx *chip) in hercules_mixer_init() argument
3474 struct snd_card *card = chip->card; in hercules_mixer_init()
3477 /* set EGPIO to default */ in hercules_mixer_init()
3478 hercules_init(chip); in hercules_mixer_init()
3480 dev_dbg(chip->card->dev, "initializing Hercules mixer\n"); in hercules_mixer_init()
3483 if (chip->in_suspend) in hercules_mixer_init()
3489 kctl = snd_ctl_new1(&snd_hercules_controls[idx], chip); in hercules_mixer_init()
3492 dev_err(card->dev, in hercules_mixer_init()
3493 "failed to initialize Hercules mixer (%d)\n", in hercules_mixer_init()
3507 static void amp_voyetra_4294(struct snd_cs46xx *chip, int change)
3509 chip->amplifier += change;
3511 if (chip->amplifier) {
3512 /* Switch the GPIO pins 7 and 8 to open drain */
3513 snd_cs46xx_codec_write(chip, 0x4C,
3514 snd_cs46xx_codec_read(chip, 0x4C) & 0xFE7F);
3515 snd_cs46xx_codec_write(chip, 0x4E,
3516 snd_cs46xx_codec_read(chip, 0x4E) | 0x0180);
3518 snd_cs46xx_codec_write(chip, 0x54,
3519 snd_cs46xx_codec_read(chip, 0x54) & ~0x0180);
3521 snd_cs46xx_codec_write(chip, 0x54,
3522 snd_cs46xx_codec_read(chip, 0x54) | 0x0180);
3530 * whenever we need to beat on the chip.
3534 * enough to make them useful.
3537 static void clkrun_hack(struct snd_cs46xx *chip, int change) in clkrun_hack() argument
3541 if (!chip->acpi_port) in clkrun_hack()
3544 chip->amplifier += change; in clkrun_hack()
3547 nval = control = inw(chip->acpi_port + 0x10); in clkrun_hack()
3550 if (! chip->amplifier) in clkrun_hack()
3555 outw(nval, chip->acpi_port + 0x10); in clkrun_hack()
3562 static void clkrun_init(struct snd_cs46xx *chip) in clkrun_init() argument
3567 chip->acpi_port = 0; in clkrun_init()
3576 chip->acpi_port = pp << 8; in clkrun_init()
3721 struct snd_cs46xx *chip = card->private_data; in snd_cs46xx_suspend() local
3725 chip->in_suspend = 1; in snd_cs46xx_suspend()
3726 // chip->ac97_powerdown = snd_cs46xx_codec_read(chip, AC97_POWER_CONTROL); in snd_cs46xx_suspend()
3727 // chip->ac97_general_purpose = snd_cs46xx_codec_read(chip, BA0_AC97_GENERAL_PURPOSE); in snd_cs46xx_suspend()
3729 snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); in snd_cs46xx_suspend()
3730 snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); in snd_cs46xx_suspend()
3734 chip->saved_regs[i] = snd_cs46xx_peekBA0(chip, saved_regs[i]); in snd_cs46xx_suspend()
3736 amp_saved = chip->amplifier; in snd_cs46xx_suspend()
3738 chip->amplifier_ctrl(chip, -chip->amplifier); in snd_cs46xx_suspend()
3739 snd_cs46xx_hw_stop(chip); in snd_cs46xx_suspend()
3741 chip->active_ctrl(chip, -chip->amplifier); in snd_cs46xx_suspend()
3742 chip->amplifier = amp_saved; /* restore the status */ in snd_cs46xx_suspend()
3749 struct snd_cs46xx *chip = card->private_data; in snd_cs46xx_resume() local
3756 amp_saved = chip->amplifier; in snd_cs46xx_resume()
3757 chip->amplifier = 0; in snd_cs46xx_resume()
3758 chip->active_ctrl(chip, 1); /* force to on */ in snd_cs46xx_resume()
3760 snd_cs46xx_chip_init(chip); in snd_cs46xx_resume()
3762 snd_cs46xx_reset(chip); in snd_cs46xx_resume()
3764 cs46xx_dsp_resume(chip); in snd_cs46xx_resume()
3767 snd_cs46xx_pokeBA0(chip, saved_regs[i], chip->saved_regs[i]); in snd_cs46xx_resume()
3769 snd_cs46xx_download_image(chip); in snd_cs46xx_resume()
3773 snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE, in snd_cs46xx_resume()
3774 chip->ac97_general_purpose); in snd_cs46xx_resume()
3775 snd_cs46xx_codec_write(chip, AC97_POWER_CONTROL, in snd_cs46xx_resume()
3776 chip->ac97_powerdown); in snd_cs46xx_resume()
3778 snd_cs46xx_codec_write(chip, BA0_AC97_POWERDOWN, in snd_cs46xx_resume()
3779 chip->ac97_powerdown); in snd_cs46xx_resume()
3783 snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); in snd_cs46xx_resume()
3784 snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); in snd_cs46xx_resume()
3789 tmp = snd_cs46xx_peek(chip, BA1_CCTL); in snd_cs46xx_resume()
3790 chip->capt.ctl = tmp & 0x0000ffff; in snd_cs46xx_resume()
3791 snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000); in snd_cs46xx_resume()
3796 snd_cs46xx_set_play_sample_rate(chip, 8000); in snd_cs46xx_resume()
3797 snd_cs46xx_set_capture_sample_rate(chip, 8000); in snd_cs46xx_resume()
3798 snd_cs46xx_proc_start(chip); in snd_cs46xx_resume()
3800 cs46xx_enable_stream_irqs(chip); in snd_cs46xx_resume()
3803 chip->amplifier_ctrl(chip, 1); /* turn amp on */ in snd_cs46xx_resume()
3805 chip->active_ctrl(chip, -1); /* disable CLKRUN */ in snd_cs46xx_resume()
3806 chip->amplifier = amp_saved; in snd_cs46xx_resume()
3807 chip->in_suspend = 0; in snd_cs46xx_resume()
3823 struct snd_cs46xx *chip = card->private_data; in snd_cs46xx_create() local
3834 spin_lock_init(&chip->reg_lock); in snd_cs46xx_create()
3836 mutex_init(&chip->spos_mutex); in snd_cs46xx_create()
3838 chip->card = card; in snd_cs46xx_create()
3839 chip->pci = pci; in snd_cs46xx_create()
3840 chip->irq = -1; in snd_cs46xx_create()
3845 chip->ba0_addr = pci_resource_start(pci, 0); in snd_cs46xx_create()
3846 chip->ba1_addr = pci_resource_start(pci, 1); in snd_cs46xx_create()
3847 if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 || in snd_cs46xx_create()
3848 chip->ba1_addr == 0 || chip->ba1_addr == (unsigned long)~0) { in snd_cs46xx_create()
3849 dev_err(chip->card->dev, in snd_cs46xx_create()
3850 "wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n", in snd_cs46xx_create()
3851 chip->ba0_addr, chip->ba1_addr); in snd_cs46xx_create()
3852 return -ENOMEM; in snd_cs46xx_create()
3855 region = &chip->region.name.ba0; in snd_cs46xx_create()
3856 strcpy(region->name, "CS46xx_BA0"); in snd_cs46xx_create()
3857 region->base = chip->ba0_addr; in snd_cs46xx_create()
3858 region->size = CS46XX_BA0_SIZE; in snd_cs46xx_create()
3860 region = &chip->region.name.data0; in snd_cs46xx_create()
3861 strcpy(region->name, "CS46xx_BA1_data0"); in snd_cs46xx_create()
3862 region->base = chip->ba1_addr + BA1_SP_DMEM0; in snd_cs46xx_create()
3863 region->size = CS46XX_BA1_DATA0_SIZE; in snd_cs46xx_create()
3865 region = &chip->region.name.data1; in snd_cs46xx_create()
3866 strcpy(region->name, "CS46xx_BA1_data1"); in snd_cs46xx_create()
3867 region->base = chip->ba1_addr + BA1_SP_DMEM1; in snd_cs46xx_create()
3868 region->size = CS46XX_BA1_DATA1_SIZE; in snd_cs46xx_create()
3870 region = &chip->region.name.pmem; in snd_cs46xx_create()
3871 strcpy(region->name, "CS46xx_BA1_pmem"); in snd_cs46xx_create()
3872 region->base = chip->ba1_addr + BA1_SP_PMEM; in snd_cs46xx_create()
3873 region->size = CS46XX_BA1_PRG_SIZE; in snd_cs46xx_create()
3875 region = &chip->region.name.reg; in snd_cs46xx_create()
3876 strcpy(region->name, "CS46xx_BA1_reg"); in snd_cs46xx_create()
3877 region->base = chip->ba1_addr + BA1_SP_REG; in snd_cs46xx_create()
3878 region->size = CS46XX_BA1_REG_SIZE; in snd_cs46xx_create()
3884 for (cp = &cards[0]; cp->name; cp++) { in snd_cs46xx_create()
3885 if (cp->vendor == ss_vendor && cp->id == ss_card) { in snd_cs46xx_create()
3886 dev_dbg(chip->card->dev, "hack for %s enabled\n", in snd_cs46xx_create()
3887 cp->name); in snd_cs46xx_create()
3889 chip->amplifier_ctrl = cp->amp; in snd_cs46xx_create()
3890 chip->active_ctrl = cp->active; in snd_cs46xx_create()
3891 chip->mixer_init = cp->mixer_init; in snd_cs46xx_create()
3893 if (cp->init) in snd_cs46xx_create()
3894 cp->init(chip); in snd_cs46xx_create()
3900 dev_info(chip->card->dev, in snd_cs46xx_create()
3902 chip->amplifier_ctrl = amp_voyetra; in snd_cs46xx_create()
3906 dev_info(chip->card->dev, in snd_cs46xx_create()
3908 chip->active_ctrl = clkrun_hack; in snd_cs46xx_create()
3909 clkrun_init(chip); in snd_cs46xx_create()
3912 if (chip->amplifier_ctrl == NULL) in snd_cs46xx_create()
3913 chip->amplifier_ctrl = amp_none; in snd_cs46xx_create()
3914 if (chip->active_ctrl == NULL) in snd_cs46xx_create()
3915 chip->active_ctrl = amp_none; in snd_cs46xx_create()
3917 chip->active_ctrl(chip, 1); /* enable CLKRUN */ in snd_cs46xx_create()
3922 region = &chip->region.idx[idx]; in snd_cs46xx_create()
3923 region->remap_addr = devm_ioremap(&pci->dev, region->base, in snd_cs46xx_create()
3924 region->size); in snd_cs46xx_create()
3925 if (region->remap_addr == NULL) { in snd_cs46xx_create()
3926 dev_err(chip->card->dev, in snd_cs46xx_create()
3927 "%s ioremap problem\n", region->name); in snd_cs46xx_create()
3928 return -ENOMEM; in snd_cs46xx_create()
3932 if (devm_request_irq(&pci->dev, pci->irq, snd_cs46xx_interrupt, in snd_cs46xx_create()
3933 IRQF_SHARED, KBUILD_MODNAME, chip)) { in snd_cs46xx_create()
3934 dev_err(chip->card->dev, "unable to grab IRQ %d\n", pci->irq); in snd_cs46xx_create()
3935 return -EBUSY; in snd_cs46xx_create()
3937 chip->irq = pci->irq; in snd_cs46xx_create()
3938 card->sync_irq = chip->irq; in snd_cs46xx_create()
3939 card->private_free = snd_cs46xx_free; in snd_cs46xx_create()
3942 chip->dsp_spos_instance = cs46xx_dsp_spos_create(chip); in snd_cs46xx_create()
3943 if (!chip->dsp_spos_instance) in snd_cs46xx_create()
3944 return -ENOMEM; in snd_cs46xx_create()
3947 err = snd_cs46xx_chip_init(chip); in snd_cs46xx_create()
3951 snd_cs46xx_proc_init(card, chip); in snd_cs46xx_create()
3954 chip->saved_regs = devm_kmalloc_array(&pci->dev, in snd_cs46xx_create()
3956 sizeof(*chip->saved_regs), in snd_cs46xx_create()
3958 if (!chip->saved_regs) in snd_cs46xx_create()
3959 return -ENOMEM; in snd_cs46xx_create()
3962 chip->active_ctrl(chip, -1); /* disable CLKRUN */ in snd_cs46xx_create()