ice1712.h 18.3 KB
Newer Older
1
/* SPDX-License-Identifier: GPL-2.0-or-later */
L
Linus Torvalds 已提交
2 3 4 5 6 7
#ifndef __SOUND_ICE1712_H
#define __SOUND_ICE1712_H

/*
 *   ALSA driver for ICEnsemble ICE1712 (Envy24)
 *
8
 *	Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
9
 */
L
Linus Torvalds 已提交
10

11
#include <linux/io.h>
L
Linus Torvalds 已提交
12 13 14 15 16 17
#include <sound/control.h>
#include <sound/ac97_codec.h>
#include <sound/rawmidi.h>
#include <sound/i2c.h>
#include <sound/ak4xxx-adda.h>
#include <sound/ak4114.h>
18
#include <sound/pt2258.h>
L
Linus Torvalds 已提交
19
#include <sound/pcm.h>
20
#include <sound/mpu401.h>
L
Linus Torvalds 已提交
21 22 23 24 25 26 27 28 29


/*
 *  Direct registers
 */

#define ICEREG(ice, x) ((ice)->port + ICE1712_REG_##x)

#define ICE1712_REG_CONTROL		0x00	/* byte */
30 31 32 33 34
#define   ICE1712_RESET			0x80	/* soft reset whole chip */
#define   ICE1712_SERR_ASSERT_DS_DMA	0x40    /* disabled SERR# assertion for the DS DMA Ch-C irq otherwise enabled */
#define   ICE1712_DOS_VOL		0x10    /* DOS WT/FM volume control */
#define   ICE1712_SERR_LEVEL		0x08	/* SERR# level otherwise edge */
#define   ICE1712_SERR_ASSERT_SB	0x02	/* disabled SERR# assertion for SB irq otherwise enabled */
L
Linus Torvalds 已提交
35 36
#define   ICE1712_NATIVE		0x01	/* native mode otherwise SB */
#define ICE1712_REG_IRQMASK		0x01	/* byte */
37 38 39 40
#define   ICE1712_IRQ_MPU1		0x80	/* MIDI irq mask */
#define   ICE1712_IRQ_TIMER		0x40	/* Timer mask */
#define   ICE1712_IRQ_MPU2		0x20	/* Secondary MIDI irq mask */
#define   ICE1712_IRQ_PROPCM		0x10	/* professional multi-track */
L
Linus Torvalds 已提交
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
#define   ICE1712_IRQ_FM		0x08	/* FM/MIDI - legacy */
#define   ICE1712_IRQ_PBKDS		0x04	/* playback DS channels */
#define   ICE1712_IRQ_CONCAP		0x02	/* consumer capture */
#define   ICE1712_IRQ_CONPBK		0x01	/* consumer playback */
#define ICE1712_REG_IRQSTAT		0x02	/* byte */
/* look to ICE1712_IRQ_* */
#define ICE1712_REG_INDEX		0x03	/* byte - indirect CCIxx regs */
#define ICE1712_REG_DATA		0x04	/* byte - indirect CCIxx regs */
#define ICE1712_REG_NMI_STAT1		0x05	/* byte */
#define ICE1712_REG_NMI_DATA		0x06	/* byte */
#define ICE1712_REG_NMI_INDEX		0x07	/* byte */
#define ICE1712_REG_AC97_INDEX		0x08	/* byte */
#define ICE1712_REG_AC97_CMD		0x09	/* byte */
#define   ICE1712_AC97_COLD		0x80	/* cold reset */
#define   ICE1712_AC97_WARM		0x40	/* warm reset */
#define   ICE1712_AC97_WRITE		0x20	/* W: write, R: write in progress */
#define   ICE1712_AC97_READ		0x10	/* W: read, R: read in progress */
#define   ICE1712_AC97_READY		0x08	/* codec ready status bit */
#define   ICE1712_AC97_PBK_VSR		0x02	/* playback VSR */
#define   ICE1712_AC97_CAP_VSR		0x01	/* capture VSR */
#define ICE1712_REG_AC97_DATA		0x0a	/* word (little endian) */
#define ICE1712_REG_MPU1_CTRL		0x0c	/* byte */
#define ICE1712_REG_MPU1_DATA		0x0d	/* byte */
#define ICE1712_REG_I2C_DEV_ADDR	0x10	/* byte */
#define   ICE1712_I2C_WRITE		0x01	/* write direction */
#define ICE1712_REG_I2C_BYTE_ADDR	0x11	/* byte */
#define ICE1712_REG_I2C_DATA		0x12	/* byte */
#define ICE1712_REG_I2C_CTRL		0x13	/* byte */
#define   ICE1712_I2C_EEPROM		0x80	/* EEPROM exists */
#define   ICE1712_I2C_BUSY		0x01	/* busy bit */
#define ICE1712_REG_CONCAP_ADDR		0x14	/* dword - consumer capture */
#define ICE1712_REG_CONCAP_COUNT	0x18	/* word - current/base count */
#define ICE1712_REG_SERR_SHADOW		0x1b	/* byte */
#define ICE1712_REG_MPU2_CTRL		0x1c	/* byte */
#define ICE1712_REG_MPU2_DATA		0x1d	/* byte */
#define ICE1712_REG_TIMER		0x1e	/* word */

