cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cs46xx_lib.c (108409B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
      4 *                   Abramo Bagnara <abramo@alsa-project.org>
      5 *                   Cirrus Logic, Inc.
      6 *  Routines for control of Cirrus Logic CS461x chips
      7 *
      8 *  KNOWN BUGS:
      9 *    - Sometimes the SPDIF input DSP tasks get's unsynchronized
     10 *      and the SPDIF get somewhat "distorcionated", or/and left right channel
     11 *      are swapped. To get around this problem when it happens, mute and unmute 
     12 *      the SPDIF input mixer control.
     13 *    - On the Hercules Game Theater XP the amplifier are sometimes turned
     14 *      off on inadecuate moments which causes distorcions on sound.
     15 *
     16 *  TODO:
     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
     21 *
     22 *  NOTE: with CONFIG_SND_CS46XX_NEW_DSP unset uses old DSP image (which
     23 *        is default configuration), no SPDIF, no secondary codec, no
     24 *        multi channel PCM.  But known to work.
     25 *
     26 *  FINALLY: A credit to the developers Tom and Jordan 
     27 *           at Cirrus for have helping me out with the DSP, however we
     28 *           still don't have sufficient documentation and technical
     29 *           references to be able to implement all fancy feutures
     30 *           supported by the cs46xx DSP's. 
     31 *           Benny <benny@hostmobility.com>
     32 */
     33
     34#include <linux/delay.h>
     35#include <linux/pci.h>
     36#include <linux/pm.h>
     37#include <linux/init.h>
     38#include <linux/interrupt.h>
     39#include <linux/slab.h>
     40#include <linux/gameport.h>
     41#include <linux/mutex.h>
     42#include <linux/export.h>
     43#include <linux/module.h>
     44#include <linux/firmware.h>
     45#include <linux/vmalloc.h>
     46#include <linux/io.h>
     47
     48#include <sound/core.h>
     49#include <sound/control.h>
     50#include <sound/info.h>
     51#include <sound/pcm.h>
     52#include <sound/pcm_params.h>
     53#include "cs46xx.h"
     54
     55#include "cs46xx_lib.h"
     56#include "dsp_spos.h"
     57
     58static void amp_voyetra(struct snd_cs46xx *chip, int change);
     59
     60#ifdef CONFIG_SND_CS46XX_NEW_DSP
     61static const struct snd_pcm_ops snd_cs46xx_playback_rear_ops;
     62static const struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops;
     63static const struct snd_pcm_ops snd_cs46xx_playback_clfe_ops;
     64static const struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops;
     65static const struct snd_pcm_ops snd_cs46xx_playback_iec958_ops;
     66static const struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops;
     67#endif
     68
     69static const struct snd_pcm_ops snd_cs46xx_playback_ops;
     70static const struct snd_pcm_ops snd_cs46xx_playback_indirect_ops;
     71static const struct snd_pcm_ops snd_cs46xx_capture_ops;
     72static const struct snd_pcm_ops snd_cs46xx_capture_indirect_ops;
     73
     74static unsigned short snd_cs46xx_codec_read(struct snd_cs46xx *chip,
     75					    unsigned short reg,
     76					    int codec_index)
     77{
     78	int count;
     79	unsigned short result,tmp;
     80	u32 offset = 0;
     81
     82	if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
     83		       codec_index != CS46XX_SECONDARY_CODEC_INDEX))
     84		return 0xffff;
     85
     86	chip->active_ctrl(chip, 1);
     87
     88	if (codec_index == CS46XX_SECONDARY_CODEC_INDEX)
     89		offset = CS46XX_SECONDARY_CODEC_OFFSET;
     90
     91	/*
     92	 *  1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
     93	 *  2. Write ACCDA = Command Data Register = 470h    for data to write to AC97 
     94	 *  3. Write ACCTL = Control Register = 460h for initiating the write7---55
     95	 *  4. Read ACCTL = 460h, DCV should be reset by now and 460h = 17h
     96	 *  5. if DCV not cleared, break and return error
     97	 *  6. Read ACSTS = Status Register = 464h, check VSTS bit
     98	 */
     99
    100	snd_cs46xx_peekBA0(chip, BA0_ACSDA + offset);
    101
    102	tmp = snd_cs46xx_peekBA0(chip, BA0_ACCTL);
    103	if ((tmp & ACCTL_VFRM) == 0) {
    104		dev_warn(chip->card->dev, "ACCTL_VFRM not set 0x%x\n", tmp);
    105		snd_cs46xx_pokeBA0(chip, BA0_ACCTL, (tmp & (~ACCTL_ESYN)) | ACCTL_VFRM );
    106		msleep(50);
    107		tmp = snd_cs46xx_peekBA0(chip, BA0_ACCTL + offset);
    108		snd_cs46xx_pokeBA0(chip, BA0_ACCTL, tmp | ACCTL_ESYN | ACCTL_VFRM );
    109
    110	}
    111
    112	/*
    113	 *  Setup the AC97 control registers on the CS461x to send the
    114	 *  appropriate command to the AC97 to perform the read.
    115	 *  ACCAD = Command Address Register = 46Ch
    116	 *  ACCDA = Command Data Register = 470h
    117	 *  ACCTL = Control Register = 460h
    118	 *  set DCV - will clear when process completed
    119	 *  set CRW - Read command
    120	 *  set VFRM - valid frame enabled
    121	 *  set ESYN - ASYNC generation enabled
    122	 *  set RSTN - ARST# inactive, AC97 codec not reset
    123	 */
    124
    125	snd_cs46xx_pokeBA0(chip, BA0_ACCAD, reg);
    126	snd_cs46xx_pokeBA0(chip, BA0_ACCDA, 0);
    127	if (codec_index == CS46XX_PRIMARY_CODEC_INDEX) {
    128		snd_cs46xx_pokeBA0(chip, BA0_ACCTL,/* clear ACCTL_DCV */ ACCTL_CRW | 
    129				   ACCTL_VFRM | ACCTL_ESYN |
    130				   ACCTL_RSTN);
    131		snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_CRW |
    132				   ACCTL_VFRM | ACCTL_ESYN |
    133				   ACCTL_RSTN);
    134	} else {
    135		snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_TC |
    136				   ACCTL_CRW | ACCTL_VFRM | ACCTL_ESYN |
    137				   ACCTL_RSTN);
    138	}
    139
    140	/*
    141	 *  Wait for the read to occur.
    142	 */
    143	for (count = 0; count < 1000; count++) {
    144		/*
    145		 *  First, we want to wait for a short time.
    146	 	 */
    147		udelay(10);
    148		/*
    149		 *  Now, check to see if the read has completed.
    150		 *  ACCTL = 460h, DCV should be reset by now and 460h = 17h
    151		 */
    152		if (!(snd_cs46xx_peekBA0(chip, BA0_ACCTL) & ACCTL_DCV))
    153			goto ok1;
    154	}
    155
    156	dev_err(chip->card->dev,
    157		"AC'97 read problem (ACCTL_DCV), reg = 0x%x\n", reg);
    158	result = 0xffff;
    159	goto end;
    160	
    161 ok1:
    162	/*
    163	 *  Wait for the valid status bit to go active.
    164	 */
    165	for (count = 0; count < 100; count++) {
    166		/*
    167		 *  Read the AC97 status register.
    168		 *  ACSTS = Status Register = 464h
    169		 *  VSTS - Valid Status
    170		 */
    171		if (snd_cs46xx_peekBA0(chip, BA0_ACSTS + offset) & ACSTS_VSTS)
    172			goto ok2;
    173		udelay(10);
    174	}
    175	
    176	dev_err(chip->card->dev,
    177		"AC'97 read problem (ACSTS_VSTS), codec_index %d, reg = 0x%x\n",
    178		codec_index, reg);
    179	result = 0xffff;
    180	goto end;
    181
    182 ok2:
    183	/*
    184	 *  Read the data returned from the AC97 register.
    185	 *  ACSDA = Status Data Register = 474h
    186	 */
    187#if 0
    188	dev_dbg(chip->card->dev,
    189		"e) reg = 0x%x, val = 0x%x, BA0_ACCAD = 0x%x\n", reg,
    190			snd_cs46xx_peekBA0(chip, BA0_ACSDA),
    191			snd_cs46xx_peekBA0(chip, BA0_ACCAD));
    192#endif
    193
    194	//snd_cs46xx_peekBA0(chip, BA0_ACCAD);
    195	result = snd_cs46xx_peekBA0(chip, BA0_ACSDA + offset);
    196 end:
    197	chip->active_ctrl(chip, -1);
    198	return result;
    199}
    200
    201static unsigned short snd_cs46xx_ac97_read(struct snd_ac97 * ac97,
    202					    unsigned short reg)
    203{
    204	struct snd_cs46xx *chip = ac97->private_data;
    205	unsigned short val;
    206	int codec_index = ac97->num;
    207
    208	if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
    209		       codec_index != CS46XX_SECONDARY_CODEC_INDEX))
    210		return 0xffff;
    211
    212	val = snd_cs46xx_codec_read(chip, reg, codec_index);
    213
    214	return val;
    215}
    216
    217
    218static void snd_cs46xx_codec_write(struct snd_cs46xx *chip,
    219				   unsigned short reg,
    220				   unsigned short val,
    221				   int codec_index)
    222{
    223	int count;
    224
    225	if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
    226		       codec_index != CS46XX_SECONDARY_CODEC_INDEX))
    227		return;
    228
    229	chip->active_ctrl(chip, 1);
    230
    231	/*
    232	 *  1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
    233	 *  2. Write ACCDA = Command Data Register = 470h    for data to write to AC97
    234	 *  3. Write ACCTL = Control Register = 460h for initiating the write
    235	 *  4. Read ACCTL = 460h, DCV should be reset by now and 460h = 07h
    236	 *  5. if DCV not cleared, break and return error
    237	 */
    238
    239	/*
    240	 *  Setup the AC97 control registers on the CS461x to send the
    241	 *  appropriate command to the AC97 to perform the read.
    242	 *  ACCAD = Command Address Register = 46Ch
    243	 *  ACCDA = Command Data Register = 470h
    244	 *  ACCTL = Control Register = 460h
    245	 *  set DCV - will clear when process completed
    246	 *  reset CRW - Write command
    247	 *  set VFRM - valid frame enabled
    248	 *  set ESYN - ASYNC generation enabled
    249	 *  set RSTN - ARST# inactive, AC97 codec not reset
    250         */
    251	snd_cs46xx_pokeBA0(chip, BA0_ACCAD , reg);
    252	snd_cs46xx_pokeBA0(chip, BA0_ACCDA , val);
    253	snd_cs46xx_peekBA0(chip, BA0_ACCTL);
    254
    255	if (codec_index == CS46XX_PRIMARY_CODEC_INDEX) {
    256		snd_cs46xx_pokeBA0(chip, BA0_ACCTL, /* clear ACCTL_DCV */ ACCTL_VFRM |
    257				   ACCTL_ESYN | ACCTL_RSTN);
    258		snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_VFRM |
    259				   ACCTL_ESYN | ACCTL_RSTN);
    260	} else {
    261		snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_TC |
    262				   ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
    263	}
    264
    265	for (count = 0; count < 4000; count++) {
    266		/*
    267		 *  First, we want to wait for a short time.
    268		 */
    269		udelay(10);
    270		/*
    271		 *  Now, check to see if the write has completed.
    272		 *  ACCTL = 460h, DCV should be reset by now and 460h = 07h
    273		 */
    274		if (!(snd_cs46xx_peekBA0(chip, BA0_ACCTL) & ACCTL_DCV)) {
    275			goto end;
    276		}
    277	}
    278	dev_err(chip->card->dev,
    279		"AC'97 write problem, codec_index = %d, reg = 0x%x, val = 0x%x\n",
    280		codec_index, reg, val);
    281 end:
    282	chip->active_ctrl(chip, -1);
    283}
    284
    285static void snd_cs46xx_ac97_write(struct snd_ac97 *ac97,
    286				   unsigned short reg,
    287				   unsigned short val)
    288{
    289	struct snd_cs46xx *chip = ac97->private_data;
    290	int codec_index = ac97->num;
    291
    292	if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
    293		       codec_index != CS46XX_SECONDARY_CODEC_INDEX))
    294		return;
    295
    296	snd_cs46xx_codec_write(chip, reg, val, codec_index);
    297}
    298
    299
    300/*
    301 *  Chip initialization
    302 */
    303
    304int snd_cs46xx_download(struct snd_cs46xx *chip,
    305			u32 *src,
    306                        unsigned long offset,
    307                        unsigned long len)
    308{
    309	void __iomem *dst;
    310	unsigned int bank = offset >> 16;
    311	offset = offset & 0xffff;
    312
    313	if (snd_BUG_ON((offset & 3) || (len & 3)))
    314		return -EINVAL;
    315	dst = chip->region.idx[bank+1].remap_addr + offset;
    316	len /= sizeof(u32);
    317
    318	/* writel already converts 32-bit value to right endianess */
    319	while (len-- > 0) {
    320		writel(*src++, dst);
    321		dst += sizeof(u32);
    322	}
    323	return 0;
    324}
    325
    326static inline void memcpy_le32(void *dst, const void *src, unsigned int len)
    327{
    328#ifdef __LITTLE_ENDIAN
    329	memcpy(dst, src, len);
    330#else
    331	u32 *_dst = dst;
    332	const __le32 *_src = src;
    333	len /= 4;
    334	while (len-- > 0)
    335		*_dst++ = le32_to_cpu(*_src++);
    336#endif
    337}
    338
    339#ifdef CONFIG_SND_CS46XX_NEW_DSP
    340
    341static const char *module_names[CS46XX_DSP_MODULES] = {
    342	"cwc4630", "cwcasync", "cwcsnoop", "cwcbinhack", "cwcdma"
    343};
    344
    345MODULE_FIRMWARE("cs46xx/cwc4630");
    346MODULE_FIRMWARE("cs46xx/cwcasync");
    347MODULE_FIRMWARE("cs46xx/cwcsnoop");
    348MODULE_FIRMWARE("cs46xx/cwcbinhack");
    349MODULE_FIRMWARE("cs46xx/cwcdma");
    350
    351static void free_module_desc(struct dsp_module_desc *module)
    352{
    353	if (!module)
    354		return;
    355	kfree(module->module_name);
    356	kfree(module->symbol_table.symbols);
    357	if (module->segments) {
    358		int i;
    359		for (i = 0; i < module->nsegments; i++)
    360			kfree(module->segments[i].data);
    361		kfree(module->segments);
    362	}
    363	kfree(module);
    364}
    365
    366/* firmware binary format:
    367 * le32 nsymbols;
    368 * struct {
    369 *	le32 address;
    370 *	char symbol_name[DSP_MAX_SYMBOL_NAME];
    371 *	le32 symbol_type;
    372 * } symbols[nsymbols];
    373 * le32 nsegments;
    374 * struct {
    375 *	le32 segment_type;
    376 *	le32 offset;
    377 *	le32 size;
    378 *	le32 data[size];
    379 * } segments[nsegments];
    380 */
    381
    382static int load_firmware(struct snd_cs46xx *chip,
    383			 struct dsp_module_desc **module_ret,
    384			 const char *fw_name)
    385{
    386	int i, err;
    387	unsigned int nums, fwlen, fwsize;
    388	const __le32 *fwdat;
    389	struct dsp_module_desc *module = NULL;
    390	const struct firmware *fw;
    391	char fw_path[32];
    392
    393	sprintf(fw_path, "cs46xx/%s", fw_name);
    394	err = request_firmware(&fw, fw_path, &chip->pci->dev);
    395	if (err < 0)
    396		return err;
    397	fwsize = fw->size / 4;
    398	if (fwsize < 2) {
    399		err = -EINVAL;
    400		goto error;
    401	}
    402
    403	err = -ENOMEM;
    404	module = kzalloc(sizeof(*module), GFP_KERNEL);
    405	if (!module)
    406		goto error;
    407	module->module_name = kstrdup(fw_name, GFP_KERNEL);
    408	if (!module->module_name)
    409		goto error;
    410
    411	fwlen = 0;
    412	fwdat = (const __le32 *)fw->data;
    413	nums = module->symbol_table.nsymbols = le32_to_cpu(fwdat[fwlen++]);
    414	if (nums >= 40)
    415		goto error_inval;
    416	module->symbol_table.symbols =
    417		kcalloc(nums, sizeof(struct dsp_symbol_entry), GFP_KERNEL);
    418	if (!module->symbol_table.symbols)
    419		goto error;
    420	for (i = 0; i < nums; i++) {
    421		struct dsp_symbol_entry *entry =
    422			&module->symbol_table.symbols[i];
    423		if (fwlen + 2 + DSP_MAX_SYMBOL_NAME / 4 > fwsize)
    424			goto error_inval;
    425		entry->address = le32_to_cpu(fwdat[fwlen++]);
    426		memcpy(entry->symbol_name, &fwdat[fwlen], DSP_MAX_SYMBOL_NAME - 1);
    427		fwlen += DSP_MAX_SYMBOL_NAME / 4;
    428		entry->symbol_type = le32_to_cpu(fwdat[fwlen++]);
    429	}
    430
    431	if (fwlen >= fwsize)
    432		goto error_inval;
    433	nums = module->nsegments = le32_to_cpu(fwdat[fwlen++]);
    434	if (nums > 10)
    435		goto error_inval;
    436	module->segments =
    437		kcalloc(nums, sizeof(struct dsp_segment_desc), GFP_KERNEL);
    438	if (!module->segments)
    439		goto error;
    440	for (i = 0; i < nums; i++) {
    441		struct dsp_segment_desc *entry = &module->segments[i];
    442		if (fwlen + 3 > fwsize)
    443			goto error_inval;
    444		entry->segment_type = le32_to_cpu(fwdat[fwlen++]);
    445		entry->offset = le32_to_cpu(fwdat[fwlen++]);
    446		entry->size = le32_to_cpu(fwdat[fwlen++]);
    447		if (fwlen + entry->size > fwsize)
    448			goto error_inval;
    449		entry->data = kmalloc_array(entry->size, 4, GFP_KERNEL);
    450		if (!entry->data)
    451			goto error;
    452		memcpy_le32(entry->data, &fwdat[fwlen], entry->size * 4);
    453		fwlen += entry->size;
    454	}
    455
    456	*module_ret = module;
    457	release_firmware(fw);
    458	return 0;
    459
    460 error_inval:
    461	err = -EINVAL;
    462 error:
    463	free_module_desc(module);
    464	release_firmware(fw);
    465	return err;
    466}
    467
    468int snd_cs46xx_clear_BA1(struct snd_cs46xx *chip,
    469                         unsigned long offset,
    470                         unsigned long len) 
    471{
    472	void __iomem *dst;
    473	unsigned int bank = offset >> 16;
    474	offset = offset & 0xffff;
    475
    476	if (snd_BUG_ON((offset & 3) || (len & 3)))
    477		return -EINVAL;
    478	dst = chip->region.idx[bank+1].remap_addr + offset;
    479	len /= sizeof(u32);
    480
    481	/* writel already converts 32-bit value to right endianess */
    482	while (len-- > 0) {
    483		writel(0, dst);
    484		dst += sizeof(u32);
    485	}
    486	return 0;
    487}
    488
    489#else /* old DSP image */
    490
    491struct ba1_struct {
    492	struct {
    493		u32 offset;
    494		u32 size;
    495	} memory[BA1_MEMORY_COUNT];
    496	u32 map[BA1_DWORD_SIZE];
    497};
    498
    499MODULE_FIRMWARE("cs46xx/ba1");
    500
    501static int load_firmware(struct snd_cs46xx *chip)
    502{
    503	const struct firmware *fw;
    504	int i, size, err;
    505
    506	err = request_firmware(&fw, "cs46xx/ba1", &chip->pci->dev);
    507	if (err < 0)
    508		return err;
    509	if (fw->size != sizeof(*chip->ba1)) {
    510		err = -EINVAL;
    511		goto error;
    512	}
    513
    514	chip->ba1 = vmalloc(sizeof(*chip->ba1));
    515	if (!chip->ba1) {
    516		err = -ENOMEM;
    517		goto error;
    518	}
    519
    520	memcpy_le32(chip->ba1, fw->data, sizeof(*chip->ba1));
    521
    522	/* sanity check */
    523	size = 0;
    524	for (i = 0; i < BA1_MEMORY_COUNT; i++)
    525		size += chip->ba1->memory[i].size;
    526	if (size > BA1_DWORD_SIZE * 4)
    527		err = -EINVAL;
    528
    529 error:
    530	release_firmware(fw);
    531	return err;
    532}
    533
    534int snd_cs46xx_download_image(struct snd_cs46xx *chip)
    535{
    536	int idx, err;
    537	unsigned int offset = 0;
    538	struct ba1_struct *ba1 = chip->ba1;
    539
    540	for (idx = 0; idx < BA1_MEMORY_COUNT; idx++) {
    541		err = snd_cs46xx_download(chip,
    542					  &ba1->map[offset],
    543					  ba1->memory[idx].offset,
    544					  ba1->memory[idx].size);
    545		if (err < 0)
    546			return err;
    547		offset += ba1->memory[idx].size >> 2;
    548	}	
    549	return 0;
    550}
    551#endif /* CONFIG_SND_CS46XX_NEW_DSP */
    552
    553/*
    554 *  Chip reset
    555 */
    556
    557static void snd_cs46xx_reset(struct snd_cs46xx *chip)
    558{
    559	int idx;
    560
    561	/*
    562	 *  Write the reset bit of the SP control register.
    563	 */
    564	snd_cs46xx_poke(chip, BA1_SPCR, SPCR_RSTSP);
    565
    566	/*
    567	 *  Write the control register.
    568	 */
    569	snd_cs46xx_poke(chip, BA1_SPCR, SPCR_DRQEN);
    570
    571	/*
    572	 *  Clear the trap registers.
    573	 */
    574	for (idx = 0; idx < 8; idx++) {
    575		snd_cs46xx_poke(chip, BA1_DREG, DREG_REGID_TRAP_SELECT + idx);
    576		snd_cs46xx_poke(chip, BA1_TWPR, 0xFFFF);
    577	}
    578	snd_cs46xx_poke(chip, BA1_DREG, 0);
    579
    580	/*
    581	 *  Set the frame timer to reflect the number of cycles per frame.
    582	 */
    583	snd_cs46xx_poke(chip, BA1_FRMT, 0xadf);
    584}
    585
    586static int cs46xx_wait_for_fifo(struct snd_cs46xx * chip,int retry_timeout) 
    587{
    588	u32 i, status = 0;
    589	/*
    590	 * Make sure the previous FIFO write operation has completed.
    591	 */
    592	for(i = 0; i < 50; i++){
    593		status = snd_cs46xx_peekBA0(chip, BA0_SERBST);
    594    
    595		if( !(status & SERBST_WBSY) )
    596			break;
    597
    598		mdelay(retry_timeout);
    599	}
    600  
    601	if(status & SERBST_WBSY) {
    602		dev_err(chip->card->dev,
    603			"failure waiting for FIFO command to complete\n");
    604		return -EINVAL;
    605	}
    606
    607	return 0;
    608}
    609
    610static void snd_cs46xx_clear_serial_FIFOs(struct snd_cs46xx *chip)
    611{
    612	int idx, powerdown = 0;
    613	unsigned int tmp;
    614
    615	/*
    616	 *  See if the devices are powered down.  If so, we must power them up first
    617	 *  or they will not respond.
    618	 */
    619	tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1);
    620	if (!(tmp & CLKCR1_SWCE)) {
    621		snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp | CLKCR1_SWCE);
    622		powerdown = 1;
    623	}
    624
    625	/*
    626	 *  We want to clear out the serial port FIFOs so we don't end up playing
    627	 *  whatever random garbage happens to be in them.  We fill the sample FIFOS
    628	 *  with zero (silence).
    629	 */
    630	snd_cs46xx_pokeBA0(chip, BA0_SERBWP, 0);
    631
    632	/*
    633	 *  Fill all 256 sample FIFO locations.
    634	 */
    635	for (idx = 0; idx < 0xFF; idx++) {
    636		/*
    637		 *  Make sure the previous FIFO write operation has completed.
    638		 */
    639		if (cs46xx_wait_for_fifo(chip,1)) {
    640			dev_dbg(chip->card->dev,
    641				"failed waiting for FIFO at addr (%02X)\n",
    642				idx);
    643
    644			if (powerdown)
    645				snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp);
    646          
    647			break;
    648		}
    649		/*
    650		 *  Write the serial port FIFO index.
    651		 */
    652		snd_cs46xx_pokeBA0(chip, BA0_SERBAD, idx);
    653		/*
    654		 *  Tell the serial port to load the new value into the FIFO location.
    655		 */
    656		snd_cs46xx_pokeBA0(chip, BA0_SERBCM, SERBCM_WRC);
    657	}
    658	/*
    659	 *  Now, if we powered up the devices, then power them back down again.
    660	 *  This is kinda ugly, but should never happen.
    661	 */
    662	if (powerdown)
    663		snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp);
    664}
    665
    666static void snd_cs46xx_proc_start(struct snd_cs46xx *chip)
    667{
    668	int cnt;
    669
    670	/*
    671	 *  Set the frame timer to reflect the number of cycles per frame.
    672	 */
    673	snd_cs46xx_poke(chip, BA1_FRMT, 0xadf);
    674	/*
    675	 *  Turn on the run, run at frame, and DMA enable bits in the local copy of
    676	 *  the SP control register.
    677	 */
    678	snd_cs46xx_poke(chip, BA1_SPCR, SPCR_RUN | SPCR_RUNFR | SPCR_DRQEN);
    679	/*
    680	 *  Wait until the run at frame bit resets itself in the SP control
    681	 *  register.
    682	 */
    683	for (cnt = 0; cnt < 25; cnt++) {
    684		udelay(50);
    685		if (!(snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR))
    686			break;
    687	}
    688
    689	if (snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR)
    690		dev_err(chip->card->dev, "SPCR_RUNFR never reset\n");
    691}
    692
    693static void snd_cs46xx_proc_stop(struct snd_cs46xx *chip)
    694{
    695	/*
    696	 *  Turn off the run, run at frame, and DMA enable bits in the local copy of
    697	 *  the SP control register.
    698	 */
    699	snd_cs46xx_poke(chip, BA1_SPCR, 0);
    700}
    701
    702/*
    703 *  Sample rate routines
    704 */
    705
    706#define GOF_PER_SEC 200
    707
    708static void snd_cs46xx_set_play_sample_rate(struct snd_cs46xx *chip, unsigned int rate)
    709{
    710	unsigned long flags;
    711	unsigned int tmp1, tmp2;
    712	unsigned int phiIncr;
    713	unsigned int correctionPerGOF, correctionPerSec;
    714
    715	/*
    716	 *  Compute the values used to drive the actual sample rate conversion.
    717	 *  The following formulas are being computed, using inline assembly
    718	 *  since we need to use 64 bit arithmetic to compute the values:
    719	 *
    720	 *  phiIncr = floor((Fs,in * 2^26) / Fs,out)
    721	 *  correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) /
    722         *                                   GOF_PER_SEC)
    723         *  ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -M
    724         *                       GOF_PER_SEC * correctionPerGOF
    725	 *
    726	 *  i.e.
    727	 *
    728	 *  phiIncr:other = dividend:remainder((Fs,in * 2^26) / Fs,out)
    729	 *  correctionPerGOF:correctionPerSec =
    730	 *      dividend:remainder(ulOther / GOF_PER_SEC)
    731	 */
    732	tmp1 = rate << 16;
    733	phiIncr = tmp1 / 48000;
    734	tmp1 -= phiIncr * 48000;
    735	tmp1 <<= 10;
    736	phiIncr <<= 10;
    737	tmp2 = tmp1 / 48000;
    738	phiIncr += tmp2;
    739	tmp1 -= tmp2 * 48000;
    740	correctionPerGOF = tmp1 / GOF_PER_SEC;
    741	tmp1 -= correctionPerGOF * GOF_PER_SEC;
    742	correctionPerSec = tmp1;
    743
    744	/*
    745	 *  Fill in the SampleRateConverter control block.
    746	 */
    747	spin_lock_irqsave(&chip->reg_lock, flags);
    748	snd_cs46xx_poke(chip, BA1_PSRC,
    749	  ((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF));
    750	snd_cs46xx_poke(chip, BA1_PPI, phiIncr);
    751	spin_unlock_irqrestore(&chip->reg_lock, flags);
    752}
    753
    754static void snd_cs46xx_set_capture_sample_rate(struct snd_cs46xx *chip, unsigned int rate)
    755{
    756	unsigned long flags;
    757	unsigned int phiIncr, coeffIncr, tmp1, tmp2;
    758	unsigned int correctionPerGOF, correctionPerSec, initialDelay;
    759	unsigned int frameGroupLength, cnt;
    760
    761	/*
    762	 *  We can only decimate by up to a factor of 1/9th the hardware rate.
    763	 *  Correct the value if an attempt is made to stray outside that limit.
    764	 */
    765	if ((rate * 9) < 48000)
    766		rate = 48000 / 9;
    767
    768	/*
    769	 *  We can not capture at a rate greater than the Input Rate (48000).
    770	 *  Return an error if an attempt is made to stray outside that limit.
    771	 */
    772	if (rate > 48000)
    773		rate = 48000;
    774
    775	/*
    776	 *  Compute the values used to drive the actual sample rate conversion.
    777	 *  The following formulas are being computed, using inline assembly
    778	 *  since we need to use 64 bit arithmetic to compute the values:
    779	 *
    780	 *     coeffIncr = -floor((Fs,out * 2^23) / Fs,in)
    781	 *     phiIncr = floor((Fs,in * 2^26) / Fs,out)
    782	 *     correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) /
    783	 *                                GOF_PER_SEC)
    784	 *     correctionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -
    785	 *                          GOF_PER_SEC * correctionPerGOF
    786	 *     initialDelay = ceil((24 * Fs,in) / Fs,out)
    787	 *
    788	 * i.e.
    789	 *
    790	 *     coeffIncr = neg(dividend((Fs,out * 2^23) / Fs,in))
    791	 *     phiIncr:ulOther = dividend:remainder((Fs,in * 2^26) / Fs,out)
    792	 *     correctionPerGOF:correctionPerSec =
    793	 * 	    dividend:remainder(ulOther / GOF_PER_SEC)
    794	 *     initialDelay = dividend(((24 * Fs,in) + Fs,out - 1) / Fs,out)
    795	 */
    796
    797	tmp1 = rate << 16;
    798	coeffIncr = tmp1 / 48000;
    799	tmp1 -= coeffIncr * 48000;
    800	tmp1 <<= 7;
    801	coeffIncr <<= 7;
    802	coeffIncr += tmp1 / 48000;
    803	coeffIncr ^= 0xFFFFFFFF;
    804	coeffIncr++;
    805	tmp1 = 48000 << 16;
    806	phiIncr = tmp1 / rate;
    807	tmp1 -= phiIncr * rate;
    808	tmp1 <<= 10;
    809	phiIncr <<= 10;
    810	tmp2 = tmp1 / rate;
    811	phiIncr += tmp2;
    812	tmp1 -= tmp2 * rate;
    813	correctionPerGOF = tmp1 / GOF_PER_SEC;
    814	tmp1 -= correctionPerGOF * GOF_PER_SEC;
    815	correctionPerSec = tmp1;
    816	initialDelay = DIV_ROUND_UP(48000 * 24, rate);
    817
    818	/*
    819	 *  Fill in the VariDecimate control block.
    820	 */
    821	spin_lock_irqsave(&chip->reg_lock, flags);
    822	snd_cs46xx_poke(chip, BA1_CSRC,
    823		((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF));
    824	snd_cs46xx_poke(chip, BA1_CCI, coeffIncr);
    825	snd_cs46xx_poke(chip, BA1_CD,
    826		(((BA1_VARIDEC_BUF_1 + (initialDelay << 2)) << 16) & 0xFFFF0000) | 0x80);
    827	snd_cs46xx_poke(chip, BA1_CPI, phiIncr);
    828	spin_unlock_irqrestore(&chip->reg_lock, flags);
    829
    830	/*
    831	 *  Figure out the frame group length for the write back task.  Basically,
    832	 *  this is just the factors of 24000 (2^6*3*5^3) that are not present in
    833	 *  the output sample rate.
    834	 */
    835	frameGroupLength = 1;
    836	for (cnt = 2; cnt <= 64; cnt *= 2) {
    837		if (((rate / cnt) * cnt) != rate)
    838			frameGroupLength *= 2;
    839	}
    840	if (((rate / 3) * 3) != rate) {
    841		frameGroupLength *= 3;
    842	}
    843	for (cnt = 5; cnt <= 125; cnt *= 5) {
    844		if (((rate / cnt) * cnt) != rate) 
    845			frameGroupLength *= 5;
    846        }
    847
    848	/*
    849	 * Fill in the WriteBack control block.
    850	 */
    851	spin_lock_irqsave(&chip->reg_lock, flags);
    852	snd_cs46xx_poke(chip, BA1_CFG1, frameGroupLength);
    853	snd_cs46xx_poke(chip, BA1_CFG2, (0x00800000 | frameGroupLength));
    854	snd_cs46xx_poke(chip, BA1_CCST, 0x0000FFFF);
    855	snd_cs46xx_poke(chip, BA1_CSPB, ((65536 * rate) / 24000));
    856	snd_cs46xx_poke(chip, (BA1_CSPB + 4), 0x0000FFFF);
    857	spin_unlock_irqrestore(&chip->reg_lock, flags);
    858}
    859
    860/*
    861 *  PCM part
    862 */
    863
    864static void snd_cs46xx_pb_trans_copy(struct snd_pcm_substream *substream,
    865				     struct snd_pcm_indirect *rec, size_t bytes)
    866{
    867	struct snd_pcm_runtime *runtime = substream->runtime;
    868	struct snd_cs46xx_pcm * cpcm = runtime->private_data;
    869	memcpy(cpcm->hw_buf.area + rec->hw_data, runtime->dma_area + rec->sw_data, bytes);
    870}
    871
    872static int snd_cs46xx_playback_transfer(struct snd_pcm_substream *substream)
    873{
    874	struct snd_pcm_runtime *runtime = substream->runtime;
    875	struct snd_cs46xx_pcm * cpcm = runtime->private_data;
    876	return snd_pcm_indirect_playback_transfer(substream, &cpcm->pcm_rec,
    877						  snd_cs46xx_pb_trans_copy);
    878}
    879
    880static void snd_cs46xx_cp_trans_copy(struct snd_pcm_substream *substream,
    881				     struct snd_pcm_indirect *rec, size_t bytes)
    882{
    883	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
    884	struct snd_pcm_runtime *runtime = substream->runtime;
    885	memcpy(runtime->dma_area + rec->sw_data,
    886	       chip->capt.hw_buf.area + rec->hw_data, bytes);
    887}
    888
    889static int snd_cs46xx_capture_transfer(struct snd_pcm_substream *substream)
    890{
    891	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
    892	return snd_pcm_indirect_capture_transfer(substream, &chip->capt.pcm_rec,
    893						 snd_cs46xx_cp_trans_copy);
    894}
    895
    896static snd_pcm_uframes_t snd_cs46xx_playback_direct_pointer(struct snd_pcm_substream *substream)
    897{
    898	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
    899	size_t ptr;
    900	struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data;
    901
    902	if (snd_BUG_ON(!cpcm->pcm_channel))
    903		return -ENXIO;
    904
    905#ifdef CONFIG_SND_CS46XX_NEW_DSP
    906	ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2);
    907#else
    908	ptr = snd_cs46xx_peek(chip, BA1_PBA);
    909#endif
    910	ptr -= cpcm->hw_buf.addr;
    911	return ptr >> cpcm->shift;
    912}
    913
    914static snd_pcm_uframes_t snd_cs46xx_playback_indirect_pointer(struct snd_pcm_substream *substream)
    915{
    916	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
    917	size_t ptr;
    918	struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data;
    919
    920#ifdef CONFIG_SND_CS46XX_NEW_DSP
    921	if (snd_BUG_ON(!cpcm->pcm_channel))
    922		return -ENXIO;
    923	ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2);
    924#else
    925	ptr = snd_cs46xx_peek(chip, BA1_PBA);
    926#endif
    927	ptr -= cpcm->hw_buf.addr;
    928	return snd_pcm_indirect_playback_pointer(substream, &cpcm->pcm_rec, ptr);
    929}
    930
    931static snd_pcm_uframes_t snd_cs46xx_capture_direct_pointer(struct snd_pcm_substream *substream)
    932{
    933	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
    934	size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_buf.addr;
    935	return ptr >> chip->capt.shift;
    936}
    937
    938static snd_pcm_uframes_t snd_cs46xx_capture_indirect_pointer(struct snd_pcm_substream *substream)
    939{
    940	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
    941	size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_buf.addr;
    942	return snd_pcm_indirect_capture_pointer(substream, &chip->capt.pcm_rec, ptr);
    943}
    944
    945static int snd_cs46xx_playback_trigger(struct snd_pcm_substream *substream,
    946				       int cmd)
    947{
    948	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
    949	/*struct snd_pcm_runtime *runtime = substream->runtime;*/
    950	int result = 0;
    951
    952#ifdef CONFIG_SND_CS46XX_NEW_DSP
    953	struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data;
    954	if (! cpcm->pcm_channel) {
    955		return -ENXIO;
    956	}
    957#endif
    958	switch (cmd) {
    959	case SNDRV_PCM_TRIGGER_START:
    960	case SNDRV_PCM_TRIGGER_RESUME:
    961#ifdef CONFIG_SND_CS46XX_NEW_DSP
    962		/* magic value to unmute PCM stream  playback volume */
    963		snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 
    964				       SCBVolumeCtrl) << 2, 0x80008000);
    965
    966		if (cpcm->pcm_channel->unlinked)
    967			cs46xx_dsp_pcm_link(chip,cpcm->pcm_channel);
    968
    969		if (substream->runtime->periods != CS46XX_FRAGS)
    970			snd_cs46xx_playback_transfer(substream);
    971#else
    972		spin_lock(&chip->reg_lock);
    973		if (substream->runtime->periods != CS46XX_FRAGS)
    974			snd_cs46xx_playback_transfer(substream);
    975		{ unsigned int tmp;
    976		tmp = snd_cs46xx_peek(chip, BA1_PCTL);
    977		tmp &= 0x0000ffff;
    978		snd_cs46xx_poke(chip, BA1_PCTL, chip->play_ctl | tmp);
    979		}
    980		spin_unlock(&chip->reg_lock);
    981#endif
    982		break;
    983	case SNDRV_PCM_TRIGGER_STOP:
    984	case SNDRV_PCM_TRIGGER_SUSPEND:
    985#ifdef CONFIG_SND_CS46XX_NEW_DSP
    986		/* magic mute channel */
    987		snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 
    988				       SCBVolumeCtrl) << 2, 0xffffffff);
    989
    990		if (!cpcm->pcm_channel->unlinked)
    991			cs46xx_dsp_pcm_unlink(chip,cpcm->pcm_channel);
    992#else
    993		spin_lock(&chip->reg_lock);
    994		{ unsigned int tmp;
    995		tmp = snd_cs46xx_peek(chip, BA1_PCTL);
    996		tmp &= 0x0000ffff;
    997		snd_cs46xx_poke(chip, BA1_PCTL, tmp);
    998		}
    999		spin_unlock(&chip->reg_lock);
   1000#endif
   1001		break;
   1002	default:
   1003		result = -EINVAL;
   1004		break;
   1005	}
   1006
   1007	return result;
   1008}
   1009
   1010static int snd_cs46xx_capture_trigger(struct snd_pcm_substream *substream,
   1011				      int cmd)
   1012{
   1013	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
   1014	unsigned int tmp;
   1015	int result = 0;
   1016
   1017	spin_lock(&chip->reg_lock);
   1018	switch (cmd) {
   1019	case SNDRV_PCM_TRIGGER_START:
   1020	case SNDRV_PCM_TRIGGER_RESUME:
   1021		tmp = snd_cs46xx_peek(chip, BA1_CCTL);
   1022		tmp &= 0xffff0000;
   1023		snd_cs46xx_poke(chip, BA1_CCTL, chip->capt.ctl | tmp);
   1024		break;
   1025	case SNDRV_PCM_TRIGGER_STOP:
   1026	case SNDRV_PCM_TRIGGER_SUSPEND:
   1027		tmp = snd_cs46xx_peek(chip, BA1_CCTL);
   1028		tmp &= 0xffff0000;
   1029		snd_cs46xx_poke(chip, BA1_CCTL, tmp);
   1030		break;
   1031	default:
   1032		result = -EINVAL;
   1033		break;
   1034	}
   1035	spin_unlock(&chip->reg_lock);
   1036
   1037	return result;
   1038}
   1039
   1040#ifdef CONFIG_SND_CS46XX_NEW_DSP
   1041static int _cs46xx_adjust_sample_rate (struct snd_cs46xx *chip, struct snd_cs46xx_pcm *cpcm,
   1042				       int sample_rate) 
   1043{
   1044
   1045	/* If PCMReaderSCB and SrcTaskSCB not created yet ... */
   1046	if ( cpcm->pcm_channel == NULL) {
   1047		cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip, sample_rate, 
   1048								   cpcm, cpcm->hw_buf.addr,cpcm->pcm_channel_id);
   1049		if (cpcm->pcm_channel == NULL) {
   1050			dev_err(chip->card->dev,
   1051				"failed to create virtual PCM channel\n");
   1052			return -ENOMEM;
   1053		}
   1054		cpcm->pcm_channel->sample_rate = sample_rate;
   1055	} else
   1056	/* if sample rate is changed */
   1057	if ((int)cpcm->pcm_channel->sample_rate != sample_rate) {
   1058		int unlinked = cpcm->pcm_channel->unlinked;
   1059		cs46xx_dsp_destroy_pcm_channel (chip,cpcm->pcm_channel);
   1060
   1061		cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel(chip, sample_rate, cpcm,
   1062								  cpcm->hw_buf.addr,
   1063								  cpcm->pcm_channel_id);
   1064		if (!cpcm->pcm_channel) {
   1065			dev_err(chip->card->dev,
   1066				"failed to re-create virtual PCM channel\n");
   1067			return -ENOMEM;
   1068		}
   1069
   1070		if (!unlinked) cs46xx_dsp_pcm_link (chip,cpcm->pcm_channel);
   1071		cpcm->pcm_channel->sample_rate = sample_rate;
   1072	}
   1073
   1074	return 0;
   1075}
   1076#endif
   1077
   1078
   1079static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream,
   1080					 struct snd_pcm_hw_params *hw_params)
   1081{
   1082	struct snd_pcm_runtime *runtime = substream->runtime;
   1083	struct snd_cs46xx_pcm *cpcm;
   1084	int err;
   1085#ifdef CONFIG_SND_CS46XX_NEW_DSP
   1086	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
   1087	int sample_rate = params_rate(hw_params);
   1088	int period_size = params_period_bytes(hw_params);
   1089#endif
   1090	cpcm = runtime->private_data;
   1091
   1092#ifdef CONFIG_SND_CS46XX_NEW_DSP
   1093	if (snd_BUG_ON(!sample_rate))
   1094		return -ENXIO;
   1095
   1096	mutex_lock(&chip->spos_mutex);
   1097
   1098	if (_cs46xx_adjust_sample_rate (chip,cpcm,sample_rate)) {
   1099		mutex_unlock(&chip->spos_mutex);
   1100		return -ENXIO;
   1101	}
   1102
   1103	snd_BUG_ON(!cpcm->pcm_channel);
   1104	if (!cpcm->pcm_channel) {
   1105		mutex_unlock(&chip->spos_mutex);
   1106		return -ENXIO;
   1107	}
   1108
   1109
   1110	if (cs46xx_dsp_pcm_channel_set_period (chip,cpcm->pcm_channel,period_size)) {
   1111		 mutex_unlock(&chip->spos_mutex);
   1112		 return -EINVAL;
   1113	 }
   1114
   1115	dev_dbg(chip->card->dev,
   1116		"period_size (%d), periods (%d) buffer_size(%d)\n",
   1117		     period_size, params_periods(hw_params),
   1118		     params_buffer_bytes(hw_params));
   1119#endif
   1120
   1121	if (params_periods(hw_params) == CS46XX_FRAGS) {
   1122		if (runtime->dma_area != cpcm->hw_buf.area)
   1123			snd_pcm_lib_free_pages(substream);
   1124		snd_pcm_set_runtime_buffer(substream, &cpcm->hw_buf);
   1125
   1126
   1127#ifdef CONFIG_SND_CS46XX_NEW_DSP
   1128		if (cpcm->pcm_channel_id == DSP_PCM_MAIN_CHANNEL) {
   1129			substream->ops = &snd_cs46xx_playback_ops;
   1130		} else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) {
   1131			substream->ops = &snd_cs46xx_playback_rear_ops;
   1132		} else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) {
   1133			substream->ops = &snd_cs46xx_playback_clfe_ops;
   1134		} else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) {
   1135			substream->ops = &snd_cs46xx_playback_iec958_ops;
   1136		} else {
   1137			snd_BUG();
   1138		}
   1139#else
   1140		substream->ops = &snd_cs46xx_playback_ops;
   1141#endif
   1142
   1143	} else {
   1144		if (runtime->dma_area == cpcm->hw_buf.area)
   1145			snd_pcm_set_runtime_buffer(substream, NULL);
   1146		err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
   1147		if (err < 0) {
   1148#ifdef CONFIG_SND_CS46XX_NEW_DSP
   1149			mutex_unlock(&chip->spos_mutex);
   1150#endif
   1151			return err;
   1152		}
   1153
   1154#ifdef CONFIG_SND_CS46XX_NEW_DSP
   1155		if (cpcm->pcm_channel_id == DSP_PCM_MAIN_CHANNEL) {
   1156			substream->ops = &snd_cs46xx_playback_indirect_ops;
   1157		} else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) {
   1158			substream->ops = &snd_cs46xx_playback_indirect_rear_ops;
   1159		} else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) {
   1160			substream->ops = &snd_cs46xx_playback_indirect_clfe_ops;
   1161		} else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) {
   1162			substream->ops = &snd_cs46xx_playback_indirect_iec958_ops;
   1163		} else {
   1164			snd_BUG();
   1165		}
   1166#else
   1167		substream->ops = &snd_cs46xx_playback_indirect_ops;
   1168#endif
   1169
   1170	}
   1171
   1172#ifdef CONFIG_SND_CS46XX_NEW_DSP
   1173	mutex_unlock(&chip->spos_mutex);
   1174#endif
   1175
   1176	return 0;
   1177}
   1178
   1179static int snd_cs46xx_playback_hw_free(struct snd_pcm_substream *substream)
   1180{
   1181	/*struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);*/
   1182	struct snd_pcm_runtime *runtime = substream->runtime;
   1183	struct snd_cs46xx_pcm *cpcm;
   1184
   1185	cpcm = runtime->private_data;
   1186
   1187	/* if play_back open fails, then this function
   1188	   is called and cpcm can actually be NULL here */
   1189	if (!cpcm) return -ENXIO;
   1190
   1191	if (runtime->dma_area != cpcm->hw_buf.area)
   1192		snd_pcm_lib_free_pages(substream);
   1193    
   1194	snd_pcm_set_runtime_buffer(substream, NULL);
   1195
   1196	return 0;
   1197}
   1198
   1199static int snd_cs46xx_playback_prepare(struct snd_pcm_substream *substream)
   1200{
   1201	unsigned int tmp;
   1202	unsigned int pfie;
   1203	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
   1204	struct snd_pcm_runtime *runtime = substream->runtime;
   1205	struct snd_cs46xx_pcm *cpcm;
   1206
   1207	cpcm = runtime->private_data;
   1208
   1209#ifdef CONFIG_SND_CS46XX_NEW_DSP
   1210	if (snd_BUG_ON(!cpcm->pcm_channel))
   1211		return -ENXIO;
   1212
   1213	pfie = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2 );
   1214	pfie &= ~0x0000f03f;
   1215#else
   1216	/* old dsp */
   1217	pfie = snd_cs46xx_peek(chip, BA1_PFIE);
   1218 	pfie &= ~0x0000f03f;
   1219#endif
   1220
   1221	cpcm->shift = 2;
   1222	/* if to convert from stereo to mono */
   1223	if (runtime->channels == 1) {
   1224		cpcm->shift--;
   1225		pfie |= 0x00002000;
   1226	}
   1227	/* if to convert from 8 bit to 16 bit */
   1228	if (snd_pcm_format_width(runtime->format) == 8) {
   1229		cpcm->shift--;
   1230		pfie |= 0x00001000;
   1231	}
   1232	/* if to convert to unsigned */
   1233	if (snd_pcm_format_unsigned(runtime->format))
   1234		pfie |= 0x00008000;
   1235
   1236	/* Never convert byte order when sample stream is 8 bit */
   1237	if (snd_pcm_format_width(runtime->format) != 8) {
   1238		/* convert from big endian to little endian */
   1239		if (snd_pcm_format_big_endian(runtime->format))
   1240			pfie |= 0x00004000;
   1241	}
   1242	
   1243	memset(&cpcm->pcm_rec, 0, sizeof(cpcm->pcm_rec));
   1244	cpcm->pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
   1245	cpcm->pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << cpcm->shift;
   1246
   1247#ifdef CONFIG_SND_CS46XX_NEW_DSP
   1248
   1249	tmp = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address) << 2);
   1250	tmp &= ~0x000003ff;
   1251	tmp |= (4 << cpcm->shift) - 1;
   1252	/* playback transaction count register */
   1253	snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address) << 2, tmp);
   1254
   1255	/* playback format && interrupt enable */
   1256	snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2, pfie | cpcm->pcm_channel->pcm_slot);
   1257#else
   1258	snd_cs46xx_poke(chip, BA1_PBA, cpcm->hw_buf.addr);
   1259	tmp = snd_cs46xx_peek(chip, BA1_PDTC);
   1260	tmp &= ~0x000003ff;
   1261	tmp |= (4 << cpcm->shift) - 1;
   1262	snd_cs46xx_poke(chip, BA1_PDTC, tmp);
   1263	snd_cs46xx_poke(chip, BA1_PFIE, pfie);
   1264	snd_cs46xx_set_play_sample_rate(chip, runtime->rate);
   1265#endif
   1266
   1267	return 0;
   1268}
   1269
   1270static int snd_cs46xx_capture_hw_params(struct snd_pcm_substream *substream,
   1271					struct snd_pcm_hw_params *hw_params)
   1272{
   1273	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
   1274	struct snd_pcm_runtime *runtime = substream->runtime;
   1275	int err;
   1276
   1277#ifdef CONFIG_SND_CS46XX_NEW_DSP
   1278	cs46xx_dsp_pcm_ostream_set_period (chip, params_period_bytes(hw_params));
   1279#endif
   1280	if (runtime->periods == CS46XX_FRAGS) {
   1281		if (runtime->dma_area != chip->capt.hw_buf.area)
   1282			snd_pcm_lib_free_pages(substream);
   1283		snd_pcm_set_runtime_buffer(substream, &chip->capt.hw_buf);
   1284		substream->ops = &snd_cs46xx_capture_ops;
   1285	} else {
   1286		if (runtime->dma_area == chip->capt.hw_buf.area)
   1287			snd_pcm_set_runtime_buffer(substream, NULL);
   1288		err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
   1289		if (err < 0)
   1290			return err;
   1291		substream->ops = &snd_cs46xx_capture_indirect_ops;
   1292	}
   1293
   1294	return 0;
   1295}
   1296
   1297static int snd_cs46xx_capture_hw_free(struct snd_pcm_substream *substream)
   1298{
   1299	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
   1300	struct snd_pcm_runtime *runtime = substream->runtime;
   1301
   1302	if (runtime->dma_area != chip->capt.hw_buf.area)
   1303		snd_pcm_lib_free_pages(substream);
   1304	snd_pcm_set_runtime_buffer(substream, NULL);
   1305
   1306	return 0;
   1307}
   1308
   1309static int snd_cs46xx_capture_prepare(struct snd_pcm_substream *substream)
   1310{
   1311	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
   1312	struct snd_pcm_runtime *runtime = substream->runtime;
   1313
   1314	snd_cs46xx_poke(chip, BA1_CBA, chip->capt.hw_buf.addr);
   1315	chip->capt.shift = 2;
   1316	memset(&chip->capt.pcm_rec, 0, sizeof(chip->capt.pcm_rec));
   1317	chip->capt.pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
   1318	chip->capt.pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << 2;
   1319	snd_cs46xx_set_capture_sample_rate(chip, runtime->rate);
   1320
   1321	return 0;
   1322}
   1323
   1324static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id)
   1325{
   1326	struct snd_cs46xx *chip = dev_id;
   1327	u32 status1;
   1328#ifdef CONFIG_SND_CS46XX_NEW_DSP
   1329	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
   1330	u32 status2;
   1331	int i;
   1332	struct snd_cs46xx_pcm *cpcm = NULL;
   1333#endif
   1334
   1335	/*
   1336	 *  Read the Interrupt Status Register to clear the interrupt
   1337	 */
   1338	status1 = snd_cs46xx_peekBA0(chip, BA0_HISR);
   1339	if ((status1 & 0x7fffffff) == 0) {
   1340		snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_CHGM | HICR_IEV);
   1341		return IRQ_NONE;
   1342	}
   1343
   1344#ifdef CONFIG_SND_CS46XX_NEW_DSP
   1345	status2 = snd_cs46xx_peekBA0(chip, BA0_HSR0);
   1346
   1347	for (i = 0; i < DSP_MAX_PCM_CHANNELS; ++i) {
   1348		if (i <= 15) {
   1349			if ( status1 & (1 << i) ) {
   1350				if (i == CS46XX_DSP_CAPTURE_CHANNEL) {
   1351					if (chip->capt.substream)
   1352						snd_pcm_period_elapsed(chip->capt.substream);
   1353				} else {
   1354					if (ins->pcm_channels[i].active &&
   1355					    ins->pcm_channels[i].private_data &&
   1356					    !ins->pcm_channels[i].unlinked) {
   1357						cpcm = ins->pcm_channels[i].private_data;
   1358						snd_pcm_period_elapsed(cpcm->substream);
   1359					}
   1360				}
   1361			}
   1362		} else {
   1363			if ( status2 & (1 << (i - 16))) {
   1364				if (ins->pcm_channels[i].active && 
   1365				    ins->pcm_channels[i].private_data &&
   1366				    !ins->pcm_channels[i].unlinked) {
   1367					cpcm = ins->pcm_channels[i].private_data;
   1368					snd_pcm_period_elapsed(cpcm->substream);
   1369				}
   1370			}
   1371		}
   1372	}
   1373
   1374#else
   1375	/* old dsp */
   1376	if ((status1 & HISR_VC0) && chip->playback_pcm) {
   1377		if (chip->playback_pcm->substream)
   1378			snd_pcm_period_elapsed(chip->playback_pcm->substream);
   1379	}
   1380	if ((status1 & HISR_VC1) && chip->pcm) {
   1381		if (chip->capt.substream)
   1382			snd_pcm_period_elapsed(chip->capt.substream);
   1383	}
   1384#endif
   1385
   1386	if ((status1 & HISR_MIDI) && chip->rmidi) {
   1387		unsigned char c;
   1388		
   1389		spin_lock(&chip->reg_lock);
   1390		while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_RBE) == 0) {
   1391			c = snd_cs46xx_peekBA0(chip, BA0_MIDRP);
   1392			if ((chip->midcr & MIDCR_RIE) == 0)
   1393				continue;
   1394			snd_rawmidi_receive(chip->midi_input, &c, 1);
   1395		}
   1396		while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_TBF) == 0) {
   1397			if ((chip->midcr & MIDCR_TIE) == 0)
   1398				break;
   1399			if (snd_rawmidi_transmit(chip->midi_output, &c, 1) != 1) {
   1400				chip->midcr &= ~MIDCR_TIE;
   1401				snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
   1402				break;
   1403			}
   1404			snd_cs46xx_pokeBA0(chip, BA0_MIDWP, c);
   1405		}
   1406		spin_unlock(&chip->reg_lock);
   1407	}
   1408	/*
   1409	 *  EOI to the PCI part....reenables interrupts
   1410	 */
   1411	snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_CHGM | HICR_IEV);
   1412
   1413	return IRQ_HANDLED;
   1414}
   1415
   1416static const struct snd_pcm_hardware snd_cs46xx_playback =
   1417{
   1418	.info =			(SNDRV_PCM_INFO_MMAP |
   1419				 SNDRV_PCM_INFO_INTERLEAVED | 
   1420				 SNDRV_PCM_INFO_BLOCK_TRANSFER /*|*/
   1421				 /*SNDRV_PCM_INFO_RESUME*/ |
   1422				 SNDRV_PCM_INFO_SYNC_APPLPTR),
   1423	.formats =		(SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
   1424				 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
   1425				 SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE),
   1426	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
   1427	.rate_min =		5500,
   1428	.rate_max =		48000,
   1429	.channels_min =		1,
   1430	.channels_max =		2,
   1431	.buffer_bytes_max =	(256 * 1024),
   1432	.period_bytes_min =	CS46XX_MIN_PERIOD_SIZE,
   1433	.period_bytes_max =	CS46XX_MAX_PERIOD_SIZE,
   1434	.periods_min =		CS46XX_FRAGS,
   1435	.periods_max =		1024,
   1436	.fifo_size =		0,
   1437};
   1438
   1439static const struct snd_pcm_hardware snd_cs46xx_capture =
   1440{
   1441	.info =			(SNDRV_PCM_INFO_MMAP |
   1442				 SNDRV_PCM_INFO_INTERLEAVED |
   1443				 SNDRV_PCM_INFO_BLOCK_TRANSFER /*|*/
   1444				 /*SNDRV_PCM_INFO_RESUME*/ |
   1445				 SNDRV_PCM_INFO_SYNC_APPLPTR),
   1446	.formats =		SNDRV_PCM_FMTBIT_S16_LE,
   1447	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
   1448	.rate_min =		5500,
   1449	.rate_max =		48000,
   1450	.channels_min =		2,
   1451	.channels_max =		2,
   1452	.buffer_bytes_max =	(256 * 1024),
   1453	.period_bytes_min =	CS46XX_MIN_PERIOD_SIZE,
   1454	.period_bytes_max =	CS46XX_MAX_PERIOD_SIZE,
   1455	.periods_min =		CS46XX_FRAGS,
   1456	.periods_max =		1024,
   1457	.fifo_size =		0,
   1458};
   1459
   1460#ifdef CONFIG_SND_CS46XX_NEW_DSP
   1461
   1462static const unsigned int period_sizes[] = { 32, 64, 128, 256, 512, 1024, 2048 };
   1463
   1464static const struct snd_pcm_hw_constraint_list hw_constraints_period_sizes = {
   1465	.count = ARRAY_SIZE(period_sizes),
   1466	.list = period_sizes,
   1467	.mask = 0
   1468};
   1469
   1470#endif
   1471
   1472static void snd_cs46xx_pcm_free_substream(struct snd_pcm_runtime *runtime)
   1473{
   1474	kfree(runtime->private_data);
   1475}
   1476
   1477static int _cs46xx_playback_open_channel (struct snd_pcm_substream *substream,int pcm_channel_id)
   1478{
   1479	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
   1480	struct snd_cs46xx_pcm * cpcm;
   1481	struct snd_pcm_runtime *runtime = substream->runtime;
   1482
   1483	cpcm = kzalloc(sizeof(*cpcm), GFP_KERNEL);
   1484	if (cpcm == NULL)
   1485		return -ENOMEM;
   1486	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &chip->pci->dev,
   1487				PAGE_SIZE, &cpcm->hw_buf) < 0) {
   1488		kfree(cpcm);
   1489		return -ENOMEM;
   1490	}
   1491
   1492	runtime->hw = snd_cs46xx_playback;
   1493	runtime->private_data = cpcm;
   1494	runtime->private_free = snd_cs46xx_pcm_free_substream;
   1495
   1496	cpcm->substream = substream;
   1497#ifdef CONFIG_SND_CS46XX_NEW_DSP
   1498	mutex_lock(&chip->spos_mutex);
   1499	cpcm->pcm_channel = NULL; 
   1500	cpcm->pcm_channel_id = pcm_channel_id;
   1501
   1502
   1503	snd_pcm_hw_constraint_list(runtime, 0,
   1504				   SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 
   1505				   &hw_constraints_period_sizes);
   1506
   1507	mutex_unlock(&chip->spos_mutex);
   1508#else
   1509	chip->playback_pcm = cpcm; /* HACK */
   1510#endif
   1511
   1512	if (chip->accept_valid)
   1513		substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID;
   1514	chip->active_ctrl(chip, 1);
   1515
   1516	return 0;
   1517}
   1518
   1519static int snd_cs46xx_playback_open(struct snd_pcm_substream *substream)
   1520{
   1521	dev_dbg(substream->pcm->card->dev, "open front channel\n");
   1522	return _cs46xx_playback_open_channel(substream,DSP_PCM_MAIN_CHANNEL);
   1523}
   1524
   1525#ifdef CONFIG_SND_CS46XX_NEW_DSP
   1526static int snd_cs46xx_playback_open_rear(struct snd_pcm_substream *substream)
   1527{
   1528	dev_dbg(substream->pcm->card->dev, "open rear channel\n");
   1529	return _cs46xx_playback_open_channel(substream,DSP_PCM_REAR_CHANNEL);
   1530}
   1531
   1532static int snd_cs46xx_playback_open_clfe(struct snd_pcm_substream *substream)
   1533{
   1534	dev_dbg(substream->pcm->card->dev, "open center - LFE channel\n");
   1535	return _cs46xx_playback_open_channel(substream,DSP_PCM_CENTER_LFE_CHANNEL);
   1536}
   1537
   1538static int snd_cs46xx_playback_open_iec958(struct snd_pcm_substream *substream)
   1539{
   1540	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
   1541
   1542	dev_dbg(chip->card->dev, "open raw iec958 channel\n");
   1543
   1544	mutex_lock(&chip->spos_mutex);
   1545	cs46xx_iec958_pre_open (chip);
   1546	mutex_unlock(&chip->spos_mutex);
   1547
   1548	return _cs46xx_playback_open_channel(substream,DSP_IEC958_CHANNEL);
   1549}
   1550
   1551static int snd_cs46xx_playback_close(struct snd_pcm_substream *substream);
   1552
   1553static int snd_cs46xx_playback_close_iec958(struct snd_pcm_substream *substream)
   1554{
   1555	int err;
   1556	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
   1557  
   1558	dev_dbg(chip->card->dev, "close raw iec958 channel\n");
   1559
   1560	err = snd_cs46xx_playback_close(substream);
   1561
   1562	mutex_lock(&chip->spos_mutex);
   1563	cs46xx_iec958_post_close (chip);
   1564	mutex_unlock(&chip->spos_mutex);
   1565
   1566	return err;
   1567}
   1568#endif
   1569
   1570static int snd_cs46xx_capture_open(struct snd_pcm_substream *substream)
   1571{
   1572	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
   1573
   1574	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &chip->pci->dev,
   1575				PAGE_SIZE, &chip->capt.hw_buf) < 0)
   1576		return -ENOMEM;
   1577	chip->capt.substream = substream;
   1578	substream->runtime->hw = snd_cs46xx_capture;
   1579
   1580	if (chip->accept_valid)
   1581		substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID;
   1582
   1583	chip->active_ctrl(chip, 1);
   1584
   1585#ifdef CONFIG_SND_CS46XX_NEW_DSP
   1586	snd_pcm_hw_constraint_list(substream->runtime, 0,
   1587				   SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 
   1588				   &hw_constraints_period_sizes);
   1589#endif
   1590	return 0;
   1591}
   1592
   1593static int snd_cs46xx_playback_close(struct snd_pcm_substream *substream)
   1594{
   1595	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
   1596	struct snd_pcm_runtime *runtime = substream->runtime;
   1597	struct snd_cs46xx_pcm * cpcm;
   1598
   1599	cpcm = runtime->private_data;
   1600
   1601	/* when playback_open fails, then cpcm can be NULL */
   1602	if (!cpcm) return -ENXIO;
   1603
   1604#ifdef CONFIG_SND_CS46XX_NEW_DSP
   1605	mutex_lock(&chip->spos_mutex);
   1606	if (cpcm->pcm_channel) {
   1607		cs46xx_dsp_destroy_pcm_channel(chip,cpcm->pcm_channel);
   1608		cpcm->pcm_channel = NULL;
   1609	}
   1610	mutex_unlock(&chip->spos_mutex);
   1611#else
   1612	chip->playback_pcm = NULL;
   1613#endif
   1614
   1615	cpcm->substream = NULL;
   1616	snd_dma_free_pages(&cpcm->hw_buf);
   1617	chip->active_ctrl(chip, -1);
   1618
   1619	return 0;
   1620}
   1621
   1622static int snd_cs46xx_capture_close(struct snd_pcm_substream *substream)
   1623{
   1624	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
   1625
   1626	chip->capt.substream = NULL;
   1627	snd_dma_free_pages(&chip->capt.hw_buf);
   1628	chip->active_ctrl(chip, -1);
   1629
   1630	return 0;
   1631}
   1632
   1633#ifdef CONFIG_SND_CS46XX_NEW_DSP
   1634static const struct snd_pcm_ops snd_cs46xx_playback_rear_ops = {
   1635	.open =			snd_cs46xx_playback_open_rear,
   1636	.close =		snd_cs46xx_playback_close,
   1637	.hw_params =		snd_cs46xx_playback_hw_params,
   1638	.hw_free =		snd_cs46xx_playback_hw_free,
   1639	.prepare =		snd_cs46xx_playback_prepare,
   1640	.trigger =		snd_cs46xx_playback_trigger,
   1641	.pointer =		snd_cs46xx_playback_direct_pointer,
   1642};
   1643
   1644static const struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops = {
   1645	.open =			snd_cs46xx_playback_open_rear,
   1646	.close =		snd_cs46xx_playback_close,
   1647	.hw_params =		snd_cs46xx_playback_hw_params,
   1648	.hw_free =		snd_cs46xx_playback_hw_free,
   1649	.prepare =		snd_cs46xx_playback_prepare,
   1650	.trigger =		snd_cs46xx_playback_trigger,
   1651	.pointer =		snd_cs46xx_playback_indirect_pointer,
   1652	.ack =			snd_cs46xx_playback_transfer,
   1653};
   1654
   1655static const struct snd_pcm_ops snd_cs46xx_playback_clfe_ops = {
   1656	.open =			snd_cs46xx_playback_open_clfe,
   1657	.close =		snd_cs46xx_playback_close,
   1658	.hw_params =		snd_cs46xx_playback_hw_params,
   1659	.hw_free =		snd_cs46xx_playback_hw_free,
   1660	.prepare =		snd_cs46xx_playback_prepare,
   1661	.trigger =		snd_cs46xx_playback_trigger,
   1662	.pointer =		snd_cs46xx_playback_direct_pointer,
   1663};
   1664
   1665static const struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops = {
   1666	.open =			snd_cs46xx_playback_open_clfe,
   1667	.close =		snd_cs46xx_playback_close,
   1668	.hw_params =		snd_cs46xx_playback_hw_params,
   1669	.hw_free =		snd_cs46xx_playback_hw_free,
   1670	.prepare =		snd_cs46xx_playback_prepare,
   1671	.trigger =		snd_cs46xx_playback_trigger,
   1672	.pointer =		snd_cs46xx_playback_indirect_pointer,
   1673	.ack =			snd_cs46xx_playback_transfer,
   1674};
   1675
   1676static const struct snd_pcm_ops snd_cs46xx_playback_iec958_ops = {
   1677	.open =			snd_cs46xx_playback_open_iec958,
   1678	.close =		snd_cs46xx_playback_close_iec958,
   1679	.hw_params =		snd_cs46xx_playback_hw_params,
   1680	.hw_free =		snd_cs46xx_playback_hw_free,
   1681	.prepare =		snd_cs46xx_playback_prepare,
   1682	.trigger =		snd_cs46xx_playback_trigger,
   1683	.pointer =		snd_cs46xx_playback_direct_pointer,
   1684};
   1685
   1686static const struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops = {
   1687	.open =			snd_cs46xx_playback_open_iec958,
   1688	.close =		snd_cs46xx_playback_close_iec958,
   1689	.hw_params =		snd_cs46xx_playback_hw_params,
   1690	.hw_free =		snd_cs46xx_playback_hw_free,
   1691	.prepare =		snd_cs46xx_playback_prepare,
   1692	.trigger =		snd_cs46xx_playback_trigger,
   1693	.pointer =		snd_cs46xx_playback_indirect_pointer,
   1694	.ack =			snd_cs46xx_playback_transfer,
   1695};
   1696
   1697#endif
   1698
   1699static const struct snd_pcm_ops snd_cs46xx_playback_ops = {
   1700	.open =			snd_cs46xx_playback_open,
   1701	.close =		snd_cs46xx_playback_close,
   1702	.hw_params =		snd_cs46xx_playback_hw_params,
   1703	.hw_free =		snd_cs46xx_playback_hw_free,
   1704	.prepare =		snd_cs46xx_playback_prepare,
   1705	.trigger =		snd_cs46xx_playback_trigger,
   1706	.pointer =		snd_cs46xx_playback_direct_pointer,
   1707};
   1708
   1709static const struct snd_pcm_ops snd_cs46xx_playback_indirect_ops = {
   1710	.open =			snd_cs46xx_playback_open,
   1711	.close =		snd_cs46xx_playback_close,
   1712	.hw_params =		snd_cs46xx_playback_hw_params,
   1713	.hw_free =		snd_cs46xx_playback_hw_free,
   1714	.prepare =		snd_cs46xx_playback_prepare,
   1715	.trigger =		snd_cs46xx_playback_trigger,
   1716	.pointer =		snd_cs46xx_playback_indirect_pointer,
   1717	.ack =			snd_cs46xx_playback_transfer,
   1718};
   1719
   1720static const struct snd_pcm_ops snd_cs46xx_capture_ops = {
   1721	.open =			snd_cs46xx_capture_open,
   1722	.close =		snd_cs46xx_capture_close,
   1723	.hw_params =		snd_cs46xx_capture_hw_params,
   1724	.hw_free =		snd_cs46xx_capture_hw_free,
   1725	.prepare =		snd_cs46xx_capture_prepare,
   1726	.trigger =		snd_cs46xx_capture_trigger,
   1727	.pointer =		snd_cs46xx_capture_direct_pointer,
   1728};
   1729
   1730static const struct snd_pcm_ops snd_cs46xx_capture_indirect_ops = {
   1731	.open =			snd_cs46xx_capture_open,
   1732	.close =		snd_cs46xx_capture_close,
   1733	.hw_params =		snd_cs46xx_capture_hw_params,
   1734	.hw_free =		snd_cs46xx_capture_hw_free,
   1735	.prepare =		snd_cs46xx_capture_prepare,
   1736	.trigger =		snd_cs46xx_capture_trigger,
   1737	.pointer =		snd_cs46xx_capture_indirect_pointer,
   1738	.ack =			snd_cs46xx_capture_transfer,
   1739};
   1740
   1741#ifdef CONFIG_SND_CS46XX_NEW_DSP
   1742#define MAX_PLAYBACK_CHANNELS	(DSP_MAX_PCM_CHANNELS - 1)
   1743#else
   1744#define MAX_PLAYBACK_CHANNELS	1
   1745#endif
   1746
   1747int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device)
   1748{
   1749	struct snd_pcm *pcm;
   1750	int err;
   1751
   1752	err = snd_pcm_new(chip->card, "CS46xx", device, MAX_PLAYBACK_CHANNELS, 1, &pcm);
   1753	if (err < 0)
   1754		return err;
   1755
   1756	pcm->private_data = chip;
   1757
   1758	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_ops);
   1759	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs46xx_capture_ops);
   1760
   1761	/* global setup */
   1762	pcm->info_flags = 0;
   1763	strcpy(pcm->name, "CS46xx");
   1764	chip->pcm = pcm;
   1765
   1766	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
   1767					      &chip->pci->dev,
   1768					      64*1024, 256*1024);
   1769
   1770	return 0;
   1771}
   1772
   1773
   1774#ifdef CONFIG_SND_CS46XX_NEW_DSP
   1775int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device)
   1776{
   1777	struct snd_pcm *pcm;
   1778	int err;
   1779
   1780	err = snd_pcm_new(chip->card, "CS46xx - Rear", device, MAX_PLAYBACK_CHANNELS, 0, &pcm);
   1781	if (err < 0)
   1782		return err;
   1783
   1784	pcm->private_data = chip;
   1785
   1786	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_rear_ops);
   1787
   1788	/* global setup */
   1789	pcm->info_flags = 0;
   1790	strcpy(pcm->name, "CS46xx - Rear");
   1791	chip->pcm_rear = pcm;
   1792
   1793	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
   1794					      &chip->pci->dev,
   1795					      64*1024, 256*1024);
   1796
   1797	return 0;
   1798}
   1799
   1800int snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device)
   1801{
   1802	struct snd_pcm *pcm;
   1803	int err;
   1804
   1805	err = snd_pcm_new(chip->card, "CS46xx - Center LFE", device, MAX_PLAYBACK_CHANNELS, 0, &pcm);
   1806	if (err < 0)
   1807		return err;
   1808
   1809	pcm->private_data = chip;
   1810
   1811	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_clfe_ops);
   1812
   1813	/* global setup */
   1814	pcm->info_flags = 0;
   1815	strcpy(pcm->name, "CS46xx - Center LFE");
   1816	chip->pcm_center_lfe = pcm;
   1817
   1818	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
   1819					      &chip->pci->dev,
   1820					      64*1024, 256*1024);
   1821
   1822	return 0;
   1823}
   1824
   1825int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device)
   1826{
   1827	struct snd_pcm *pcm;
   1828	int err;
   1829
   1830	err = snd_pcm_new(chip->card, "CS46xx - IEC958", device, 1, 0, &pcm);
   1831	if (err < 0)
   1832		return err;
   1833
   1834	pcm->private_data = chip;
   1835
   1836	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_iec958_ops);
   1837
   1838	/* global setup */
   1839	pcm->info_flags = 0;
   1840	strcpy(pcm->name, "CS46xx - IEC958");
   1841	chip->pcm_iec958 = pcm;
   1842
   1843	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
   1844					      &chip->pci->dev,
   1845					      64*1024, 256*1024);
   1846
   1847	return 0;
   1848}
   1849#endif
   1850
   1851/*
   1852 *  Mixer routines
   1853 */
   1854static void snd_cs46xx_mixer_free_ac97(struct snd_ac97 *ac97)
   1855{
   1856	struct snd_cs46xx *chip = ac97->private_data;
   1857
   1858	if (snd_BUG_ON(ac97 != chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] &&
   1859		       ac97 != chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]))
   1860		return;
   1861
   1862	if (ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) {
   1863		chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] = NULL;
   1864		chip->eapd_switch = NULL;
   1865	}
   1866	else
   1867		chip->ac97[CS46XX_SECONDARY_CODEC_INDEX] = NULL;
   1868}
   1869
   1870static int snd_cs46xx_vol_info(struct snd_kcontrol *kcontrol, 
   1871			       struct snd_ctl_elem_info *uinfo)
   1872{
   1873	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
   1874	uinfo->count = 2;
   1875	uinfo->value.integer.min = 0;
   1876	uinfo->value.integer.max = 0x7fff;
   1877	return 0;
   1878}
   1879
   1880static int snd_cs46xx_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
   1881{
   1882	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
   1883	int reg = kcontrol->private_value;
   1884	unsigned int val = snd_cs46xx_peek(chip, reg);
   1885	ucontrol->value.integer.value[0] = 0xffff - (val >> 16);
   1886	ucontrol->value.integer.value[1] = 0xffff - (val & 0xffff);
   1887	return 0;
   1888}
   1889
   1890static int snd_cs46xx_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
   1891{
   1892	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
   1893	int reg = kcontrol->private_value;
   1894	unsigned int val = ((0xffff - ucontrol->value.integer.value[0]) << 16 | 
   1895			    (0xffff - ucontrol->value.integer.value[1]));
   1896	unsigned int old = snd_cs46xx_peek(chip, reg);
   1897	int change = (old != val);
   1898
   1899	if (change) {
   1900		snd_cs46xx_poke(chip, reg, val);
   1901	}
   1902
   1903	return change;
   1904}
   1905
   1906#ifdef CONFIG_SND_CS46XX_NEW_DSP
   1907
   1908static int snd_cs46xx_vol_dac_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
   1909{
   1910	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
   1911
   1912	ucontrol->value.integer.value[0] = chip->dsp_spos_instance->dac_volume_left;
   1913	ucontrol->value.integer.value[1] = chip->dsp_spos_instance->dac_volume_right;
   1914
   1915	return 0;
   1916}
   1917
   1918static int snd_cs46xx_vol_dac_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
   1919{
   1920	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
   1921	int change = 0;
   1922
   1923	if (chip->dsp_spos_instance->dac_volume_right != ucontrol->value.integer.value[0] ||
   1924	    chip->dsp_spos_instance->dac_volume_left != ucontrol->value.integer.value[1]) {
   1925		cs46xx_dsp_set_dac_volume(chip,
   1926					  ucontrol->value.integer.value[0],
   1927					  ucontrol->value.integer.value[1]);
   1928		change = 1;
   1929	}
   1930
   1931	return change;
   1932}
   1933
   1934#if 0
   1935static int snd_cs46xx_vol_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
   1936{
   1937	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
   1938
   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;
   1941	return 0;
   1942}
   1943
   1944static int snd_cs46xx_vol_iec958_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
   1945{
   1946	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
   1947	int change = 0;
   1948
   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]);
   1954		change = 1;
   1955	}
   1956
   1957	return change;
   1958}
   1959#endif
   1960
   1961#define snd_mixer_boolean_info		snd_ctl_boolean_mono_info
   1962
   1963static int snd_cs46xx_iec958_get(struct snd_kcontrol *kcontrol, 
   1964                                 struct snd_ctl_elem_value *ucontrol)
   1965{
   1966	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
   1967	int reg = kcontrol->private_value;
   1968
   1969	if (reg == CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT)
   1970		ucontrol->value.integer.value[0] = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED);
   1971	else
   1972		ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_status_in;
   1973
   1974	return 0;
   1975}
   1976
   1977static int snd_cs46xx_iec958_put(struct snd_kcontrol *kcontrol, 
   1978                                  struct snd_ctl_elem_value *ucontrol)
   1979{
   1980	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
   1981	int change, res;
   1982
   1983	switch (kcontrol->private_value) {
   1984	case CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT:
   1985		mutex_lock(&chip->spos_mutex);
   1986		change = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED);
   1987		if (ucontrol->value.integer.value[0] && !change) 
   1988			cs46xx_dsp_enable_spdif_out(chip);
   1989		else if (change && !ucontrol->value.integer.value[0])
   1990			cs46xx_dsp_disable_spdif_out(chip);
   1991
   1992		res = (change != (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED));
   1993		mutex_unlock(&chip->spos_mutex);
   1994		break;
   1995	case CS46XX_MIXER_SPDIF_INPUT_ELEMENT:
   1996		change = chip->dsp_spos_instance->spdif_status_in;
   1997		if (ucontrol->value.integer.value[0] && !change) {
   1998			cs46xx_dsp_enable_spdif_in(chip);
   1999			/* restore volume */
   2000		}
   2001		else if (change && !ucontrol->value.integer.value[0])
   2002			cs46xx_dsp_disable_spdif_in(chip);
   2003		
   2004		res = (change != chip->dsp_spos_instance->spdif_status_in);
   2005		break;
   2006	default:
   2007		res = -EINVAL;
   2008		snd_BUG(); /* should never happen ... */
   2009	}
   2010
   2011	return res;
   2012}
   2013
   2014static int snd_cs46xx_adc_capture_get(struct snd_kcontrol *kcontrol, 
   2015                                      struct snd_ctl_elem_value *ucontrol)
   2016{
   2017	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
   2018	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
   2019
   2020	if (ins->adc_input != NULL) 
   2021		ucontrol->value.integer.value[0] = 1;
   2022	else 
   2023		ucontrol->value.integer.value[0] = 0;
   2024	
   2025	return 0;
   2026}
   2027
   2028static int snd_cs46xx_adc_capture_put(struct snd_kcontrol *kcontrol, 
   2029                                      struct snd_ctl_elem_value *ucontrol)
   2030{
   2031	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
   2032	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
   2033	int change = 0;
   2034
   2035	if (ucontrol->value.integer.value[0] && !ins->adc_input) {
   2036		cs46xx_dsp_enable_adc_capture(chip);
   2037		change = 1;
   2038	} else  if (!ucontrol->value.integer.value[0] && ins->adc_input) {
   2039		cs46xx_dsp_disable_adc_capture(chip);
   2040		change = 1;
   2041	}
   2042	return change;
   2043}
   2044
   2045static int snd_cs46xx_pcm_capture_get(struct snd_kcontrol *kcontrol, 
   2046                                      struct snd_ctl_elem_value *ucontrol)
   2047{
   2048	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
   2049	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
   2050
   2051	if (ins->pcm_input != NULL) 
   2052		ucontrol->value.integer.value[0] = 1;
   2053	else 
   2054		ucontrol->value.integer.value[0] = 0;
   2055
   2056	return 0;
   2057}
   2058
   2059
   2060static int snd_cs46xx_pcm_capture_put(struct snd_kcontrol *kcontrol, 
   2061                                      struct snd_ctl_elem_value *ucontrol)
   2062{
   2063	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
   2064	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
   2065	int change = 0;
   2066
   2067	if (ucontrol->value.integer.value[0] && !ins->pcm_input) {
   2068		cs46xx_dsp_enable_pcm_capture(chip);
   2069		change = 1;
   2070	} else  if (!ucontrol->value.integer.value[0] && ins->pcm_input) {
   2071		cs46xx_dsp_disable_pcm_capture(chip);
   2072		change = 1;
   2073	}
   2074
   2075	return change;
   2076}
   2077
   2078static int snd_herc_spdif_select_get(struct snd_kcontrol *kcontrol, 
   2079                                     struct snd_ctl_elem_value *ucontrol)
   2080{
   2081	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
   2082
   2083	int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR);
   2084
   2085	if (val1 & EGPIODR_GPOE0)
   2086		ucontrol->value.integer.value[0] = 1;
   2087	else
   2088		ucontrol->value.integer.value[0] = 0;
   2089
   2090	return 0;
   2091}
   2092
   2093/*
   2094 *	Game Theatre XP card - EGPIO[0] is used to select SPDIF input optical or coaxial.
   2095 */ 
   2096static int snd_herc_spdif_select_put(struct snd_kcontrol *kcontrol, 
   2097                                       struct snd_ctl_elem_value *ucontrol)
   2098{
   2099	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
   2100	int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR);
   2101	int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR);
   2102
   2103	if (ucontrol->value.integer.value[0]) {
   2104		/* optical is default */
   2105		snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, 
   2106				   EGPIODR_GPOE0 | val1);  /* enable EGPIO0 output */
   2107		snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, 
   2108				   EGPIOPTR_GPPT0 | val2); /* open-drain on output */
   2109	} else {
   2110		/* coaxial */
   2111		snd_cs46xx_pokeBA0(chip, BA0_EGPIODR,  val1 & ~EGPIODR_GPOE0); /* disable */
   2112		snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT0); /* disable */
   2113	}
   2114
   2115	/* checking diff from the EGPIO direction register 
   2116	   should be enough */
   2117	return (val1 != (int)snd_cs46xx_peekBA0(chip, BA0_EGPIODR));
   2118}
   2119
   2120
   2121static int snd_cs46xx_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
   2122{
   2123	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
   2124	uinfo->count = 1;
   2125	return 0;
   2126}
   2127
   2128static int snd_cs46xx_spdif_default_get(struct snd_kcontrol *kcontrol,
   2129					struct snd_ctl_elem_value *ucontrol)
   2130{
   2131	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
   2132	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
   2133
   2134	mutex_lock(&chip->spos_mutex);
   2135	ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_default >> 24) & 0xff);
   2136	ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_default >> 16) & 0xff);
   2137	ucontrol->value.iec958.status[2] = 0;
   2138	ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_default) & 0xff);
   2139	mutex_unlock(&chip->spos_mutex);
   2140
   2141	return 0;
   2142}
   2143
   2144static int snd_cs46xx_spdif_default_put(struct snd_kcontrol *kcontrol,
   2145					struct snd_ctl_elem_value *ucontrol)
   2146{
   2147	struct snd_cs46xx * chip = snd_kcontrol_chip(kcontrol);
   2148	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
   2149	unsigned int val;
   2150	int change;
   2151
   2152	mutex_lock(&chip->spos_mutex);
   2153	val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) |
   2154		((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[2]) << 16) |
   2155		((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3]))  |
   2156		/* left and right validity bit */
   2157		(1 << 13) | (1 << 12);
   2158
   2159
   2160	change = (unsigned int)ins->spdif_csuv_default != val;
   2161	ins->spdif_csuv_default = val;
   2162
   2163	if ( !(ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) )
   2164		cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val);
   2165
   2166	mutex_unlock(&chip->spos_mutex);
   2167
   2168	return change;
   2169}
   2170
   2171static int snd_cs46xx_spdif_mask_get(struct snd_kcontrol *kcontrol,
   2172				     struct snd_ctl_elem_value *ucontrol)
   2173{
   2174	ucontrol->value.iec958.status[0] = 0xff;
   2175	ucontrol->value.iec958.status[1] = 0xff;
   2176	ucontrol->value.iec958.status[2] = 0x00;
   2177	ucontrol->value.iec958.status[3] = 0xff;
   2178	return 0;
   2179}
   2180
   2181static int snd_cs46xx_spdif_stream_get(struct snd_kcontrol *kcontrol,
   2182                                         struct snd_ctl_elem_value *ucontrol)
   2183{
   2184	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
   2185	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
   2186
   2187	mutex_lock(&chip->spos_mutex);
   2188	ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_stream >> 24) & 0xff);
   2189	ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_stream >> 16) & 0xff);
   2190	ucontrol->value.iec958.status[2] = 0;
   2191	ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_stream) & 0xff);
   2192	mutex_unlock(&chip->spos_mutex);
   2193
   2194	return 0;
   2195}
   2196
   2197static int snd_cs46xx_spdif_stream_put(struct snd_kcontrol *kcontrol,
   2198                                        struct snd_ctl_elem_value *ucontrol)
   2199{
   2200	struct snd_cs46xx * chip = snd_kcontrol_chip(kcontrol);
   2201	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
   2202	unsigned int val;
   2203	int change;
   2204
   2205	mutex_lock(&chip->spos_mutex);
   2206	val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) |
   2207		((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[1]) << 16) |
   2208		((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) |
   2209		/* left and right validity bit */
   2210		(1 << 13) | (1 << 12);
   2211
   2212
   2213	change = ins->spdif_csuv_stream != val;
   2214	ins->spdif_csuv_stream = val;
   2215
   2216	if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN )
   2217		cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val);
   2218
   2219	mutex_unlock(&chip->spos_mutex);
   2220
   2221	return change;
   2222}
   2223
   2224#endif /* CONFIG_SND_CS46XX_NEW_DSP */
   2225
   2226
   2227static const struct snd_kcontrol_new snd_cs46xx_controls[] = {
   2228{
   2229	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
   2230	.name = "DAC Volume",
   2231	.info = snd_cs46xx_vol_info,
   2232#ifndef CONFIG_SND_CS46XX_NEW_DSP
   2233	.get = snd_cs46xx_vol_get,
   2234	.put = snd_cs46xx_vol_put,
   2235	.private_value = BA1_PVOL,
   2236#else
   2237	.get = snd_cs46xx_vol_dac_get,
   2238	.put = snd_cs46xx_vol_dac_put,
   2239#endif
   2240},
   2241
   2242{
   2243	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
   2244	.name = "ADC Volume",
   2245	.info = snd_cs46xx_vol_info,
   2246	.get = snd_cs46xx_vol_get,
   2247	.put = snd_cs46xx_vol_put,
   2248#ifndef CONFIG_SND_CS46XX_NEW_DSP
   2249	.private_value = BA1_CVOL,
   2250#else
   2251	.private_value = (VARIDECIMATE_SCB_ADDR + 0xE) << 2,
   2252#endif
   2253},
   2254#ifdef CONFIG_SND_CS46XX_NEW_DSP
   2255{
   2256	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
   2257	.name = "ADC Capture Switch",
   2258	.info = snd_mixer_boolean_info,
   2259	.get = snd_cs46xx_adc_capture_get,
   2260	.put = snd_cs46xx_adc_capture_put
   2261},
   2262{
   2263	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
   2264	.name = "DAC Capture Switch",
   2265	.info = snd_mixer_boolean_info,
   2266	.get = snd_cs46xx_pcm_capture_get,
   2267	.put = snd_cs46xx_pcm_capture_put
   2268},
   2269{
   2270	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
   2271	.name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH),
   2272	.info = snd_mixer_boolean_info,
   2273	.get = snd_cs46xx_iec958_get,
   2274	.put = snd_cs46xx_iec958_put,
   2275	.private_value = CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT,
   2276},
   2277{
   2278	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
   2279	.name = SNDRV_CTL_NAME_IEC958("Input ",NONE,SWITCH),
   2280	.info = snd_mixer_boolean_info,
   2281	.get = snd_cs46xx_iec958_get,
   2282	.put = snd_cs46xx_iec958_put,
   2283	.private_value = CS46XX_MIXER_SPDIF_INPUT_ELEMENT,
   2284},
   2285#if 0
   2286/* Input IEC958 volume does not work for the moment. (Benny) */
   2287{
   2288	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
   2289	.name = SNDRV_CTL_NAME_IEC958("Input ",NONE,VOLUME),
   2290	.info = snd_cs46xx_vol_info,
   2291	.get = snd_cs46xx_vol_iec958_get,
   2292	.put = snd_cs46xx_vol_iec958_put,
   2293	.private_value = (ASYNCRX_SCB_ADDR + 0xE) << 2,
   2294},
   2295#endif
   2296{
   2297	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
   2298	.name =  SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
   2299	.info =	 snd_cs46xx_spdif_info,
   2300	.get =	 snd_cs46xx_spdif_default_get,
   2301	.put =   snd_cs46xx_spdif_default_put,
   2302},
   2303{
   2304	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
   2305	.name =	 SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
   2306	.info =	 snd_cs46xx_spdif_info,
   2307        .get =	 snd_cs46xx_spdif_mask_get,
   2308	.access = SNDRV_CTL_ELEM_ACCESS_READ
   2309},
   2310{
   2311	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
   2312	.name =	 SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
   2313	.info =	 snd_cs46xx_spdif_info,
   2314	.get =	 snd_cs46xx_spdif_stream_get,
   2315	.put =	 snd_cs46xx_spdif_stream_put
   2316},
   2317
   2318#endif
   2319};
   2320
   2321#ifdef CONFIG_SND_CS46XX_NEW_DSP
   2322/* set primary cs4294 codec into Extended Audio Mode */
   2323static int snd_cs46xx_front_dup_get(struct snd_kcontrol *kcontrol, 
   2324				    struct snd_ctl_elem_value *ucontrol)
   2325{
   2326	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
   2327	unsigned short val;
   2328	val = snd_ac97_read(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], AC97_CSR_ACMODE);
   2329	ucontrol->value.integer.value[0] = (val & 0x200) ? 0 : 1;
   2330	return 0;
   2331}
   2332
   2333static int snd_cs46xx_front_dup_put(struct snd_kcontrol *kcontrol, 
   2334				    struct snd_ctl_elem_value *ucontrol)
   2335{
   2336	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
   2337	return snd_ac97_update_bits(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX],
   2338				    AC97_CSR_ACMODE, 0x200,
   2339				    ucontrol->value.integer.value[0] ? 0 : 0x200);
   2340}
   2341
   2342static const struct snd_kcontrol_new snd_cs46xx_front_dup_ctl = {
   2343	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
   2344	.name = "Duplicate Front",
   2345	.info = snd_mixer_boolean_info,
   2346	.get = snd_cs46xx_front_dup_get,
   2347	.put = snd_cs46xx_front_dup_put,
   2348};
   2349#endif
   2350
   2351#ifdef CONFIG_SND_CS46XX_NEW_DSP
   2352/* Only available on the Hercules Game Theater XP soundcard */
   2353static const struct snd_kcontrol_new snd_hercules_controls[] = {
   2354{
   2355	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
   2356	.name = "Optical/Coaxial SPDIF Input Switch",
   2357	.info = snd_mixer_boolean_info,
   2358	.get = snd_herc_spdif_select_get,
   2359	.put = snd_herc_spdif_select_put,
   2360},
   2361};
   2362
   2363
   2364static void snd_cs46xx_codec_reset (struct snd_ac97 * ac97)
   2365{
   2366	unsigned long end_time;
   2367	int err;
   2368
   2369	/* reset to defaults */
   2370	snd_ac97_write(ac97, AC97_RESET, 0);	
   2371
   2372	/* set the desired CODEC mode */
   2373	if (ac97->num == CS46XX_PRIMARY_CODEC_INDEX) {
   2374		dev_dbg(ac97->bus->card->dev, "CODEC1 mode %04x\n", 0x0);
   2375		snd_cs46xx_ac97_write(ac97, AC97_CSR_ACMODE, 0x0);
   2376	} else if (ac97->num == CS46XX_SECONDARY_CODEC_INDEX) {
   2377		dev_dbg(ac97->bus->card->dev, "CODEC2 mode %04x\n", 0x3);
   2378		snd_cs46xx_ac97_write(ac97, AC97_CSR_ACMODE, 0x3);
   2379	} else {
   2380		snd_BUG(); /* should never happen ... */
   2381	}
   2382
   2383	udelay(50);
   2384
   2385	/* it's necessary to wait awhile until registers are accessible after RESET */
   2386	/* because the PCM or MASTER volume registers can be modified, */
   2387	/* the REC_GAIN register is used for tests */
   2388	end_time = jiffies + HZ;
   2389	do {
   2390		unsigned short ext_mid;
   2391    
   2392		/* use preliminary reads to settle the communication */
   2393		snd_ac97_read(ac97, AC97_RESET);
   2394		snd_ac97_read(ac97, AC97_VENDOR_ID1);
   2395		snd_ac97_read(ac97, AC97_VENDOR_ID2);
   2396		/* modem? */
   2397		ext_mid = snd_ac97_read(ac97, AC97_EXTENDED_MID);
   2398		if (ext_mid != 0xffff && (ext_mid & 1) != 0)
   2399			return;
   2400
   2401		/* test if we can write to the record gain volume register */
   2402		snd_ac97_write(ac97, AC97_REC_GAIN, 0x8a05);
   2403		err = snd_ac97_read(ac97, AC97_REC_GAIN);
   2404		if (err == 0x8a05)
   2405			return;
   2406
   2407		msleep(10);
   2408	} while (time_after_eq(end_time, jiffies));
   2409
   2410	dev_err(ac97->bus->card->dev,
   2411		"CS46xx secondary codec doesn't respond!\n");
   2412}
   2413#endif
   2414
   2415static int cs46xx_detect_codec(struct snd_cs46xx *chip, int codec)
   2416{
   2417	int idx, err;
   2418	struct snd_ac97_template ac97;
   2419
   2420	memset(&ac97, 0, sizeof(ac97));
   2421	ac97.private_data = chip;
   2422	ac97.private_free = snd_cs46xx_mixer_free_ac97;
   2423	ac97.num = codec;
   2424	if (chip->amplifier_ctrl == amp_voyetra)
   2425		ac97.scaps = AC97_SCAP_INV_EAPD;
   2426
   2427	if (codec == CS46XX_SECONDARY_CODEC_INDEX) {
   2428		snd_cs46xx_codec_write(chip, AC97_RESET, 0, codec);
   2429		udelay(10);
   2430		if (snd_cs46xx_codec_read(chip, AC97_RESET, codec) & 0x8000) {
   2431			dev_dbg(chip->card->dev,
   2432				"secondary codec not present\n");
   2433			return -ENXIO;
   2434		}
   2435	}
   2436
   2437	snd_cs46xx_codec_write(chip, AC97_MASTER, 0x8000, codec);
   2438	for (idx = 0; idx < 100; ++idx) {
   2439		if (snd_cs46xx_codec_read(chip, AC97_MASTER, codec) == 0x8000) {
   2440			err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97[codec]);
   2441			return err;
   2442		}
   2443		msleep(10);
   2444	}
   2445	dev_dbg(chip->card->dev, "codec %d detection timeout\n", codec);
   2446	return -ENXIO;
   2447}
   2448
   2449int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device)
   2450{
   2451	struct snd_card *card = chip->card;
   2452	struct snd_ctl_elem_id id;
   2453	int err;
   2454	unsigned int idx;
   2455	static const struct snd_ac97_bus_ops ops = {
   2456#ifdef CONFIG_SND_CS46XX_NEW_DSP
   2457		.reset = snd_cs46xx_codec_reset,
   2458#endif
   2459		.write = snd_cs46xx_ac97_write,
   2460		.read = snd_cs46xx_ac97_read,
   2461	};
   2462
   2463	/* detect primary codec */
   2464	chip->nr_ac97_codecs = 0;
   2465	dev_dbg(chip->card->dev, "detecting primary codec\n");
   2466	err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus);
   2467	if (err < 0)
   2468		return err;
   2469
   2470	if (cs46xx_detect_codec(chip, CS46XX_PRIMARY_CODEC_INDEX) < 0)
   2471		return -ENXIO;
   2472	chip->nr_ac97_codecs = 1;
   2473
   2474#ifdef CONFIG_SND_CS46XX_NEW_DSP
   2475	dev_dbg(chip->card->dev, "detecting secondary codec\n");
   2476	/* try detect a secondary codec */
   2477	if (! cs46xx_detect_codec(chip, CS46XX_SECONDARY_CODEC_INDEX))
   2478		chip->nr_ac97_codecs = 2;
   2479#endif /* CONFIG_SND_CS46XX_NEW_DSP */
   2480
   2481	/* add cs4630 mixer controls */
   2482	for (idx = 0; idx < ARRAY_SIZE(snd_cs46xx_controls); idx++) {
   2483		struct snd_kcontrol *kctl;
   2484		kctl = snd_ctl_new1(&snd_cs46xx_controls[idx], chip);
   2485		if (kctl && kctl->id.iface == SNDRV_CTL_ELEM_IFACE_PCM)
   2486			kctl->id.device = spdif_device;
   2487		err = snd_ctl_add(card, kctl);
   2488		if (err < 0)
   2489			return err;
   2490	}
   2491
   2492	/* get EAPD mixer switch (for voyetra hack) */
   2493	memset(&id, 0, sizeof(id));
   2494	id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
   2495	strcpy(id.name, "External Amplifier");
   2496	chip->eapd_switch = snd_ctl_find_id(chip->card, &id);
   2497    
   2498#ifdef CONFIG_SND_CS46XX_NEW_DSP
   2499	if (chip->nr_ac97_codecs == 1) {
   2500		unsigned int id2 = chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]->id & 0xffff;
   2501		if ((id2 & 0xfff0) == 0x5920) {	/* CS4294 and CS4298 */
   2502			err = snd_ctl_add(card, snd_ctl_new1(&snd_cs46xx_front_dup_ctl, chip));
   2503			if (err < 0)
   2504				return err;
   2505			snd_ac97_write_cache(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX],
   2506					     AC97_CSR_ACMODE, 0x200);
   2507		}
   2508	}
   2509	/* do soundcard specific mixer setup */
   2510	if (chip->mixer_init) {
   2511		dev_dbg(chip->card->dev, "calling chip->mixer_init(chip);\n");
   2512		chip->mixer_init(chip);
   2513	}
   2514#endif
   2515
   2516 	/* turn on amplifier */
   2517	chip->amplifier_ctrl(chip, 1);
   2518    
   2519	return 0;
   2520}
   2521
   2522/*
   2523 *  RawMIDI interface
   2524 */
   2525
   2526static void snd_cs46xx_midi_reset(struct snd_cs46xx *chip)
   2527{
   2528	snd_cs46xx_pokeBA0(chip, BA0_MIDCR, MIDCR_MRST);
   2529	udelay(100);
   2530	snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
   2531}
   2532
   2533static int snd_cs46xx_midi_input_open(struct snd_rawmidi_substream *substream)
   2534{
   2535	struct snd_cs46xx *chip = substream->rmidi->private_data;
   2536
   2537	chip->active_ctrl(chip, 1);
   2538	spin_lock_irq(&chip->reg_lock);
   2539	chip->uartm |= CS46XX_MODE_INPUT;
   2540	chip->midcr |= MIDCR_RXE;
   2541	chip->midi_input = substream;
   2542	if (!(chip->uartm & CS46XX_MODE_OUTPUT)) {
   2543		snd_cs46xx_midi_reset(chip);
   2544	} else {
   2545		snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
   2546	}
   2547	spin_unlock_irq(&chip->reg_lock);
   2548	return 0;
   2549}
   2550
   2551static int snd_cs46xx_midi_input_close(struct snd_rawmidi_substream *substream)
   2552{
   2553	struct snd_cs46xx *chip = substream->rmidi->private_data;
   2554
   2555	spin_lock_irq(&chip->reg_lock);
   2556	chip->midcr &= ~(MIDCR_RXE | MIDCR_RIE);
   2557	chip->midi_input = NULL;
   2558	if (!(chip->uartm & CS46XX_MODE_OUTPUT)) {
   2559		snd_cs46xx_midi_reset(chip);
   2560	} else {
   2561		snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
   2562	}
   2563	chip->uartm &= ~CS46XX_MODE_INPUT;
   2564	spin_unlock_irq(&chip->reg_lock);
   2565	chip->active_ctrl(chip, -1);
   2566	return 0;
   2567}
   2568
   2569static int snd_cs46xx_midi_output_open(struct snd_rawmidi_substream *substream)
   2570{
   2571	struct snd_cs46xx *chip = substream->rmidi->private_data;
   2572
   2573	chip->active_ctrl(chip, 1);
   2574
   2575	spin_lock_irq(&chip->reg_lock);
   2576	chip->uartm |= CS46XX_MODE_OUTPUT;
   2577	chip->midcr |= MIDCR_TXE;
   2578	chip->midi_output = substream;
   2579	if (!(chip->uartm & CS46XX_MODE_INPUT)) {
   2580		snd_cs46xx_midi_reset(chip);
   2581	} else {
   2582		snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
   2583	}
   2584	spin_unlock_irq(&chip->reg_lock);
   2585	return 0;
   2586}
   2587
   2588static int snd_cs46xx_midi_output_close(struct snd_rawmidi_substream *substream)
   2589{
   2590	struct snd_cs46xx *chip = substream->rmidi->private_data;
   2591
   2592	spin_lock_irq(&chip->reg_lock);
   2593	chip->midcr &= ~(MIDCR_TXE | MIDCR_TIE);
   2594	chip->midi_output = NULL;
   2595	if (!(chip->uartm & CS46XX_MODE_INPUT)) {
   2596		snd_cs46xx_midi_reset(chip);
   2597	} else {
   2598		snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
   2599	}
   2600	chip->uartm &= ~CS46XX_MODE_OUTPUT;
   2601	spin_unlock_irq(&chip->reg_lock);
   2602	chip->active_ctrl(chip, -1);
   2603	return 0;
   2604}
   2605
   2606static void snd_cs46xx_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
   2607{
   2608	unsigned long flags;
   2609	struct snd_cs46xx *chip = substream->rmidi->private_data;
   2610
   2611	spin_lock_irqsave(&chip->reg_lock, flags);
   2612	if (up) {
   2613		if ((chip->midcr & MIDCR_RIE) == 0) {
   2614			chip->midcr |= MIDCR_RIE;
   2615			snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
   2616		}
   2617	} else {
   2618		if (chip->midcr & MIDCR_RIE) {
   2619			chip->midcr &= ~MIDCR_RIE;
   2620			snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
   2621		}
   2622	}
   2623	spin_unlock_irqrestore(&chip->reg_lock, flags);
   2624}
   2625
   2626static void snd_cs46xx_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
   2627{
   2628	unsigned long flags;
   2629	struct snd_cs46xx *chip = substream->rmidi->private_data;
   2630	unsigned char byte;
   2631
   2632	spin_lock_irqsave(&chip->reg_lock, flags);
   2633	if (up) {
   2634		if ((chip->midcr & MIDCR_TIE) == 0) {
   2635			chip->midcr |= MIDCR_TIE;
   2636			/* fill UART FIFO buffer at first, and turn Tx interrupts only if necessary */
   2637			while ((chip->midcr & MIDCR_TIE) &&
   2638			       (snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_TBF) == 0) {
   2639				if (snd_rawmidi_transmit(substream, &byte, 1) != 1) {
   2640					chip->midcr &= ~MIDCR_TIE;
   2641				} else {
   2642					snd_cs46xx_pokeBA0(chip, BA0_MIDWP, byte);
   2643				}
   2644			}
   2645			snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
   2646		}
   2647	} else {
   2648		if (chip->midcr & MIDCR_TIE) {
   2649			chip->midcr &= ~MIDCR_TIE;
   2650			snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
   2651		}
   2652	}
   2653	spin_unlock_irqrestore(&chip->reg_lock, flags);
   2654}
   2655
   2656static const struct snd_rawmidi_ops snd_cs46xx_midi_output =
   2657{
   2658	.open =		snd_cs46xx_midi_output_open,
   2659	.close =	snd_cs46xx_midi_output_close,
   2660	.trigger =	snd_cs46xx_midi_output_trigger,
   2661};
   2662
   2663static const struct snd_rawmidi_ops snd_cs46xx_midi_input =
   2664{
   2665	.open =		snd_cs46xx_midi_input_open,
   2666	.close =	snd_cs46xx_midi_input_close,
   2667	.trigger =	snd_cs46xx_midi_input_trigger,
   2668};
   2669
   2670int snd_cs46xx_midi(struct snd_cs46xx *chip, int device)
   2671{
   2672	struct snd_rawmidi *rmidi;
   2673	int err;
   2674
   2675	err = snd_rawmidi_new(chip->card, "CS46XX", device, 1, 1, &rmidi);
   2676	if (err < 0)
   2677		return err;
   2678	strcpy(rmidi->name, "CS46XX");
   2679	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_cs46xx_midi_output);
   2680	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_cs46xx_midi_input);
   2681	rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
   2682	rmidi->private_data = chip;
   2683	chip->rmidi = rmidi;
   2684	return 0;
   2685}
   2686
   2687
   2688/*
   2689 * gameport interface
   2690 */
   2691
   2692#if IS_REACHABLE(CONFIG_GAMEPORT)
   2693
   2694static void snd_cs46xx_gameport_trigger(struct gameport *gameport)
   2695{
   2696	struct snd_cs46xx *chip = gameport_get_port_data(gameport);
   2697
   2698	if (snd_BUG_ON(!chip))
   2699		return;
   2700	snd_cs46xx_pokeBA0(chip, BA0_JSPT, 0xFF);  //outb(gameport->io, 0xFF);
   2701}
   2702
   2703static unsigned char snd_cs46xx_gameport_read(struct gameport *gameport)
   2704{
   2705	struct snd_cs46xx *chip = gameport_get_port_data(gameport);
   2706
   2707	if (snd_BUG_ON(!chip))
   2708		return 0;
   2709	return snd_cs46xx_peekBA0(chip, BA0_JSPT); //inb(gameport->io);
   2710}
   2711
   2712static int snd_cs46xx_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
   2713{
   2714	struct snd_cs46xx *chip = gameport_get_port_data(gameport);
   2715	unsigned js1, js2, jst;
   2716
   2717	if (snd_BUG_ON(!chip))
   2718		return 0;
   2719
   2720	js1 = snd_cs46xx_peekBA0(chip, BA0_JSC1);
   2721	js2 = snd_cs46xx_peekBA0(chip, BA0_JSC2);
   2722	jst = snd_cs46xx_peekBA0(chip, BA0_JSPT);
   2723	
   2724	*buttons = (~jst >> 4) & 0x0F; 
   2725	
   2726	axes[0] = ((js1 & JSC1_Y1V_MASK) >> JSC1_Y1V_SHIFT) & 0xFFFF;
   2727	axes[1] = ((js1 & JSC1_X1V_MASK) >> JSC1_X1V_SHIFT) & 0xFFFF;
   2728	axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF;
   2729	axes[3] = ((js2 & JSC2_X2V_MASK) >> JSC2_X2V_SHIFT) & 0xFFFF;
   2730
   2731	for(jst=0;jst<4;++jst)
   2732		if(axes[jst]==0xFFFF) axes[jst] = -1;
   2733	return 0;
   2734}
   2735
   2736static int snd_cs46xx_gameport_open(struct gameport *gameport, int mode)
   2737{
   2738	switch (mode) {
   2739	case GAMEPORT_MODE_COOKED:
   2740		return 0;
   2741	case GAMEPORT_MODE_RAW:
   2742		return 0;
   2743	default:
   2744		return -1;
   2745	}
   2746	return 0;
   2747}
   2748
   2749int snd_cs46xx_gameport(struct snd_cs46xx *chip)
   2750{
   2751	struct gameport *gp;
   2752
   2753	chip->gameport = gp = gameport_allocate_port();
   2754	if (!gp) {
   2755		dev_err(chip->card->dev,
   2756			"cannot allocate memory for gameport\n");
   2757		return -ENOMEM;
   2758	}
   2759
   2760	gameport_set_name(gp, "CS46xx Gameport");
   2761	gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
   2762	gameport_set_dev_parent(gp, &chip->pci->dev);
   2763	gameport_set_port_data(gp, chip);
   2764
   2765	gp->open = snd_cs46xx_gameport_open;
   2766	gp->read = snd_cs46xx_gameport_read;
   2767	gp->trigger = snd_cs46xx_gameport_trigger;
   2768	gp->cooked_read = snd_cs46xx_gameport_cooked_read;
   2769
   2770	snd_cs46xx_pokeBA0(chip, BA0_JSIO, 0xFF); // ?
   2771	snd_cs46xx_pokeBA0(chip, BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW);
   2772
   2773	gameport_register_port(gp);
   2774
   2775	return 0;
   2776}
   2777
   2778static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip)
   2779{
   2780	if (chip->gameport) {
   2781		gameport_unregister_port(chip->gameport);
   2782		chip->gameport = NULL;
   2783	}
   2784}
   2785#else
   2786int snd_cs46xx_gameport(struct snd_cs46xx *chip) { return -ENOSYS; }
   2787static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip) { }
   2788#endif /* CONFIG_GAMEPORT */
   2789
   2790#ifdef CONFIG_SND_PROC_FS
   2791/*
   2792 *  proc interface
   2793 */
   2794
   2795static ssize_t snd_cs46xx_io_read(struct snd_info_entry *entry,
   2796				  void *file_private_data,
   2797				  struct file *file, char __user *buf,
   2798				  size_t count, loff_t pos)
   2799{
   2800	struct snd_cs46xx_region *region = entry->private_data;
   2801	
   2802	if (copy_to_user_fromio(buf, region->remap_addr + pos, count))
   2803		return -EFAULT;
   2804	return count;
   2805}
   2806
   2807static const struct snd_info_entry_ops snd_cs46xx_proc_io_ops = {
   2808	.read = snd_cs46xx_io_read,
   2809};
   2810
   2811static int snd_cs46xx_proc_init(struct snd_card *card, struct snd_cs46xx *chip)
   2812{
   2813	struct snd_info_entry *entry;
   2814	int idx;
   2815	
   2816	for (idx = 0; idx < 5; idx++) {
   2817		struct snd_cs46xx_region *region = &chip->region.idx[idx];
   2818		if (! snd_card_proc_new(card, region->name, &entry)) {
   2819			entry->content = SNDRV_INFO_CONTENT_DATA;
   2820			entry->private_data = chip;
   2821			entry->c.ops = &snd_cs46xx_proc_io_ops;
   2822			entry->size = region->size;
   2823			entry->mode = S_IFREG | 0400;
   2824		}
   2825	}
   2826#ifdef CONFIG_SND_CS46XX_NEW_DSP
   2827	cs46xx_dsp_proc_init(card, chip);
   2828#endif
   2829	return 0;
   2830}
   2831
   2832static int snd_cs46xx_proc_done(struct snd_cs46xx *chip)
   2833{
   2834#ifdef CONFIG_SND_CS46XX_NEW_DSP
   2835	cs46xx_dsp_proc_done(chip);
   2836#endif
   2837	return 0;
   2838}
   2839#else /* !CONFIG_SND_PROC_FS */
   2840#define snd_cs46xx_proc_init(card, chip)
   2841#define snd_cs46xx_proc_done(chip)
   2842#endif
   2843
   2844/*
   2845 * stop the h/w
   2846 */
   2847static void snd_cs46xx_hw_stop(struct snd_cs46xx *chip)
   2848{
   2849	unsigned int tmp;
   2850
   2851	tmp = snd_cs46xx_peek(chip, BA1_PFIE);
   2852	tmp &= ~0x0000f03f;
   2853	tmp |=  0x00000010;
   2854	snd_cs46xx_poke(chip, BA1_PFIE, tmp);	/* playback interrupt disable */
   2855
   2856	tmp = snd_cs46xx_peek(chip, BA1_CIE);
   2857	tmp &= ~0x0000003f;
   2858	tmp |=  0x00000011;
   2859	snd_cs46xx_poke(chip, BA1_CIE, tmp);	/* capture interrupt disable */
   2860
   2861	/*
   2862         *  Stop playback DMA.
   2863	 */
   2864	tmp = snd_cs46xx_peek(chip, BA1_PCTL);
   2865	snd_cs46xx_poke(chip, BA1_PCTL, tmp & 0x0000ffff);
   2866
   2867	/*
   2868         *  Stop capture DMA.
   2869	 */
   2870	tmp = snd_cs46xx_peek(chip, BA1_CCTL);
   2871	snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000);
   2872
   2873	/*
   2874         *  Reset the processor.
   2875         */
   2876	snd_cs46xx_reset(chip);
   2877
   2878	snd_cs46xx_proc_stop(chip);
   2879
   2880	/*
   2881	 *  Power down the PLL.
   2882	 */
   2883	snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, 0);
   2884
   2885	/*
   2886	 *  Turn off the Processor by turning off the software clock enable flag in 
   2887	 *  the clock control register.
   2888	 */
   2889	tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE;
   2890	snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp);
   2891}
   2892
   2893
   2894static void snd_cs46xx_free(struct snd_card *card)
   2895{
   2896	struct snd_cs46xx *chip = card->private_data;
   2897#ifdef CONFIG_SND_CS46XX_NEW_DSP
   2898	int idx;
   2899#endif
   2900
   2901	if (chip->active_ctrl)
   2902		chip->active_ctrl(chip, 1);
   2903
   2904	snd_cs46xx_remove_gameport(chip);
   2905
   2906	if (chip->amplifier_ctrl)
   2907		chip->amplifier_ctrl(chip, -chip->amplifier); /* force to off */
   2908	
   2909	snd_cs46xx_proc_done(chip);
   2910
   2911	snd_cs46xx_hw_stop(chip);
   2912
   2913	if (chip->active_ctrl)
   2914		chip->active_ctrl(chip, -chip->amplifier);
   2915
   2916#ifdef CONFIG_SND_CS46XX_NEW_DSP
   2917	if (chip->dsp_spos_instance) {
   2918		cs46xx_dsp_spos_destroy(chip);
   2919		chip->dsp_spos_instance = NULL;
   2920	}
   2921	for (idx = 0; idx < CS46XX_DSP_MODULES; idx++)
   2922		free_module_desc(chip->modules[idx]);
   2923#else
   2924	vfree(chip->ba1);
   2925#endif
   2926}
   2927
   2928/*
   2929 *  initialize chip
   2930 */
   2931static int snd_cs46xx_chip_init(struct snd_cs46xx *chip)
   2932{
   2933	int timeout;
   2934
   2935	/* 
   2936	 *  First, blast the clock control register to zero so that the PLL starts
   2937         *  out in a known state, and blast the master serial port control register
   2938         *  to zero so that the serial ports also start out in a known state.
   2939         */
   2940        snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, 0);
   2941        snd_cs46xx_pokeBA0(chip, BA0_SERMC1, 0);
   2942
   2943	/*
   2944	 *  If we are in AC97 mode, then we must set the part to a host controlled
   2945         *  AC-link.  Otherwise, we won't be able to bring up the link.
   2946         */        
   2947#ifdef CONFIG_SND_CS46XX_NEW_DSP
   2948	snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0 | 
   2949			   SERACC_TWO_CODECS);	/* 2.00 dual codecs */
   2950	/* snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0); */ /* 2.00 codec */
   2951#else
   2952	snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_1_03); /* 1.03 codec */
   2953#endif
   2954
   2955        /*
   2956         *  Drive the ARST# pin low for a minimum of 1uS (as defined in the AC97
   2957         *  spec) and then drive it high.  This is done for non AC97 modes since
   2958         *  there might be logic external to the CS461x that uses the ARST# line
   2959         *  for a reset.
   2960         */
   2961	snd_cs46xx_pokeBA0(chip, BA0_ACCTL, 0);
   2962#ifdef CONFIG_SND_CS46XX_NEW_DSP
   2963	snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, 0);
   2964#endif
   2965	udelay(50);
   2966	snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_RSTN);
   2967#ifdef CONFIG_SND_CS46XX_NEW_DSP
   2968	snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_RSTN);
   2969#endif
   2970    
   2971	/*
   2972	 *  The first thing we do here is to enable sync generation.  As soon
   2973	 *  as we start receiving bit clock, we'll start producing the SYNC
   2974	 *  signal.
   2975	 */
   2976	snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_ESYN | ACCTL_RSTN);
   2977#ifdef CONFIG_SND_CS46XX_NEW_DSP
   2978	snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_ESYN | ACCTL_RSTN);
   2979#endif
   2980
   2981	/*
   2982	 *  Now wait for a short while to allow the AC97 part to start
   2983	 *  generating bit clock (so we don't try to start the PLL without an
   2984	 *  input clock).
   2985	 */
   2986	mdelay(10);
   2987
   2988	/*
   2989	 *  Set the serial port timing configuration, so that
   2990	 *  the clock control circuit gets its clock from the correct place.
   2991	 */
   2992	snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97);
   2993
   2994	/*
   2995	 *  Write the selected clock control setup to the hardware.  Do not turn on
   2996	 *  SWCE yet (if requested), so that the devices clocked by the output of
   2997	 *  PLL are not clocked until the PLL is stable.
   2998	 */
   2999	snd_cs46xx_pokeBA0(chip, BA0_PLLCC, PLLCC_LPF_1050_2780_KHZ | PLLCC_CDR_73_104_MHZ);
   3000	snd_cs46xx_pokeBA0(chip, BA0_PLLM, 0x3a);
   3001	snd_cs46xx_pokeBA0(chip, BA0_CLKCR2, CLKCR2_PDIVS_8);
   3002
   3003	/*
   3004	 *  Power up the PLL.
   3005	 */
   3006	snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP);
   3007
   3008	/*
   3009         *  Wait until the PLL has stabilized.
   3010	 */
   3011	msleep(100);
   3012
   3013	/*
   3014	 *  Turn on clocking of the core so that we can setup the serial ports.
   3015	 */
   3016	snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP | CLKCR1_SWCE);
   3017
   3018	/*
   3019	 * Enable FIFO  Host Bypass
   3020	 */
   3021	snd_cs46xx_pokeBA0(chip, BA0_SERBCF, SERBCF_HBP);
   3022
   3023	/*
   3024	 *  Fill the serial port FIFOs with silence.
   3025	 */
   3026	snd_cs46xx_clear_serial_FIFOs(chip);
   3027
   3028	/*
   3029	 *  Set the serial port FIFO pointer to the first sample in the FIFO.
   3030	 */
   3031	/* snd_cs46xx_pokeBA0(chip, BA0_SERBSP, 0); */
   3032
   3033	/*
   3034	 *  Write the serial port configuration to the part.  The master
   3035	 *  enable bit is not set until all other values have been written.
   3036	 */
   3037	snd_cs46xx_pokeBA0(chip, BA0_SERC1, SERC1_SO1F_AC97 | SERC1_SO1EN);
   3038	snd_cs46xx_pokeBA0(chip, BA0_SERC2, SERC2_SI1F_AC97 | SERC1_SO1EN);
   3039	snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97 | SERMC1_MSPE);
   3040
   3041
   3042#ifdef CONFIG_SND_CS46XX_NEW_DSP
   3043	snd_cs46xx_pokeBA0(chip, BA0_SERC7, SERC7_ASDI2EN);
   3044	snd_cs46xx_pokeBA0(chip, BA0_SERC3, 0);
   3045	snd_cs46xx_pokeBA0(chip, BA0_SERC4, 0);
   3046	snd_cs46xx_pokeBA0(chip, BA0_SERC5, 0);
   3047	snd_cs46xx_pokeBA0(chip, BA0_SERC6, 1);
   3048#endif
   3049
   3050	mdelay(5);
   3051
   3052
   3053	/*
   3054	 * Wait for the codec ready signal from the AC97 codec.
   3055	 */
   3056	timeout = 150;
   3057	while (timeout-- > 0) {
   3058		/*
   3059		 *  Read the AC97 status register to see if we've seen a CODEC READY
   3060		 *  signal from the AC97 codec.
   3061		 */
   3062		if (snd_cs46xx_peekBA0(chip, BA0_ACSTS) & ACSTS_CRDY)
   3063			goto ok1;
   3064		msleep(10);
   3065	}
   3066
   3067
   3068	dev_err(chip->card->dev,
   3069		"create - never read codec ready from AC'97\n");
   3070	dev_err(chip->card->dev,
   3071		"it is not probably bug, try to use CS4236 driver\n");
   3072	return -EIO;
   3073 ok1:
   3074#ifdef CONFIG_SND_CS46XX_NEW_DSP
   3075	{
   3076		int count;
   3077		for (count = 0; count < 150; count++) {
   3078			/* First, we want to wait for a short time. */
   3079			udelay(25);
   3080        
   3081			if (snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY)
   3082				break;
   3083		}
   3084
   3085		/*
   3086		 *  Make sure CODEC is READY.
   3087		 */
   3088		if (!(snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY))
   3089			dev_dbg(chip->card->dev,
   3090				"never read card ready from secondary AC'97\n");
   3091	}
   3092#endif
   3093
   3094	/*
   3095	 *  Assert the vaid frame signal so that we can start sending commands
   3096	 *  to the AC97 codec.
   3097	 */
   3098	snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
   3099#ifdef CONFIG_SND_CS46XX_NEW_DSP
   3100	snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
   3101#endif
   3102
   3103
   3104	/*
   3105	 *  Wait until we've sampled input slots 3 and 4 as valid, meaning that
   3106	 *  the codec is pumping ADC data across the AC-link.
   3107	 */
   3108	timeout = 150;
   3109	while (timeout-- > 0) {
   3110		/*
   3111		 *  Read the input slot valid register and see if input slots 3 and
   3112		 *  4 are valid yet.
   3113		 */
   3114		if ((snd_cs46xx_peekBA0(chip, BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) == (ACISV_ISV3 | ACISV_ISV4))
   3115			goto ok2;
   3116		msleep(10);
   3117	}
   3118
   3119#ifndef CONFIG_SND_CS46XX_NEW_DSP
   3120	dev_err(chip->card->dev,
   3121		"create - never read ISV3 & ISV4 from AC'97\n");
   3122	return -EIO;
   3123#else
   3124	/* This may happen on a cold boot with a Terratec SiXPack 5.1.
   3125	   Reloading the driver may help, if there's other soundcards 
   3126	   with the same problem I would like to know. (Benny) */
   3127
   3128	dev_err(chip->card->dev, "never read ISV3 & ISV4 from AC'97\n");
   3129	dev_err(chip->card->dev,
   3130		"Try reloading the ALSA driver, if you find something\n");
   3131	dev_err(chip->card->dev,
   3132		"broken or not working on your soundcard upon\n");
   3133	dev_err(chip->card->dev,
   3134		"this message please report to alsa-devel@alsa-project.org\n");
   3135
   3136	return -EIO;
   3137#endif
   3138 ok2:
   3139
   3140	/*
   3141	 *  Now, assert valid frame and the slot 3 and 4 valid bits.  This will
   3142	 *  commense the transfer of digital audio data to the AC97 codec.
   3143	 */
   3144
   3145	snd_cs46xx_pokeBA0(chip, BA0_ACOSV, ACOSV_SLV3 | ACOSV_SLV4);
   3146
   3147
   3148	/*
   3149	 *  Power down the DAC and ADC.  We will power them up (if) when we need
   3150	 *  them.
   3151	 */
   3152	/* snd_cs46xx_pokeBA0(chip, BA0_AC97_POWERDOWN, 0x300); */
   3153
   3154	/*
   3155	 *  Turn off the Processor by turning off the software clock enable flag in 
   3156	 *  the clock control register.
   3157	 */
   3158	/* tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE; */
   3159	/* snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); */
   3160
   3161	return 0;
   3162}
   3163
   3164/*
   3165 *  start and load DSP 
   3166 */
   3167
   3168static void cs46xx_enable_stream_irqs(struct snd_cs46xx *chip)
   3169{
   3170	unsigned int tmp;
   3171
   3172	snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM);
   3173        
   3174	tmp = snd_cs46xx_peek(chip, BA1_PFIE);
   3175	tmp &= ~0x0000f03f;
   3176	snd_cs46xx_poke(chip, BA1_PFIE, tmp);	/* playback interrupt enable */
   3177
   3178	tmp = snd_cs46xx_peek(chip, BA1_CIE);
   3179	tmp &= ~0x0000003f;
   3180	tmp |=  0x00000001;
   3181	snd_cs46xx_poke(chip, BA1_CIE, tmp);	/* capture interrupt enable */
   3182}
   3183
   3184int snd_cs46xx_start_dsp(struct snd_cs46xx *chip)
   3185{	
   3186	unsigned int tmp;
   3187#ifdef CONFIG_SND_CS46XX_NEW_DSP
   3188	int i;
   3189#endif
   3190	int err;
   3191
   3192	/*
   3193	 *  Reset the processor.
   3194	 */
   3195	snd_cs46xx_reset(chip);
   3196	/*
   3197	 *  Download the image to the processor.
   3198	 */
   3199#ifdef CONFIG_SND_CS46XX_NEW_DSP
   3200	for (i = 0; i < CS46XX_DSP_MODULES; i++) {
   3201		err = load_firmware(chip, &chip->modules[i], module_names[i]);
   3202		if (err < 0) {
   3203			dev_err(chip->card->dev, "firmware load error [%s]\n",
   3204				   module_names[i]);
   3205			return err;
   3206		}
   3207		err = cs46xx_dsp_load_module(chip, chip->modules[i]);
   3208		if (err < 0) {
   3209			dev_err(chip->card->dev, "image download error [%s]\n",
   3210				   module_names[i]);
   3211			return err;
   3212		}
   3213	}
   3214
   3215	if (cs46xx_dsp_scb_and_task_init(chip) < 0)
   3216		return -EIO;
   3217#else
   3218	err = load_firmware(chip);
   3219	if (err < 0)
   3220		return err;
   3221
   3222	/* old image */
   3223	err = snd_cs46xx_download_image(chip);
   3224	if (err < 0) {
   3225		dev_err(chip->card->dev, "image download error\n");
   3226		return err;
   3227	}
   3228
   3229	/*
   3230         *  Stop playback DMA.
   3231	 */
   3232	tmp = snd_cs46xx_peek(chip, BA1_PCTL);
   3233	chip->play_ctl = tmp & 0xffff0000;
   3234	snd_cs46xx_poke(chip, BA1_PCTL, tmp & 0x0000ffff);
   3235#endif
   3236
   3237	/*
   3238         *  Stop capture DMA.
   3239	 */
   3240	tmp = snd_cs46xx_peek(chip, BA1_CCTL);
   3241	chip->capt.ctl = tmp & 0x0000ffff;
   3242	snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000);
   3243
   3244	mdelay(5);
   3245
   3246	snd_cs46xx_set_play_sample_rate(chip, 8000);
   3247	snd_cs46xx_set_capture_sample_rate(chip, 8000);
   3248
   3249	snd_cs46xx_proc_start(chip);
   3250
   3251	cs46xx_enable_stream_irqs(chip);
   3252	
   3253#ifndef CONFIG_SND_CS46XX_NEW_DSP
   3254	/* set the attenuation to 0dB */ 
   3255	snd_cs46xx_poke(chip, BA1_PVOL, 0x80008000);
   3256	snd_cs46xx_poke(chip, BA1_CVOL, 0x80008000);
   3257#endif
   3258
   3259	return 0;
   3260}
   3261
   3262
   3263/*
   3264 *	AMP control - null AMP
   3265 */
   3266 
   3267static void amp_none(struct snd_cs46xx *chip, int change)
   3268{	
   3269}
   3270
   3271#ifdef CONFIG_SND_CS46XX_NEW_DSP
   3272static int voyetra_setup_eapd_slot(struct snd_cs46xx *chip)
   3273{
   3274	
   3275	u32 idx, valid_slots,tmp,powerdown = 0;
   3276	u16 modem_power,pin_config,logic_type;
   3277
   3278	dev_dbg(chip->card->dev, "cs46xx_setup_eapd_slot()+\n");
   3279
   3280	/*
   3281	 *  See if the devices are powered down.  If so, we must power them up first
   3282	 *  or they will not respond.
   3283	 */
   3284	tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1);
   3285
   3286	if (!(tmp & CLKCR1_SWCE)) {
   3287		snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp | CLKCR1_SWCE);
   3288		powerdown = 1;
   3289	}
   3290
   3291	/*
   3292	 * Clear PRA.  The Bonzo chip will be used for GPIO not for modem
   3293	 * stuff.
   3294	 */
   3295	if(chip->nr_ac97_codecs != 2) {
   3296		dev_err(chip->card->dev,
   3297			"cs46xx_setup_eapd_slot() - no secondary codec configured\n");
   3298		return -EINVAL;
   3299	}
   3300
   3301	modem_power = snd_cs46xx_codec_read (chip, 
   3302					     AC97_EXTENDED_MSTATUS,
   3303					     CS46XX_SECONDARY_CODEC_INDEX);
   3304	modem_power &=0xFEFF;
   3305
   3306	snd_cs46xx_codec_write(chip, 
   3307			       AC97_EXTENDED_MSTATUS, modem_power,
   3308			       CS46XX_SECONDARY_CODEC_INDEX);
   3309
   3310	/*
   3311	 * Set GPIO pin's 7 and 8 so that they are configured for output.
   3312	 */
   3313	pin_config = snd_cs46xx_codec_read (chip, 
   3314					    AC97_GPIO_CFG,
   3315					    CS46XX_SECONDARY_CODEC_INDEX);
   3316	pin_config &=0x27F;
   3317
   3318	snd_cs46xx_codec_write(chip, 
   3319			       AC97_GPIO_CFG, pin_config,
   3320			       CS46XX_SECONDARY_CODEC_INDEX);
   3321    
   3322	/*
   3323	 * Set GPIO pin's 7 and 8 so that they are compatible with CMOS logic.
   3324	 */
   3325
   3326	logic_type = snd_cs46xx_codec_read(chip, AC97_GPIO_POLARITY,
   3327					   CS46XX_SECONDARY_CODEC_INDEX);
   3328	logic_type &=0x27F; 
   3329
   3330	snd_cs46xx_codec_write (chip, AC97_GPIO_POLARITY, logic_type,
   3331				CS46XX_SECONDARY_CODEC_INDEX);
   3332
   3333	valid_slots = snd_cs46xx_peekBA0(chip, BA0_ACOSV);
   3334	valid_slots |= 0x200;
   3335	snd_cs46xx_pokeBA0(chip, BA0_ACOSV, valid_slots);
   3336
   3337	if ( cs46xx_wait_for_fifo(chip,1) ) {
   3338		dev_dbg(chip->card->dev, "FIFO is busy\n");
   3339	  
   3340	  return -EINVAL;
   3341	}
   3342
   3343	/*
   3344	 * Fill slots 12 with the correct value for the GPIO pins. 
   3345	 */
   3346	for(idx = 0x90; idx <= 0x9F; idx++) {
   3347		/*
   3348		 * Initialize the fifo so that bits 7 and 8 are on.
   3349		 *
   3350		 * Remember that the GPIO pins in bonzo are shifted by 4 bits to
   3351		 * the left.  0x1800 corresponds to bits 7 and 8.
   3352		 */
   3353		snd_cs46xx_pokeBA0(chip, BA0_SERBWP, 0x1800);
   3354
   3355		/*
   3356		 * Wait for command to complete
   3357		 */
   3358		if ( cs46xx_wait_for_fifo(chip,200) ) {
   3359			dev_dbg(chip->card->dev,
   3360				"failed waiting for FIFO at addr (%02X)\n",
   3361				idx);
   3362
   3363			return -EINVAL;
   3364		}
   3365            
   3366		/*
   3367		 * Write the serial port FIFO index.
   3368		 */
   3369		snd_cs46xx_pokeBA0(chip, BA0_SERBAD, idx);
   3370      
   3371		/*
   3372		 * Tell the serial port to load the new value into the FIFO location.
   3373		 */
   3374		snd_cs46xx_pokeBA0(chip, BA0_SERBCM, SERBCM_WRC);
   3375	}
   3376
   3377	/* wait for last command to complete */
   3378	cs46xx_wait_for_fifo(chip,200);
   3379
   3380	/*
   3381	 *  Now, if we powered up the devices, then power them back down again.
   3382	 *  This is kinda ugly, but should never happen.
   3383	 */
   3384	if (powerdown)
   3385		snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp);
   3386
   3387	return 0;
   3388}
   3389#endif
   3390
   3391/*
   3392 *	Crystal EAPD mode
   3393 */
   3394 
   3395static void amp_voyetra(struct snd_cs46xx *chip, int change)
   3396{
   3397	/* Manage the EAPD bit on the Crystal 4297 
   3398	   and the Analog AD1885 */
   3399	   
   3400#ifdef CONFIG_SND_CS46XX_NEW_DSP
   3401	int old = chip->amplifier;
   3402#endif
   3403	int oval, val;
   3404	
   3405	chip->amplifier += change;
   3406	oval = snd_cs46xx_codec_read(chip, AC97_POWERDOWN,
   3407				     CS46XX_PRIMARY_CODEC_INDEX);
   3408	val = oval;
   3409	if (chip->amplifier) {
   3410		/* Turn the EAPD amp on */
   3411		val |= 0x8000;
   3412	} else {
   3413		/* Turn the EAPD amp off */
   3414		val &= ~0x8000;
   3415	}
   3416	if (val != oval) {
   3417		snd_cs46xx_codec_write(chip, AC97_POWERDOWN, val,
   3418				       CS46XX_PRIMARY_CODEC_INDEX);
   3419		if (chip->eapd_switch)
   3420			snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
   3421				       &chip->eapd_switch->id);
   3422	}
   3423
   3424#ifdef CONFIG_SND_CS46XX_NEW_DSP
   3425	if (chip->amplifier && !old) {
   3426		voyetra_setup_eapd_slot(chip);
   3427	}
   3428#endif
   3429}
   3430
   3431static void hercules_init(struct snd_cs46xx *chip) 
   3432{
   3433	/* default: AMP off, and SPDIF input optical */
   3434	snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0);
   3435	snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0);
   3436}
   3437
   3438
   3439/*
   3440 *	Game Theatre XP card - EGPIO[2] is used to enable the external amp.
   3441 */ 
   3442static void amp_hercules(struct snd_cs46xx *chip, int change)
   3443{
   3444	int old = chip->amplifier;
   3445	int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR);
   3446	int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR);
   3447
   3448	chip->amplifier += change;
   3449	if (chip->amplifier && !old) {
   3450		dev_dbg(chip->card->dev, "Hercules amplifier ON\n");
   3451
   3452		snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, 
   3453				   EGPIODR_GPOE2 | val1);     /* enable EGPIO2 output */
   3454		snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, 
   3455				   EGPIOPTR_GPPT2 | val2);   /* open-drain on output */
   3456	} else if (old && !chip->amplifier) {
   3457		dev_dbg(chip->card->dev, "Hercules amplifier OFF\n");
   3458		snd_cs46xx_pokeBA0(chip, BA0_EGPIODR,  val1 & ~EGPIODR_GPOE2); /* disable */
   3459		snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT2); /* disable */
   3460	}
   3461}
   3462
   3463static void voyetra_mixer_init (struct snd_cs46xx *chip)
   3464{
   3465	dev_dbg(chip->card->dev, "initializing Voyetra mixer\n");
   3466
   3467	/* Enable SPDIF out */
   3468	snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0);
   3469	snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0);
   3470}
   3471
   3472static void hercules_mixer_init (struct snd_cs46xx *chip)
   3473{
   3474#ifdef CONFIG_SND_CS46XX_NEW_DSP
   3475	unsigned int idx;
   3476	int err;
   3477	struct snd_card *card = chip->card;
   3478#endif
   3479
   3480	/* set EGPIO to default */
   3481	hercules_init(chip);
   3482
   3483	dev_dbg(chip->card->dev, "initializing Hercules mixer\n");
   3484
   3485#ifdef CONFIG_SND_CS46XX_NEW_DSP
   3486	if (chip->in_suspend)
   3487		return;
   3488
   3489	for (idx = 0 ; idx < ARRAY_SIZE(snd_hercules_controls); idx++) {
   3490		struct snd_kcontrol *kctl;
   3491
   3492		kctl = snd_ctl_new1(&snd_hercules_controls[idx], chip);
   3493		err = snd_ctl_add(card, kctl);
   3494		if (err < 0) {
   3495			dev_err(card->dev,
   3496				"failed to initialize Hercules mixer (%d)\n",
   3497				err);
   3498			break;
   3499		}
   3500	}
   3501#endif
   3502}
   3503
   3504
   3505#if 0
   3506/*
   3507 *	Untested
   3508 */
   3509 
   3510static void amp_voyetra_4294(struct snd_cs46xx *chip, int change)
   3511{
   3512	chip->amplifier += change;
   3513
   3514	if (chip->amplifier) {
   3515		/* Switch the GPIO pins 7 and 8 to open drain */
   3516		snd_cs46xx_codec_write(chip, 0x4C,
   3517				       snd_cs46xx_codec_read(chip, 0x4C) & 0xFE7F);
   3518		snd_cs46xx_codec_write(chip, 0x4E,
   3519				       snd_cs46xx_codec_read(chip, 0x4E) | 0x0180);
   3520		/* Now wake the AMP (this might be backwards) */
   3521		snd_cs46xx_codec_write(chip, 0x54,
   3522				       snd_cs46xx_codec_read(chip, 0x54) & ~0x0180);
   3523	} else {
   3524		snd_cs46xx_codec_write(chip, 0x54,
   3525				       snd_cs46xx_codec_read(chip, 0x54) | 0x0180);
   3526	}
   3527}
   3528#endif
   3529
   3530
   3531/*
   3532 *	Handle the CLKRUN on a thinkpad. We must disable CLKRUN support
   3533 *	whenever we need to beat on the chip.
   3534 *
   3535 *	The original idea and code for this hack comes from David Kaiser at
   3536 *	Linuxcare. Perhaps one day Crystal will document their chips well
   3537 *	enough to make them useful.
   3538 */
   3539 
   3540static void clkrun_hack(struct snd_cs46xx *chip, int change)
   3541{
   3542	u16 control, nval;
   3543	
   3544	if (!chip->acpi_port)
   3545		return;
   3546
   3547	chip->amplifier += change;
   3548	
   3549	/* Read ACPI port */	
   3550	nval = control = inw(chip->acpi_port + 0x10);
   3551
   3552	/* Flip CLKRUN off while running */
   3553	if (! chip->amplifier)
   3554		nval |= 0x2000;
   3555	else
   3556		nval &= ~0x2000;
   3557	if (nval != control)
   3558		outw(nval, chip->acpi_port + 0x10);
   3559}
   3560
   3561	
   3562/*
   3563 * detect intel piix4
   3564 */
   3565static void clkrun_init(struct snd_cs46xx *chip)
   3566{
   3567	struct pci_dev *pdev;
   3568	u8 pp;
   3569
   3570	chip->acpi_port = 0;
   3571	
   3572	pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
   3573		PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
   3574	if (pdev == NULL)
   3575		return;		/* Not a thinkpad thats for sure */
   3576
   3577	/* Find the control port */		
   3578	pci_read_config_byte(pdev, 0x41, &pp);
   3579	chip->acpi_port = pp << 8;
   3580	pci_dev_put(pdev);
   3581}
   3582
   3583
   3584/*
   3585 * Card subid table
   3586 */
   3587 
   3588struct cs_card_type
   3589{
   3590	u16 vendor;
   3591	u16 id;
   3592	char *name;
   3593	void (*init)(struct snd_cs46xx *);
   3594	void (*amp)(struct snd_cs46xx *, int);
   3595	void (*active)(struct snd_cs46xx *, int);
   3596	void (*mixer_init)(struct snd_cs46xx *);
   3597};
   3598
   3599static struct cs_card_type cards[] = {
   3600	{
   3601		.vendor = 0x1489,
   3602		.id = 0x7001,
   3603		.name = "Genius Soundmaker 128 value",
   3604		/* nothing special */
   3605	},
   3606	{
   3607		.vendor = 0x5053,
   3608		.id = 0x3357,
   3609		.name = "Voyetra",
   3610		.amp = amp_voyetra,
   3611		.mixer_init = voyetra_mixer_init,
   3612	},
   3613	{
   3614		.vendor = 0x1071,
   3615		.id = 0x6003,
   3616		.name = "Mitac MI6020/21",
   3617		.amp = amp_voyetra,
   3618	},
   3619	/* Hercules Game Theatre XP */
   3620	{
   3621		.vendor = 0x14af, /* Guillemot Corporation */
   3622		.id = 0x0050,
   3623		.name = "Hercules Game Theatre XP",
   3624		.amp = amp_hercules,
   3625		.mixer_init = hercules_mixer_init,
   3626	},
   3627	{
   3628		.vendor = 0x1681,
   3629		.id = 0x0050,
   3630		.name = "Hercules Game Theatre XP",
   3631		.amp = amp_hercules,
   3632		.mixer_init = hercules_mixer_init,
   3633	},
   3634	{
   3635		.vendor = 0x1681,
   3636		.id = 0x0051,
   3637		.name = "Hercules Game Theatre XP",
   3638		.amp = amp_hercules,
   3639		.mixer_init = hercules_mixer_init,
   3640
   3641	},
   3642	{
   3643		.vendor = 0x1681,
   3644		.id = 0x0052,
   3645		.name = "Hercules Game Theatre XP",
   3646		.amp = amp_hercules,
   3647		.mixer_init = hercules_mixer_init,
   3648	},
   3649	{
   3650		.vendor = 0x1681,
   3651		.id = 0x0053,
   3652		.name = "Hercules Game Theatre XP",
   3653		.amp = amp_hercules,
   3654		.mixer_init = hercules_mixer_init,
   3655	},
   3656	{
   3657		.vendor = 0x1681,
   3658		.id = 0x0054,
   3659		.name = "Hercules Game Theatre XP",
   3660		.amp = amp_hercules,
   3661		.mixer_init = hercules_mixer_init,
   3662	},
   3663	/* Herculess Fortissimo */
   3664	{
   3665		.vendor = 0x1681,
   3666		.id = 0xa010,
   3667		.name = "Hercules Gamesurround Fortissimo II",
   3668	},
   3669	{
   3670		.vendor = 0x1681,
   3671		.id = 0xa011,
   3672		.name = "Hercules Gamesurround Fortissimo III 7.1",
   3673	},
   3674	/* Teratec */
   3675	{
   3676		.vendor = 0x153b,
   3677		.id = 0x112e,
   3678		.name = "Terratec DMX XFire 1024",
   3679	},
   3680	{
   3681		.vendor = 0x153b,
   3682		.id = 0x1136,
   3683		.name = "Terratec SiXPack 5.1",
   3684	},
   3685	/* Not sure if the 570 needs the clkrun hack */
   3686	{
   3687		.vendor = PCI_VENDOR_ID_IBM,
   3688		.id = 0x0132,
   3689		.name = "Thinkpad 570",
   3690		.init = clkrun_init,
   3691		.active = clkrun_hack,
   3692	},
   3693	{
   3694		.vendor = PCI_VENDOR_ID_IBM,
   3695		.id = 0x0153,
   3696		.name = "Thinkpad 600X/A20/T20",
   3697		.init = clkrun_init,
   3698		.active = clkrun_hack,
   3699	},
   3700	{
   3701		.vendor = PCI_VENDOR_ID_IBM,
   3702		.id = 0x1010,
   3703		.name = "Thinkpad 600E (unsupported)",
   3704	},
   3705	{} /* terminator */
   3706};
   3707
   3708
   3709/*
   3710 * APM support
   3711 */
   3712#ifdef CONFIG_PM_SLEEP
   3713static const unsigned int saved_regs[] = {
   3714	BA0_ACOSV,
   3715	/*BA0_ASER_FADDR,*/
   3716	BA0_ASER_MASTER,
   3717	BA1_PVOL,
   3718	BA1_CVOL,
   3719};
   3720
   3721static int snd_cs46xx_suspend(struct device *dev)
   3722{
   3723	struct snd_card *card = dev_get_drvdata(dev);
   3724	struct snd_cs46xx *chip = card->private_data;
   3725	int i, amp_saved;
   3726
   3727	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
   3728	chip->in_suspend = 1;
   3729	// chip->ac97_powerdown = snd_cs46xx_codec_read(chip, AC97_POWER_CONTROL);
   3730	// chip->ac97_general_purpose = snd_cs46xx_codec_read(chip, BA0_AC97_GENERAL_PURPOSE);
   3731
   3732	snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
   3733	snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
   3734
   3735	/* save some registers */
   3736	for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
   3737		chip->saved_regs[i] = snd_cs46xx_peekBA0(chip, saved_regs[i]);
   3738
   3739	amp_saved = chip->amplifier;
   3740	/* turn off amp */
   3741	chip->amplifier_ctrl(chip, -chip->amplifier);
   3742	snd_cs46xx_hw_stop(chip);
   3743	/* disable CLKRUN */
   3744	chip->active_ctrl(chip, -chip->amplifier);
   3745	chip->amplifier = amp_saved; /* restore the status */
   3746	return 0;
   3747}
   3748
   3749static int snd_cs46xx_resume(struct device *dev)
   3750{
   3751	struct snd_card *card = dev_get_drvdata(dev);
   3752	struct snd_cs46xx *chip = card->private_data;
   3753	int amp_saved;
   3754#ifdef CONFIG_SND_CS46XX_NEW_DSP
   3755	int i;
   3756#endif
   3757	unsigned int tmp;
   3758
   3759	amp_saved = chip->amplifier;
   3760	chip->amplifier = 0;
   3761	chip->active_ctrl(chip, 1); /* force to on */
   3762
   3763	snd_cs46xx_chip_init(chip);
   3764
   3765	snd_cs46xx_reset(chip);
   3766#ifdef CONFIG_SND_CS46XX_NEW_DSP
   3767	cs46xx_dsp_resume(chip);
   3768	/* restore some registers */
   3769	for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
   3770		snd_cs46xx_pokeBA0(chip, saved_regs[i], chip->saved_regs[i]);
   3771#else
   3772	snd_cs46xx_download_image(chip);
   3773#endif
   3774
   3775#if 0
   3776	snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE, 
   3777			       chip->ac97_general_purpose);
   3778	snd_cs46xx_codec_write(chip, AC97_POWER_CONTROL, 
   3779			       chip->ac97_powerdown);
   3780	mdelay(10);
   3781	snd_cs46xx_codec_write(chip, BA0_AC97_POWERDOWN,
   3782			       chip->ac97_powerdown);
   3783	mdelay(5);
   3784#endif
   3785
   3786	snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
   3787	snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
   3788
   3789	/*
   3790         *  Stop capture DMA.
   3791	 */
   3792	tmp = snd_cs46xx_peek(chip, BA1_CCTL);
   3793	chip->capt.ctl = tmp & 0x0000ffff;
   3794	snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000);
   3795
   3796	mdelay(5);
   3797
   3798	/* reset playback/capture */
   3799	snd_cs46xx_set_play_sample_rate(chip, 8000);
   3800	snd_cs46xx_set_capture_sample_rate(chip, 8000);
   3801	snd_cs46xx_proc_start(chip);
   3802
   3803	cs46xx_enable_stream_irqs(chip);
   3804
   3805	if (amp_saved)
   3806		chip->amplifier_ctrl(chip, 1); /* turn amp on */
   3807	else
   3808		chip->active_ctrl(chip, -1); /* disable CLKRUN */
   3809	chip->amplifier = amp_saved;
   3810	chip->in_suspend = 0;
   3811	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
   3812	return 0;
   3813}
   3814
   3815SIMPLE_DEV_PM_OPS(snd_cs46xx_pm, snd_cs46xx_suspend, snd_cs46xx_resume);
   3816#endif /* CONFIG_PM_SLEEP */
   3817
   3818
   3819/*
   3820 */
   3821
   3822int snd_cs46xx_create(struct snd_card *card,
   3823		      struct pci_dev *pci,
   3824		      int external_amp, int thinkpad)
   3825{
   3826	struct snd_cs46xx *chip = card->private_data;
   3827	int err, idx;
   3828	struct snd_cs46xx_region *region;
   3829	struct cs_card_type *cp;
   3830	u16 ss_card, ss_vendor;
   3831	
   3832	/* enable PCI device */
   3833	err = pcim_enable_device(pci);
   3834	if (err < 0)
   3835		return err;
   3836
   3837	spin_lock_init(&chip->reg_lock);
   3838#ifdef CONFIG_SND_CS46XX_NEW_DSP
   3839	mutex_init(&chip->spos_mutex);
   3840#endif
   3841	chip->card = card;
   3842	chip->pci = pci;
   3843	chip->irq = -1;
   3844
   3845	err = pci_request_regions(pci, "CS46xx");
   3846	if (err < 0)
   3847		return err;
   3848	chip->ba0_addr = pci_resource_start(pci, 0);
   3849	chip->ba1_addr = pci_resource_start(pci, 1);
   3850	if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 ||
   3851	    chip->ba1_addr == 0 || chip->ba1_addr == (unsigned long)~0) {
   3852		dev_err(chip->card->dev,
   3853			"wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n",
   3854			   chip->ba0_addr, chip->ba1_addr);
   3855	    	return -ENOMEM;
   3856	}
   3857
   3858	region = &chip->region.name.ba0;
   3859	strcpy(region->name, "CS46xx_BA0");
   3860	region->base = chip->ba0_addr;
   3861	region->size = CS46XX_BA0_SIZE;
   3862
   3863	region = &chip->region.name.data0;
   3864	strcpy(region->name, "CS46xx_BA1_data0");
   3865	region->base = chip->ba1_addr + BA1_SP_DMEM0;
   3866	region->size = CS46XX_BA1_DATA0_SIZE;
   3867
   3868	region = &chip->region.name.data1;
   3869	strcpy(region->name, "CS46xx_BA1_data1");
   3870	region->base = chip->ba1_addr + BA1_SP_DMEM1;
   3871	region->size = CS46XX_BA1_DATA1_SIZE;
   3872
   3873	region = &chip->region.name.pmem;
   3874	strcpy(region->name, "CS46xx_BA1_pmem");
   3875	region->base = chip->ba1_addr + BA1_SP_PMEM;
   3876	region->size = CS46XX_BA1_PRG_SIZE;
   3877
   3878	region = &chip->region.name.reg;
   3879	strcpy(region->name, "CS46xx_BA1_reg");
   3880	region->base = chip->ba1_addr + BA1_SP_REG;
   3881	region->size = CS46XX_BA1_REG_SIZE;
   3882
   3883	/* set up amp and clkrun hack */
   3884	pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &ss_vendor);
   3885	pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &ss_card);
   3886
   3887	for (cp = &cards[0]; cp->name; cp++) {
   3888		if (cp->vendor == ss_vendor && cp->id == ss_card) {
   3889			dev_dbg(chip->card->dev, "hack for %s enabled\n",
   3890				cp->name);
   3891
   3892			chip->amplifier_ctrl = cp->amp;
   3893			chip->active_ctrl = cp->active;
   3894			chip->mixer_init = cp->mixer_init;
   3895
   3896			if (cp->init)
   3897				cp->init(chip);
   3898			break;
   3899		}
   3900	}
   3901
   3902	if (external_amp) {
   3903		dev_info(chip->card->dev,
   3904			 "Crystal EAPD support forced on.\n");
   3905		chip->amplifier_ctrl = amp_voyetra;
   3906	}
   3907
   3908	if (thinkpad) {
   3909		dev_info(chip->card->dev,
   3910			 "Activating CLKRUN hack for Thinkpad.\n");
   3911		chip->active_ctrl = clkrun_hack;
   3912		clkrun_init(chip);
   3913	}
   3914	
   3915	if (chip->amplifier_ctrl == NULL)
   3916		chip->amplifier_ctrl = amp_none;
   3917	if (chip->active_ctrl == NULL)
   3918		chip->active_ctrl = amp_none;
   3919
   3920	chip->active_ctrl(chip, 1); /* enable CLKRUN */
   3921
   3922	pci_set_master(pci);
   3923
   3924	for (idx = 0; idx < 5; idx++) {
   3925		region = &chip->region.idx[idx];
   3926		region->remap_addr = devm_ioremap(&pci->dev, region->base,
   3927						  region->size);
   3928		if (region->remap_addr == NULL) {
   3929			dev_err(chip->card->dev,
   3930				"%s ioremap problem\n", region->name);
   3931			return -ENOMEM;
   3932		}
   3933	}
   3934
   3935	if (devm_request_irq(&pci->dev, pci->irq, snd_cs46xx_interrupt,
   3936			     IRQF_SHARED, KBUILD_MODNAME, chip)) {
   3937		dev_err(chip->card->dev, "unable to grab IRQ %d\n", pci->irq);
   3938		return -EBUSY;
   3939	}
   3940	chip->irq = pci->irq;
   3941	card->sync_irq = chip->irq;
   3942	card->private_free = snd_cs46xx_free;
   3943
   3944#ifdef CONFIG_SND_CS46XX_NEW_DSP
   3945	chip->dsp_spos_instance = cs46xx_dsp_spos_create(chip);
   3946	if (!chip->dsp_spos_instance)
   3947		return -ENOMEM;
   3948#endif
   3949
   3950	err = snd_cs46xx_chip_init(chip);
   3951	if (err < 0)
   3952		return err;
   3953	
   3954	snd_cs46xx_proc_init(card, chip);
   3955
   3956#ifdef CONFIG_PM_SLEEP
   3957	chip->saved_regs = devm_kmalloc_array(&pci->dev,
   3958					      ARRAY_SIZE(saved_regs),
   3959					      sizeof(*chip->saved_regs),
   3960					      GFP_KERNEL);
   3961	if (!chip->saved_regs)
   3962		return -ENOMEM;
   3963#endif
   3964
   3965	chip->active_ctrl(chip, -1); /* disable CLKRUN */
   3966	return 0;
   3967}