static int __devinit snd_vt1724_amp_init(struct snd_ice1712 *ice)
{
	static const unsigned short wm_inits[] = {
		WM_ATTEN_L,	0x0000,	/* 0 db */
		WM_ATTEN_R,	0x0000,	/* 0 db */
		WM_DAC_CTRL,	0x0008,	/* 24bit I2S */
		WM_INT_CTRL,	0x0001, /* 24bit I2S */
	};

	unsigned int i;

	/* only use basic functionality for now */

	/* VT1616 6ch codec connected to PSDOUT0 using packed mode */
	ice->num_total_dacs = 6;
	ice->num_total_adcs = 2;

	/* Chaintech AV-710 has another WM8728 codec connected to PSDOUT4
	   (shared with the SPDIF output). Mixer control for this codec
	   is not yet supported. */
	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AV710) {
		for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
			wm_put(ice, wm_inits[i], wm_inits[i+1]);
	}

	return 0;
}
Beispiel #2
0
static int __devinit snd_vt1724_amp_init(struct snd_ice1712 *ice)
{
	static unsigned short wm_inits[] = {
		WM_ATTEN_L,	0x0000,	/* 0 db */
		WM_ATTEN_R,	0x0000,	/* 0 db */
		WM_DAC_CTRL,	0x0008,	/* 24bit I2S */
		WM_INT_CTRL,	0x0001, /* 24bit I2S */	
	};

	unsigned int i;

	/* only use basic functionality for now */

	ice->num_total_dacs = 2;	/* only PSDOUT0 is connected */
	ice->num_total_adcs = 2;

	/* Chaintech AV-710 has another codecs, which need initialization */
	/* initialize WM8728 codec */
	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AV710) {
		for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
			wm_put(ice, wm_inits[i], wm_inits[i+1]);
	}

	return 0;
}
Beispiel #3
0
static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
{
	unsigned char nvol;

	if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
		nvol = 0;
	else
		nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];

	wm_put(ice, index, nvol);
	wm_put_nocache(ice, index, 0x180 | nvol);
}
/*
 * WM codec registers
 */