/*
 *  Indirect registers
 */

#define ICE1712_IREG_PBK_COUNT_LO	0x00
#define ICE1712_IREG_PBK_COUNT_HI	0x01
#define ICE1712_IREG_PBK_CTRL		0x02
#define ICE1712_IREG_PBK_LEFT		0x03	/* left volume */
#define ICE1712_IREG_PBK_RIGHT		0x04	/* right volume */
#define ICE1712_IREG_PBK_SOFT		0x05	/* soft volume */
#define ICE1712_IREG_PBK_RATE_LO	0x06
#define ICE1712_IREG_PBK_RATE_MID	0x07
#define ICE1712_IREG_PBK_RATE_HI	0x08
#define ICE1712_IREG_CAP_COUNT_LO	0x10
#define ICE1712_IREG_CAP_COUNT_HI	0x11
#define ICE1712_IREG_CAP_CTRL		0x12
#define ICE1712_IREG_GPIO_DATA		0x20
#define ICE1712_IREG_GPIO_WRITE_MASK	0x21
#define ICE1712_IREG_GPIO_DIRECTION	0x22
#define ICE1712_IREG_CONSUMER_POWERDOWN	0x30
#define ICE1712_IREG_PRO_POWERDOWN	0x31

/*
 *  Consumer section direct DMA registers
 */

#define ICEDS(ice, x) ((ice)->dmapath_port + ICE1712_DS_##x)
105

L
Linus Torvalds 已提交
106 107 108 109 110 111 112 113
#define ICE1712_DS_INTMASK		0x00	/* word - interrupt mask */
#define ICE1712_DS_INTSTAT		0x02	/* word - interrupt status */
#define ICE1712_DS_DATA			0x04	/* dword - channel data */
#define ICE1712_DS_INDEX		0x08	/* dword - channel index */

/*
 *  Consumer section channel registers
 */
114

L
Linus Torvalds 已提交
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
#define ICE1712_DSC_ADDR0		0x00	/* dword - base address 0 */
#define ICE1712_DSC_COUNT0		0x01	/* word - count 0 */
#define ICE1712_DSC_ADDR1		0x02	/* dword - base address 1 */
#define ICE1712_DSC_COUNT1		0x03	/* word - count 1 */
#define ICE1712_DSC_CONTROL		0x04	/* byte - control & status */
#define   ICE1712_BUFFER1		0x80	/* buffer1 is active */
#define   ICE1712_BUFFER1_AUTO		0x40	/* buffer1 auto init */
#define   ICE1712_BUFFER0_AUTO		0x20	/* buffer0 auto init */
#define   ICE1712_FLUSH			0x10	/* flush FIFO */
#define   ICE1712_STEREO		0x08	/* stereo */
#define   ICE1712_16BIT			0x04	/* 16-bit data */
#define   ICE1712_PAUSE			0x02	/* pause */
#define   ICE1712_START			0x01	/* start */
#define ICE1712_DSC_RATE		0x05	/* dword - rate */
#define ICE1712_DSC_VOLUME		0x06	/* word - volume control */

131
/*
L
Linus Torvalds 已提交
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
 *  Professional multi-track direct control registers
 */

#define ICEMT(ice, x) ((ice)->profi_port + ICE1712_MT_##x)

