Lines Matching +full:chip +full:- +full:to +full:- +full:chip
3 * Abramo Bagnara <abramo@alsa-project.org>
8 * - Sometimes the SPDIF input DSP tasks get's unsynchronized
10 * are swapped. To get around this problem when it happens, mute and unmute
12 * - On the Hercules Game Theater XP the amplifier are sometimes turned
16 * - Secondary CODEC on some soundcards
17 * - SPDIF input support for other sample rates then 48khz
18 * - Posibility to mix the SPDIF output with analog sources.
19 * - PCM channels for Center and LFE on secondary codec
23 * multi channel PCM. But known to work.
25 * FINALLY: A credit to the developers Tom and Jordan
28 * references to be able to implement all fancy feutures
43 * along with this program; if not, write to the Free Software
44 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
71 static void amp_voyetra(struct snd_cs46xx *chip, int change);
87 static unsigned short snd_cs46xx_codec_read(struct snd_cs46xx *chip, in snd_cs46xx_codec_read() argument
97 return -EINVAL; in snd_cs46xx_codec_read()
99 chip->active_ctrl(chip, 1); in snd_cs46xx_codec_read()
106 * 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 in snd_cs46xx_codec_read()
107 * 3. Write ACCTL = Control Register = 460h for initiating the write7---55 in snd_cs46xx_codec_read()
113 snd_cs46xx_peekBA0(chip, BA0_ACSDA + offset); in snd_cs46xx_codec_read()
115 tmp = snd_cs46xx_peekBA0(chip, BA0_ACCTL); in snd_cs46xx_codec_read()
118 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, (tmp & (~ACCTL_ESYN)) | ACCTL_VFRM ); in snd_cs46xx_codec_read()
120 tmp = snd_cs46xx_peekBA0(chip, BA0_ACCTL + offset); in snd_cs46xx_codec_read()
121 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, tmp | ACCTL_ESYN | ACCTL_VFRM ); in snd_cs46xx_codec_read()
126 * Setup the AC97 control registers on the CS461x to send the in snd_cs46xx_codec_read()
127 * appropriate command to the AC97 to perform the read. in snd_cs46xx_codec_read()
131 * set DCV - will clear when process completed in snd_cs46xx_codec_read()
132 * set CRW - Read command in snd_cs46xx_codec_read()
133 * set VFRM - valid frame enabled in snd_cs46xx_codec_read()
134 * set ESYN - ASYNC generation enabled in snd_cs46xx_codec_read()
135 * set RSTN - ARST# inactive, AC97 codec not reset in snd_cs46xx_codec_read()
138 snd_cs46xx_pokeBA0(chip, BA0_ACCAD, reg); in snd_cs46xx_codec_read()
139 snd_cs46xx_pokeBA0(chip, BA0_ACCDA, 0); in snd_cs46xx_codec_read()
141 snd_cs46xx_pokeBA0(chip, BA0_ACCTL,/* clear ACCTL_DCV */ ACCTL_CRW | in snd_cs46xx_codec_read()
144 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_CRW | in snd_cs46xx_codec_read()
148 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_TC | in snd_cs46xx_codec_read()
154 * Wait for the read to occur. in snd_cs46xx_codec_read()
158 * First, we want to wait for a short time. in snd_cs46xx_codec_read()
162 * Now, check to see if the read has completed. in snd_cs46xx_codec_read()
165 if (!(snd_cs46xx_peekBA0(chip, BA0_ACCTL) & ACCTL_DCV)) in snd_cs46xx_codec_read()
175 * Wait for the valid status bit to go active. in snd_cs46xx_codec_read()
181 * VSTS - Valid Status in snd_cs46xx_codec_read()
183 if (snd_cs46xx_peekBA0(chip, BA0_ACSTS + offset) & ACSTS_VSTS) in snd_cs46xx_codec_read()
199 snd_cs46xx_peekBA0(chip, BA0_ACSDA), in snd_cs46xx_codec_read()
200 snd_cs46xx_peekBA0(chip, BA0_ACCAD)); in snd_cs46xx_codec_read()
203 //snd_cs46xx_peekBA0(chip, BA0_ACCAD); in snd_cs46xx_codec_read()
204 result = snd_cs46xx_peekBA0(chip, BA0_ACSDA + offset); in snd_cs46xx_codec_read()
206 chip->active_ctrl(chip, -1); in snd_cs46xx_codec_read()
213 struct snd_cs46xx *chip = ac97->private_data; in snd_cs46xx_ac97_read() local
215 int codec_index = ac97->num; in snd_cs46xx_ac97_read()
221 val = snd_cs46xx_codec_read(chip, reg, codec_index); in snd_cs46xx_ac97_read()
227 static void snd_cs46xx_codec_write(struct snd_cs46xx *chip, in snd_cs46xx_codec_write() argument
238 chip->active_ctrl(chip, 1); in snd_cs46xx_codec_write()
242 * 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 in snd_cs46xx_codec_write()
249 * Setup the AC97 control registers on the CS461x to send the in snd_cs46xx_codec_write()
250 * appropriate command to the AC97 to perform the read. in snd_cs46xx_codec_write()
254 * set DCV - will clear when process completed in snd_cs46xx_codec_write()
255 * reset CRW - Write command in snd_cs46xx_codec_write()
256 * set VFRM - valid frame enabled in snd_cs46xx_codec_write()
257 * set ESYN - ASYNC generation enabled in snd_cs46xx_codec_write()
258 * set RSTN - ARST# inactive, AC97 codec not reset in snd_cs46xx_codec_write()
260 snd_cs46xx_pokeBA0(chip, BA0_ACCAD , reg); in snd_cs46xx_codec_write()
261 snd_cs46xx_pokeBA0(chip, BA0_ACCDA , val); in snd_cs46xx_codec_write()
262 snd_cs46xx_peekBA0(chip, BA0_ACCTL); in snd_cs46xx_codec_write()
265 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, /* clear ACCTL_DCV */ ACCTL_VFRM | in snd_cs46xx_codec_write()
267 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_VFRM | in snd_cs46xx_codec_write()
270 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_TC | in snd_cs46xx_codec_write()
276 * First, we want to wait for a short time. in snd_cs46xx_codec_write()
280 * Now, check to see if the write has completed. in snd_cs46xx_codec_write()
283 if (!(snd_cs46xx_peekBA0(chip, BA0_ACCTL) & ACCTL_DCV)) { in snd_cs46xx_codec_write()
289 chip->active_ctrl(chip, -1); in snd_cs46xx_codec_write()
296 struct snd_cs46xx *chip = ac97->private_data; in snd_cs46xx_ac97_write() local
297 int codec_index = ac97->num; in snd_cs46xx_ac97_write()
303 snd_cs46xx_codec_write(chip, reg, val, codec_index); in snd_cs46xx_ac97_write()
308 * Chip initialization
311 int snd_cs46xx_download(struct snd_cs46xx *chip, in snd_cs46xx_download() argument
321 return -EINVAL; in snd_cs46xx_download()
322 dst = chip->region.idx[bank+1].remap_addr + offset; in snd_cs46xx_download()
325 /* writel already converts 32-bit value to right endianess */ in snd_cs46xx_download()
326 while (len-- > 0) { in snd_cs46xx_download()
341 int snd_cs46xx_clear_BA1(struct snd_cs46xx *chip, in snd_cs46xx_clear_BA1() argument
350 return -EINVAL; in snd_cs46xx_clear_BA1()
351 dst = chip->region.idx[bank+1].remap_addr + offset; in snd_cs46xx_clear_BA1()
354 /* writel already converts 32-bit value to right endianess */ in snd_cs46xx_clear_BA1()
355 while (len-- > 0) { in snd_cs46xx_clear_BA1()
366 int snd_cs46xx_download_image(struct snd_cs46xx *chip) in snd_cs46xx_download_image() argument
372 if ((err = snd_cs46xx_download(chip, in snd_cs46xx_download_image()
384 * Chip reset
387 static void snd_cs46xx_reset(struct snd_cs46xx *chip) in snd_cs46xx_reset() argument
394 snd_cs46xx_poke(chip, BA1_SPCR, SPCR_RSTSP); in snd_cs46xx_reset()
399 snd_cs46xx_poke(chip, BA1_SPCR, SPCR_DRQEN); in snd_cs46xx_reset()
405 snd_cs46xx_poke(chip, BA1_DREG, DREG_REGID_TRAP_SELECT + idx); in snd_cs46xx_reset()
406 snd_cs46xx_poke(chip, BA1_TWPR, 0xFFFF); in snd_cs46xx_reset()
408 snd_cs46xx_poke(chip, BA1_DREG, 0); in snd_cs46xx_reset()
411 * Set the frame timer to reflect the number of cycles per frame. in snd_cs46xx_reset()
413 snd_cs46xx_poke(chip, BA1_FRMT, 0xadf); in snd_cs46xx_reset()
416 static int cs46xx_wait_for_fifo(struct snd_cs46xx * chip,int retry_timeout) in cs46xx_wait_for_fifo() argument
423 status = snd_cs46xx_peekBA0(chip, BA0_SERBST); in cs46xx_wait_for_fifo()
433 "FIFO command to complete\n"); in cs46xx_wait_for_fifo()
434 return -EINVAL; in cs46xx_wait_for_fifo()
440 static void snd_cs46xx_clear_serial_FIFOs(struct snd_cs46xx *chip) in snd_cs46xx_clear_serial_FIFOs() argument
449 tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1); in snd_cs46xx_clear_serial_FIFOs()
451 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp | CLKCR1_SWCE); in snd_cs46xx_clear_serial_FIFOs()
456 * We want to clear out the serial port FIFOs so we don't end up playing in snd_cs46xx_clear_serial_FIFOs()
457 * whatever random garbage happens to be in them. We fill the sample FIFOS in snd_cs46xx_clear_serial_FIFOs()
460 snd_cs46xx_pokeBA0(chip, BA0_SERBWP, 0); in snd_cs46xx_clear_serial_FIFOs()
469 if (cs46xx_wait_for_fifo(chip,1)) { in snd_cs46xx_clear_serial_FIFOs()
473 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); in snd_cs46xx_clear_serial_FIFOs()
480 snd_cs46xx_pokeBA0(chip, BA0_SERBAD, idx); in snd_cs46xx_clear_serial_FIFOs()
482 * Tell the serial port to load the new value into the FIFO location. in snd_cs46xx_clear_serial_FIFOs()
484 snd_cs46xx_pokeBA0(chip, BA0_SERBCM, SERBCM_WRC); in snd_cs46xx_clear_serial_FIFOs()
491 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); in snd_cs46xx_clear_serial_FIFOs()
494 static void snd_cs46xx_proc_start(struct snd_cs46xx *chip) in snd_cs46xx_proc_start() argument
499 * Set the frame timer to reflect the number of cycles per frame. in snd_cs46xx_proc_start()
501 snd_cs46xx_poke(chip, BA1_FRMT, 0xadf); in snd_cs46xx_proc_start()
506 snd_cs46xx_poke(chip, BA1_SPCR, SPCR_RUN | SPCR_RUNFR | SPCR_DRQEN); in snd_cs46xx_proc_start()
513 if (!(snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR)) in snd_cs46xx_proc_start()
517 if (snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR) in snd_cs46xx_proc_start()
521 static void snd_cs46xx_proc_stop(struct snd_cs46xx *chip) in snd_cs46xx_proc_stop() argument
527 snd_cs46xx_poke(chip, BA1_SPCR, 0); in snd_cs46xx_proc_stop()
536 static void snd_cs46xx_set_play_sample_rate(struct snd_cs46xx *chip, unsigned int rate) in snd_cs46xx_set_play_sample_rate() argument
544 * Compute the values used to drive the actual sample rate conversion. in snd_cs46xx_set_play_sample_rate()
546 * since we need to use 64 bit arithmetic to compute the values: in snd_cs46xx_set_play_sample_rate()
549 * correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) / in snd_cs46xx_set_play_sample_rate()
551 * ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -M in snd_cs46xx_set_play_sample_rate()
562 tmp1 -= phiIncr * 48000; in snd_cs46xx_set_play_sample_rate()
567 tmp1 -= tmp2 * 48000; in snd_cs46xx_set_play_sample_rate()
569 tmp1 -= correctionPerGOF * GOF_PER_SEC; in snd_cs46xx_set_play_sample_rate()
575 spin_lock_irqsave(&chip->reg_lock, flags); in snd_cs46xx_set_play_sample_rate()
576 snd_cs46xx_poke(chip, BA1_PSRC, in snd_cs46xx_set_play_sample_rate()
578 snd_cs46xx_poke(chip, BA1_PPI, phiIncr); in snd_cs46xx_set_play_sample_rate()
579 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_cs46xx_set_play_sample_rate()
582 static void snd_cs46xx_set_capture_sample_rate(struct snd_cs46xx *chip, unsigned int rate) in snd_cs46xx_set_capture_sample_rate() argument
590 * We can only decimate by up to a factor of 1/9th the hardware rate. in snd_cs46xx_set_capture_sample_rate()
591 * Correct the value if an attempt is made to stray outside that limit. in snd_cs46xx_set_capture_sample_rate()
598 * Return an error if an attempt is made to stray outside that limit. in snd_cs46xx_set_capture_sample_rate()
604 * Compute the values used to drive the actual sample rate conversion. in snd_cs46xx_set_capture_sample_rate()
606 * since we need to use 64 bit arithmetic to compute the values: in snd_cs46xx_set_capture_sample_rate()
608 * coeffIncr = -floor((Fs,out * 2^23) / Fs,in) in snd_cs46xx_set_capture_sample_rate()
610 * correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) / in snd_cs46xx_set_capture_sample_rate()
612 * correctionPerSec = Fs,in * 2^26 - Fs,out * phiIncr - in snd_cs46xx_set_capture_sample_rate()
622 * initialDelay = dividend(((24 * Fs,in) + Fs,out - 1) / Fs,out) in snd_cs46xx_set_capture_sample_rate()
627 tmp1 -= coeffIncr * 48000; in snd_cs46xx_set_capture_sample_rate()
635 tmp1 -= phiIncr * rate; in snd_cs46xx_set_capture_sample_rate()
640 tmp1 -= tmp2 * rate; in snd_cs46xx_set_capture_sample_rate()
642 tmp1 -= correctionPerGOF * GOF_PER_SEC; in snd_cs46xx_set_capture_sample_rate()
644 initialDelay = ((48000 * 24) + rate - 1) / rate; in snd_cs46xx_set_capture_sample_rate()
649 spin_lock_irqsave(&chip->reg_lock, flags); in snd_cs46xx_set_capture_sample_rate()
650 snd_cs46xx_poke(chip, BA1_CSRC, in snd_cs46xx_set_capture_sample_rate()
652 snd_cs46xx_poke(chip, BA1_CCI, coeffIncr); in snd_cs46xx_set_capture_sample_rate()
653 snd_cs46xx_poke(chip, BA1_CD, in snd_cs46xx_set_capture_sample_rate()
655 snd_cs46xx_poke(chip, BA1_CPI, phiIncr); in snd_cs46xx_set_capture_sample_rate()
656 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_cs46xx_set_capture_sample_rate()
679 spin_lock_irqsave(&chip->reg_lock, flags); in snd_cs46xx_set_capture_sample_rate()
680 snd_cs46xx_poke(chip, BA1_CFG1, frameGroupLength); in snd_cs46xx_set_capture_sample_rate()
681 snd_cs46xx_poke(chip, BA1_CFG2, (0x00800000 | frameGroupLength)); in snd_cs46xx_set_capture_sample_rate()
682 snd_cs46xx_poke(chip, BA1_CCST, 0x0000FFFF); in snd_cs46xx_set_capture_sample_rate()
683 snd_cs46xx_poke(chip, BA1_CSPB, ((65536 * rate) / 24000)); in snd_cs46xx_set_capture_sample_rate()
684 snd_cs46xx_poke(chip, (BA1_CSPB + 4), 0x0000FFFF); in snd_cs46xx_set_capture_sample_rate()
685 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_cs46xx_set_capture_sample_rate()
695 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_pb_trans_copy()
696 struct snd_cs46xx_pcm * cpcm = runtime->private_data; in snd_cs46xx_pb_trans_copy()
697 memcpy(cpcm->hw_buf.area + rec->hw_data, runtime->dma_area + rec->sw_data, bytes); in snd_cs46xx_pb_trans_copy()
702 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_playback_transfer()
703 struct snd_cs46xx_pcm * cpcm = runtime->private_data; in snd_cs46xx_playback_transfer()
704 snd_pcm_indirect_playback_transfer(substream, &cpcm->pcm_rec, snd_cs46xx_pb_trans_copy); in snd_cs46xx_playback_transfer()
711 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_cp_trans_copy() local
712 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_cp_trans_copy()
713 memcpy(runtime->dma_area + rec->sw_data, in snd_cs46xx_cp_trans_copy()
714 chip->capt.hw_buf.area + rec->hw_data, bytes); in snd_cs46xx_cp_trans_copy()
719 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_capture_transfer() local
720 snd_pcm_indirect_capture_transfer(substream, &chip->capt.pcm_rec, snd_cs46xx_cp_trans_copy); in snd_cs46xx_capture_transfer()
726 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_playback_direct_pointer() local
728 struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data; in snd_cs46xx_playback_direct_pointer()
730 if (snd_BUG_ON(!cpcm->pcm_channel)) in snd_cs46xx_playback_direct_pointer()
731 return -ENXIO; in snd_cs46xx_playback_direct_pointer()
734 ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2); in snd_cs46xx_playback_direct_pointer()
736 ptr = snd_cs46xx_peek(chip, BA1_PBA); in snd_cs46xx_playback_direct_pointer()
738 ptr -= cpcm->hw_buf.addr; in snd_cs46xx_playback_direct_pointer()
739 return ptr >> cpcm->shift; in snd_cs46xx_playback_direct_pointer()
744 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_playback_indirect_pointer() local
746 struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data; in snd_cs46xx_playback_indirect_pointer()
749 if (snd_BUG_ON(!cpcm->pcm_channel)) in snd_cs46xx_playback_indirect_pointer()
750 return -ENXIO; in snd_cs46xx_playback_indirect_pointer()
751 ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2); in snd_cs46xx_playback_indirect_pointer()
753 ptr = snd_cs46xx_peek(chip, BA1_PBA); in snd_cs46xx_playback_indirect_pointer()
755 ptr -= cpcm->hw_buf.addr; in snd_cs46xx_playback_indirect_pointer()
756 return snd_pcm_indirect_playback_pointer(substream, &cpcm->pcm_rec, ptr); in snd_cs46xx_playback_indirect_pointer()
761 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_capture_direct_pointer() local
762 size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_buf.addr; in snd_cs46xx_capture_direct_pointer()
763 return ptr >> chip->capt.shift; in snd_cs46xx_capture_direct_pointer()
768 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_capture_indirect_pointer() local
769 size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_buf.addr; in snd_cs46xx_capture_indirect_pointer()
770 return snd_pcm_indirect_capture_pointer(substream, &chip->capt.pcm_rec, ptr); in snd_cs46xx_capture_indirect_pointer()
776 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_playback_trigger() local
777 /*struct snd_pcm_runtime *runtime = substream->runtime;*/ in snd_cs46xx_playback_trigger()
781 struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data; in snd_cs46xx_playback_trigger()
782 if (! cpcm->pcm_channel) { in snd_cs46xx_playback_trigger()
783 return -ENXIO; in snd_cs46xx_playback_trigger()
790 /* magic value to unmute PCM stream playback volume */ in snd_cs46xx_playback_trigger()
791 snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + in snd_cs46xx_playback_trigger()
794 if (cpcm->pcm_channel->unlinked) in snd_cs46xx_playback_trigger()
795 cs46xx_dsp_pcm_link(chip,cpcm->pcm_channel); in snd_cs46xx_playback_trigger()
797 if (substream->runtime->periods != CS46XX_FRAGS) in snd_cs46xx_playback_trigger()
800 spin_lock(&chip->reg_lock); in snd_cs46xx_playback_trigger()
801 if (substream->runtime->periods != CS46XX_FRAGS) in snd_cs46xx_playback_trigger()
804 tmp = snd_cs46xx_peek(chip, BA1_PCTL); in snd_cs46xx_playback_trigger()
806 snd_cs46xx_poke(chip, BA1_PCTL, chip->play_ctl | tmp); in snd_cs46xx_playback_trigger()
808 spin_unlock(&chip->reg_lock); in snd_cs46xx_playback_trigger()
815 snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + in snd_cs46xx_playback_trigger()
818 if (!cpcm->pcm_channel->unlinked) in snd_cs46xx_playback_trigger()
819 cs46xx_dsp_pcm_unlink(chip,cpcm->pcm_channel); in snd_cs46xx_playback_trigger()
821 spin_lock(&chip->reg_lock); in snd_cs46xx_playback_trigger()
823 tmp = snd_cs46xx_peek(chip, BA1_PCTL); in snd_cs46xx_playback_trigger()
825 snd_cs46xx_poke(chip, BA1_PCTL, tmp); in snd_cs46xx_playback_trigger()
827 spin_unlock(&chip->reg_lock); in snd_cs46xx_playback_trigger()
831 result = -EINVAL; in snd_cs46xx_playback_trigger()
841 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_capture_trigger() local
845 spin_lock(&chip->reg_lock); in snd_cs46xx_capture_trigger()
849 tmp = snd_cs46xx_peek(chip, BA1_CCTL); in snd_cs46xx_capture_trigger()
851 snd_cs46xx_poke(chip, BA1_CCTL, chip->capt.ctl | tmp); in snd_cs46xx_capture_trigger()
855 tmp = snd_cs46xx_peek(chip, BA1_CCTL); in snd_cs46xx_capture_trigger()
857 snd_cs46xx_poke(chip, BA1_CCTL, tmp); in snd_cs46xx_capture_trigger()
860 result = -EINVAL; in snd_cs46xx_capture_trigger()
863 spin_unlock(&chip->reg_lock); in snd_cs46xx_capture_trigger()
869 static int _cs46xx_adjust_sample_rate (struct snd_cs46xx *chip, struct snd_cs46xx_pcm *cpcm, in _cs46xx_adjust_sample_rate() argument
874 if ( cpcm->pcm_channel == NULL) { in _cs46xx_adjust_sample_rate()
875 cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip, sample_rate, in _cs46xx_adjust_sample_rate()
876 cpcm, cpcm->hw_buf.addr,cpcm->pcm_channel_id); in _cs46xx_adjust_sample_rate()
877 if (cpcm->pcm_channel == NULL) { in _cs46xx_adjust_sample_rate()
878 snd_printk(KERN_ERR "cs46xx: failed to create virtual PCM channel\n"); in _cs46xx_adjust_sample_rate()
879 return -ENOMEM; in _cs46xx_adjust_sample_rate()
881 cpcm->pcm_channel->sample_rate = sample_rate; in _cs46xx_adjust_sample_rate()
884 if ((int)cpcm->pcm_channel->sample_rate != sample_rate) { in _cs46xx_adjust_sample_rate()
885 int unlinked = cpcm->pcm_channel->unlinked; in _cs46xx_adjust_sample_rate()
886 cs46xx_dsp_destroy_pcm_channel (chip,cpcm->pcm_channel); in _cs46xx_adjust_sample_rate()
888 if ( (cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip, sample_rate, cpcm, in _cs46xx_adjust_sample_rate()
889 cpcm->hw_buf.addr, in _cs46xx_adjust_sample_rate()
890 cpcm->pcm_channel_id)) == NULL) { in _cs46xx_adjust_sample_rate()
891 snd_printk(KERN_ERR "cs46xx: failed to re-create virtual PCM channel\n"); in _cs46xx_adjust_sample_rate()
892 return -ENOMEM; in _cs46xx_adjust_sample_rate()
895 if (!unlinked) cs46xx_dsp_pcm_link (chip,cpcm->pcm_channel); in _cs46xx_adjust_sample_rate()
896 cpcm->pcm_channel->sample_rate = sample_rate; in _cs46xx_adjust_sample_rate()
907 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_playback_hw_params()
911 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_playback_hw_params() local
915 cpcm = runtime->private_data; in snd_cs46xx_playback_hw_params()
919 return -ENXIO; in snd_cs46xx_playback_hw_params()
921 mutex_lock(&chip->spos_mutex); in snd_cs46xx_playback_hw_params()
923 if (_cs46xx_adjust_sample_rate (chip,cpcm,sample_rate)) { in snd_cs46xx_playback_hw_params()
924 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_hw_params()
925 return -ENXIO; in snd_cs46xx_playback_hw_params()
928 snd_BUG_ON(!cpcm->pcm_channel); in snd_cs46xx_playback_hw_params()
929 if (!cpcm->pcm_channel) { in snd_cs46xx_playback_hw_params()
930 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_hw_params()
931 return -ENXIO; in snd_cs46xx_playback_hw_params()
935 if (cs46xx_dsp_pcm_channel_set_period (chip,cpcm->pcm_channel,period_size)) { in snd_cs46xx_playback_hw_params()
936 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_hw_params()
937 return -EINVAL; in snd_cs46xx_playback_hw_params()
946 if (runtime->dma_area != cpcm->hw_buf.area) in snd_cs46xx_playback_hw_params()
948 runtime->dma_area = cpcm->hw_buf.area; in snd_cs46xx_playback_hw_params()
949 runtime->dma_addr = cpcm->hw_buf.addr; in snd_cs46xx_playback_hw_params()
950 runtime->dma_bytes = cpcm->hw_buf.bytes; in snd_cs46xx_playback_hw_params()
954 if (cpcm->pcm_channel_id == DSP_PCM_MAIN_CHANNEL) { in snd_cs46xx_playback_hw_params()
955 substream->ops = &snd_cs46xx_playback_ops; in snd_cs46xx_playback_hw_params()
956 } else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) { in snd_cs46xx_playback_hw_params()
957 substream->ops = &snd_cs46xx_playback_rear_ops; in snd_cs46xx_playback_hw_params()
958 } else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) { in snd_cs46xx_playback_hw_params()
959 substream->ops = &snd_cs46xx_playback_clfe_ops; in snd_cs46xx_playback_hw_params()
960 } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) { in snd_cs46xx_playback_hw_params()
961 substream->ops = &snd_cs46xx_playback_iec958_ops; in snd_cs46xx_playback_hw_params()
966 substream->ops = &snd_cs46xx_playback_ops; in snd_cs46xx_playback_hw_params()
970 if (runtime->dma_area == cpcm->hw_buf.area) { in snd_cs46xx_playback_hw_params()
971 runtime->dma_area = NULL; in snd_cs46xx_playback_hw_params()
972 runtime->dma_addr = 0; in snd_cs46xx_playback_hw_params()
973 runtime->dma_bytes = 0; in snd_cs46xx_playback_hw_params()
977 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_hw_params()
983 if (cpcm->pcm_channel_id == DSP_PCM_MAIN_CHANNEL) { in snd_cs46xx_playback_hw_params()
984 substream->ops = &snd_cs46xx_playback_indirect_ops; in snd_cs46xx_playback_hw_params()
985 } else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) { in snd_cs46xx_playback_hw_params()
986 substream->ops = &snd_cs46xx_playback_indirect_rear_ops; in snd_cs46xx_playback_hw_params()
987 } else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) { in snd_cs46xx_playback_hw_params()
988 substream->ops = &snd_cs46xx_playback_indirect_clfe_ops; in snd_cs46xx_playback_hw_params()
989 } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) { in snd_cs46xx_playback_hw_params()
990 substream->ops = &snd_cs46xx_playback_indirect_iec958_ops; in snd_cs46xx_playback_hw_params()
995 substream->ops = &snd_cs46xx_playback_indirect_ops; in snd_cs46xx_playback_hw_params()
1001 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_hw_params()
1009 /*struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);*/ in snd_cs46xx_playback_hw_free()
1010 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_playback_hw_free()
1013 cpcm = runtime->private_data; in snd_cs46xx_playback_hw_free()
1017 if (!cpcm) return -ENXIO; in snd_cs46xx_playback_hw_free()
1019 if (runtime->dma_area != cpcm->hw_buf.area) in snd_cs46xx_playback_hw_free()
1022 runtime->dma_area = NULL; in snd_cs46xx_playback_hw_free()
1023 runtime->dma_addr = 0; in snd_cs46xx_playback_hw_free()
1024 runtime->dma_bytes = 0; in snd_cs46xx_playback_hw_free()
1033 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_playback_prepare() local
1034 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_playback_prepare()
1037 cpcm = runtime->private_data; in snd_cs46xx_playback_prepare()
1040 if (snd_BUG_ON(!cpcm->pcm_channel)) in snd_cs46xx_playback_prepare()
1041 return -ENXIO; in snd_cs46xx_playback_prepare()
1043 pfie = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2 ); in snd_cs46xx_playback_prepare()
1047 pfie = snd_cs46xx_peek(chip, BA1_PFIE); in snd_cs46xx_playback_prepare()
1051 cpcm->shift = 2; in snd_cs46xx_playback_prepare()
1052 /* if to convert from stereo to mono */ in snd_cs46xx_playback_prepare()
1053 if (runtime->channels == 1) { in snd_cs46xx_playback_prepare()
1054 cpcm->shift--; in snd_cs46xx_playback_prepare()
1057 /* if to convert from 8 bit to 16 bit */ in snd_cs46xx_playback_prepare()
1058 if (snd_pcm_format_width(runtime->format) == 8) { in snd_cs46xx_playback_prepare()
1059 cpcm->shift--; in snd_cs46xx_playback_prepare()
1062 /* if to convert to unsigned */ in snd_cs46xx_playback_prepare()
1063 if (snd_pcm_format_unsigned(runtime->format)) in snd_cs46xx_playback_prepare()
1067 if (snd_pcm_format_width(runtime->format) != 8) { in snd_cs46xx_playback_prepare()
1068 /* convert from big endian to little endian */ in snd_cs46xx_playback_prepare()
1069 if (snd_pcm_format_big_endian(runtime->format)) in snd_cs46xx_playback_prepare()
1073 memset(&cpcm->pcm_rec, 0, sizeof(cpcm->pcm_rec)); in snd_cs46xx_playback_prepare()
1074 cpcm->pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); in snd_cs46xx_playback_prepare()
1075 cpcm->pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << cpcm->shift; in snd_cs46xx_playback_prepare()
1079 tmp = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address) << 2); in snd_cs46xx_playback_prepare()
1081 tmp |= (4 << cpcm->shift) - 1; in snd_cs46xx_playback_prepare()
1083 snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address) << 2, tmp); in snd_cs46xx_playback_prepare()
1086 …snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2, pfie | cpcm->pcm_chan… in snd_cs46xx_playback_prepare()
1088 snd_cs46xx_poke(chip, BA1_PBA, cpcm->hw_buf.addr); in snd_cs46xx_playback_prepare()
1089 tmp = snd_cs46xx_peek(chip, BA1_PDTC); in snd_cs46xx_playback_prepare()
1091 tmp |= (4 << cpcm->shift) - 1; in snd_cs46xx_playback_prepare()
1092 snd_cs46xx_poke(chip, BA1_PDTC, tmp); in snd_cs46xx_playback_prepare()
1093 snd_cs46xx_poke(chip, BA1_PFIE, pfie); in snd_cs46xx_playback_prepare()
1094 snd_cs46xx_set_play_sample_rate(chip, runtime->rate); in snd_cs46xx_playback_prepare()
1103 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_capture_hw_params() local
1104 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_capture_hw_params()
1108 cs46xx_dsp_pcm_ostream_set_period (chip, params_period_bytes(hw_params)); in snd_cs46xx_capture_hw_params()
1110 if (runtime->periods == CS46XX_FRAGS) { in snd_cs46xx_capture_hw_params()
1111 if (runtime->dma_area != chip->capt.hw_buf.area) in snd_cs46xx_capture_hw_params()
1113 runtime->dma_area = chip->capt.hw_buf.area; in snd_cs46xx_capture_hw_params()
1114 runtime->dma_addr = chip->capt.hw_buf.addr; in snd_cs46xx_capture_hw_params()
1115 runtime->dma_bytes = chip->capt.hw_buf.bytes; in snd_cs46xx_capture_hw_params()
1116 substream->ops = &snd_cs46xx_capture_ops; in snd_cs46xx_capture_hw_params()
1118 if (runtime->dma_area == chip->capt.hw_buf.area) { in snd_cs46xx_capture_hw_params()
1119 runtime->dma_area = NULL; in snd_cs46xx_capture_hw_params()
1120 runtime->dma_addr = 0; in snd_cs46xx_capture_hw_params()
1121 runtime->dma_bytes = 0; in snd_cs46xx_capture_hw_params()
1125 substream->ops = &snd_cs46xx_capture_indirect_ops; in snd_cs46xx_capture_hw_params()
1133 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_capture_hw_free() local
1134 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_capture_hw_free()
1136 if (runtime->dma_area != chip->capt.hw_buf.area) in snd_cs46xx_capture_hw_free()
1138 runtime->dma_area = NULL; in snd_cs46xx_capture_hw_free()
1139 runtime->dma_addr = 0; in snd_cs46xx_capture_hw_free()
1140 runtime->dma_bytes = 0; in snd_cs46xx_capture_hw_free()
1147 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_capture_prepare() local
1148 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_capture_prepare()
1150 snd_cs46xx_poke(chip, BA1_CBA, chip->capt.hw_buf.addr); in snd_cs46xx_capture_prepare()
1151 chip->capt.shift = 2; in snd_cs46xx_capture_prepare()
1152 memset(&chip->capt.pcm_rec, 0, sizeof(chip->capt.pcm_rec)); in snd_cs46xx_capture_prepare()
1153 chip->capt.pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); in snd_cs46xx_capture_prepare()
1154 chip->capt.pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << 2; in snd_cs46xx_capture_prepare()
1155 snd_cs46xx_set_capture_sample_rate(chip, runtime->rate); in snd_cs46xx_capture_prepare()
1162 struct snd_cs46xx *chip = dev_id; in snd_cs46xx_interrupt() local
1165 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_interrupt()
1172 * Read the Interrupt Status Register to clear the interrupt in snd_cs46xx_interrupt()
1174 status1 = snd_cs46xx_peekBA0(chip, BA0_HISR); in snd_cs46xx_interrupt()
1176 snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_CHGM | HICR_IEV); in snd_cs46xx_interrupt()
1181 status2 = snd_cs46xx_peekBA0(chip, BA0_HSR0); in snd_cs46xx_interrupt()
1187 if (chip->capt.substream) in snd_cs46xx_interrupt()
1188 snd_pcm_period_elapsed(chip->capt.substream); in snd_cs46xx_interrupt()
1190 if (ins->pcm_channels[i].active && in snd_cs46xx_interrupt()
1191 ins->pcm_channels[i].private_data && in snd_cs46xx_interrupt()
1192 !ins->pcm_channels[i].unlinked) { in snd_cs46xx_interrupt()
1193 cpcm = ins->pcm_channels[i].private_data; in snd_cs46xx_interrupt()
1194 snd_pcm_period_elapsed(cpcm->substream); in snd_cs46xx_interrupt()
1199 if ( status2 & (1 << (i - 16))) { in snd_cs46xx_interrupt()
1200 if (ins->pcm_channels[i].active && in snd_cs46xx_interrupt()
1201 ins->pcm_channels[i].private_data && in snd_cs46xx_interrupt()
1202 !ins->pcm_channels[i].unlinked) { in snd_cs46xx_interrupt()
1203 cpcm = ins->pcm_channels[i].private_data; in snd_cs46xx_interrupt()
1204 snd_pcm_period_elapsed(cpcm->substream); in snd_cs46xx_interrupt()
1212 if ((status1 & HISR_VC0) && chip->playback_pcm) { in snd_cs46xx_interrupt()
1213 if (chip->playback_pcm->substream) in snd_cs46xx_interrupt()
1214 snd_pcm_period_elapsed(chip->playback_pcm->substream); in snd_cs46xx_interrupt()
1216 if ((status1 & HISR_VC1) && chip->pcm) { in snd_cs46xx_interrupt()
1217 if (chip->capt.substream) in snd_cs46xx_interrupt()
1218 snd_pcm_period_elapsed(chip->capt.substream); in snd_cs46xx_interrupt()
1222 if ((status1 & HISR_MIDI) && chip->rmidi) { in snd_cs46xx_interrupt()
1225 spin_lock(&chip->reg_lock); in snd_cs46xx_interrupt()
1226 while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_RBE) == 0) { in snd_cs46xx_interrupt()
1227 c = snd_cs46xx_peekBA0(chip, BA0_MIDRP); in snd_cs46xx_interrupt()
1228 if ((chip->midcr & MIDCR_RIE) == 0) in snd_cs46xx_interrupt()
1230 snd_rawmidi_receive(chip->midi_input, &c, 1); in snd_cs46xx_interrupt()
1232 while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_TBF) == 0) { in snd_cs46xx_interrupt()
1233 if ((chip->midcr & MIDCR_TIE) == 0) in snd_cs46xx_interrupt()
1235 if (snd_rawmidi_transmit(chip->midi_output, &c, 1) != 1) { in snd_cs46xx_interrupt()
1236 chip->midcr &= ~MIDCR_TIE; in snd_cs46xx_interrupt()
1237 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_interrupt()
1240 snd_cs46xx_pokeBA0(chip, BA0_MIDWP, c); in snd_cs46xx_interrupt()
1242 spin_unlock(&chip->reg_lock); in snd_cs46xx_interrupt()
1245 * EOI to the PCI part....reenables interrupts in snd_cs46xx_interrupt()
1247 snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_CHGM | HICR_IEV); in snd_cs46xx_interrupt()
1308 kfree(runtime->private_data); in snd_cs46xx_pcm_free_substream()
1313 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in _cs46xx_playback_open_channel() local
1315 struct snd_pcm_runtime *runtime = substream->runtime; in _cs46xx_playback_open_channel()
1319 return -ENOMEM; in _cs46xx_playback_open_channel()
1320 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), in _cs46xx_playback_open_channel()
1321 PAGE_SIZE, &cpcm->hw_buf) < 0) { in _cs46xx_playback_open_channel()
1323 return -ENOMEM; in _cs46xx_playback_open_channel()
1326 runtime->hw = snd_cs46xx_playback; in _cs46xx_playback_open_channel()
1327 runtime->private_data = cpcm; in _cs46xx_playback_open_channel()
1328 runtime->private_free = snd_cs46xx_pcm_free_substream; in _cs46xx_playback_open_channel()
1330 cpcm->substream = substream; in _cs46xx_playback_open_channel()
1332 mutex_lock(&chip->spos_mutex); in _cs46xx_playback_open_channel()
1333 cpcm->pcm_channel = NULL; in _cs46xx_playback_open_channel()
1334 cpcm->pcm_channel_id = pcm_channel_id; in _cs46xx_playback_open_channel()
1341 mutex_unlock(&chip->spos_mutex); in _cs46xx_playback_open_channel()
1343 chip->playback_pcm = cpcm; /* HACK */ in _cs46xx_playback_open_channel()
1346 if (chip->accept_valid) in _cs46xx_playback_open_channel()
1347 substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID; in _cs46xx_playback_open_channel()
1348 chip->active_ctrl(chip, 1); in _cs46xx_playback_open_channel()
1369 snd_printdd("open center - LFE channel\n"); in snd_cs46xx_playback_open_clfe()
1376 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_playback_open_iec958() local
1380 mutex_lock(&chip->spos_mutex); in snd_cs46xx_playback_open_iec958()
1381 cs46xx_iec958_pre_open (chip); in snd_cs46xx_playback_open_iec958()
1382 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_open_iec958()
1392 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_playback_close_iec958() local
1398 mutex_lock(&chip->spos_mutex); in snd_cs46xx_playback_close_iec958()
1399 cs46xx_iec958_post_close (chip); in snd_cs46xx_playback_close_iec958()
1400 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_close_iec958()
1408 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_capture_open() local
1410 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), in snd_cs46xx_capture_open()
1411 PAGE_SIZE, &chip->capt.hw_buf) < 0) in snd_cs46xx_capture_open()
1412 return -ENOMEM; in snd_cs46xx_capture_open()
1413 chip->capt.substream = substream; in snd_cs46xx_capture_open()
1414 substream->runtime->hw = snd_cs46xx_capture; in snd_cs46xx_capture_open()
1416 if (chip->accept_valid) in snd_cs46xx_capture_open()
1417 substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID; in snd_cs46xx_capture_open()
1419 chip->active_ctrl(chip, 1); in snd_cs46xx_capture_open()
1422 snd_pcm_hw_constraint_list(substream->runtime, 0, in snd_cs46xx_capture_open()
1431 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_playback_close() local
1432 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cs46xx_playback_close()
1435 cpcm = runtime->private_data; in snd_cs46xx_playback_close()
1438 if (!cpcm) return -ENXIO; in snd_cs46xx_playback_close()
1441 mutex_lock(&chip->spos_mutex); in snd_cs46xx_playback_close()
1442 if (cpcm->pcm_channel) { in snd_cs46xx_playback_close()
1443 cs46xx_dsp_destroy_pcm_channel(chip,cpcm->pcm_channel); in snd_cs46xx_playback_close()
1444 cpcm->pcm_channel = NULL; in snd_cs46xx_playback_close()
1446 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_playback_close()
1448 chip->playback_pcm = NULL; in snd_cs46xx_playback_close()
1451 cpcm->substream = NULL; in snd_cs46xx_playback_close()
1452 snd_dma_free_pages(&cpcm->hw_buf); in snd_cs46xx_playback_close()
1453 chip->active_ctrl(chip, -1); in snd_cs46xx_playback_close()
1460 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); in snd_cs46xx_capture_close() local
1462 chip->capt.substream = NULL; in snd_cs46xx_capture_close()
1463 snd_dma_free_pages(&chip->capt.hw_buf); in snd_cs46xx_capture_close()
1464 chip->active_ctrl(chip, -1); in snd_cs46xx_capture_close()
1588 #define MAX_PLAYBACK_CHANNELS (DSP_MAX_PCM_CHANNELS - 1)
1593 int __devinit snd_cs46xx_pcm(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm) in snd_cs46xx_pcm() argument
1600 if ((err = snd_pcm_new(chip->card, "CS46xx", device, MAX_PLAYBACK_CHANNELS, 1, &pcm)) < 0) in snd_cs46xx_pcm()
1603 pcm->private_data = chip; in snd_cs46xx_pcm()
1609 pcm->info_flags = 0; in snd_cs46xx_pcm()
1610 strcpy(pcm->name, "CS46xx"); in snd_cs46xx_pcm()
1611 chip->pcm = pcm; in snd_cs46xx_pcm()
1614 snd_dma_pci_data(chip->pci), 64*1024, 256*1024); in snd_cs46xx_pcm()
1624 int __devinit snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm) in snd_cs46xx_pcm_rear() argument
1632 if ((err = snd_pcm_new(chip->card, "CS46xx - Rear", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0) in snd_cs46xx_pcm_rear()
1635 pcm->private_data = chip; in snd_cs46xx_pcm_rear()
1640 pcm->info_flags = 0; in snd_cs46xx_pcm_rear()
1641 strcpy(pcm->name, "CS46xx - Rear"); in snd_cs46xx_pcm_rear()
1642 chip->pcm_rear = pcm; in snd_cs46xx_pcm_rear()
1645 snd_dma_pci_data(chip->pci), 64*1024, 256*1024); in snd_cs46xx_pcm_rear()
1653 int __devinit snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm) in snd_cs46xx_pcm_center_lfe() argument
1661 …if ((err = snd_pcm_new(chip->card, "CS46xx - Center LFE", device, MAX_PLAYBACK_CHANNELS, 0, &pcm))… in snd_cs46xx_pcm_center_lfe()
1664 pcm->private_data = chip; in snd_cs46xx_pcm_center_lfe()
1669 pcm->info_flags = 0; in snd_cs46xx_pcm_center_lfe()
1670 strcpy(pcm->name, "CS46xx - Center LFE"); in snd_cs46xx_pcm_center_lfe()
1671 chip->pcm_center_lfe = pcm; in snd_cs46xx_pcm_center_lfe()
1674 snd_dma_pci_data(chip->pci), 64*1024, 256*1024); in snd_cs46xx_pcm_center_lfe()
1682 int __devinit snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm) in snd_cs46xx_pcm_iec958() argument
1690 if ((err = snd_pcm_new(chip->card, "CS46xx - IEC958", device, 1, 0, &pcm)) < 0) in snd_cs46xx_pcm_iec958()
1693 pcm->private_data = chip; in snd_cs46xx_pcm_iec958()
1698 pcm->info_flags = 0; in snd_cs46xx_pcm_iec958()
1699 strcpy(pcm->name, "CS46xx - IEC958"); in snd_cs46xx_pcm_iec958()
1700 chip->pcm_rear = pcm; in snd_cs46xx_pcm_iec958()
1703 snd_dma_pci_data(chip->pci), 64*1024, 256*1024); in snd_cs46xx_pcm_iec958()
1717 struct snd_cs46xx *chip = bus->private_data; in snd_cs46xx_mixer_free_ac97_bus() local
1719 chip->ac97_bus = NULL; in snd_cs46xx_mixer_free_ac97_bus()
1724 struct snd_cs46xx *chip = ac97->private_data; in snd_cs46xx_mixer_free_ac97() local
1726 if (snd_BUG_ON(ac97 != chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] && in snd_cs46xx_mixer_free_ac97()
1727 ac97 != chip->ac97[CS46XX_SECONDARY_CODEC_INDEX])) in snd_cs46xx_mixer_free_ac97()
1730 if (ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) { in snd_cs46xx_mixer_free_ac97()
1731 chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] = NULL; in snd_cs46xx_mixer_free_ac97()
1732 chip->eapd_switch = NULL; in snd_cs46xx_mixer_free_ac97()
1735 chip->ac97[CS46XX_SECONDARY_CODEC_INDEX] = NULL; in snd_cs46xx_mixer_free_ac97()
1741 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_cs46xx_vol_info()
1742 uinfo->count = 2; in snd_cs46xx_vol_info()
1743 uinfo->value.integer.min = 0; in snd_cs46xx_vol_info()
1744 uinfo->value.integer.max = 0x7fff; in snd_cs46xx_vol_info()
1750 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_vol_get() local
1751 int reg = kcontrol->private_value; in snd_cs46xx_vol_get()
1752 unsigned int val = snd_cs46xx_peek(chip, reg); in snd_cs46xx_vol_get()
1753 ucontrol->value.integer.value[0] = 0xffff - (val >> 16); in snd_cs46xx_vol_get()
1754 ucontrol->value.integer.value[1] = 0xffff - (val & 0xffff); in snd_cs46xx_vol_get()
1760 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_vol_put() local
1761 int reg = kcontrol->private_value; in snd_cs46xx_vol_put()
1762 unsigned int val = ((0xffff - ucontrol->value.integer.value[0]) << 16 | in snd_cs46xx_vol_put()
1763 (0xffff - ucontrol->value.integer.value[1])); in snd_cs46xx_vol_put()
1764 unsigned int old = snd_cs46xx_peek(chip, reg); in snd_cs46xx_vol_put()
1768 snd_cs46xx_poke(chip, reg, val); in snd_cs46xx_vol_put()
1778 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_vol_dac_get() local
1780 ucontrol->value.integer.value[0] = chip->dsp_spos_instance->dac_volume_left; in snd_cs46xx_vol_dac_get()
1781 ucontrol->value.integer.value[1] = chip->dsp_spos_instance->dac_volume_right; in snd_cs46xx_vol_dac_get()
1788 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_vol_dac_put() local
1791 if (chip->dsp_spos_instance->dac_volume_right != ucontrol->value.integer.value[0] || in snd_cs46xx_vol_dac_put()
1792 chip->dsp_spos_instance->dac_volume_left != ucontrol->value.integer.value[1]) { in snd_cs46xx_vol_dac_put()
1793 cs46xx_dsp_set_dac_volume(chip, in snd_cs46xx_vol_dac_put()
1794 ucontrol->value.integer.value[0], in snd_cs46xx_vol_dac_put()
1795 ucontrol->value.integer.value[1]); in snd_cs46xx_vol_dac_put()
1805 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1807 ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_input_volume_left;
1808 ucontrol->value.integer.value[1] = chip->dsp_spos_instance->spdif_input_volume_right;
1814 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1817 if (chip->dsp_spos_instance->spdif_input_volume_left != ucontrol->value.integer.value[0] ||
1818 chip->dsp_spos_instance->spdif_input_volume_right!= ucontrol->value.integer.value[1]) {
1819 cs46xx_dsp_set_iec958_volume (chip,
1820 ucontrol->value.integer.value[0],
1821 ucontrol->value.integer.value[1]);
1834 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_iec958_get() local
1835 int reg = kcontrol->private_value; in snd_cs46xx_iec958_get()
1838 …ucontrol->value.integer.value[0] = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_O… in snd_cs46xx_iec958_get()
1840 ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_status_in; in snd_cs46xx_iec958_get()
1848 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_iec958_put() local
1851 switch (kcontrol->private_value) { in snd_cs46xx_iec958_put()
1853 mutex_lock(&chip->spos_mutex); in snd_cs46xx_iec958_put()
1854 change = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED); in snd_cs46xx_iec958_put()
1855 if (ucontrol->value.integer.value[0] && !change) in snd_cs46xx_iec958_put()
1856 cs46xx_dsp_enable_spdif_out(chip); in snd_cs46xx_iec958_put()
1857 else if (change && !ucontrol->value.integer.value[0]) in snd_cs46xx_iec958_put()
1858 cs46xx_dsp_disable_spdif_out(chip); in snd_cs46xx_iec958_put()
1860 res = (change != (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED)); in snd_cs46xx_iec958_put()
1861 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_iec958_put()
1864 change = chip->dsp_spos_instance->spdif_status_in; in snd_cs46xx_iec958_put()
1865 if (ucontrol->value.integer.value[0] && !change) { in snd_cs46xx_iec958_put()
1866 cs46xx_dsp_enable_spdif_in(chip); in snd_cs46xx_iec958_put()
1869 else if (change && !ucontrol->value.integer.value[0]) in snd_cs46xx_iec958_put()
1870 cs46xx_dsp_disable_spdif_in(chip); in snd_cs46xx_iec958_put()
1872 res = (change != chip->dsp_spos_instance->spdif_status_in); in snd_cs46xx_iec958_put()
1875 res = -EINVAL; in snd_cs46xx_iec958_put()
1885 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_adc_capture_get() local
1886 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_adc_capture_get()
1888 if (ins->adc_input != NULL) in snd_cs46xx_adc_capture_get()
1889 ucontrol->value.integer.value[0] = 1; in snd_cs46xx_adc_capture_get()
1891 ucontrol->value.integer.value[0] = 0; in snd_cs46xx_adc_capture_get()
1899 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_adc_capture_put() local
1900 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_adc_capture_put()
1903 if (ucontrol->value.integer.value[0] && !ins->adc_input) { in snd_cs46xx_adc_capture_put()
1904 cs46xx_dsp_enable_adc_capture(chip); in snd_cs46xx_adc_capture_put()
1906 } else if (!ucontrol->value.integer.value[0] && ins->adc_input) { in snd_cs46xx_adc_capture_put()
1907 cs46xx_dsp_disable_adc_capture(chip); in snd_cs46xx_adc_capture_put()
1916 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_pcm_capture_get() local
1917 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_pcm_capture_get()
1919 if (ins->pcm_input != NULL) in snd_cs46xx_pcm_capture_get()
1920 ucontrol->value.integer.value[0] = 1; in snd_cs46xx_pcm_capture_get()
1922 ucontrol->value.integer.value[0] = 0; in snd_cs46xx_pcm_capture_get()
1931 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_pcm_capture_put() local
1932 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_pcm_capture_put()
1935 if (ucontrol->value.integer.value[0] && !ins->pcm_input) { in snd_cs46xx_pcm_capture_put()
1936 cs46xx_dsp_enable_pcm_capture(chip); in snd_cs46xx_pcm_capture_put()
1938 } else if (!ucontrol->value.integer.value[0] && ins->pcm_input) { in snd_cs46xx_pcm_capture_put()
1939 cs46xx_dsp_disable_pcm_capture(chip); in snd_cs46xx_pcm_capture_put()
1949 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_herc_spdif_select_get() local
1951 int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR); in snd_herc_spdif_select_get()
1954 ucontrol->value.integer.value[0] = 1; in snd_herc_spdif_select_get()
1956 ucontrol->value.integer.value[0] = 0; in snd_herc_spdif_select_get()
1962 * Game Theatre XP card - EGPIO[0] is used to select SPDIF input optical or coaxial.
1967 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_herc_spdif_select_put() local
1968 int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR); in snd_herc_spdif_select_put()
1969 int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR); in snd_herc_spdif_select_put()
1971 if (ucontrol->value.integer.value[0]) { in snd_herc_spdif_select_put()
1973 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, in snd_herc_spdif_select_put()
1975 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, in snd_herc_spdif_select_put()
1976 EGPIOPTR_GPPT0 | val2); /* open-drain on output */ in snd_herc_spdif_select_put()
1979 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, val1 & ~EGPIODR_GPOE0); /* disable */ in snd_herc_spdif_select_put()
1980 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT0); /* disable */ in snd_herc_spdif_select_put()
1985 return (val1 != (int)snd_cs46xx_peekBA0(chip, BA0_EGPIODR)); in snd_herc_spdif_select_put()
1991 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; in snd_cs46xx_spdif_info()
1992 uinfo->count = 1; in snd_cs46xx_spdif_info()
1999 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_spdif_default_get() local
2000 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_spdif_default_get()
2002 mutex_lock(&chip->spos_mutex); in snd_cs46xx_spdif_default_get()
2003 ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_default >> 24) & 0xff); in snd_cs46xx_spdif_default_get()
2004 ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_default >> 16) & 0xff); in snd_cs46xx_spdif_default_get()
2005 ucontrol->value.iec958.status[2] = 0; in snd_cs46xx_spdif_default_get()
2006 ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_default) & 0xff); in snd_cs46xx_spdif_default_get()
2007 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_spdif_default_get()
2015 struct snd_cs46xx * chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_spdif_default_put() local
2016 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_spdif_default_put()
2020 mutex_lock(&chip->spos_mutex); in snd_cs46xx_spdif_default_put()
2021 val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) | in snd_cs46xx_spdif_default_put()
2022 ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[2]) << 16) | in snd_cs46xx_spdif_default_put()
2023 ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) | in snd_cs46xx_spdif_default_put()
2028 change = (unsigned int)ins->spdif_csuv_default != val; in snd_cs46xx_spdif_default_put()
2029 ins->spdif_csuv_default = val; in snd_cs46xx_spdif_default_put()
2031 if ( !(ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) ) in snd_cs46xx_spdif_default_put()
2032 cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val); in snd_cs46xx_spdif_default_put()
2034 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_spdif_default_put()
2042 ucontrol->value.iec958.status[0] = 0xff; in snd_cs46xx_spdif_mask_get()
2043 ucontrol->value.iec958.status[1] = 0xff; in snd_cs46xx_spdif_mask_get()
2044 ucontrol->value.iec958.status[2] = 0x00; in snd_cs46xx_spdif_mask_get()
2045 ucontrol->value.iec958.status[3] = 0xff; in snd_cs46xx_spdif_mask_get()
2052 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_spdif_stream_get() local
2053 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_spdif_stream_get()
2055 mutex_lock(&chip->spos_mutex); in snd_cs46xx_spdif_stream_get()
2056 ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_stream >> 24) & 0xff); in snd_cs46xx_spdif_stream_get()
2057 ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_stream >> 16) & 0xff); in snd_cs46xx_spdif_stream_get()
2058 ucontrol->value.iec958.status[2] = 0; in snd_cs46xx_spdif_stream_get()
2059 ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_stream) & 0xff); in snd_cs46xx_spdif_stream_get()
2060 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_spdif_stream_get()
2068 struct snd_cs46xx * chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_spdif_stream_put() local
2069 struct dsp_spos_instance * ins = chip->dsp_spos_instance; in snd_cs46xx_spdif_stream_put()
2073 mutex_lock(&chip->spos_mutex); in snd_cs46xx_spdif_stream_put()
2074 val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) | in snd_cs46xx_spdif_stream_put()
2075 ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[1]) << 16) | in snd_cs46xx_spdif_stream_put()
2076 ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) | in snd_cs46xx_spdif_stream_put()
2081 change = ins->spdif_csuv_stream != val; in snd_cs46xx_spdif_stream_put()
2082 ins->spdif_csuv_stream = val; in snd_cs46xx_spdif_stream_put()
2084 if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN ) in snd_cs46xx_spdif_stream_put()
2085 cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val); in snd_cs46xx_spdif_stream_put()
2087 mutex_unlock(&chip->spos_mutex); in snd_cs46xx_spdif_stream_put()
2194 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_front_dup_get() local
2196 val = snd_ac97_read(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], AC97_CSR_ACMODE); in snd_cs46xx_front_dup_get()
2197 ucontrol->value.integer.value[0] = (val & 0x200) ? 0 : 1; in snd_cs46xx_front_dup_get()
2204 struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); in snd_cs46xx_front_dup_put() local
2205 return snd_ac97_update_bits(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], in snd_cs46xx_front_dup_put()
2207 ucontrol->value.integer.value[0] ? 0 : 0x200); in snd_cs46xx_front_dup_put()
2237 /* reset to defaults */ in snd_cs46xx_codec_reset()
2241 if (ac97->num == CS46XX_PRIMARY_CODEC_INDEX) { in snd_cs46xx_codec_reset()
2244 } else if (ac97->num == CS46XX_SECONDARY_CODEC_INDEX) { in snd_cs46xx_codec_reset()
2253 /* it's necessary to wait awhile until registers are accessible after RESET */ in snd_cs46xx_codec_reset()
2260 /* use preliminary reads to settle the communication */ in snd_cs46xx_codec_reset()
2269 /* test if we can write to the record gain volume register */ in snd_cs46xx_codec_reset()
2281 static int __devinit cs46xx_detect_codec(struct snd_cs46xx *chip, int codec) in cs46xx_detect_codec() argument
2287 ac97.private_data = chip; in cs46xx_detect_codec()
2290 if (chip->amplifier_ctrl == amp_voyetra) in cs46xx_detect_codec()
2294 snd_cs46xx_codec_write(chip, AC97_RESET, 0, codec); in cs46xx_detect_codec()
2296 if (snd_cs46xx_codec_read(chip, AC97_RESET, codec) & 0x8000) { in cs46xx_detect_codec()
2298 return -ENXIO; in cs46xx_detect_codec()
2302 snd_cs46xx_codec_write(chip, AC97_MASTER, 0x8000, codec); in cs46xx_detect_codec()
2304 if (snd_cs46xx_codec_read(chip, AC97_MASTER, codec) == 0x8000) { in cs46xx_detect_codec()
2305 err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97[codec]); in cs46xx_detect_codec()
2311 return -ENXIO; in cs46xx_detect_codec()
2314 int __devinit snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device) in snd_cs46xx_mixer() argument
2316 struct snd_card *card = chip->card; in snd_cs46xx_mixer()
2329 chip->nr_ac97_codecs = 0; in snd_cs46xx_mixer()
2331 if ((err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus)) < 0) in snd_cs46xx_mixer()
2333 chip->ac97_bus->private_free = snd_cs46xx_mixer_free_ac97_bus; in snd_cs46xx_mixer()
2335 if (cs46xx_detect_codec(chip, CS46XX_PRIMARY_CODEC_INDEX) < 0) in snd_cs46xx_mixer()
2336 return -ENXIO; in snd_cs46xx_mixer()
2337 chip->nr_ac97_codecs = 1; in snd_cs46xx_mixer()
2342 if (! cs46xx_detect_codec(chip, CS46XX_SECONDARY_CODEC_INDEX)) in snd_cs46xx_mixer()
2343 chip->nr_ac97_codecs = 2; in snd_cs46xx_mixer()
2349 kctl = snd_ctl_new1(&snd_cs46xx_controls[idx], chip); in snd_cs46xx_mixer()
2350 if (kctl && kctl->id.iface == SNDRV_CTL_ELEM_IFACE_PCM) in snd_cs46xx_mixer()
2351 kctl->id.device = spdif_device; in snd_cs46xx_mixer()
2360 chip->eapd_switch = snd_ctl_find_id(chip->card, &id); in snd_cs46xx_mixer()
2363 if (chip->nr_ac97_codecs == 1) { in snd_cs46xx_mixer()
2364 unsigned int id2 = chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]->id & 0xffff; in snd_cs46xx_mixer()
2366 err = snd_ctl_add(card, snd_ctl_new1(&snd_cs46xx_front_dup_ctl, chip)); in snd_cs46xx_mixer()
2369 snd_ac97_write_cache(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], in snd_cs46xx_mixer()
2374 if (chip->mixer_init) { in snd_cs46xx_mixer()
2375 snd_printdd ("calling chip->mixer_init(chip);\n"); in snd_cs46xx_mixer()
2376 chip->mixer_init(chip); in snd_cs46xx_mixer()
2381 chip->amplifier_ctrl(chip, 1); in snd_cs46xx_mixer()
2390 static void snd_cs46xx_midi_reset(struct snd_cs46xx *chip) in snd_cs46xx_midi_reset() argument
2392 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, MIDCR_MRST); in snd_cs46xx_midi_reset()
2394 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_reset()
2399 struct snd_cs46xx *chip = substream->rmidi->private_data; in snd_cs46xx_midi_input_open() local
2401 chip->active_ctrl(chip, 1); in snd_cs46xx_midi_input_open()
2402 spin_lock_irq(&chip->reg_lock); in snd_cs46xx_midi_input_open()
2403 chip->uartm |= CS46XX_MODE_INPUT; in snd_cs46xx_midi_input_open()
2404 chip->midcr |= MIDCR_RXE; in snd_cs46xx_midi_input_open()
2405 chip->midi_input = substream; in snd_cs46xx_midi_input_open()
2406 if (!(chip->uartm & CS46XX_MODE_OUTPUT)) { in snd_cs46xx_midi_input_open()
2407 snd_cs46xx_midi_reset(chip); in snd_cs46xx_midi_input_open()
2409 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_input_open()
2411 spin_unlock_irq(&chip->reg_lock); in snd_cs46xx_midi_input_open()
2417 struct snd_cs46xx *chip = substream->rmidi->private_data; in snd_cs46xx_midi_input_close() local
2419 spin_lock_irq(&chip->reg_lock); in snd_cs46xx_midi_input_close()
2420 chip->midcr &= ~(MIDCR_RXE | MIDCR_RIE); in snd_cs46xx_midi_input_close()
2421 chip->midi_input = NULL; in snd_cs46xx_midi_input_close()
2422 if (!(chip->uartm & CS46XX_MODE_OUTPUT)) { in snd_cs46xx_midi_input_close()
2423 snd_cs46xx_midi_reset(chip); in snd_cs46xx_midi_input_close()
2425 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_input_close()
2427 chip->uartm &= ~CS46XX_MODE_INPUT; in snd_cs46xx_midi_input_close()
2428 spin_unlock_irq(&chip->reg_lock); in snd_cs46xx_midi_input_close()
2429 chip->active_ctrl(chip, -1); in snd_cs46xx_midi_input_close()
2435 struct snd_cs46xx *chip = substream->rmidi->private_data; in snd_cs46xx_midi_output_open() local
2437 chip->active_ctrl(chip, 1); in snd_cs46xx_midi_output_open()
2439 spin_lock_irq(&chip->reg_lock); in snd_cs46xx_midi_output_open()
2440 chip->uartm |= CS46XX_MODE_OUTPUT; in snd_cs46xx_midi_output_open()
2441 chip->midcr |= MIDCR_TXE; in snd_cs46xx_midi_output_open()
2442 chip->midi_output = substream; in snd_cs46xx_midi_output_open()
2443 if (!(chip->uartm & CS46XX_MODE_INPUT)) { in snd_cs46xx_midi_output_open()
2444 snd_cs46xx_midi_reset(chip); in snd_cs46xx_midi_output_open()
2446 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_output_open()
2448 spin_unlock_irq(&chip->reg_lock); in snd_cs46xx_midi_output_open()
2454 struct snd_cs46xx *chip = substream->rmidi->private_data; in snd_cs46xx_midi_output_close() local
2456 spin_lock_irq(&chip->reg_lock); in snd_cs46xx_midi_output_close()
2457 chip->midcr &= ~(MIDCR_TXE | MIDCR_TIE); in snd_cs46xx_midi_output_close()
2458 chip->midi_output = NULL; in snd_cs46xx_midi_output_close()
2459 if (!(chip->uartm & CS46XX_MODE_INPUT)) { in snd_cs46xx_midi_output_close()
2460 snd_cs46xx_midi_reset(chip); in snd_cs46xx_midi_output_close()
2462 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_output_close()
2464 chip->uartm &= ~CS46XX_MODE_OUTPUT; in snd_cs46xx_midi_output_close()
2465 spin_unlock_irq(&chip->reg_lock); in snd_cs46xx_midi_output_close()
2466 chip->active_ctrl(chip, -1); in snd_cs46xx_midi_output_close()
2473 struct snd_cs46xx *chip = substream->rmidi->private_data; in snd_cs46xx_midi_input_trigger() local
2475 spin_lock_irqsave(&chip->reg_lock, flags); in snd_cs46xx_midi_input_trigger()
2477 if ((chip->midcr & MIDCR_RIE) == 0) { in snd_cs46xx_midi_input_trigger()
2478 chip->midcr |= MIDCR_RIE; in snd_cs46xx_midi_input_trigger()
2479 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_input_trigger()
2482 if (chip->midcr & MIDCR_RIE) { in snd_cs46xx_midi_input_trigger()
2483 chip->midcr &= ~MIDCR_RIE; in snd_cs46xx_midi_input_trigger()
2484 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_input_trigger()
2487 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_cs46xx_midi_input_trigger()
2493 struct snd_cs46xx *chip = substream->rmidi->private_data; in snd_cs46xx_midi_output_trigger() local
2496 spin_lock_irqsave(&chip->reg_lock, flags); in snd_cs46xx_midi_output_trigger()
2498 if ((chip->midcr & MIDCR_TIE) == 0) { in snd_cs46xx_midi_output_trigger()
2499 chip->midcr |= MIDCR_TIE; in snd_cs46xx_midi_output_trigger()
2501 while ((chip->midcr & MIDCR_TIE) && in snd_cs46xx_midi_output_trigger()
2502 (snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_TBF) == 0) { in snd_cs46xx_midi_output_trigger()
2504 chip->midcr &= ~MIDCR_TIE; in snd_cs46xx_midi_output_trigger()
2506 snd_cs46xx_pokeBA0(chip, BA0_MIDWP, byte); in snd_cs46xx_midi_output_trigger()
2509 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_output_trigger()
2512 if (chip->midcr & MIDCR_TIE) { in snd_cs46xx_midi_output_trigger()
2513 chip->midcr &= ~MIDCR_TIE; in snd_cs46xx_midi_output_trigger()
2514 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); in snd_cs46xx_midi_output_trigger()
2517 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_cs46xx_midi_output_trigger()
2534 int __devinit snd_cs46xx_midi(struct snd_cs46xx *chip, int device, struct snd_rawmidi **rrawmidi) in snd_cs46xx_midi() argument
2541 if ((err = snd_rawmidi_new(chip->card, "CS46XX", device, 1, 1, &rmidi)) < 0) in snd_cs46xx_midi()
2543 strcpy(rmidi->name, "CS46XX"); in snd_cs46xx_midi()
2546 …rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUP… in snd_cs46xx_midi()
2547 rmidi->private_data = chip; in snd_cs46xx_midi()
2548 chip->rmidi = rmidi; in snd_cs46xx_midi()
2563 struct snd_cs46xx *chip = gameport_get_port_data(gameport); in snd_cs46xx_gameport_trigger() local
2565 if (snd_BUG_ON(!chip)) in snd_cs46xx_gameport_trigger()
2567 snd_cs46xx_pokeBA0(chip, BA0_JSPT, 0xFF); //outb(gameport->io, 0xFF); in snd_cs46xx_gameport_trigger()
2572 struct snd_cs46xx *chip = gameport_get_port_data(gameport); in snd_cs46xx_gameport_read() local
2574 if (snd_BUG_ON(!chip)) in snd_cs46xx_gameport_read()
2576 return snd_cs46xx_peekBA0(chip, BA0_JSPT); //inb(gameport->io); in snd_cs46xx_gameport_read()
2581 struct snd_cs46xx *chip = gameport_get_port_data(gameport); in snd_cs46xx_gameport_cooked_read() local
2584 if (snd_BUG_ON(!chip)) in snd_cs46xx_gameport_cooked_read()
2587 js1 = snd_cs46xx_peekBA0(chip, BA0_JSC1); in snd_cs46xx_gameport_cooked_read()
2588 js2 = snd_cs46xx_peekBA0(chip, BA0_JSC2); in snd_cs46xx_gameport_cooked_read()
2589 jst = snd_cs46xx_peekBA0(chip, BA0_JSPT); in snd_cs46xx_gameport_cooked_read()
2599 if(axes[jst]==0xFFFF) axes[jst] = -1; in snd_cs46xx_gameport_cooked_read()
2611 return -1; in snd_cs46xx_gameport_open()
2616 int __devinit snd_cs46xx_gameport(struct snd_cs46xx *chip) in snd_cs46xx_gameport() argument
2620 chip->gameport = gp = gameport_allocate_port(); in snd_cs46xx_gameport()
2623 return -ENOMEM; in snd_cs46xx_gameport()
2627 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci)); in snd_cs46xx_gameport()
2628 gameport_set_dev_parent(gp, &chip->pci->dev); in snd_cs46xx_gameport()
2629 gameport_set_port_data(gp, chip); in snd_cs46xx_gameport()
2631 gp->open = snd_cs46xx_gameport_open; in snd_cs46xx_gameport()
2632 gp->read = snd_cs46xx_gameport_read; in snd_cs46xx_gameport()
2633 gp->trigger = snd_cs46xx_gameport_trigger; in snd_cs46xx_gameport()
2634 gp->cooked_read = snd_cs46xx_gameport_cooked_read; in snd_cs46xx_gameport()
2636 snd_cs46xx_pokeBA0(chip, BA0_JSIO, 0xFF); // ? in snd_cs46xx_gameport()
2637 snd_cs46xx_pokeBA0(chip, BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW); in snd_cs46xx_gameport()
2644 static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip) in snd_cs46xx_remove_gameport() argument
2646 if (chip->gameport) { in snd_cs46xx_remove_gameport()
2647 gameport_unregister_port(chip->gameport); in snd_cs46xx_remove_gameport()
2648 chip->gameport = NULL; in snd_cs46xx_remove_gameport()
2652 int __devinit snd_cs46xx_gameport(struct snd_cs46xx *chip) { return -ENOSYS; } in snd_cs46xx_gameport() argument
2653 static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip) { } in snd_cs46xx_remove_gameport() argument
2666 struct snd_cs46xx_region *region = entry->private_data; in snd_cs46xx_io_read()
2668 if (copy_to_user_fromio(buf, region->remap_addr + pos, count)) in snd_cs46xx_io_read()
2669 return -EFAULT; in snd_cs46xx_io_read()
2677 static int __devinit snd_cs46xx_proc_init(struct snd_card *card, struct snd_cs46xx *chip) in snd_cs46xx_proc_init() argument
2683 struct snd_cs46xx_region *region = &chip->region.idx[idx]; in snd_cs46xx_proc_init()
2684 if (! snd_card_proc_new(card, region->name, &entry)) { in snd_cs46xx_proc_init()
2685 entry->content = SNDRV_INFO_CONTENT_DATA; in snd_cs46xx_proc_init()
2686 entry->private_data = chip; in snd_cs46xx_proc_init()
2687 entry->c.ops = &snd_cs46xx_proc_io_ops; in snd_cs46xx_proc_init()
2688 entry->size = region->size; in snd_cs46xx_proc_init()
2689 entry->mode = S_IFREG | S_IRUSR; in snd_cs46xx_proc_init()
2693 cs46xx_dsp_proc_init(card, chip); in snd_cs46xx_proc_init()
2698 static int snd_cs46xx_proc_done(struct snd_cs46xx *chip) in snd_cs46xx_proc_done() argument
2701 cs46xx_dsp_proc_done(chip); in snd_cs46xx_proc_done()
2706 #define snd_cs46xx_proc_init(card, chip) argument
2707 #define snd_cs46xx_proc_done(chip) argument
2713 static void snd_cs46xx_hw_stop(struct snd_cs46xx *chip) in snd_cs46xx_hw_stop() argument
2717 tmp = snd_cs46xx_peek(chip, BA1_PFIE); in snd_cs46xx_hw_stop()
2720 snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt disable */ in snd_cs46xx_hw_stop()
2722 tmp = snd_cs46xx_peek(chip, BA1_CIE); in snd_cs46xx_hw_stop()
2725 snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt disable */ in snd_cs46xx_hw_stop()
2730 tmp = snd_cs46xx_peek(chip, BA1_PCTL); in snd_cs46xx_hw_stop()
2731 snd_cs46xx_poke(chip, BA1_PCTL, tmp & 0x0000ffff); in snd_cs46xx_hw_stop()
2736 tmp = snd_cs46xx_peek(chip, BA1_CCTL); in snd_cs46xx_hw_stop()
2737 snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000); in snd_cs46xx_hw_stop()
2742 snd_cs46xx_reset(chip); in snd_cs46xx_hw_stop()
2744 snd_cs46xx_proc_stop(chip); in snd_cs46xx_hw_stop()
2749 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, 0); in snd_cs46xx_hw_stop()
2755 tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE; in snd_cs46xx_hw_stop()
2756 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); in snd_cs46xx_hw_stop()
2760 static int snd_cs46xx_free(struct snd_cs46xx *chip) in snd_cs46xx_free() argument
2764 if (snd_BUG_ON(!chip)) in snd_cs46xx_free()
2765 return -EINVAL; in snd_cs46xx_free()
2767 if (chip->active_ctrl) in snd_cs46xx_free()
2768 chip->active_ctrl(chip, 1); in snd_cs46xx_free()
2770 snd_cs46xx_remove_gameport(chip); in snd_cs46xx_free()
2772 if (chip->amplifier_ctrl) in snd_cs46xx_free()
2773 chip->amplifier_ctrl(chip, -chip->amplifier); /* force to off */ in snd_cs46xx_free()
2775 snd_cs46xx_proc_done(chip); in snd_cs46xx_free()
2777 if (chip->region.idx[0].resource) in snd_cs46xx_free()
2778 snd_cs46xx_hw_stop(chip); in snd_cs46xx_free()
2780 if (chip->irq >= 0) in snd_cs46xx_free()
2781 free_irq(chip->irq, chip); in snd_cs46xx_free()
2783 if (chip->active_ctrl) in snd_cs46xx_free()
2784 chip->active_ctrl(chip, -chip->amplifier); in snd_cs46xx_free()
2787 struct snd_cs46xx_region *region = &chip->region.idx[idx]; in snd_cs46xx_free()
2788 if (region->remap_addr) in snd_cs46xx_free()
2789 iounmap(region->remap_addr); in snd_cs46xx_free()
2790 release_and_free_resource(region->resource); in snd_cs46xx_free()
2794 if (chip->dsp_spos_instance) { in snd_cs46xx_free()
2795 cs46xx_dsp_spos_destroy(chip); in snd_cs46xx_free()
2796 chip->dsp_spos_instance = NULL; in snd_cs46xx_free()
2801 kfree(chip->saved_regs); in snd_cs46xx_free()
2804 pci_disable_device(chip->pci); in snd_cs46xx_free()
2805 kfree(chip); in snd_cs46xx_free()
2811 struct snd_cs46xx *chip = device->device_data; in snd_cs46xx_dev_free() local
2812 return snd_cs46xx_free(chip); in snd_cs46xx_dev_free()
2816 * initialize chip
2818 static int snd_cs46xx_chip_init(struct snd_cs46xx *chip) in snd_cs46xx_chip_init() argument
2823 * First, blast the clock control register to zero so that the PLL starts in snd_cs46xx_chip_init()
2825 * to zero so that the serial ports also start out in a known state. in snd_cs46xx_chip_init()
2827 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, 0); in snd_cs46xx_chip_init()
2828 snd_cs46xx_pokeBA0(chip, BA0_SERMC1, 0); in snd_cs46xx_chip_init()
2831 * If we are in AC97 mode, then we must set the part to a host controlled in snd_cs46xx_chip_init()
2832 * AC-link. Otherwise, we won't be able to bring up the link. in snd_cs46xx_chip_init()
2835 snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0 | in snd_cs46xx_chip_init()
2837 /* snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0); */ /* 2.00 codec */ in snd_cs46xx_chip_init()
2839 snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_1_03); /* 1.03 codec */ in snd_cs46xx_chip_init()
2845 * there might be logic external to the CS461x that uses the ARST# line in snd_cs46xx_chip_init()
2848 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, 0); in snd_cs46xx_chip_init()
2850 snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, 0); in snd_cs46xx_chip_init()
2853 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_RSTN); in snd_cs46xx_chip_init()
2855 snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_RSTN); in snd_cs46xx_chip_init()
2859 * The first thing we do here is to enable sync generation. As soon in snd_cs46xx_chip_init()
2863 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_ESYN | ACCTL_RSTN); in snd_cs46xx_chip_init()
2865 snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_ESYN | ACCTL_RSTN); in snd_cs46xx_chip_init()
2869 * Now wait for a short while to allow the AC97 part to start in snd_cs46xx_chip_init()
2870 * generating bit clock (so we don't try to start the PLL without an in snd_cs46xx_chip_init()
2879 snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97); in snd_cs46xx_chip_init()
2882 * Write the selected clock control setup to the hardware. Do not turn on in snd_cs46xx_chip_init()
2886 snd_cs46xx_pokeBA0(chip, BA0_PLLCC, PLLCC_LPF_1050_2780_KHZ | PLLCC_CDR_73_104_MHZ); in snd_cs46xx_chip_init()
2887 snd_cs46xx_pokeBA0(chip, BA0_PLLM, 0x3a); in snd_cs46xx_chip_init()
2888 snd_cs46xx_pokeBA0(chip, BA0_CLKCR2, CLKCR2_PDIVS_8); in snd_cs46xx_chip_init()
2893 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP); in snd_cs46xx_chip_init()
2903 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP | CLKCR1_SWCE); in snd_cs46xx_chip_init()
2908 snd_cs46xx_pokeBA0(chip, BA0_SERBCF, SERBCF_HBP); in snd_cs46xx_chip_init()
2913 snd_cs46xx_clear_serial_FIFOs(chip); in snd_cs46xx_chip_init()
2916 * Set the serial port FIFO pointer to the first sample in the FIFO. in snd_cs46xx_chip_init()
2918 /* snd_cs46xx_pokeBA0(chip, BA0_SERBSP, 0); */ in snd_cs46xx_chip_init()
2921 * Write the serial port configuration to the part. The master in snd_cs46xx_chip_init()
2924 snd_cs46xx_pokeBA0(chip, BA0_SERC1, SERC1_SO1F_AC97 | SERC1_SO1EN); in snd_cs46xx_chip_init()
2925 snd_cs46xx_pokeBA0(chip, BA0_SERC2, SERC2_SI1F_AC97 | SERC1_SO1EN); in snd_cs46xx_chip_init()
2926 snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97 | SERMC1_MSPE); in snd_cs46xx_chip_init()
2930 snd_cs46xx_pokeBA0(chip, BA0_SERC7, SERC7_ASDI2EN); in snd_cs46xx_chip_init()
2931 snd_cs46xx_pokeBA0(chip, BA0_SERC3, 0); in snd_cs46xx_chip_init()
2932 snd_cs46xx_pokeBA0(chip, BA0_SERC4, 0); in snd_cs46xx_chip_init()
2933 snd_cs46xx_pokeBA0(chip, BA0_SERC5, 0); in snd_cs46xx_chip_init()
2934 snd_cs46xx_pokeBA0(chip, BA0_SERC6, 1); in snd_cs46xx_chip_init()
2944 while (timeout-- > 0) { in snd_cs46xx_chip_init()
2946 * Read the AC97 status register to see if we've seen a CODEC READY in snd_cs46xx_chip_init()
2949 if (snd_cs46xx_peekBA0(chip, BA0_ACSTS) & ACSTS_CRDY) in snd_cs46xx_chip_init()
2955 snd_printk(KERN_ERR "create - never read codec ready from AC'97\n"); in snd_cs46xx_chip_init()
2956 snd_printk(KERN_ERR "it is not probably bug, try to use CS4236 driver\n"); in snd_cs46xx_chip_init()
2957 return -EIO; in snd_cs46xx_chip_init()
2963 /* First, we want to wait for a short time. */ in snd_cs46xx_chip_init()
2966 if (snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY) in snd_cs46xx_chip_init()
2973 if (!(snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY)) in snd_cs46xx_chip_init()
2980 * to the AC97 codec. in snd_cs46xx_chip_init()
2982 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN); in snd_cs46xx_chip_init()
2984 snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN); in snd_cs46xx_chip_init()
2990 * the codec is pumping ADC data across the AC-link. in snd_cs46xx_chip_init()
2993 while (timeout-- > 0) { in snd_cs46xx_chip_init()
2998 …if ((snd_cs46xx_peekBA0(chip, BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) == (ACISV_ISV3 | ACISV_ISV4)) in snd_cs46xx_chip_init()
3004 snd_printk(KERN_ERR "create - never read ISV3 & ISV4 from AC'97\n"); in snd_cs46xx_chip_init()
3005 return -EIO; in snd_cs46xx_chip_init()
3009 with the same problem I would like to know. (Benny) */ in snd_cs46xx_chip_init()
3011 snd_printk(KERN_ERR "ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n"); in snd_cs46xx_chip_init()
3014 snd_printk(KERN_ERR " this message please report to alsa-devel@alsa-project.org\n"); in snd_cs46xx_chip_init()
3016 return -EIO; in snd_cs46xx_chip_init()
3022 * commense the transfer of digital audio data to the AC97 codec. in snd_cs46xx_chip_init()
3025 snd_cs46xx_pokeBA0(chip, BA0_ACOSV, ACOSV_SLV3 | ACOSV_SLV4); in snd_cs46xx_chip_init()
3032 /* snd_cs46xx_pokeBA0(chip, BA0_AC97_POWERDOWN, 0x300); */ in snd_cs46xx_chip_init()
3038 /* tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE; */ in snd_cs46xx_chip_init()
3039 /* snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); */ in snd_cs46xx_chip_init()
3048 static void cs46xx_enable_stream_irqs(struct snd_cs46xx *chip) in cs46xx_enable_stream_irqs() argument
3052 snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM); in cs46xx_enable_stream_irqs()
3054 tmp = snd_cs46xx_peek(chip, BA1_PFIE); in cs46xx_enable_stream_irqs()
3056 snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */ in cs46xx_enable_stream_irqs()
3058 tmp = snd_cs46xx_peek(chip, BA1_CIE); in cs46xx_enable_stream_irqs()
3061 snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */ in cs46xx_enable_stream_irqs()
3064 int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip) in snd_cs46xx_start_dsp() argument
3070 snd_cs46xx_reset(chip); in snd_cs46xx_start_dsp()
3072 * Download the image to the processor. in snd_cs46xx_start_dsp()
3076 if (cs46xx_dsp_load_module(chip, &cwcemb80_module) < 0) { in snd_cs46xx_start_dsp()
3078 return -EIO; in snd_cs46xx_start_dsp()
3082 if (cs46xx_dsp_load_module(chip, &cwc4630_module) < 0) { in snd_cs46xx_start_dsp()
3084 return -EIO; in snd_cs46xx_start_dsp()
3087 if (cs46xx_dsp_load_module(chip, &cwcasync_module) < 0) { in snd_cs46xx_start_dsp()
3089 return -EIO; in snd_cs46xx_start_dsp()
3092 if (cs46xx_dsp_load_module(chip, &cwcsnoop_module) < 0) { in snd_cs46xx_start_dsp()
3094 return -EIO; in snd_cs46xx_start_dsp()
3097 if (cs46xx_dsp_load_module(chip, &cwcbinhack_module) < 0) { in snd_cs46xx_start_dsp()
3099 return -EIO; in snd_cs46xx_start_dsp()
3102 if (cs46xx_dsp_load_module(chip, &cwcdma_module) < 0) { in snd_cs46xx_start_dsp()
3104 return -EIO; in snd_cs46xx_start_dsp()
3107 if (cs46xx_dsp_scb_and_task_init(chip) < 0) in snd_cs46xx_start_dsp()
3108 return -EIO; in snd_cs46xx_start_dsp()
3111 if (snd_cs46xx_download_image(chip) < 0) { in snd_cs46xx_start_dsp()
3113 return -EIO; in snd_cs46xx_start_dsp()
3119 tmp = snd_cs46xx_peek(chip, BA1_PCTL); in snd_cs46xx_start_dsp()
3120 chip->play_ctl = tmp & 0xffff0000; in snd_cs46xx_start_dsp()
3121 snd_cs46xx_poke(chip, BA1_PCTL, tmp & 0x0000ffff); in snd_cs46xx_start_dsp()
3127 tmp = snd_cs46xx_peek(chip, BA1_CCTL); in snd_cs46xx_start_dsp()
3128 chip->capt.ctl = tmp & 0x0000ffff; in snd_cs46xx_start_dsp()
3129 snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000); in snd_cs46xx_start_dsp()
3133 snd_cs46xx_set_play_sample_rate(chip, 8000); in snd_cs46xx_start_dsp()
3134 snd_cs46xx_set_capture_sample_rate(chip, 8000); in snd_cs46xx_start_dsp()
3136 snd_cs46xx_proc_start(chip); in snd_cs46xx_start_dsp()
3138 cs46xx_enable_stream_irqs(chip); in snd_cs46xx_start_dsp()
3141 /* set the attenuation to 0dB */ in snd_cs46xx_start_dsp()
3142 snd_cs46xx_poke(chip, BA1_PVOL, 0x80008000); in snd_cs46xx_start_dsp()
3143 snd_cs46xx_poke(chip, BA1_CVOL, 0x80008000); in snd_cs46xx_start_dsp()
3151 * AMP control - null AMP
3154 static void amp_none(struct snd_cs46xx *chip, int change) in amp_none() argument
3159 static int voyetra_setup_eapd_slot(struct snd_cs46xx *chip) in voyetra_setup_eapd_slot() argument
3171 tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1); in voyetra_setup_eapd_slot()
3174 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp | CLKCR1_SWCE); in voyetra_setup_eapd_slot()
3179 * Clear PRA. The Bonzo chip will be used for GPIO not for modem in voyetra_setup_eapd_slot()
3182 if(chip->nr_ac97_codecs != 2) { in voyetra_setup_eapd_slot()
3183 snd_printk (KERN_ERR "cs46xx: cs46xx_setup_eapd_slot() - no secondary codec configured\n"); in voyetra_setup_eapd_slot()
3184 return -EINVAL; in voyetra_setup_eapd_slot()
3187 modem_power = snd_cs46xx_codec_read (chip, in voyetra_setup_eapd_slot()
3192 snd_cs46xx_codec_write(chip, in voyetra_setup_eapd_slot()
3199 pin_config = snd_cs46xx_codec_read (chip, in voyetra_setup_eapd_slot()
3204 snd_cs46xx_codec_write(chip, in voyetra_setup_eapd_slot()
3212 logic_type = snd_cs46xx_codec_read(chip, AC97_GPIO_POLARITY, in voyetra_setup_eapd_slot()
3216 snd_cs46xx_codec_write (chip, AC97_GPIO_POLARITY, logic_type, in voyetra_setup_eapd_slot()
3219 valid_slots = snd_cs46xx_peekBA0(chip, BA0_ACOSV); in voyetra_setup_eapd_slot()
3221 snd_cs46xx_pokeBA0(chip, BA0_ACOSV, valid_slots); in voyetra_setup_eapd_slot()
3223 if ( cs46xx_wait_for_fifo(chip,1) ) { in voyetra_setup_eapd_slot()
3226 return -EINVAL; in voyetra_setup_eapd_slot()
3236 * Remember that the GPIO pins in bonzo are shifted by 4 bits to in voyetra_setup_eapd_slot()
3237 * the left. 0x1800 corresponds to bits 7 and 8. in voyetra_setup_eapd_slot()
3239 snd_cs46xx_pokeBA0(chip, BA0_SERBWP, 0x1800); in voyetra_setup_eapd_slot()
3242 * Wait for command to complete in voyetra_setup_eapd_slot()
3244 if ( cs46xx_wait_for_fifo(chip,200) ) { in voyetra_setup_eapd_slot()
3247 return -EINVAL; in voyetra_setup_eapd_slot()
3253 snd_cs46xx_pokeBA0(chip, BA0_SERBAD, idx); in voyetra_setup_eapd_slot()
3256 * Tell the serial port to load the new value into the FIFO location. in voyetra_setup_eapd_slot()
3258 snd_cs46xx_pokeBA0(chip, BA0_SERBCM, SERBCM_WRC); in voyetra_setup_eapd_slot()
3261 /* wait for last command to complete */ in voyetra_setup_eapd_slot()
3262 cs46xx_wait_for_fifo(chip,200); in voyetra_setup_eapd_slot()
3269 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); in voyetra_setup_eapd_slot()
3279 static void amp_voyetra(struct snd_cs46xx *chip, int change) in amp_voyetra() argument
3285 int old = chip->amplifier; in amp_voyetra()
3289 chip->amplifier += change; in amp_voyetra()
3290 oval = snd_cs46xx_codec_read(chip, AC97_POWERDOWN, in amp_voyetra()
3293 if (chip->amplifier) { in amp_voyetra()
3301 snd_cs46xx_codec_write(chip, AC97_POWERDOWN, val, in amp_voyetra()
3303 if (chip->eapd_switch) in amp_voyetra()
3304 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, in amp_voyetra()
3305 &chip->eapd_switch->id); in amp_voyetra()
3309 if (chip->amplifier && !old) { in amp_voyetra()
3310 voyetra_setup_eapd_slot(chip); in amp_voyetra()
3315 static void hercules_init(struct snd_cs46xx *chip) in hercules_init() argument
3318 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0); in hercules_init()
3319 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0); in hercules_init()
3324 * Game Theatre XP card - EGPIO[2] is used to enable the external amp.
3326 static void amp_hercules(struct snd_cs46xx *chip, int change) in amp_hercules() argument
3328 int old = chip->amplifier; in amp_hercules()
3329 int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR); in amp_hercules()
3330 int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR); in amp_hercules()
3332 chip->amplifier += change; in amp_hercules()
3333 if (chip->amplifier && !old) { in amp_hercules()
3336 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, in amp_hercules()
3338 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, in amp_hercules()
3339 EGPIOPTR_GPPT2 | val2); /* open-drain on output */ in amp_hercules()
3340 } else if (old && !chip->amplifier) { in amp_hercules()
3342 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, val1 & ~EGPIODR_GPOE2); /* disable */ in amp_hercules()
3343 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT2); /* disable */ in amp_hercules()
3347 static void voyetra_mixer_init (struct snd_cs46xx *chip) in voyetra_mixer_init() argument
3352 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0); in voyetra_mixer_init()
3353 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0); in voyetra_mixer_init()
3356 static void hercules_mixer_init (struct snd_cs46xx *chip) in hercules_mixer_init() argument
3361 struct snd_card *card = chip->card; in hercules_mixer_init()
3364 /* set EGPIO to default */ in hercules_mixer_init()
3365 hercules_init(chip); in hercules_mixer_init()
3370 if (chip->in_suspend) in hercules_mixer_init()
3376 kctl = snd_ctl_new1(&snd_hercules_controls[idx], chip); in hercules_mixer_init()
3378 printk (KERN_ERR "cs46xx: failed to initialize Hercules mixer (%d)\n",err); in hercules_mixer_init()
3391 static void amp_voyetra_4294(struct snd_cs46xx *chip, int change)
3393 chip->amplifier += change;
3395 if (chip->amplifier) {
3396 /* Switch the GPIO pins 7 and 8 to open drain */
3397 snd_cs46xx_codec_write(chip, 0x4C,
3398 snd_cs46xx_codec_read(chip, 0x4C) & 0xFE7F);
3399 snd_cs46xx_codec_write(chip, 0x4E,
3400 snd_cs46xx_codec_read(chip, 0x4E) | 0x0180);
3402 snd_cs46xx_codec_write(chip, 0x54,
3403 snd_cs46xx_codec_read(chip, 0x54) & ~0x0180);
3405 snd_cs46xx_codec_write(chip, 0x54,
3406 snd_cs46xx_codec_read(chip, 0x54) | 0x0180);
3414 * whenever we need to beat on the chip.
3418 * enough to make them useful.
3421 static void clkrun_hack(struct snd_cs46xx *chip, int change) in clkrun_hack() argument
3425 if (!chip->acpi_port) in clkrun_hack()
3428 chip->amplifier += change; in clkrun_hack()
3431 nval = control = inw(chip->acpi_port + 0x10); in clkrun_hack()
3434 if (! chip->amplifier) in clkrun_hack()
3439 outw(nval, chip->acpi_port + 0x10); in clkrun_hack()
3446 static void clkrun_init(struct snd_cs46xx *chip) in clkrun_init() argument
3451 chip->acpi_port = 0; in clkrun_init()
3460 chip->acpi_port = pp << 8; in clkrun_init()
3605 struct snd_cs46xx *chip = card->private_data; in snd_cs46xx_suspend() local
3609 chip->in_suspend = 1; in snd_cs46xx_suspend()
3610 snd_pcm_suspend_all(chip->pcm); in snd_cs46xx_suspend()
3611 // chip->ac97_powerdown = snd_cs46xx_codec_read(chip, AC97_POWER_CONTROL); in snd_cs46xx_suspend()
3612 // chip->ac97_general_purpose = snd_cs46xx_codec_read(chip, BA0_AC97_GENERAL_PURPOSE); in snd_cs46xx_suspend()
3614 snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); in snd_cs46xx_suspend()
3615 snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); in snd_cs46xx_suspend()
3619 chip->saved_regs[i] = snd_cs46xx_peekBA0(chip, saved_regs[i]); in snd_cs46xx_suspend()
3621 amp_saved = chip->amplifier; in snd_cs46xx_suspend()
3623 chip->amplifier_ctrl(chip, -chip->amplifier); in snd_cs46xx_suspend()
3624 snd_cs46xx_hw_stop(chip); in snd_cs46xx_suspend()
3626 chip->active_ctrl(chip, -chip->amplifier); in snd_cs46xx_suspend()
3627 chip->amplifier = amp_saved; /* restore the status */ in snd_cs46xx_suspend()
3638 struct snd_cs46xx *chip = card->private_data; in snd_cs46xx_resume() local
3651 return -EIO; in snd_cs46xx_resume()
3655 amp_saved = chip->amplifier; in snd_cs46xx_resume()
3656 chip->amplifier = 0; in snd_cs46xx_resume()
3657 chip->active_ctrl(chip, 1); /* force to on */ in snd_cs46xx_resume()
3659 snd_cs46xx_chip_init(chip); in snd_cs46xx_resume()
3661 snd_cs46xx_reset(chip); in snd_cs46xx_resume()
3663 cs46xx_dsp_resume(chip); in snd_cs46xx_resume()
3666 snd_cs46xx_pokeBA0(chip, saved_regs[i], chip->saved_regs[i]); in snd_cs46xx_resume()
3668 snd_cs46xx_download_image(chip); in snd_cs46xx_resume()
3672 snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE, in snd_cs46xx_resume()
3673 chip->ac97_general_purpose); in snd_cs46xx_resume()
3674 snd_cs46xx_codec_write(chip, AC97_POWER_CONTROL, in snd_cs46xx_resume()
3675 chip->ac97_powerdown); in snd_cs46xx_resume()
3677 snd_cs46xx_codec_write(chip, BA0_AC97_POWERDOWN, in snd_cs46xx_resume()
3678 chip->ac97_powerdown); in snd_cs46xx_resume()
3682 snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); in snd_cs46xx_resume()
3683 snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); in snd_cs46xx_resume()
3688 tmp = snd_cs46xx_peek(chip, BA1_CCTL); in snd_cs46xx_resume()
3689 chip->capt.ctl = tmp & 0x0000ffff; in snd_cs46xx_resume()
3690 snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000); in snd_cs46xx_resume()
3695 snd_cs46xx_set_play_sample_rate(chip, 8000); in snd_cs46xx_resume()
3696 snd_cs46xx_set_capture_sample_rate(chip, 8000); in snd_cs46xx_resume()
3697 snd_cs46xx_proc_start(chip); in snd_cs46xx_resume()
3699 cs46xx_enable_stream_irqs(chip); in snd_cs46xx_resume()
3702 chip->amplifier_ctrl(chip, 1); /* turn amp on */ in snd_cs46xx_resume()
3704 chip->active_ctrl(chip, -1); /* disable CLKRUN */ in snd_cs46xx_resume()
3705 chip->amplifier = amp_saved; in snd_cs46xx_resume()
3706 chip->in_suspend = 0; in snd_cs46xx_resume()
3721 struct snd_cs46xx *chip; in snd_cs46xx_create() local
3736 chip = kzalloc(sizeof(*chip), GFP_KERNEL); in snd_cs46xx_create()
3737 if (chip == NULL) { in snd_cs46xx_create()
3739 return -ENOMEM; in snd_cs46xx_create()
3741 spin_lock_init(&chip->reg_lock); in snd_cs46xx_create()
3743 mutex_init(&chip->spos_mutex); in snd_cs46xx_create()
3745 chip->card = card; in snd_cs46xx_create()
3746 chip->pci = pci; in snd_cs46xx_create()
3747 chip->irq = -1; in snd_cs46xx_create()
3748 chip->ba0_addr = pci_resource_start(pci, 0); in snd_cs46xx_create()
3749 chip->ba1_addr = pci_resource_start(pci, 1); in snd_cs46xx_create()
3750 if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 || in snd_cs46xx_create()
3751 chip->ba1_addr == 0 || chip->ba1_addr == (unsigned long)~0) { in snd_cs46xx_create()
3752 snd_printk(KERN_ERR "wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n", in snd_cs46xx_create()
3753 chip->ba0_addr, chip->ba1_addr); in snd_cs46xx_create()
3754 snd_cs46xx_free(chip); in snd_cs46xx_create()
3755 return -ENOMEM; in snd_cs46xx_create()
3758 region = &chip->region.name.ba0; in snd_cs46xx_create()
3759 strcpy(region->name, "CS46xx_BA0"); in snd_cs46xx_create()
3760 region->base = chip->ba0_addr; in snd_cs46xx_create()
3761 region->size = CS46XX_BA0_SIZE; in snd_cs46xx_create()
3763 region = &chip->region.name.data0; in snd_cs46xx_create()
3764 strcpy(region->name, "CS46xx_BA1_data0"); in snd_cs46xx_create()
3765 region->base = chip->ba1_addr + BA1_SP_DMEM0; in snd_cs46xx_create()
3766 region->size = CS46XX_BA1_DATA0_SIZE; in snd_cs46xx_create()
3768 region = &chip->region.name.data1; in snd_cs46xx_create()
3769 strcpy(region->name, "CS46xx_BA1_data1"); in snd_cs46xx_create()
3770 region->base = chip->ba1_addr + BA1_SP_DMEM1; in snd_cs46xx_create()
3771 region->size = CS46XX_BA1_DATA1_SIZE; in snd_cs46xx_create()
3773 region = &chip->region.name.pmem; in snd_cs46xx_create()
3774 strcpy(region->name, "CS46xx_BA1_pmem"); in snd_cs46xx_create()
3775 region->base = chip->ba1_addr + BA1_SP_PMEM; in snd_cs46xx_create()
3776 region->size = CS46XX_BA1_PRG_SIZE; in snd_cs46xx_create()
3778 region = &chip->region.name.reg; in snd_cs46xx_create()
3779 strcpy(region->name, "CS46xx_BA1_reg"); in snd_cs46xx_create()
3780 region->base = chip->ba1_addr + BA1_SP_REG; in snd_cs46xx_create()
3781 region->size = CS46XX_BA1_REG_SIZE; in snd_cs46xx_create()
3787 for (cp = &cards[0]; cp->name; cp++) { in snd_cs46xx_create()
3788 if (cp->vendor == ss_vendor && cp->id == ss_card) { in snd_cs46xx_create()
3789 snd_printdd ("hack for %s enabled\n", cp->name); in snd_cs46xx_create()
3791 chip->amplifier_ctrl = cp->amp; in snd_cs46xx_create()
3792 chip->active_ctrl = cp->active; in snd_cs46xx_create()
3793 chip->mixer_init = cp->mixer_init; in snd_cs46xx_create()
3795 if (cp->init) in snd_cs46xx_create()
3796 cp->init(chip); in snd_cs46xx_create()
3803 chip->amplifier_ctrl = amp_voyetra; in snd_cs46xx_create()
3808 chip->active_ctrl = clkrun_hack; in snd_cs46xx_create()
3809 clkrun_init(chip); in snd_cs46xx_create()
3812 if (chip->amplifier_ctrl == NULL) in snd_cs46xx_create()
3813 chip->amplifier_ctrl = amp_none; in snd_cs46xx_create()
3814 if (chip->active_ctrl == NULL) in snd_cs46xx_create()
3815 chip->active_ctrl = amp_none; in snd_cs46xx_create()
3817 chip->active_ctrl(chip, 1); /* enable CLKRUN */ in snd_cs46xx_create()
3822 region = &chip->region.idx[idx]; in snd_cs46xx_create()
3823 if ((region->resource = request_mem_region(region->base, region->size, in snd_cs46xx_create()
3824 region->name)) == NULL) { in snd_cs46xx_create()
3825 snd_printk(KERN_ERR "unable to request memory region 0x%lx-0x%lx\n", in snd_cs46xx_create()
3826 region->base, region->base + region->size - 1); in snd_cs46xx_create()
3827 snd_cs46xx_free(chip); in snd_cs46xx_create()
3828 return -EBUSY; in snd_cs46xx_create()
3830 region->remap_addr = ioremap_nocache(region->base, region->size); in snd_cs46xx_create()
3831 if (region->remap_addr == NULL) { in snd_cs46xx_create()
3832 snd_printk(KERN_ERR "%s ioremap problem\n", region->name); in snd_cs46xx_create()
3833 snd_cs46xx_free(chip); in snd_cs46xx_create()
3834 return -ENOMEM; in snd_cs46xx_create()
3838 if (request_irq(pci->irq, snd_cs46xx_interrupt, IRQF_SHARED, in snd_cs46xx_create()
3839 KBUILD_MODNAME, chip)) { in snd_cs46xx_create()
3840 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); in snd_cs46xx_create()
3841 snd_cs46xx_free(chip); in snd_cs46xx_create()
3842 return -EBUSY; in snd_cs46xx_create()
3844 chip->irq = pci->irq; in snd_cs46xx_create()
3847 chip->dsp_spos_instance = cs46xx_dsp_spos_create(chip); in snd_cs46xx_create()
3848 if (chip->dsp_spos_instance == NULL) { in snd_cs46xx_create()
3849 snd_cs46xx_free(chip); in snd_cs46xx_create()
3850 return -ENOMEM; in snd_cs46xx_create()
3854 err = snd_cs46xx_chip_init(chip); in snd_cs46xx_create()
3856 snd_cs46xx_free(chip); in snd_cs46xx_create()
3860 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { in snd_cs46xx_create()
3861 snd_cs46xx_free(chip); in snd_cs46xx_create()
3865 snd_cs46xx_proc_init(card, chip); in snd_cs46xx_create()
3868 chip->saved_regs = kmalloc(sizeof(*chip->saved_regs) * in snd_cs46xx_create()
3870 if (!chip->saved_regs) { in snd_cs46xx_create()
3871 snd_cs46xx_free(chip); in snd_cs46xx_create()
3872 return -ENOMEM; in snd_cs46xx_create()
3876 chip->active_ctrl(chip, -1); /* disable CLKRUN */ in snd_cs46xx_create()
3878 snd_card_set_dev(card, &pci->dev); in snd_cs46xx_create()
3880 *rchip = chip; in snd_cs46xx_create()