static void wm_proc_regs_write(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
{
	ice1712_t *ice = (ice1712_t *)entry->private_data;
	char line[64];
	unsigned int reg, val;
	down(&ice->gpio_mutex);
	while (!snd_info_get_line(buffer, line, sizeof(line))) {
		if (sscanf(line, "%x %x", &reg, &val) != 2)
			continue;
		if (reg <= 0x17 && val <= 0xffff)
			wm_put(ice, reg, val);
	}
	up(&ice->gpio_mutex);
}
/*
 * WM codec registers
 */
static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
{
	struct snd_ice1712 *ice = entry->private_data;
	char line[64];
	unsigned int reg, val;
	mutex_lock(&ice->gpio_mutex);
	while (!snd_info_get_line(buffer, line, sizeof(line))) {
		if (sscanf(line, "%x %x", &reg, &val) != 2)
			continue;
		if (reg <= 0x17 && val <= 0xffff)
			wm_put(ice, reg, val);
	}
	mutex_unlock(&ice->gpio_mutex);
}
Beispiel #6
0
static int phase28_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	int temp, temp2;
	temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
	if (ucontrol->value.integer.value[0])
		temp |= 0xf;
	else
		temp &= ~0xf;
	if (temp != temp2) {
		wm_put(ice, WM_DAC_CTRL2, temp);
		return 1;
	}
	return 0;
}
Beispiel #7
0
static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	unsigned short nval, oval;
	int change;

	snd_ice1712_save_gpio_status(ice);
	oval = wm_get(ice, WM_MUTE);
	nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
	if ((change = (nval != oval)))
		wm_put(ice, WM_MUTE, nval);
	snd_ice1712_restore_gpio_status(ice);

	return change;
}
static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index,
		       unsigned short vol, unsigned short master)
{
	unsigned char nvol;
	
	if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
		nvol = 0;
	else {
		nvol = (((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 128)
				& WM_VOL_MAX;
		nvol = (nvol ? (nvol + DAC_MIN) : 0) & 0xff;
	}
	
	wm_put(ice, index, nvol);
	wm_put_nocache(ice, index, 0x100 | nvol);
}
static int wm_adc_mux_enum_put(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	unsigned short oval, nval;
	int change = 0;

	mutex_lock(&ice->gpio_mutex);
	oval = wm_get(ice, WM_ADC_MUX);
	nval = (oval & 0xe0) | ucontrol->value.integer.value[0];
	if (nval != oval) {
		wm_put(ice, WM_ADC_MUX, nval);
		change = 1;
	}
	mutex_unlock(&ice->gpio_mutex);
	return change;
}
Beispiel #10
0
static int phase28_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	int temp, temp2;
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);

	temp2 = temp = wm_get(ice, WM_MASTER);

	if (ucontrol->value.enumerated.item[0])
		temp |= 0x8;
	else
		temp &= ~0x8;

	if (temp != temp2) {
		wm_put(ice, WM_MASTER, temp);
		return 1;
	}
	return 0;
}
Beispiel #11
0
static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	unsigned short ovol, nvol;
	int change = 0;

	snd_ice1712_save_gpio_status(ice);
	nvol = ucontrol->value.integer.value[0];
	nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
	ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
	if (ovol != nvol) {
		wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
		wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */
		change = 1;
	}
	snd_ice1712_restore_gpio_status(ice);
	return change;
}
static int wm_bypass_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	unsigned short val, oval;
	int change = 0;

	mutex_lock(&ice->gpio_mutex);
	val = oval = wm_get(ice, WM_OUT_MUX);
	if (ucontrol->value.integer.value[0])
		val |= 0x04;
	else
		val &= ~0x04;
	if (val != oval) {
		wm_put(ice, WM_OUT_MUX, val);
		change = 1;
	}
	mutex_unlock(&ice->gpio_mutex);
	return change;
}
static int wm_bypass_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
	unsigned short val, oval;
	int change = 0;

	down(&ice->gpio_mutex);
	val = oval = wm_get(ice, WM_OUT_MUX);
	if (ucontrol->value.integer.value[0])
		val |= 0x04;
	else
		val &= ~0x04;
	if (val != oval) {
		wm_put(ice, WM_OUT_MUX, val);
		change = 1;
	}
	up(&ice->gpio_mutex);
	return change;
}
static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	int bit = kcontrol->private_value;
	unsigned short oval, nval;
	int change;

	mutex_lock(&ice->gpio_mutex);
	nval = oval = wm_get(ice, WM_ADC_MUX);
	if (ucontrol->value.integer.value[0])
		nval |= (1 << bit);
	else
		nval &= ~(1 << bit);
	change = nval != oval;
	if (change) {
		wm_put(ice, WM_ADC_MUX, nval);
	}
	mutex_unlock(&ice->gpio_mutex);
	return change;
}
static int wm_adc_mux_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
	int bit = kcontrol->private_value;
	unsigned short oval, nval;
	int change;

	down(&ice->gpio_mutex);
	nval = oval = wm_get(ice, WM_ADC_MUX);
	if (ucontrol->value.integer.value[0])
		nval |= (1 << bit);
	else
		nval &= ~(1 << bit);
	change = nval != oval;
	if (change) {
		wm_put(ice, WM_ADC_MUX, nval);
	}
	up(&ice->gpio_mutex);
	return 0;
}
static int wm_adc_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
	unsigned short ovol, nvol;
	int i, idx, change = 0;

	down(&ice->gpio_mutex);
	for (i = 0; i < 2; i++) {
		nvol = ucontrol->value.integer.value[i];
		nvol = nvol ? (nvol + ADC_MIN) : 0;
		idx  = WM_ADC_ATTEN_L + i;
		ovol = wm_get(ice, idx) & 0xff;
		if (ovol != nvol) {
			wm_put(ice, idx, nvol);
			change = 1;
		}
	}
	up(&ice->gpio_mutex);
	return change;
}
static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	unsigned short oval, nval;
	int i, idx, change = 0;

	mutex_lock(&ice->gpio_mutex);
	for (i = 0; i < 2; i++) {
		nval = ucontrol->value.integer.value[i];
		nval = (nval ? (nval + DAC_MIN) : 0) & 0xff;
		idx = WM_DAC_ATTEN_L + i;
		oval = wm_get(ice, idx) & 0xff;
		if (oval != nval) {
			wm_put(ice, idx, nval);
			wm_put_nocache(ice, idx, nval | 0x100);
			change = 1;
		}
	}
	mutex_unlock(&ice->gpio_mutex);
	return change;
}
static int wm_chswap_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
	unsigned short val, oval;
	int change = 0;

	down(&ice->gpio_mutex);
	oval = wm_get(ice, WM_DAC_CTRL1);
	val = oval & 0x0f;
	if (ucontrol->value.integer.value[0])
		val |= 0x60;
	else
		val |= 0x90;
	if (val != oval) {
		wm_put(ice, WM_DAC_CTRL1, val);
		wm_put_nocache(ice, WM_DAC_CTRL1, val);
		change = 1;
	}
	up(&ice->gpio_mutex);
	return change;
}
static int __devinit prodigy_hifi_init(struct snd_ice1712 *ice)
{
	static unsigned short wm_inits[] = {
		
		WM_ADC_MUX,	0x0003,	
		
		
		WM_DAC_MUTE,	0x0001,	
		WM_DAC_CTRL1,	0x0000,	

		WM_POWERDOWN,	0x0008,	
		WM_RESET,	0x0000,	
	};
	static unsigned short wm_inits2[] = {
		WM_MASTER_CTRL,  0x0022, 
		WM_DAC_INT,	0x0022,	
		WM_ADC_INT,	0x0022,	
		WM_DAC_CTRL1,	0x0090,	
		WM_OUT_MUX,	0x0001,	
		WM_HP_ATTEN_L,	0x0179,	
		WM_HP_ATTEN_R,	0x0179,	
		WM_DAC_ATTEN_L,	0x0000,	
		WM_DAC_ATTEN_L,	0x0100,	
		WM_DAC_ATTEN_R,	0x0000,	
		WM_DAC_ATTEN_R,	0x0100,	
		WM_PHASE_SWAP,	0x0000,	
#if 0
		WM_DAC_MASTER,	0x0100,	
#endif
		WM_DAC_CTRL2,	0x0000,	
		WM_ADC_ATTEN_L,	0x0000,	
		WM_ADC_ATTEN_R,	0x0000,	
#if 1
		WM_ALC_CTRL1,	0x007b,	
		WM_ALC_CTRL2,	0x0000,	
		WM_ALC_CTRL3,	0x0000,	
		WM_NOISE_GATE,	0x0000,	
#endif
		WM_DAC_MUTE,	0x0000,	
		WM_ADC_MUX,	0x0003,	
	};
	static unsigned short wm8766_inits[] = {
		WM8766_RESET,	   0x0000,
		WM8766_DAC_CTRL,	0x0120,
		WM8766_INT_CTRL,	0x0022, 
		WM8766_DAC_CTRL2,       0x0001,
		WM8766_DAC_CTRL3,       0x0080,
		WM8766_LDA1,	    0x0100,
		WM8766_LDA2,	    0x0100,
		WM8766_LDA3,	    0x0100,
		WM8766_RDA1,	    0x0100,
		WM8766_RDA2,	    0x0100,
		WM8766_RDA3,	    0x0100,
		WM8766_MUTE1,	   0x0000,
		WM8766_MUTE2,	   0x0000,
	};

	struct prodigy_hifi_spec *spec;
	unsigned int i;

	ice->vt1720 = 0;
	ice->vt1724 = 1;

	ice->num_total_dacs = 8;
	ice->num_total_adcs = 1;

	/* HACK - use this as the SPDIF source.
	* don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
	*/
	ice->gpio.saved[0] = 0;
	

	ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
	if (! ice->akm)
		return -ENOMEM;
	ice->akm_codecs = 1;

	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
	if (!spec)
		return -ENOMEM;
	ice->spec = spec;

	
	for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
		wm_put(ice, wm_inits[i], wm_inits[i+1]);
	schedule_timeout_uninterruptible(1);
	for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2)
		wm_put(ice, wm_inits2[i], wm_inits2[i+1]);

	
	for (i = 0; i < ARRAY_SIZE(wm8766_inits); i += 2)
		wm8766_spi_write(ice, wm8766_inits[i], wm8766_inits[i+1]);


	return 0;
}
Beispiel #20
0
static int __devinit phase28_init(struct snd_ice1712 *ice)
{
	static const unsigned short wm_inits_phase28[] = {
		/* These come first to reduce init pop noise */
		0x1b, 0x044,		/* ADC Mux (AC'97 source) */
		0x1c, 0x00B,		/* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
		0x1d, 0x009,		/* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */

		0x18, 0x000,		/* All power-up */

		0x16, 0x122,		/* I2S, normal polarity, 24bit */
		0x17, 0x022,		/* 256fs, slave mode */
		0x00, 0,		/* DAC1 analog mute */
		0x01, 0,		/* DAC2 analog mute */
		0x02, 0,		/* DAC3 analog mute */
		0x03, 0,		/* DAC4 analog mute */
		0x04, 0,		/* DAC5 analog mute */
		0x05, 0,		/* DAC6 analog mute */
		0x06, 0,		/* DAC7 analog mute */
		0x07, 0,		/* DAC8 analog mute */
		0x08, 0x100,		/* master analog mute */
		0x09, 0xff,		/* DAC1 digital full */
		0x0a, 0xff,		/* DAC2 digital full */
		0x0b, 0xff,		/* DAC3 digital full */
		0x0c, 0xff,		/* DAC4 digital full */
		0x0d, 0xff,		/* DAC5 digital full */
		0x0e, 0xff,		/* DAC6 digital full */
		0x0f, 0xff,		/* DAC7 digital full */
		0x10, 0xff,		/* DAC8 digital full */
		0x11, 0x1ff,		/* master digital full */
		0x12, 0x000,		/* phase normal */
		0x13, 0x090,		/* unmute DAC L/R */
		0x14, 0x000,		/* all unmute */
		0x15, 0x000,		/* no deemphasis, no ZFLG */
		0x19, 0x000,		/* -12dB ADC/L */
		0x1a, 0x000,		/* -12dB ADC/R */
		(unsigned short)-1
	};

	unsigned int tmp;
	struct snd_akm4xxx *ak;
	const unsigned short *p;
	int i;

	ice->num_total_dacs = 8;
	ice->num_total_adcs = 2;

	// Initialize analog chips
	ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
	if (!ak)
		return -ENOMEM;
	ice->akm_codecs = 1;

	snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */

	/* reset the wm codec as the SPI mode */
	snd_ice1712_save_gpio_status(ice);
	snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RESET|PHASE28_WM_CS|PHASE28_HP_SEL));

	tmp = snd_ice1712_gpio_read(ice);
	tmp &= ~PHASE28_WM_RESET;
	snd_ice1712_gpio_write(ice, tmp);
	udelay(1);
	tmp |= PHASE28_WM_CS;
	snd_ice1712_gpio_write(ice, tmp);
	udelay(1);
	tmp |= PHASE28_WM_RESET;
	snd_ice1712_gpio_write(ice, tmp);
	udelay(1);

	p = wm_inits_phase28;
	for (; *p != (unsigned short)-1; p += 2)
		wm_put(ice, p[0], p[1]);

	snd_ice1712_restore_gpio_status(ice);

	ice->spec.phase28.master[0] = WM_VOL_MUTE;
	ice->spec.phase28.master[1] = WM_VOL_MUTE;
	for (i = 0; i < ice->num_total_dacs; i++) {
		ice->spec.phase28.vol[i] = WM_VOL_MUTE;
		wm_set_vol(ice, i, ice->spec.phase28.vol[i], ice->spec.phase28.master[i % 2]);
	}

	return 0;
}
/*
 * initialize the chip
 */