#define ICE1712_MT_IRQ			0x00	/* byte - interrupt mask */
#define   ICE1712_MULTI_CAPTURE		0x80	/* capture IRQ */
#define   ICE1712_MULTI_PLAYBACK	0x40	/* playback IRQ */
#define   ICE1712_MULTI_CAPSTATUS	0x02	/* capture IRQ status */
#define   ICE1712_MULTI_PBKSTATUS	0x01	/* playback IRQ status */
#define ICE1712_MT_RATE			0x01	/* byte - sampling rate select */
#define   ICE1712_SPDIF_MASTER		0x10	/* S/PDIF input is master clock */
#define ICE1712_MT_I2S_FORMAT		0x02	/* byte - I2S data format */
#define ICE1712_MT_AC97_INDEX		0x04	/* byte - AC'97 index */
#define ICE1712_MT_AC97_CMD		0x05	/* byte - AC'97 command & status */
/* look to ICE1712_AC97_* */
#define ICE1712_MT_AC97_DATA		0x06	/* word - AC'97 data */
#define ICE1712_MT_PLAYBACK_ADDR	0x10	/* dword - playback address */
#define ICE1712_MT_PLAYBACK_SIZE	0x14	/* word - playback size */
#define ICE1712_MT_PLAYBACK_COUNT	0x16	/* word - playback count */
#define ICE1712_MT_PLAYBACK_CONTROL	0x18	/* byte - control */
#define   ICE1712_CAPTURE_START_SHADOW	0x04	/* capture start */
#define   ICE1712_PLAYBACK_PAUSE	0x02	/* playback pause */
#define   ICE1712_PLAYBACK_START	0x01	/* playback start */
#define ICE1712_MT_CAPTURE_ADDR		0x20	/* dword - capture address */
#define ICE1712_MT_CAPTURE_SIZE		0x24	/* word - capture size */
#define ICE1712_MT_CAPTURE_COUNT	0x26	/* word - capture count */
#define ICE1712_MT_CAPTURE_CONTROL	0x28	/* byte - control */
#define   ICE1712_CAPTURE_START		0x01	/* capture start */
#define ICE1712_MT_ROUTE_PSDOUT03	0x30	/* word */
#define ICE1712_MT_ROUTE_SPDOUT		0x32	/* word */
#define ICE1712_MT_ROUTE_CAPTURE	0x34	/* dword */
#define ICE1712_MT_MONITOR_VOLUME	0x38	/* word */
#define ICE1712_MT_MONITOR_INDEX	0x3a	/* byte */
#define ICE1712_MT_MONITOR_RATE		0x3b	/* byte */
#define ICE1712_MT_MONITOR_ROUTECTRL	0x3c	/* byte */
#define   ICE1712_ROUTE_AC97		0x01	/* route digital mixer output to AC'97 */
#define ICE1712_MT_MONITOR_PEAKINDEX	0x3e	/* byte */
#define ICE1712_MT_MONITOR_PEAKDATA	0x3f	/* byte */

/*
 *  Codec configuration bits
 */

/* PCI[60] System Configuration */
#define ICE1712_CFG_CLOCK	0xc0
#define   ICE1712_CFG_CLOCK512	0x00	/* 22.5692Mhz, 44.1kHz*512 */
#define   ICE1712_CFG_CLOCK384  0x40	/* 16.9344Mhz, 44.1kHz*384 */
#define   ICE1712_CFG_EXT	0x80	/* external clock */
#define ICE1712_CFG_2xMPU401	0x20	/* two MPU401 UARTs */
#define ICE1712_CFG_NO_CON_AC97 0x10	/* consumer AC'97 codec is not present */
#define ICE1712_CFG_ADC_MASK	0x0c	/* one, two, three, four stereo ADCs */
#define ICE1712_CFG_DAC_MASK	0x03	/* one, two, three, four stereo DACs */
/* PCI[61] AC-Link Configuration */
#define ICE1712_CFG_PRO_I2S	0x80	/* multitrack converter: I2S or AC'97 */
#define ICE1712_CFG_AC97_PACKED	0x01	/* split or packed mode - AC'97 */
/* PCI[62] I2S Features */
#define ICE1712_CFG_I2S_VOLUME	0x80	/* volume/mute capability */
#define ICE1712_CFG_I2S_96KHZ	0x40	/* supports 96kHz sampling */
#define ICE1712_CFG_I2S_RESMASK	0x30	/* resolution mask, 16,18,20,24-bit */
#define ICE1712_CFG_I2S_OTHER	0x0f	/* other I2S IDs */
/* PCI[63] S/PDIF Configuration */
#define ICE1712_CFG_I2S_CHIPID	0xfc	/* I2S chip ID */
#define ICE1712_CFG_SPDIF_IN	0x02	/* S/PDIF input is present */
#define ICE1712_CFG_SPDIF_OUT	0x01	/* S/PDIF output is present */

/*
 * DMA mode values
 * identical with DMA_XXX on i386 architecture.
 */
#define ICE1712_DMA_MODE_WRITE		0x48
#define ICE1712_DMA_AUTOINIT		0x10


/*
207
 * I2C EEPROM Address
L
Linus Torvalds 已提交
208
 */
209
#define ICE_I2C_EEPROM_ADDR		0xA0
L
Linus Torvalds 已提交
210

211
struct snd_ice1712;
L
Linus Torvalds 已提交
212

213
struct snd_ice1712_eeprom {
L
Linus Torvalds 已提交
214 215 216 217 218 219 220
	unsigned int subvendor;	/* PCI[2c-2f] */
	unsigned char size;	/* size of EEPROM image in bytes */
	unsigned char version;	/* must be 1 (or 2 for vt1724) */
	unsigned char data[32];
	unsigned int gpiomask;
	unsigned int gpiostate;
	unsigned int gpiodir;
221
};
L
Linus Torvalds 已提交
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246

enum {
	ICE_EEP1_CODEC = 0,	/* 06 */
	ICE_EEP1_ACLINK,	/* 07 */
	ICE_EEP1_I2SID,		/* 08 */
	ICE_EEP1_SPDIF,		/* 09 */
	ICE_EEP1_GPIO_MASK,	/* 0a */
	ICE_EEP1_GPIO_STATE,	/* 0b */
	ICE_EEP1_GPIO_DIR,	/* 0c */
	ICE_EEP1_AC97_MAIN_LO,	/* 0d */
	ICE_EEP1_AC97_MAIN_HI,	/* 0e */
	ICE_EEP1_AC97_PCM_LO,	/* 0f */
	ICE_EEP1_AC97_PCM_HI,	/* 10 */
	ICE_EEP1_AC97_REC_LO,	/* 11 */
	ICE_EEP1_AC97_REC_HI,	/* 12 */
	ICE_EEP1_AC97_RECSRC,	/* 13 */
	ICE_EEP1_DAC_ID,	/* 14 */
	ICE_EEP1_DAC_ID1,
	ICE_EEP1_DAC_ID2,
	ICE_EEP1_DAC_ID3,
	ICE_EEP1_ADC_ID,	/* 18 */
	ICE_EEP1_ADC_ID1,
	ICE_EEP1_ADC_ID2,
	ICE_EEP1_ADC_ID3
};
247

L
Linus Torvalds 已提交
248 249 250 251
#define ice_has_con_ac97(ice)	(!((ice)->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97))


struct snd_ak4xxx_private {
252
	unsigned int cif:1;		/* CIF mode */
L
Linus Torvalds 已提交
253 254 255 256 257 258 259 260 261
	unsigned char caddr;		/* C0 and C1 bits */
	unsigned int data_mask;		/* DATA gpio bit */
	unsigned int clk_mask;		/* CLK gpio bit */
	unsigned int cs_mask;		/* bit mask for select/deselect address */
	unsigned int cs_addr;		/* bits to select address */
	unsigned int cs_none;		/* bits to deselect address */
	unsigned int add_flags;		/* additional bits at init */
	unsigned int mask_flags;	/* total mask bits */
	struct snd_akm4xxx_ops {
262
		void (*set_rate_val)(struct snd_akm4xxx *ak, unsigned int rate);
L
Linus Torvalds 已提交
263 264 265 266 267 268
	} ops;
};

struct snd_ice1712_spdif {
	unsigned char cs8403_bits;
	unsigned char cs8403_stream_bits;
269
	struct snd_kcontrol *stream_ctl;
L
Linus Torvalds 已提交
270 271