static int __devinit pontis_init(ice1712_t *ice)
{
	static unsigned short wm_inits[] = {
		/* These come first to reduce init pop noise */
		WM_ADC_MUX,	0x00c0,	/* ADC mute */
		WM_DAC_MUTE,	0x0001,	/* DAC softmute */
		WM_DAC_CTRL1,	0x0000,	/* DAC mute */

		WM_POWERDOWN,	0x0008,	/* All power-up except HP */
		WM_RESET,	0x0000,	/* reset */
	};
	static unsigned short wm_inits2[] = {
		WM_MASTER_CTRL,	0x0022,	/* 256fs, slave mode */
		WM_DAC_INT,	0x0022,	/* I2S, normal polarity, 24bit */
		WM_ADC_INT,	0x0022,	/* I2S, normal polarity, 24bit */
		WM_DAC_CTRL1,	0x0090,	/* DAC L/R */
		WM_OUT_MUX,	0x0001,	/* OUT DAC */
		WM_HP_ATTEN_L,	0x0179,	/* HP 0dB */
		WM_HP_ATTEN_R,	0x0179,	/* HP 0dB */
		WM_DAC_ATTEN_L,	0x0000,	/* DAC 0dB */
		WM_DAC_ATTEN_L,	0x0100,	/* DAC 0dB */
		WM_DAC_ATTEN_R,	0x0000,	/* DAC 0dB */
		WM_DAC_ATTEN_R,	0x0100,	/* DAC 0dB */
		// WM_DAC_MASTER,	0x0100,	/* DAC master muted */
		WM_PHASE_SWAP,	0x0000,	/* phase normal */
		WM_DAC_CTRL2,	0x0000,	/* no deemphasis, no ZFLG */
		WM_ADC_ATTEN_L,	0x0000,	/* ADC muted */
		WM_ADC_ATTEN_R,	0x0000,	/* ADC muted */
#if 0
		WM_ALC_CTRL1,	0x007b,	/* */
		WM_ALC_CTRL2,	0x0000,	/* */
		WM_ALC_CTRL3,	0x0000,	/* */
		WM_NOISE_GATE,	0x0000,	/* */
#endif
		WM_DAC_MUTE,	0x0000,	/* DAC unmute */
		WM_ADC_MUX,	0x0003,	/* ADC unmute, both CD/Line On */
	};
	static unsigned char cs_inits[] = {
		0x04,	0x80,	/* RUN, RXP0 */
		0x05,	0x05,	/* slave, 24bit */
		0x01,	0x00,
		0x02,	0x00,
		0x03,	0x00,
	};
	unsigned int i;

	ice->vt1720 = 1;
	ice->num_total_dacs = 2;
	ice->num_total_adcs = 2;

	/* to remeber the register values */
	ice->akm = kzalloc(sizeof(akm4xxx_t), GFP_KERNEL);
	if (! ice->akm)
		return -ENOMEM;
	ice->akm_codecs = 1;

	/* HACK - use this as the SPDIF source.
	 * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
	 */
	ice->gpio.saved[0] = 0;

	/* initialize WM8776 codec */
	for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
		wm_put(ice, wm_inits[i], wm_inits[i+1]);
	schedule_timeout_uninterruptible(1);
	for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2)
		wm_put(ice, wm_inits2[i], wm_inits2[i+1]);

	/* initialize CS8416 codec */
	/* assert PRST#; MT05 bit 7 */
	outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));
	mdelay(5);
	/* deassert PRST# */
	outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));

	for (i = 0; i < ARRAY_SIZE(cs_inits); i += 2)
		spi_write(ice, CS_DEV, cs_inits[i], cs_inits[i+1]);

	return 0;
}