	struct snd_ice1712_spdif_ops {
272 273 274 275 276 277 278
		void (*open)(struct snd_ice1712 *, struct snd_pcm_substream *);
		void (*setup_rate)(struct snd_ice1712 *, int rate);
		void (*close)(struct snd_ice1712 *, struct snd_pcm_substream *);
		void (*default_get)(struct snd_ice1712 *, struct snd_ctl_elem_value *ucontrol);
		int (*default_put)(struct snd_ice1712 *, struct snd_ctl_elem_value *ucontrol);
		void (*stream_get)(struct snd_ice1712 *, struct snd_ctl_elem_value *ucontrol);
		int (*stream_put)(struct snd_ice1712 *, struct snd_ctl_elem_value *ucontrol);
L
Linus Torvalds 已提交
279 280 281
	} ops;
};

282
struct snd_ice1712_card_info;
L
Linus Torvalds 已提交
283

284
struct snd_ice1712 {
L
Linus Torvalds 已提交
285 286 287 288 289 290 291 292 293 294 295 296
	unsigned long conp_dma_size;
	unsigned long conc_dma_size;
	unsigned long prop_dma_size;
	unsigned long proc_dma_size;
	int irq;

	unsigned long port;
	unsigned long ddma_port;
	unsigned long dmapath_port;
	unsigned long profi_port;

	struct pci_dev *pci;
297 298 299 300
	struct snd_card *card;
	struct snd_pcm *pcm;
	struct snd_pcm *pcm_ds;
	struct snd_pcm *pcm_pro;
301 302 303 304 305
	struct snd_pcm_substream *playback_con_substream;
	struct snd_pcm_substream *playback_con_substream_ds[6];
	struct snd_pcm_substream *capture_con_substream;
	struct snd_pcm_substream *playback_pro_substream;
	struct snd_pcm_substream *capture_pro_substream;
L
Linus Torvalds 已提交
306 307 308 309 310 311
	unsigned int playback_pro_size;
	unsigned int capture_pro_size;
	unsigned int playback_con_virt_addr[6];
	unsigned int playback_con_active_buf[6];
	unsigned int capture_con_virt_addr;
	unsigned int ac97_ext_id;
312 313
	struct snd_ac97 *ac97;
	struct snd_rawmidi *rmidi[2];
L
Linus Torvalds 已提交
314 315

	spinlock_t reg_lock;
316
	struct snd_info_entry *proc_entry;
L
Linus Torvalds 已提交
317

318
	struct snd_ice1712_eeprom eeprom;
319
	const struct snd_ice1712_card_info *card_info;
L
Linus Torvalds 已提交
320 321

	unsigned int pro_volumes[20];
322 323 324 325 326 327 328 329 330
	unsigned int omni:1;		/* Delta Omni I/O */
	unsigned int dxr_enable:1;	/* Terratec DXR enable for DMX6FIRE */
	unsigned int vt1724:1;
	unsigned int vt1720:1;
	unsigned int has_spdif:1;	/* VT1720/4 - has SPDIF I/O */
	unsigned int force_pdma4:1;	/* VT1720/4 - PDMA4 as non-spdif */
	unsigned int force_rdma1:1;	/* VT1720/4 - RDMA1 as non-spdif */
	unsigned int midi_output:1;	/* VT1720/4: MIDI output triggered */
	unsigned int midi_input:1;	/* VT1720/4: MIDI input triggered */
331
	unsigned int own_routing:1;	/* VT1720/4: use own routing ctls */
L
Linus Torvalds 已提交
332 333 334 335
	unsigned int num_total_dacs;	/* total DACs */
	unsigned int num_total_adcs;	/* total ADCs */
	unsigned int cur_rate;		/* current rate */

336
	struct mutex open_mutex;
337
	struct snd_pcm_substream *pcm_reserved[4];
338
	const struct snd_pcm_hw_constraint_list *hw_rates; /* card-specific rate constraints */
L
Linus Torvalds 已提交
339 340

	unsigned int akm_codecs;
341
	struct snd_akm4xxx *akm;
L
Linus Torvalds 已提交
342 343
	struct snd_ice1712_spdif spdif;

344
	struct mutex i2c_mutex;	/* I2C mutex for ICE1724 registers */
345 346
	struct snd_i2c_bus *i2c;		/* I2C bus */
	struct snd_i2c_device *cs8427;	/* CS8427 I2C device */
L
Linus Torvalds 已提交
347
	unsigned int cs8427_timeout;	/* CS8427 reset timeout in HZ/100 */
348

L
Linus Torvalds 已提交
349 350 351 352 353
	struct ice1712_gpio {
		unsigned int direction;		/* current direction bits */
		unsigned int write_mask;	/* current mask bits */
		unsigned int saved[2];		/* for ewx_i2c */
		/* operators */
354
		void (*set_mask)(struct snd_ice1712 *ice, unsigned int data);
355
		unsigned int (*get_mask)(struct snd_ice1712 *ice);
356
		void (*set_dir)(struct snd_ice1712 *ice, unsigned int data);
357
		unsigned int (*get_dir)(struct snd_ice1712 *ice);
358 359
		void (*set_data)(struct snd_ice1712 *ice, unsigned int data);
		unsigned int (*get_data)(struct snd_ice1712 *ice);
L
Linus Torvalds 已提交
360
		/* misc operators - move to another place? */
361 362
		void (*set_pro_rate)(struct snd_ice1712 *ice, unsigned int rate);
		void (*i2s_mclk_changed)(struct snd_ice1712 *ice);
L
Linus Torvalds 已提交
363
	} gpio;
364
	struct mutex gpio_mutex;
L
Linus Torvalds 已提交
365 366

	/* other board-specific data */
367
	void *spec;
368 369 370 371 372 373 374

	/* VT172x specific */
	int pro_rate_default;
	int (*is_spdif_master)(struct snd_ice1712 *ice);
	unsigned int (*get_rate)(struct snd_ice1712 *ice);
	void (*set_rate)(struct snd_ice1712 *ice, unsigned int rate);
	unsigned char (*set_mclk)(struct snd_ice1712 *ice, unsigned int rate);
375 376
	int (*set_spdif_clock)(struct snd_ice1712 *ice, int type);
	int (*get_spdif_master_type)(struct snd_ice1712 *ice);
377
	const char * const *ext_clock_names;
378 379
	int ext_clock_count;
	void (*pro_open)(struct snd_ice1712 *, struct snd_pcm_substream *);
380
#ifdef CONFIG_PM_SLEEP
381 382
	int (*pm_suspend)(struct snd_ice1712 *);
	int (*pm_resume)(struct snd_ice1712 *);
383 384
	unsigned int pm_suspend_enabled:1;
	unsigned int pm_saved_is_spdif_master:1;
385 386 387 388
	unsigned int pm_saved_spdif_ctrl;
	unsigned char pm_saved_spdif_cfg;
	unsigned int pm_saved_route;
#endif
L
Linus Torvalds 已提交
389 390 391 392 393 394
};


/*
 * gpio access functions
 */
395
static inline void snd_ice1712_gpio_set_dir(struct snd_ice1712 *ice, unsigned int bits)
L
Linus Torvalds 已提交
396 397 398 399
{
	ice->gpio.set_dir(ice, bits);
}

400 401 402 403 404
static inline unsigned int snd_ice1712_gpio_get_dir(struct snd_ice1712 *ice)
{
	return ice->gpio.get_dir(ice);
}

405
static inline void snd_ice1712_gpio_set_mask(struct snd_ice1712 *ice, unsigned int bits)
L
Linus Torvalds 已提交
406 407 408 409
{
	ice->gpio.set_mask(ice, bits);
}

410
static inline void snd_ice1712_gpio_write(struct snd_ice1712 *ice, unsigned int val)
L
Linus Torvalds 已提交
411 412 413 414
{
	ice->gpio.set_data(ice, val);
}

415
static inline unsigned int snd_ice1712_gpio_read(struct snd_ice1712 *ice)
L
Linus Torvalds 已提交
416 417 418 419 420 421 422 423 424
{
	return ice->gpio.get_data(ice);
}

/*
 * save and restore gpio status
 * The access to gpio will be protected by mutex, so don't forget to
 * restore!
 */
425
static inline void snd_ice1712_save_gpio_status(struct snd_ice1712 *ice)
L
Linus Torvalds 已提交
426
{
427
	mutex_lock(&ice->gpio_mutex);
L
Linus Torvalds 已提交
428 429 430 431
	ice->gpio.saved[0] = ice->gpio.direction;
	ice->gpio.saved[1] = ice->gpio.write_mask;
}

432
static inline void snd_ice1712_restore_gpio_status(struct snd_ice1712 *ice)
L
Linus Torvalds 已提交
433 434 435 436 437
{
	ice->gpio.set_dir(ice, ice->gpio.saved[0]);
	ice->gpio.set_mask(ice, ice->gpio.saved[1]);
	ice->gpio.direction = ice->gpio.saved[0];
	ice->gpio.write_mask = ice->gpio.saved[1];
438
	mutex_unlock(&ice->gpio_mutex);
L
Linus Torvalds 已提交
439 440 441 442
}

/* for bit controls */
#define ICE1712_GPIO(xiface, xname, xindex, mask, invert, xaccess) \
443
{ .iface = xiface, .name = xname, .access = xaccess, .info = snd_ctl_boolean_mono_info, \
L
Linus Torvalds 已提交
444 445 446
  .get = snd_ice1712_gpio_get, .put = snd_ice1712_gpio_put, \
  .private_value = mask | (invert << 24) }

447 448
int snd_ice1712_gpio_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
int snd_ice1712_gpio_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
L
Linus Torvalds 已提交
449 450 451 452

/*
 * set gpio direction, write mask and data
 */
453 454
static inline void snd_ice1712_gpio_write_bits(struct snd_ice1712 *ice,
					       unsigned int mask, unsigned int bits)
L
Linus Torvalds 已提交
455
{
456 457
	unsigned val;

L
Linus Torvalds 已提交
458 459
	ice->gpio.direction |= mask;
	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
460 461 462 463
	val = snd_ice1712_gpio_read(ice);
	val &= ~mask;
	val |= mask & bits;
	snd_ice1712_gpio_write(ice, val);
L
Linus Torvalds 已提交
464 465
}

466 467 468 469 470
static inline int snd_ice1712_gpio_read_bits(struct snd_ice1712 *ice,
					      unsigned int mask)
{
	ice->gpio.direction &= ~mask;
	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
471
	return  snd_ice1712_gpio_read(ice) & mask;
472 473
}

474 475 476 477 478
/* route access functions */
int snd_ice1724_get_route_val(struct snd_ice1712 *ice, int shift);
int snd_ice1724_put_route_val(struct snd_ice1712 *ice, unsigned int val,
								int shift);

479
int snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice);
L
Linus Torvalds 已提交
480

481 482 483 484
int snd_ice1712_akm4xxx_init(struct snd_akm4xxx *ak,
			     const struct snd_akm4xxx *template,
			     const struct snd_ak4xxx_private *priv,
			     struct snd_ice1712 *ice);
485 486
void snd_ice1712_akm4xxx_free(struct snd_ice1712 *ice);
int snd_ice1712_akm4xxx_build_controls(struct snd_ice1712 *ice);
L
Linus Torvalds 已提交
487

488
int snd_ice1712_init_cs8427(struct snd_ice1712 *ice, int addr);
L
Linus Torvalds 已提交
489

490
static inline void snd_ice1712_write(struct snd_ice1712 *ice, u8 addr, u8 data)
L
Linus Torvalds 已提交
491 492 493 494 495
{
	outb(addr, ICEREG(ice, INDEX));
	outb(data, ICEREG(ice, DATA));
}

496
static inline u8 snd_ice1712_read(struct snd_ice1712 *ice, u8 addr)
L
Linus Torvalds 已提交
497 498 499 500 501 502 503 504 505 506 507 508
{
	outb(addr, ICEREG(ice, INDEX));
	return inb(ICEREG(ice, DATA));
}


/*
 * entry pointer
 */

struct snd_ice1712_card_info {
	unsigned int subvendor;
509 510 511
	const char *name;
	const char *model;
	const char *driver;
512
	int (*chip_init)(struct snd_ice1712 *);
513
	void (*chip_exit)(struct snd_ice1712 *);
514
	int (*build_controls)(struct snd_ice1712 *);
515
	unsigned int no_mpu401:1;
516 517
	unsigned int mpu401_1_info_flags;
	unsigned int mpu401_2_info_flags;
518 519
	const char *mpu401_1_name;
	const char *mpu401_2_name;
520 521
	const unsigned int eeprom_size;
	const unsigned char *eeprom_data;
L
Linus Torvalds 已提交
522 523 524 525
};


#endif /* __SOUND_ICE1712_H */