diff options
Diffstat (limited to 'sound/pci/ice1712')
29 files changed, 2639 insertions, 449 deletions
diff --git a/sound/pci/ice1712/Makefile b/sound/pci/ice1712/Makefile index f7ce33f00ea..7e50c132455 100644 --- a/sound/pci/ice1712/Makefile +++ b/sound/pci/ice1712/Makefile @@ -5,7 +5,7 @@  snd-ice17xx-ak4xxx-objs := ak4xxx.o  snd-ice1712-objs := ice1712.o delta.o hoontech.o ews.o -snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o vt1720_mobo.o pontis.o prodigy192.o prodigy_hifi.o juli.o phase.o wtm.o se.o maya44.o quartet.o +snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o vt1720_mobo.o pontis.o prodigy192.o prodigy_hifi.o juli.o phase.o wtm.o se.o maya44.o quartet.o psc724.o wm8766.o wm8776.o  # Toplevel Module Dependency  obj-$(CONFIG_SND_ICE1712) += snd-ice1712.o snd-ice17xx-ak4xxx.o diff --git a/sound/pci/ice1712/ak4xxx.c b/sound/pci/ice1712/ak4xxx.c index 90d560c3df1..3981823f909 100644 --- a/sound/pci/ice1712/ak4xxx.c +++ b/sound/pci/ice1712/ak4xxx.c @@ -26,6 +26,7 @@  #include <linux/interrupt.h>  #include <linux/slab.h>  #include <linux/init.h> +#include <linux/module.h>  #include <sound/core.h>  #include <sound/initval.h>  #include "ice1712.h" diff --git a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c index e328cfb7620..2f9b9346786 100644 --- a/sound/pci/ice1712/amp.c +++ b/sound/pci/ice1712/amp.c @@ -21,7 +21,6 @@   *   */       -#include <asm/io.h>  #include <linux/delay.h>  #include <linux/interrupt.h>  #include <linux/init.h> @@ -38,7 +37,7 @@ static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)  	snd_vt1724_write_i2c(ice, WM_DEV, cval >> 8, cval & 0xff);  } -static int __devinit snd_vt1724_amp_init(struct snd_ice1712 *ice) +static int snd_vt1724_amp_init(struct snd_ice1712 *ice)  {  	static const unsigned short wm_inits[] = {  		WM_ATTEN_L,	0x0000,	/* 0 db */ @@ -66,16 +65,19 @@ static int __devinit snd_vt1724_amp_init(struct snd_ice1712 *ice)  	return 0;  } -static int __devinit snd_vt1724_amp_add_controls(struct snd_ice1712 *ice) +static int snd_vt1724_amp_add_controls(struct snd_ice1712 *ice)  { -	/* we use pins 39 and 41 of the VT1616 for left and right read outputs */ -	snd_ac97_write_cache(ice->ac97, 0x5a, snd_ac97_read(ice->ac97, 0x5a) & ~0x8000); +	if (ice->ac97) +		/* we use pins 39 and 41 of the VT1616 for left and right +		read outputs */ +		snd_ac97_write_cache(ice->ac97, 0x5a, +			snd_ac97_read(ice->ac97, 0x5a) & ~0x8000);  	return 0;  }  /* entry point */ -struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_amp_cards[] = {  	{  		.subvendor = VT1724_SUBDEVICE_AV710,  		.name = "Chaintech AV-710", diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c index 2f6252266a0..3b3cf4ac906 100644 --- a/sound/pci/ice1712/aureon.c +++ b/sound/pci/ice1712/aureon.c @@ -46,7 +46,6 @@   *                    on mixer switch and other coll stuff.   */ -#include <linux/io.h>  #include <linux/delay.h>  #include <linux/interrupt.h>  #include <linux/init.h> @@ -148,7 +147,7 @@ static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg,  	udelay(100);  	/*  	 * send device address, command and value, -	 * skipping ack cycles inbetween +	 * skipping ack cycles in between  	 */  	for (j = 0; j < 3; j++) {  		switch (j) { @@ -203,7 +202,8 @@ static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg,  static int aureon_universe_inmux_info(struct snd_kcontrol *kcontrol,  				      struct snd_ctl_elem_info *uinfo)  { -	char *texts[3] = {"Internal Aux", "Wavetable", "Rear Line-In"}; +	static const char * const texts[3] = +		{"Internal Aux", "Wavetable", "Rear Line-In"};  	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;  	uinfo->count = 1; @@ -1433,7 +1433,7 @@ static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl   * mixers   */ -static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = { +static struct snd_kcontrol_new aureon_dac_controls[] = {  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "Master Playback Switch", @@ -1548,7 +1548,7 @@ static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {  	}  }; -static struct snd_kcontrol_new wm_controls[] __devinitdata = { +static struct snd_kcontrol_new wm_controls[] = {  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "PCM Playback Switch", @@ -1614,7 +1614,7 @@ static struct snd_kcontrol_new wm_controls[] __devinitdata = {  	}  }; -static struct snd_kcontrol_new ac97_controls[] __devinitdata = { +static struct snd_kcontrol_new ac97_controls[] = {  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "AC97 Playback Switch", @@ -1719,7 +1719,7 @@ static struct snd_kcontrol_new ac97_controls[] __devinitdata = {  	}  }; -static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = { +static struct snd_kcontrol_new universe_ac97_controls[] = {  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "AC97 Playback Switch", @@ -1851,7 +1851,7 @@ static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {  }; -static struct snd_kcontrol_new cs8415_controls[] __devinitdata = { +static struct snd_kcontrol_new cs8415_controls[] = {  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH), @@ -1896,7 +1896,7 @@ static struct snd_kcontrol_new cs8415_controls[] __devinitdata = {  	}  }; -static int __devinit aureon_add_controls(struct snd_ice1712 *ice) +static int aureon_add_controls(struct snd_ice1712 *ice)  {  	unsigned int i, counts;  	int err; @@ -1937,9 +1937,12 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice)  		snd_ice1712_save_gpio_status(ice);  		id = aureon_cs8415_get(ice, CS8415_ID);  		if (id != 0x41) -			snd_printk(KERN_INFO "No CS8415 chip. Skipping CS8415 controls.\n"); +			dev_info(ice->card->dev, +				 "No CS8415 chip. Skipping CS8415 controls.\n");  		else if ((id & 0x0F) != 0x01) -			snd_printk(KERN_INFO "Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1)); +			dev_info(ice->card->dev, +				 "Detected unsupported CS8415 rev. (%c)\n", +				 (char)((id & 0x0F) + 'A' - 1));  		else {  			for (i = 0; i < ARRAY_SIZE(cs8415_controls); i++) {  				struct snd_kcontrol *kctl; @@ -2103,7 +2106,7 @@ static int aureon_reset(struct snd_ice1712 *ice)  /*   * suspend/resume   */ -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP  static int aureon_resume(struct snd_ice1712 *ice)  {  	struct aureon_spec *spec = ice->spec; @@ -2124,7 +2127,7 @@ static int aureon_resume(struct snd_ice1712 *ice)  /*   * initialize the chip   */ -static int __devinit aureon_init(struct snd_ice1712 *ice) +static int aureon_init(struct snd_ice1712 *ice)  {  	struct aureon_spec *spec;  	int i, err; @@ -2143,7 +2146,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)  		ice->num_total_adcs = 2;  	} -	/* to remeber the register values of CS8415 */ +	/* to remember the register values of CS8415 */  	ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);  	if (!ice->akm)  		return -ENOMEM; @@ -2160,7 +2163,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)  		wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);  	} -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP  	ice->pm_resume = aureon_resume;  	ice->pm_suspend_enabled = 1;  #endif @@ -2174,7 +2177,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)   * hence the driver needs to sets up it properly.   */ -static unsigned char aureon51_eeprom[] __devinitdata = { +static unsigned char aureon51_eeprom[] = {  	[ICE_EEP2_SYSCONF]     = 0x0a,	/* clock 512, spdif-in/ADC, 3DACs */  	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */  	[ICE_EEP2_I2S]         = 0xfc,	/* vol, 96k, 24bit, 192k */ @@ -2190,7 +2193,7 @@ static unsigned char aureon51_eeprom[] __devinitdata = {  	[ICE_EEP2_GPIO_STATE2] = 0x00,  }; -static unsigned char aureon71_eeprom[] __devinitdata = { +static unsigned char aureon71_eeprom[] = {  	[ICE_EEP2_SYSCONF]     = 0x0b,	/* clock 512, spdif-in/ADC, 4DACs */  	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */  	[ICE_EEP2_I2S]         = 0xfc,	/* vol, 96k, 24bit, 192k */ @@ -2207,7 +2210,7 @@ static unsigned char aureon71_eeprom[] __devinitdata = {  };  #define prodigy71_eeprom aureon71_eeprom -static unsigned char aureon71_universe_eeprom[] __devinitdata = { +static unsigned char aureon71_universe_eeprom[] = {  	[ICE_EEP2_SYSCONF]     = 0x2b,	/* clock 512, mpu401, spdif-in/ADC,  					 * 4DACs  					 */ @@ -2225,7 +2228,7 @@ static unsigned char aureon71_universe_eeprom[] __devinitdata = {  	[ICE_EEP2_GPIO_STATE2] = 0x00,  }; -static unsigned char prodigy71lt_eeprom[] __devinitdata = { +static unsigned char prodigy71lt_eeprom[] = {  	[ICE_EEP2_SYSCONF]     = 0x4b,	/* clock 384, spdif-in/ADC, 4DACs */  	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */  	[ICE_EEP2_I2S]         = 0xfc,	/* vol, 96k, 24bit, 192k */ @@ -2243,7 +2246,7 @@ static unsigned char prodigy71lt_eeprom[] __devinitdata = {  #define prodigy71xt_eeprom prodigy71lt_eeprom  /* entry point */ -struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_aureon_cards[] = {  	{  		.subvendor = VT1724_SUBDEVICE_AUREON51_SKY,  		.name = "Terratec Aureon 5.1-Sky", diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c index 712c1710f9a..496dbd0ad5d 100644 --- a/sound/pci/ice1712/delta.c +++ b/sound/pci/ice1712/delta.c @@ -22,7 +22,6 @@   *   */       -#include <asm/io.h>  #include <linux/delay.h>  #include <linux/interrupt.h>  #include <linux/init.h> @@ -96,6 +95,11 @@ static unsigned char ap_cs8427_codec_select(struct snd_ice1712 *ice)  		tmp |= ICE1712_DELTA_AP_CCLK | ICE1712_DELTA_AP_CS_CODEC;  		tmp &= ~ICE1712_DELTA_AP_CS_DIGITAL;  		break; +	case ICE1712_SUBDEVICE_DELTA66E: +		tmp |= ICE1712_DELTA_66E_CCLK | ICE1712_DELTA_66E_CS_CHIP_A | +		       ICE1712_DELTA_66E_CS_CHIP_B; +		tmp &= ~ICE1712_DELTA_66E_CS_CS8427; +		break;  	case ICE1712_SUBDEVICE_VX442:  		tmp |= ICE1712_VX442_CCLK | ICE1712_VX442_CODEC_CHIP_A | ICE1712_VX442_CODEC_CHIP_B;  		tmp &= ~ICE1712_VX442_CS_DIGITAL; @@ -119,6 +123,9 @@ static void ap_cs8427_codec_deassert(struct snd_ice1712 *ice, unsigned char tmp)  	case ICE1712_SUBDEVICE_DELTA410:  		tmp |= ICE1712_DELTA_AP_CS_DIGITAL;  		break; +	case ICE1712_SUBDEVICE_DELTA66E: +		tmp |= ICE1712_DELTA_66E_CS_CS8427; +		break;  	case ICE1712_SUBDEVICE_VX442:  		tmp |= ICE1712_VX442_CS_DIGITAL;  		break; @@ -276,6 +283,20 @@ static void delta1010lt_ak4524_lock(struct snd_akm4xxx *ak, int chip)  }  /* + * AK4524 on Delta66 rev E to choose the chip address + */ +static void delta66e_ak4524_lock(struct snd_akm4xxx *ak, int chip) +{ +	struct snd_ak4xxx_private *priv = (void *)ak->private_value[0]; +	struct snd_ice1712 *ice = ak->private_data[0]; + +	snd_ice1712_save_gpio_status(ice); +	priv->cs_mask = +	priv->cs_addr = chip == 0 ? ICE1712_DELTA_66E_CS_CHIP_A : +				    ICE1712_DELTA_66E_CS_CHIP_B; +} + +/*   * AK4528 on VX442 to choose the chip mask   */  static void vx442_ak4524_lock(struct snd_akm4xxx *ak, int chip) @@ -404,13 +425,14 @@ static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kco  	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);  	if (snd_i2c_sendbytes(ice->cs8427, ®, 1) != 1) -		snd_printk(KERN_ERR "unable to send register 0x%x byte to CS8427\n", reg); +		dev_err(ice->card->dev, +			"unable to send register 0x%x byte to CS8427\n", reg);  	snd_i2c_readbytes(ice->cs8427, ®, 1);  	ucontrol->value.integer.value[0] = (reg & CS8427_UNLOCK) ? 1 : 0;  	return 0;  } -static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata = +static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status =  {  	.access =	(SNDRV_CTL_ELEM_ACCESS_READ),  	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER, @@ -423,7 +445,7 @@ static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devini   * initialize the chips on M-Audio cards   */ -static struct snd_akm4xxx akm_audiophile __devinitdata = { +static struct snd_akm4xxx akm_audiophile = {  	.type = SND_AK4528,  	.num_adcs = 2,  	.num_dacs = 2, @@ -432,7 +454,7 @@ static struct snd_akm4xxx akm_audiophile __devinitdata = {  	}  }; -static struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = { +static struct snd_ak4xxx_private akm_audiophile_priv = {  	.caddr = 2,  	.cif = 0,  	.data_mask = ICE1712_DELTA_AP_DOUT, @@ -444,7 +466,7 @@ static struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = {  	.mask_flags = 0,  }; -static struct snd_akm4xxx akm_delta410 __devinitdata = { +static struct snd_akm4xxx akm_delta410 = {  	.type = SND_AK4529,  	.num_adcs = 2,  	.num_dacs = 8, @@ -453,7 +475,7 @@ static struct snd_akm4xxx akm_delta410 __devinitdata = {  	}  }; -static struct snd_ak4xxx_private akm_delta410_priv __devinitdata = { +static struct snd_ak4xxx_private akm_delta410_priv = {  	.caddr = 0,  	.cif = 0,  	.data_mask = ICE1712_DELTA_AP_DOUT, @@ -465,7 +487,7 @@ static struct snd_ak4xxx_private akm_delta410_priv __devinitdata = {  	.mask_flags = 0,  }; -static struct snd_akm4xxx akm_delta1010lt __devinitdata = { +static struct snd_akm4xxx akm_delta1010lt = {  	.type = SND_AK4524,  	.num_adcs = 8,  	.num_dacs = 8, @@ -475,7 +497,7 @@ static struct snd_akm4xxx akm_delta1010lt __devinitdata = {  	}  }; -static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = { +static struct snd_ak4xxx_private akm_delta1010lt_priv = {  	.caddr = 2,  	.cif = 0, /* the default level of the CIF pin from AK4524 */  	.data_mask = ICE1712_DELTA_1010LT_DOUT, @@ -487,7 +509,30 @@ static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {  	.mask_flags = 0,  }; -static struct snd_akm4xxx akm_delta44 __devinitdata = { +static struct snd_akm4xxx akm_delta66e = { +	.type = SND_AK4524, +	.num_adcs = 4, +	.num_dacs = 4, +	.ops = { +		.lock = delta66e_ak4524_lock, +		.set_rate_val = delta_ak4524_set_rate_val +	} +}; + +static struct snd_ak4xxx_private akm_delta66e_priv = { +	.caddr = 2, +	.cif = 0, /* the default level of the CIF pin from AK4524 */ +	.data_mask = ICE1712_DELTA_66E_DOUT, +	.clk_mask = ICE1712_DELTA_66E_CCLK, +	.cs_mask = 0, +	.cs_addr = 0, /* set later */ +	.cs_none = 0, +	.add_flags = 0, +	.mask_flags = 0, +}; + + +static struct snd_akm4xxx akm_delta44 = {  	.type = SND_AK4524,  	.num_adcs = 4,  	.num_dacs = 4, @@ -497,7 +542,7 @@ static struct snd_akm4xxx akm_delta44 __devinitdata = {  	}  }; -static struct snd_ak4xxx_private akm_delta44_priv __devinitdata = { +static struct snd_ak4xxx_private akm_delta44_priv = {  	.caddr = 2,  	.cif = 0, /* the default level of the CIF pin from AK4524 */  	.data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA, @@ -509,7 +554,7 @@ static struct snd_ak4xxx_private akm_delta44_priv __devinitdata = {  	.mask_flags = 0,  }; -static struct snd_akm4xxx akm_vx442 __devinitdata = { +static struct snd_akm4xxx akm_vx442 = {  	.type = SND_AK4524,  	.num_adcs = 4,  	.num_dacs = 4, @@ -519,7 +564,7 @@ static struct snd_akm4xxx akm_vx442 __devinitdata = {  	}  }; -static struct snd_ak4xxx_private akm_vx442_priv __devinitdata = { +static struct snd_ak4xxx_private akm_vx442_priv = {  	.caddr = 2,  	.cif = 0,  	.data_mask = ICE1712_VX442_DOUT, @@ -531,10 +576,60 @@ static struct snd_ak4xxx_private akm_vx442_priv __devinitdata = {  	.mask_flags = 0,  }; -static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice) +#ifdef CONFIG_PM_SLEEP +static int snd_ice1712_delta_resume(struct snd_ice1712 *ice) +{ +	unsigned char akm_img_bak[AK4XXX_IMAGE_SIZE]; +	unsigned char akm_vol_bak[AK4XXX_IMAGE_SIZE]; + +	/* init spdif */ +	switch (ice->eeprom.subvendor) { +	case ICE1712_SUBDEVICE_AUDIOPHILE: +	case ICE1712_SUBDEVICE_DELTA410: +	case ICE1712_SUBDEVICE_DELTA1010E: +	case ICE1712_SUBDEVICE_DELTA1010LT: +	case ICE1712_SUBDEVICE_VX442: +	case ICE1712_SUBDEVICE_DELTA66E: +		snd_cs8427_init(ice->i2c, ice->cs8427); +		break; +	case ICE1712_SUBDEVICE_DELTA1010: +	case ICE1712_SUBDEVICE_MEDIASTATION: +		/* nothing */ +		break; +	case ICE1712_SUBDEVICE_DELTADIO2496: +	case ICE1712_SUBDEVICE_DELTA66: +		/* Set spdif defaults */ +		snd_ice1712_delta_cs8403_spdif_write(ice, ice->spdif.cs8403_bits); +		break; +	} + +	/* init codec and restore registers */ +	if (ice->akm_codecs) { +		memcpy(akm_img_bak, ice->akm->images, sizeof(akm_img_bak)); +		memcpy(akm_vol_bak, ice->akm->volumes, sizeof(akm_vol_bak)); +		snd_akm4xxx_init(ice->akm); +		memcpy(ice->akm->images, akm_img_bak, sizeof(akm_img_bak)); +		memcpy(ice->akm->volumes, akm_vol_bak, sizeof(akm_vol_bak)); +		snd_akm4xxx_reset(ice->akm, 0); +	} + +	return 0; +} + +static int snd_ice1712_delta_suspend(struct snd_ice1712 *ice) +{ +	if (ice->akm_codecs) /* reset & mute codec */ +		snd_akm4xxx_reset(ice->akm, 1); + +	return 0; +} +#endif + +static int snd_ice1712_delta_init(struct snd_ice1712 *ice)  {  	int err;  	struct snd_akm4xxx *ak; +	unsigned char tmp;  	if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DELTA1010 &&  	    ice->eeprom.gpiodir == 0x7b) @@ -571,11 +666,21 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)  		ice->num_total_dacs = 4;	/* two AK4324 codecs */  		break;  	case ICE1712_SUBDEVICE_VX442: -	case ICE1712_SUBDEVICE_DELTA66E:	/* omni not suported yet */ +	case ICE1712_SUBDEVICE_DELTA66E:	/* omni not supported yet */  		ice->num_total_dacs = 4;  		ice->num_total_adcs = 4;  		break;  	} +#ifdef CONFIG_PM_SLEEP +	ice->pm_resume = snd_ice1712_delta_resume; +	ice->pm_suspend = snd_ice1712_delta_suspend; +	ice->pm_suspend_enabled = 1; +#endif +	/* initialize the SPI clock to high */ +	tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); +	tmp |= ICE1712_DELTA_AP_CCLK; +	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); +	udelay(5);  	/* initialize spdif */  	switch (ice->eeprom.subvendor) { @@ -586,7 +691,7 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)  	case ICE1712_SUBDEVICE_VX442:  	case ICE1712_SUBDEVICE_DELTA66E:  		if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) { -			snd_printk(KERN_ERR "unable to create I2C bus\n"); +			dev_err(ice->card->dev, "unable to create I2C bus\n");  			return err;  		}  		ice->i2c->private_data = ice; @@ -644,9 +749,11 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)  		err = snd_ice1712_akm4xxx_init(ak, &akm_delta44, &akm_delta44_priv, ice);  		break;  	case ICE1712_SUBDEVICE_VX442: -	case ICE1712_SUBDEVICE_DELTA66E:  		err = snd_ice1712_akm4xxx_init(ak, &akm_vx442, &akm_vx442_priv, ice);  		break; +	case ICE1712_SUBDEVICE_DELTA66E: +		err = snd_ice1712_akm4xxx_init(ak, &akm_delta66e, &akm_delta66e_priv, ice); +		break;  	default:  		snd_BUG();  		return -EINVAL; @@ -660,19 +767,19 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)   * additional controls for M-Audio cards   */ -static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata = +static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select =  ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0); -static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata = +static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select =  ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 0, 0); -static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata = +static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status =  ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); -static struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata = +static struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select =  ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0); -static struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status __devinitdata = +static struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status =  ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Delta IEC958 Input Status", 0, ICE1712_DELTA_SPDIF_IN_STAT, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); -static int __devinit snd_ice1712_delta_add_controls(struct snd_ice1712 *ice) +static int snd_ice1712_delta_add_controls(struct snd_ice1712 *ice)  {  	int err; @@ -748,7 +855,7 @@ static int __devinit snd_ice1712_delta_add_controls(struct snd_ice1712 *ice)  /* entry point */ -struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_ice1712_delta_cards[] = {  	{  		.subvendor = ICE1712_SUBDEVICE_DELTA1010,  		.name = "M Audio Delta 1010", diff --git a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h index 1a0ac6cd650..11a9c3a7650 100644 --- a/sound/pci/ice1712/delta.h +++ b/sound/pci/ice1712/delta.h @@ -144,6 +144,17 @@ extern struct snd_ice1712_card_info snd_ice1712_delta_cards[];  #define ICE1712_DELTA_1010LT_CS_NONE	0x50	/* nothing */  #define ICE1712_DELTA_1010LT_WORDCLOCK 0x80	/* sample clock source: 0 = Word Clock Input, 1 = S/PDIF Input ??? */ +/* M-Audio Delta 66 rev. E definitions. + * Newer revisions of Delta 66 have CS8427 over SPI for + * S/PDIF transceiver instead of CS8404/CS8414. */ +/* 0x01 = DFS */ +#define ICE1712_DELTA_66E_CCLK		0x02	/* SPI clock */ +#define ICE1712_DELTA_66E_DIN		0x04	/* data input */ +#define ICE1712_DELTA_66E_DOUT		0x08	/* data output */ +#define ICE1712_DELTA_66E_CS_CS8427	0x10	/* chip select, low = CS8427 */ +#define ICE1712_DELTA_66E_CS_CHIP_A	0x20	/* AK4524 #0 */ +#define ICE1712_DELTA_66E_CS_CHIP_B	0x40	/* AK4524 #1 */ +  /* Digigram VX442 definitions */  #define ICE1712_VX442_CCLK		0x02	/* SPI clock */  #define ICE1712_VX442_DIN		0x04	/* data input */ diff --git a/sound/pci/ice1712/envy24ht.h b/sound/pci/ice1712/envy24ht.h index a0c5e009bb4..4ca33a800bc 100644 --- a/sound/pci/ice1712/envy24ht.h +++ b/sound/pci/ice1712/envy24ht.h @@ -66,6 +66,7 @@ enum {  #define     VT1724_CFG_CLOCK384  0x40	/* 16.9344Mhz, 44.1kHz*384 */  #define   VT1724_CFG_MPU401	0x20		/* MPU401 UARTs */  #define   VT1724_CFG_ADC_MASK	0x0c	/* one, two or one and S/PDIF, stereo ADCs */ +#define   VT1724_CFG_ADC_NONE	0x0c	/* no ADCs */  #define   VT1724_CFG_DAC_MASK	0x03	/* one, two, three, four stereo DACs */  #define VT1724_REG_AC97_CFG		0x05	/* byte */ diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c index 6fe35b81204..817a1bc50a6 100644 --- a/sound/pci/ice1712/ews.c +++ b/sound/pci/ice1712/ews.c @@ -22,7 +22,6 @@   *   */       -#include <asm/io.h>  #include <linux/delay.h>  #include <linux/interrupt.h>  #include <linux/init.h> @@ -164,7 +163,8 @@ static int snd_ice1712_ews88mt_chip_select(struct snd_ice1712 *ice, int chip_mas       __error:  	snd_i2c_unlock(ice->i2c); -	snd_printk(KERN_ERR "AK4524 chip select failed, check cable to the front module\n"); +	dev_err(ice->card->dev, +		"AK4524 chip select failed, check cable to the front module\n");  	return -EIO;  } @@ -175,7 +175,7 @@ static void ews88mt_ak4524_lock(struct snd_akm4xxx *ak, int chip)  	unsigned char tmp;  	/* assert AK4524 CS */  	if (snd_ice1712_ews88mt_chip_select(ice, ~(1 << chip) & 0x0f) < 0) -		snd_printk(KERN_ERR "fatal error (ews88mt chip select)\n"); +		dev_err(ice->card->dev, "fatal error (ews88mt chip select)\n");  	snd_ice1712_save_gpio_status(ice);  	tmp = ICE1712_EWS88_SERIAL_DATA |  		ICE1712_EWS88_SERIAL_CLOCK | @@ -344,7 +344,7 @@ static void ews88_setup_spdif(struct snd_ice1712 *ice, int rate)  /*   */ -static struct snd_akm4xxx akm_ews88mt __devinitdata = { +static struct snd_akm4xxx akm_ews88mt = {  	.num_adcs = 8,  	.num_dacs = 8,  	.type = SND_AK4524, @@ -354,7 +354,7 @@ static struct snd_akm4xxx akm_ews88mt __devinitdata = {  	}  }; -static struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = { +static struct snd_ak4xxx_private akm_ews88mt_priv = {  	.caddr = 2,  	.cif = 1, /* CIF high */  	.data_mask = ICE1712_EWS88_SERIAL_DATA, @@ -366,7 +366,7 @@ static struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = {  	.mask_flags = 0,  }; -static struct snd_akm4xxx akm_ewx2496 __devinitdata = { +static struct snd_akm4xxx akm_ewx2496 = {  	.num_adcs = 2,  	.num_dacs = 2,  	.type = SND_AK4524, @@ -375,7 +375,7 @@ static struct snd_akm4xxx akm_ewx2496 __devinitdata = {  	}  }; -static struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = { +static struct snd_ak4xxx_private akm_ewx2496_priv = {  	.caddr = 2,  	.cif = 1, /* CIF high */  	.data_mask = ICE1712_EWS88_SERIAL_DATA, @@ -387,7 +387,7 @@ static struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = {  	.mask_flags = 0,  }; -static struct snd_akm4xxx akm_6fire __devinitdata = { +static struct snd_akm4xxx akm_6fire = {  	.num_adcs = 6,  	.num_dacs = 6,  	.type = SND_AK4524, @@ -396,7 +396,7 @@ static struct snd_akm4xxx akm_6fire __devinitdata = {  	}  }; -static struct snd_ak4xxx_private akm_6fire_priv __devinitdata = { +static struct snd_ak4xxx_private akm_6fire_priv = {  	.caddr = 2,  	.cif = 1, /* CIF high */  	.data_mask = ICE1712_6FIRE_SERIAL_DATA, @@ -420,7 +420,7 @@ static struct snd_ak4xxx_private akm_6fire_priv __devinitdata = {  static int snd_ice1712_6fire_write_pca(struct snd_ice1712 *ice, unsigned char reg, unsigned char data); -static int __devinit snd_ice1712_ews_init(struct snd_ice1712 *ice) +static int snd_ice1712_ews_init(struct snd_ice1712 *ice)  {  	int err;  	struct snd_akm4xxx *ak; @@ -457,7 +457,7 @@ static int __devinit snd_ice1712_ews_init(struct snd_ice1712 *ice)  	/* create i2c */  	if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) { -		snd_printk(KERN_ERR "unable to create I2C bus\n"); +		dev_err(ice->card->dev, "unable to create I2C bus\n");  		return err;  	}  	ice->i2c->private_data = ice; @@ -470,7 +470,8 @@ static int __devinit snd_ice1712_ews_init(struct snd_ice1712 *ice)  					    ICE1712_6FIRE_PCF9554_ADDR,  					    &spec->i2cdevs[EWS_I2C_6FIRE]);  		if (err < 0) { -			snd_printk(KERN_ERR "PCF9554 initialization failed\n"); +			dev_err(ice->card->dev, +				"PCF9554 initialization failed\n");  			return err;  		}  		snd_ice1712_6fire_write_pca(ice, PCF9554_REG_CONFIG, 0x80); @@ -576,7 +577,7 @@ static int __devinit snd_ice1712_ews_init(struct snd_ice1712 *ice)  /* i/o sensitivity - this callback is shared among other devices, too */  static int snd_ice1712_ewx_io_sense_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){ -	static char *texts[2] = { +	static const char * const texts[2] = {  		"+4dBu", "-10dBV",  	};  	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; @@ -616,7 +617,7 @@ static int snd_ice1712_ewx_io_sense_put(struct snd_kcontrol *kcontrol, struct sn  	return val != nval;  } -static struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] = {  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "Input Sensitivity Switch", @@ -724,7 +725,7 @@ static int snd_ice1712_ews88mt_input_sense_put(struct snd_kcontrol *kcontrol, st  	return ndata != data;  } -static struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense = {  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.name = "Input Sensitivity Switch",  	.info = snd_ice1712_ewx_io_sense_info, @@ -733,7 +734,7 @@ static struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = {  	.count = 8,  }; -static struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense = {  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.name = "Output Sensitivity Switch",  	.info = snd_ice1712_ewx_io_sense_info, @@ -811,7 +812,7 @@ static int snd_ice1712_ews88d_control_put(struct snd_kcontrol *kcontrol, struct    .private_value = xshift | (xinvert << 8),\  } -static struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_ews88d_controls[] = {  	EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, 1, 0), /* inverted */  	EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Output Optical", 1, 0, 0),  	EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT External Master Clock", 2, 0, 0), @@ -835,7 +836,7 @@ static int snd_ice1712_6fire_read_pca(struct snd_ice1712 *ice, unsigned char reg  	byte = 0;  	if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_6FIRE], &byte, 1) != 1) {  		snd_i2c_unlock(ice->i2c); -		printk(KERN_ERR "cannot read pca\n"); +		dev_err(ice->card->dev, "cannot read pca\n");  		return -EIO;  	}  	snd_i2c_unlock(ice->i2c); @@ -899,7 +900,7 @@ static int snd_ice1712_6fire_control_put(struct snd_kcontrol *kcontrol, struct s  static int snd_ice1712_6fire_select_input_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)  { -	static char *texts[4] = { +	static const char * const texts[4] = {  		"Internal", "Front Input", "Rear Input", "Wave Table"  	};  	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; @@ -948,7 +949,7 @@ static int snd_ice1712_6fire_select_input_put(struct snd_kcontrol *kcontrol, str    .private_value = xshift | (xinvert << 8),\  } -static struct snd_kcontrol_new snd_ice1712_6fire_controls[] __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_6fire_controls[] = {  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "Analog Input Select", @@ -964,7 +965,7 @@ static struct snd_kcontrol_new snd_ice1712_6fire_controls[] __devinitdata = {  }; -static int __devinit snd_ice1712_ews_add_controls(struct snd_ice1712 *ice) +static int snd_ice1712_ews_add_controls(struct snd_ice1712 *ice)  {  	unsigned int idx;  	int err; @@ -1030,7 +1031,7 @@ static int __devinit snd_ice1712_ews_add_controls(struct snd_ice1712 *ice)  /* entry point */ -struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_ice1712_ews_cards[] = {  	{  		.subvendor = ICE1712_SUBDEVICE_EWX2496,  		.name = "TerraTec EWX24/96", diff --git a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c index 6914189073a..59e37c58169 100644 --- a/sound/pci/ice1712/hoontech.c +++ b/sound/pci/ice1712/hoontech.c @@ -21,7 +21,6 @@   *   */       -#include <asm/io.h>  #include <linux/delay.h>  #include <linux/interrupt.h>  #include <linux/init.h> @@ -40,7 +39,7 @@ struct hoontech_spec {  	unsigned short boxconfig[4];  }; -static void __devinit snd_ice1712_stdsp24_gpio_write(struct snd_ice1712 *ice, unsigned char byte) +static void snd_ice1712_stdsp24_gpio_write(struct snd_ice1712 *ice, unsigned char byte)  {  	byte |= ICE1712_STDSP24_CLOCK_BIT;  	udelay(100); @@ -53,7 +52,7 @@ static void __devinit snd_ice1712_stdsp24_gpio_write(struct snd_ice1712 *ice, un  	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);  } -static void __devinit snd_ice1712_stdsp24_darear(struct snd_ice1712 *ice, int activate) +static void snd_ice1712_stdsp24_darear(struct snd_ice1712 *ice, int activate)  {  	struct hoontech_spec *spec = ice->spec;  	mutex_lock(&ice->gpio_mutex); @@ -62,7 +61,7 @@ static void __devinit snd_ice1712_stdsp24_darear(struct snd_ice1712 *ice, int ac  	mutex_unlock(&ice->gpio_mutex);  } -static void __devinit snd_ice1712_stdsp24_mute(struct snd_ice1712 *ice, int activate) +static void snd_ice1712_stdsp24_mute(struct snd_ice1712 *ice, int activate)  {  	struct hoontech_spec *spec = ice->spec;  	mutex_lock(&ice->gpio_mutex); @@ -71,7 +70,7 @@ static void __devinit snd_ice1712_stdsp24_mute(struct snd_ice1712 *ice, int acti  	mutex_unlock(&ice->gpio_mutex);  } -static void __devinit snd_ice1712_stdsp24_insel(struct snd_ice1712 *ice, int activate) +static void snd_ice1712_stdsp24_insel(struct snd_ice1712 *ice, int activate)  {  	struct hoontech_spec *spec = ice->spec;  	mutex_lock(&ice->gpio_mutex); @@ -80,7 +79,7 @@ static void __devinit snd_ice1712_stdsp24_insel(struct snd_ice1712 *ice, int act  	mutex_unlock(&ice->gpio_mutex);  } -static void __devinit snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, int box, int chn, int activate) +static void snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, int box, int chn, int activate)  {  	struct hoontech_spec *spec = ice->spec; @@ -130,7 +129,7 @@ static void __devinit snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, i  	mutex_unlock(&ice->gpio_mutex);  } -static void __devinit snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int box, int master) +static void snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int box, int master)  {  	struct hoontech_spec *spec = ice->spec; @@ -158,7 +157,7 @@ static void __devinit snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int  	mutex_unlock(&ice->gpio_mutex);  } -static void __devinit snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int activate) +static void snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int activate)  {  	struct hoontech_spec *spec = ice->spec;  	mutex_lock(&ice->gpio_mutex); @@ -167,7 +166,7 @@ static void __devinit snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int act  	mutex_unlock(&ice->gpio_mutex);  } -static int __devinit snd_ice1712_hoontech_init(struct snd_ice1712 *ice) +static int snd_ice1712_hoontech_init(struct snd_ice1712 *ice)  {  	struct hoontech_spec *spec;  	int box, chn; @@ -267,10 +266,10 @@ static void stdsp24_ak4524_lock(struct snd_akm4xxx *ak, int chip)  	snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);  } -static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice) +static int snd_ice1712_value_init(struct snd_ice1712 *ice)  {  	/* Hoontech STDSP24 with modified hardware */ -	static struct snd_akm4xxx akm_stdsp24_mv __devinitdata = { +	static struct snd_akm4xxx akm_stdsp24_mv = {  		.num_adcs = 2,  		.num_dacs = 2,  		.type = SND_AK4524, @@ -279,7 +278,7 @@ static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice)  		}  	}; -	static struct snd_ak4xxx_private akm_stdsp24_mv_priv __devinitdata = { +	static struct snd_ak4xxx_private akm_stdsp24_mv_priv = {  		.caddr = 2,  		.cif = 1, /* CIF high */  		.data_mask = ICE1712_STDSP24_SERIAL_DATA, @@ -317,7 +316,7 @@ static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice)  	return 0;  } -static int __devinit snd_ice1712_ez8_init(struct snd_ice1712 *ice) +static int snd_ice1712_ez8_init(struct snd_ice1712 *ice)  {  	ice->gpio.write_mask = ice->eeprom.gpiomask;  	ice->gpio.direction = ice->eeprom.gpiodir; @@ -329,7 +328,7 @@ static int __devinit snd_ice1712_ez8_init(struct snd_ice1712 *ice)  /* entry point */ -struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] = {  	{  		.subvendor = ICE1712_SUBDEVICE_STDSP24,  		.name = "Hoontech SoundTrack Audio DSP24", diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 4fc6d8bc637..d9b9e4595f1 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -47,14 +47,13 @@   */ -#include <linux/io.h>  #include <linux/delay.h>  #include <linux/interrupt.h>  #include <linux/init.h>  #include <linux/pci.h>  #include <linux/dma-mapping.h>  #include <linux/slab.h> -#include <linux/moduleparam.h> +#include <linux/module.h>  #include <linux/mutex.h>  #include <sound/core.h> @@ -84,10 +83,10 @@ MODULE_SUPPORTED_DEVICE("{"  static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */  static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */  static char *model[SNDRV_CARDS]; -static int omni[SNDRV_CARDS];				/* Delta44 & 66 Omni I/O support */ -static int cs8427_timeout[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 500}; /* CS8427 S/PDIF transciever reset timeout value in msec */ +static bool omni[SNDRV_CARDS];				/* Delta44 & 66 Omni I/O support */ +static int cs8427_timeout[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 500}; /* CS8427 S/PDIF transceiver reset timeout value in msec */  static int dxr_enable[SNDRV_CARDS];			/* DXR enable for DMX6FIRE */  module_param_array(index, int, NULL, 0444); @@ -280,7 +279,7 @@ static int snd_ice1712_digmix_route_ac97_put(struct snd_kcontrol *kcontrol, stru  	return val != nval;  } -static struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 = {  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.name = "Digital Mixer To AC97",  	.info = snd_ice1712_digmix_route_ac97_info, @@ -388,14 +387,14 @@ static void setup_cs8427(struct snd_ice1712 *ice, int rate)  /*   * create and initialize callbacks for cs8427 interface   */ -int __devinit snd_ice1712_init_cs8427(struct snd_ice1712 *ice, int addr) +int snd_ice1712_init_cs8427(struct snd_ice1712 *ice, int addr)  {  	int err;  	err = snd_cs8427_create(ice->i2c, addr,  		(ice->cs8427_timeout * HZ) / 1000, &ice->cs8427);  	if (err < 0) { -		snd_printk(KERN_ERR "CS8427 initialization failed\n"); +		dev_err(ice->card->dev, "CS8427 initialization failed\n");  		return err;  	}  	ice->spdif.ops.open = open_cs8427; @@ -468,7 +467,7 @@ static irqreturn_t snd_ice1712_interrupt(int irq, void *dev_id)  			u16 pbkstatus;  			struct snd_pcm_substream *substream;  			pbkstatus = inw(ICEDS(ice, INTSTAT)); -			/* printk(KERN_DEBUG "pbkstatus = 0x%x\n", pbkstatus); */ +			/* dev_dbg(ice->card->dev, "pbkstatus = 0x%x\n", pbkstatus); */  			for (idx = 0; idx < 6; idx++) {  				if ((pbkstatus & (3 << (idx * 2))) == 0)  					continue; @@ -686,9 +685,10 @@ static snd_pcm_uframes_t snd_ice1712_playback_pointer(struct snd_pcm_substream *  	if (!(snd_ice1712_read(ice, ICE1712_IREG_PBK_CTRL) & 1))  		return 0;  	ptr = runtime->buffer_size - inw(ice->ddma_port + 4); +	ptr = bytes_to_frames(substream->runtime, ptr);  	if (ptr == runtime->buffer_size)  		ptr = 0; -	return bytes_to_frames(substream->runtime, ptr); +	return ptr;  }  static snd_pcm_uframes_t snd_ice1712_playback_ds_pointer(struct snd_pcm_substream *substream) @@ -705,9 +705,10 @@ static snd_pcm_uframes_t snd_ice1712_playback_ds_pointer(struct snd_pcm_substrea  		addr = ICE1712_DSC_ADDR0;  	ptr = snd_ice1712_ds_read(ice, substream->number * 2, addr) -  		ice->playback_con_virt_addr[substream->number]; +	ptr = bytes_to_frames(substream->runtime, ptr);  	if (ptr == substream->runtime->buffer_size)  		ptr = 0; -	return bytes_to_frames(substream->runtime, ptr); +	return ptr;  }  static snd_pcm_uframes_t snd_ice1712_capture_pointer(struct snd_pcm_substream *substream) @@ -718,9 +719,10 @@ static snd_pcm_uframes_t snd_ice1712_capture_pointer(struct snd_pcm_substream *s  	if (!(snd_ice1712_read(ice, ICE1712_IREG_CAP_CTRL) & 1))  		return 0;  	ptr = inl(ICEREG(ice, CONCAP_ADDR)) - ice->capture_con_virt_addr; +	ptr = bytes_to_frames(substream->runtime, ptr);  	if (ptr == substream->runtime->buffer_size)  		ptr = 0; -	return bytes_to_frames(substream->runtime, ptr); +	return ptr;  }  static const struct snd_pcm_hardware snd_ice1712_playback = { @@ -879,7 +881,7 @@ static struct snd_pcm_ops snd_ice1712_capture_ops = {  	.pointer =	snd_ice1712_capture_pointer,  }; -static int __devinit snd_ice1712_pcm(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm) +static int snd_ice1712_pcm(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm)  {  	struct snd_pcm *pcm;  	int err; @@ -904,12 +906,13 @@ static int __devinit snd_ice1712_pcm(struct snd_ice1712 *ice, int device, struct  	if (rpcm)  		*rpcm = pcm; -	printk(KERN_WARNING "Consumer PCM code does not work well at the moment --jk\n"); +	dev_warn(ice->card->dev, +		 "Consumer PCM code does not work well at the moment --jk\n");  	return 0;  } -static int __devinit snd_ice1712_pcm_ds(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm) +static int snd_ice1712_pcm_ds(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm)  {  	struct snd_pcm *pcm;  	int err; @@ -1048,6 +1051,8 @@ __out:  	old = inb(ICEMT(ice, RATE));  	if (!force && old == val)  		goto __out; + +	ice->cur_rate = rate;  	outb(val, ICEMT(ice, RATE));  	spin_unlock_irqrestore(&ice->reg_lock, flags); @@ -1114,9 +1119,10 @@ static snd_pcm_uframes_t snd_ice1712_playback_pro_pointer(struct snd_pcm_substre  	if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_PLAYBACK_START))  		return 0;  	ptr = ice->playback_pro_size - (inw(ICEMT(ice, PLAYBACK_SIZE)) << 2); +	ptr = bytes_to_frames(substream->runtime, ptr);  	if (ptr == substream->runtime->buffer_size)  		ptr = 0; -	return bytes_to_frames(substream->runtime, ptr); +	return ptr;  }  static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(struct snd_pcm_substream *substream) @@ -1127,9 +1133,10 @@ static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(struct snd_pcm_substrea  	if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_CAPTURE_START_SHADOW))  		return 0;  	ptr = ice->capture_pro_size - (inw(ICEMT(ice, CAPTURE_SIZE)) << 2); +	ptr = bytes_to_frames(substream->runtime, ptr);  	if (ptr == substream->runtime->buffer_size)  		ptr = 0; -	return bytes_to_frames(substream->runtime, ptr); +	return ptr;  }  static const struct snd_pcm_hardware snd_ice1712_playback_pro = { @@ -1254,7 +1261,7 @@ static struct snd_pcm_ops snd_ice1712_capture_pro_ops = {  	.pointer =	snd_ice1712_capture_pro_pointer,  }; -static int __devinit snd_ice1712_pcm_profi(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm) +static int snd_ice1712_pcm_profi(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm)  {  	struct snd_pcm *pcm;  	int err; @@ -1388,7 +1395,7 @@ static int snd_ice1712_pro_mixer_volume_put(struct snd_kcontrol *kcontrol, struc  static const DECLARE_TLV_DB_SCALE(db_scale_playback, -14400, 150, 0); -static struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] = {  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "Multi Playback Switch", @@ -1412,7 +1419,7 @@ static struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devinitdata  	},  }; -static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch = {  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.name = "H/W Multi Capture Switch",  	.info = snd_ice1712_pro_mixer_switch_info, @@ -1421,7 +1428,7 @@ static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinit  	.private_value = 10,  }; -static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch = {  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, SWITCH),  	.info = snd_ice1712_pro_mixer_switch_info, @@ -1431,7 +1438,7 @@ static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitd  	.count = 2,  }; -static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume = {  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |  		   SNDRV_CTL_ELEM_ACCESS_TLV_READ), @@ -1443,7 +1450,7 @@ static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinit  	.tlv = { .p = db_scale_playback }  }; -static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume = {  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, VOLUME),  	.info = snd_ice1712_pro_mixer_volume_info, @@ -1453,7 +1460,7 @@ static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitd  	.count = 2,  }; -static int __devinit snd_ice1712_build_pro_mixer(struct snd_ice1712 *ice) +static int snd_ice1712_build_pro_mixer(struct snd_ice1712 *ice)  {  	struct snd_card *card = ice->card;  	unsigned int idx; @@ -1512,7 +1519,7 @@ static void snd_ice1712_mixer_free_ac97(struct snd_ac97 *ac97)  	ice->ac97 = NULL;  } -static int __devinit snd_ice1712_ac97_mixer(struct snd_ice1712 *ice) +static int snd_ice1712_ac97_mixer(struct snd_ice1712 *ice)  {  	int err, bus_num = 0;  	struct snd_ac97_template ac97; @@ -1535,7 +1542,8 @@ static int __devinit snd_ice1712_ac97_mixer(struct snd_ice1712 *ice)  		ac97.private_free = snd_ice1712_mixer_free_ac97;  		err = snd_ac97_mixer(pbus, &ac97, &ice->ac97);  		if (err < 0) -			printk(KERN_WARNING "ice1712: cannot initialize ac97 for consumer, skipped\n"); +			dev_warn(ice->card->dev, +				 "cannot initialize ac97 for consumer, skipped\n");  		else {  			err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_digmix_route_ac97, ice));  			if (err < 0) @@ -1553,7 +1561,8 @@ static int __devinit snd_ice1712_ac97_mixer(struct snd_ice1712 *ice)  		ac97.private_free = snd_ice1712_mixer_free_ac97;  		err = snd_ac97_mixer(pbus, &ac97, &ice->ac97);  		if (err < 0) -			printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n"); +			dev_warn(ice->card->dev, +				 "cannot initialize pro ac97, skipped\n");  		else  			return 0;  	} @@ -1611,7 +1620,7 @@ static void snd_ice1712_proc_read(struct snd_info_entry *entry,  	snd_iprintf(buffer, "  GPIO_DIRECTION   : 0x%02x\n", (unsigned)snd_ice1712_read(ice, ICE1712_IREG_GPIO_DIRECTION));  } -static void __devinit snd_ice1712_proc_init(struct snd_ice1712 *ice) +static void snd_ice1712_proc_init(struct snd_ice1712 *ice)  {  	struct snd_info_entry *entry; @@ -1640,7 +1649,7 @@ static int snd_ice1712_eeprom_get(struct snd_kcontrol *kcontrol,  	return 0;  } -static struct snd_kcontrol_new snd_ice1712_eeprom __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_eeprom = {  	.iface = SNDRV_CTL_ELEM_IFACE_CARD,  	.name = "ICE1712 EEPROM",  	.access = SNDRV_CTL_ELEM_ACCESS_READ, @@ -1676,7 +1685,7 @@ static int snd_ice1712_spdif_default_put(struct snd_kcontrol *kcontrol,  	return 0;  } -static struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata = +static struct snd_kcontrol_new snd_ice1712_spdif_default =  {  	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,  	.name =         SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), @@ -1727,7 +1736,7 @@ static int snd_ice1712_spdif_maskp_get(struct snd_kcontrol *kcontrol,  	return 0;  } -static struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata = +static struct snd_kcontrol_new snd_ice1712_spdif_maskc =  {  	.access =	SNDRV_CTL_ELEM_ACCESS_READ,  	.iface =	SNDRV_CTL_ELEM_IFACE_PCM, @@ -1736,7 +1745,7 @@ static struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata =  	.get =		snd_ice1712_spdif_maskc_get,  }; -static struct snd_kcontrol_new snd_ice1712_spdif_maskp __devinitdata = +static struct snd_kcontrol_new snd_ice1712_spdif_maskp =  {  	.access =	SNDRV_CTL_ELEM_ACCESS_READ,  	.iface =	SNDRV_CTL_ELEM_IFACE_PCM, @@ -1763,7 +1772,7 @@ static int snd_ice1712_spdif_stream_put(struct snd_kcontrol *kcontrol,  	return 0;  } -static struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata = +static struct snd_kcontrol_new snd_ice1712_spdif_stream =  {  	.access =	(SNDRV_CTL_ELEM_ACCESS_READWRITE |  			 SNDRV_CTL_ELEM_ACCESS_INACTIVE), @@ -1894,7 +1903,7 @@ static int snd_ice1712_pro_internal_clock_put(struct snd_kcontrol *kcontrol,  	return change;  } -static struct snd_kcontrol_new snd_ice1712_pro_internal_clock __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_pro_internal_clock = {  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.name = "Multi Track Internal Clock",  	.info = snd_ice1712_pro_internal_clock_info, @@ -1965,7 +1974,7 @@ static int snd_ice1712_pro_internal_clock_default_put(struct snd_kcontrol *kcont  	return change;  } -static struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default = {  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.name = "Multi Track Internal Clock Default",  	.info = snd_ice1712_pro_internal_clock_default_info, @@ -1996,7 +2005,7 @@ static int snd_ice1712_pro_rate_locking_put(struct snd_kcontrol *kcontrol,  	return change;  } -static struct snd_kcontrol_new snd_ice1712_pro_rate_locking __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_pro_rate_locking = {  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.name = "Multi Track Rate Locking",  	.info = snd_ice1712_pro_rate_locking_info, @@ -2027,7 +2036,7 @@ static int snd_ice1712_pro_rate_reset_put(struct snd_kcontrol *kcontrol,  	return change;  } -static struct snd_kcontrol_new snd_ice1712_pro_rate_reset __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_pro_rate_reset = {  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.name = "Multi Track Rate Reset",  	.info = snd_ice1712_pro_rate_reset_info, @@ -2194,7 +2203,7 @@ static int snd_ice1712_pro_route_spdif_put(struct snd_kcontrol *kcontrol,  	return change;  } -static struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route = {  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.name = "H/W Playback Route",  	.info = snd_ice1712_pro_route_info, @@ -2202,7 +2211,7 @@ static struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata  	.put = snd_ice1712_pro_route_analog_put,  }; -static struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route = {  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route",  	.info = snd_ice1712_pro_route_info, @@ -2244,7 +2253,7 @@ static int snd_ice1712_pro_volume_rate_put(struct snd_kcontrol *kcontrol,  	return change;  } -static struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate = {  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.name = "Multi Track Volume Rate",  	.info = snd_ice1712_pro_volume_rate_info, @@ -2277,7 +2286,7 @@ static int snd_ice1712_pro_peak_get(struct snd_kcontrol *kcontrol,  	return 0;  } -static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak = {  	.iface = SNDRV_CTL_ELEM_IFACE_PCM,  	.name = "Multi Track Peak",  	.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, @@ -2292,16 +2301,16 @@ static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = {  /*   * list of available boards   */ -static struct snd_ice1712_card_info *card_tables[] __devinitdata = { +static struct snd_ice1712_card_info *card_tables[] = {  	snd_ice1712_hoontech_cards,  	snd_ice1712_delta_cards,  	snd_ice1712_ews_cards,  	NULL,  }; -static unsigned char __devinit snd_ice1712_read_i2c(struct snd_ice1712 *ice, -						 unsigned char dev, -						 unsigned char addr) +static unsigned char snd_ice1712_read_i2c(struct snd_ice1712 *ice, +					  unsigned char dev, +					  unsigned char addr)  {  	long t = 0x10000; @@ -2311,8 +2320,8 @@ static unsigned char __devinit snd_ice1712_read_i2c(struct snd_ice1712 *ice,  	return inb(ICEREG(ice, I2C_DATA));  } -static int __devinit snd_ice1712_read_eeprom(struct snd_ice1712 *ice, -					     const char *modelname) +static int snd_ice1712_read_eeprom(struct snd_ice1712 *ice, +				   const char *modelname)  {  	int dev = 0xa0;		/* EEPROM device address */  	unsigned int i, size; @@ -2333,7 +2342,8 @@ static int __devinit snd_ice1712_read_eeprom(struct snd_ice1712 *ice,  			pci_read_config_word(ice->pci, PCI_SUBSYSTEM_ID, &device);  			ice->eeprom.subvendor = ((unsigned int)swab16(vendor) << 16) | swab16(device);  			if (ice->eeprom.subvendor == 0 || ice->eeprom.subvendor == (unsigned int)-1) { -				printk(KERN_ERR "ice1712: No valid ID is found\n"); +				dev_err(ice->card->dev, +					"No valid ID is found\n");  				return -ENXIO;  			}  		} @@ -2341,21 +2351,22 @@ static int __devinit snd_ice1712_read_eeprom(struct snd_ice1712 *ice,  	for (tbl = card_tables; *tbl; tbl++) {  		for (c = *tbl; c->subvendor; c++) {  			if (modelname && c->model && !strcmp(modelname, c->model)) { -				printk(KERN_INFO "ice1712: Using board model %s\n", c->name); +				dev_info(ice->card->dev, +					 "Using board model %s\n", c->name);  				ice->eeprom.subvendor = c->subvendor;  			} else if (c->subvendor != ice->eeprom.subvendor)  				continue;  			if (!c->eeprom_size || !c->eeprom_data)  				goto found;  			/* if the EEPROM is given by the driver, use it */ -			snd_printdd("using the defined eeprom..\n"); +			dev_dbg(ice->card->dev, "using the defined eeprom..\n");  			ice->eeprom.version = 1;  			ice->eeprom.size = c->eeprom_size + 6;  			memcpy(ice->eeprom.data, c->eeprom_data, c->eeprom_size);  			goto read_skipped;  		}  	} -	printk(KERN_WARNING "ice1712: No matching model found for ID 0x%x\n", +	dev_warn(ice->card->dev, "No matching model found for ID 0x%x\n",  	       ice->eeprom.subvendor);   found: @@ -2363,12 +2374,13 @@ static int __devinit snd_ice1712_read_eeprom(struct snd_ice1712 *ice,  	if (ice->eeprom.size < 6)  		ice->eeprom.size = 32; /* FIXME: any cards without the correct size? */  	else if (ice->eeprom.size > 32) { -		snd_printk(KERN_ERR "invalid EEPROM (size = %i)\n", ice->eeprom.size); +		dev_err(ice->card->dev, +			"invalid EEPROM (size = %i)\n", ice->eeprom.size);  		return -EIO;  	}  	ice->eeprom.version = snd_ice1712_read_i2c(ice, dev, 0x05);  	if (ice->eeprom.version != 1) { -		snd_printk(KERN_ERR "invalid EEPROM version %i\n", +		dev_err(ice->card->dev, "invalid EEPROM version %i\n",  			   ice->eeprom.version);  		/* return -EIO; */  	} @@ -2386,7 +2398,7 @@ static int __devinit snd_ice1712_read_eeprom(struct snd_ice1712 *ice, -static int __devinit snd_ice1712_chip_init(struct snd_ice1712 *ice) +static int snd_ice1712_chip_init(struct snd_ice1712 *ice)  {  	outb(ICE1712_RESET | ICE1712_NATIVE, ICEREG(ice, CONTROL));  	udelay(200); @@ -2429,11 +2441,18 @@ static int __devinit snd_ice1712_chip_init(struct snd_ice1712 *ice)  		snd_ice1712_write(ice, ICE1712_IREG_CONSUMER_POWERDOWN, 0);  	}  	snd_ice1712_set_pro_rate(ice, 48000, 1); +	/* unmask used interrupts */ +	outb(((ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401) == 0 ? +	      ICE1712_IRQ_MPU2 : 0) | +	     ((ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97) ? +	      ICE1712_IRQ_PBKDS | ICE1712_IRQ_CONCAP | ICE1712_IRQ_CONPBK : 0), +	     ICEREG(ice, IRQMASK)); +	outb(0x00, ICEMT(ice, IRQ));  	return 0;  } -int __devinit snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice) +int snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice)  {  	int err;  	struct snd_kcontrol *kctl; @@ -2461,7 +2480,7 @@ int __devinit snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice)  } -static int __devinit snd_ice1712_build_controls(struct snd_ice1712 *ice) +static int snd_ice1712_build_controls(struct snd_ice1712 *ice)  {  	int err; @@ -2531,13 +2550,13 @@ static int snd_ice1712_dev_free(struct snd_device *device)  	return snd_ice1712_free(ice);  } -static int __devinit snd_ice1712_create(struct snd_card *card, -					struct pci_dev *pci, -					const char *modelname, -					int omni, -					int cs8427_timeout, -					int dxr_enable, -					struct snd_ice1712 **r_ice1712) +static int snd_ice1712_create(struct snd_card *card, +			      struct pci_dev *pci, +			      const char *modelname, +			      int omni, +			      int cs8427_timeout, +			      int dxr_enable, +			      struct snd_ice1712 **r_ice1712)  {  	struct snd_ice1712 *ice;  	int err; @@ -2554,7 +2573,8 @@ static int __devinit snd_ice1712_create(struct snd_card *card,  	/* check, if we can restrict PCI DMA transfers to 28 bits */  	if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 ||  	    pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) { -		snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n"); +		dev_err(card->dev, +			"architecture does not support 28bit PCI busmaster DMA\n");  		pci_disable_device(pci);  		return -ENXIO;  	} @@ -2590,11 +2610,14 @@ static int __devinit snd_ice1712_create(struct snd_card *card,  	ice->pci = pci;  	ice->irq = -1;  	pci_set_master(pci); +	/* disable legacy emulation */  	pci_write_config_word(ice->pci, 0x40, 0x807f);  	pci_write_config_word(ice->pci, 0x42, 0x0006);  	snd_ice1712_proc_init(ice);  	synchronize_irq(pci->irq); +	card->private_data = ice; +  	err = pci_request_regions(pci, "ICE1712");  	if (err < 0) {  		kfree(ice); @@ -2607,8 +2630,8 @@ static int __devinit snd_ice1712_create(struct snd_card *card,  	ice->profi_port = pci_resource_start(pci, 3);  	if (request_irq(pci->irq, snd_ice1712_interrupt, IRQF_SHARED, -			"ICE1712", ice)) { -		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); +			KBUILD_MODNAME, ice)) { +		dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);  		snd_ice1712_free(ice);  		return -EIO;  	} @@ -2624,22 +2647,12 @@ static int __devinit snd_ice1712_create(struct snd_card *card,  		return -EIO;  	} -	/* unmask used interrupts */ -	outb(((ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401) == 0 ? -	      ICE1712_IRQ_MPU2 : 0) | -	     ((ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97) ? -	      ICE1712_IRQ_PBKDS | ICE1712_IRQ_CONCAP | ICE1712_IRQ_CONPBK : 0), -	     ICEREG(ice, IRQMASK)); -	outb(0x00, ICEMT(ice, IRQ)); -  	err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops);  	if (err < 0) {  		snd_ice1712_free(ice);  		return err;  	} -	snd_card_set_dev(card, &pci->dev); -  	*r_ice1712 = ice;  	return 0;  } @@ -2651,10 +2664,10 @@ static int __devinit snd_ice1712_create(struct snd_card *card,   *   */ -static struct snd_ice1712_card_info no_matched __devinitdata; +static struct snd_ice1712_card_info no_matched; -static int __devinit snd_ice1712_probe(struct pci_dev *pci, -				       const struct pci_device_id *pci_id) +static int snd_ice1712_probe(struct pci_dev *pci, +			     const struct pci_device_id *pci_id)  {  	static int dev;  	struct snd_card *card; @@ -2669,7 +2682,8 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,  		return -ENOENT;  	} -	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); +	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, +			   0, &card);  	if (err < 0)  		return err; @@ -2686,6 +2700,7 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,  	for (tbl = card_tables; *tbl; tbl++) {  		for (c = *tbl; c->subvendor; c++) {  			if (c->subvendor == ice->eeprom.subvendor) { +				ice->card_info = c;  				strcpy(card->shortname, c->name);  				if (c->driver) /* specific driver? */  					strcpy(card->driver, c->driver); @@ -2748,14 +2763,15 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,  	if (!c->no_mpu401) {  		err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712,  			ICEREG(ice, MPU1_CTRL), -			(c->mpu401_1_info_flags | MPU401_INFO_INTEGRATED), -			ice->irq, 0, &ice->rmidi[0]); +			c->mpu401_1_info_flags | +			MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK, +			-1, &ice->rmidi[0]);  		if (err < 0) {  			snd_card_free(card);  			return err;  		}  		if (c->mpu401_1_name) -			/*  Prefered name available in card_info */ +			/*  Preferred name available in card_info */  			snprintf(ice->rmidi[0]->name,  				 sizeof(ice->rmidi[0]->name),  				 "%s %d", c->mpu401_1_name, card->number); @@ -2764,15 +2780,16 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,  			/*  2nd port used  */  			err = snd_mpu401_uart_new(card, 1, MPU401_HW_ICE1712,  				ICEREG(ice, MPU2_CTRL), -				(c->mpu401_2_info_flags | MPU401_INFO_INTEGRATED), -				ice->irq, 0, &ice->rmidi[1]); +				c->mpu401_2_info_flags | +				MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK, +				-1, &ice->rmidi[1]);  			if (err < 0) {  				snd_card_free(card);  				return err;  			}  			if (c->mpu401_2_name) -				/*  Prefered name available in card_info */ +				/*  Preferred name available in card_info */  				snprintf(ice->rmidi[1]->name,  					 sizeof(ice->rmidi[1]->name),  					 "%s %d", c->mpu401_2_name, @@ -2795,28 +2812,120 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,  	return 0;  } -static void __devexit snd_ice1712_remove(struct pci_dev *pci) +static void snd_ice1712_remove(struct pci_dev *pci)  { -	snd_card_free(pci_get_drvdata(pci)); -	pci_set_drvdata(pci, NULL); -} +	struct snd_card *card = pci_get_drvdata(pci); +	struct snd_ice1712 *ice = card->private_data; -static struct pci_driver driver = { -	.name = "ICE1712", -	.id_table = snd_ice1712_ids, -	.probe = snd_ice1712_probe, -	.remove = __devexit_p(snd_ice1712_remove), -}; +	if (ice->card_info && ice->card_info->chip_exit) +		ice->card_info->chip_exit(ice); +	snd_card_free(card); +} -static int __init alsa_card_ice1712_init(void) +#ifdef CONFIG_PM_SLEEP +static int snd_ice1712_suspend(struct device *dev)  { -	return pci_register_driver(&driver); +	struct pci_dev *pci = to_pci_dev(dev); +	struct snd_card *card = dev_get_drvdata(dev); +	struct snd_ice1712 *ice = card->private_data; + +	if (!ice->pm_suspend_enabled) +		return 0; + +	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + +	snd_pcm_suspend_all(ice->pcm); +	snd_pcm_suspend_all(ice->pcm_pro); +	snd_pcm_suspend_all(ice->pcm_ds); +	snd_ac97_suspend(ice->ac97); + +	spin_lock_irq(&ice->reg_lock); +	ice->pm_saved_is_spdif_master = is_spdif_master(ice); +	ice->pm_saved_spdif_ctrl = inw(ICEMT(ice, ROUTE_SPDOUT)); +	ice->pm_saved_route = inw(ICEMT(ice, ROUTE_PSDOUT03)); +	spin_unlock_irq(&ice->reg_lock); + +	if (ice->pm_suspend) +		ice->pm_suspend(ice); + +	pci_disable_device(pci); +	pci_save_state(pci); +	pci_set_power_state(pci, PCI_D3hot); +	return 0;  } -static void __exit alsa_card_ice1712_exit(void) +static int snd_ice1712_resume(struct device *dev)  { -	pci_unregister_driver(&driver); +	struct pci_dev *pci = to_pci_dev(dev); +	struct snd_card *card = dev_get_drvdata(dev); +	struct snd_ice1712 *ice = card->private_data; +	int rate; + +	if (!ice->pm_suspend_enabled) +		return 0; + +	pci_set_power_state(pci, PCI_D0); +	pci_restore_state(pci); + +	if (pci_enable_device(pci) < 0) { +		snd_card_disconnect(card); +		return -EIO; +	} + +	pci_set_master(pci); + +	if (ice->cur_rate) +		rate = ice->cur_rate; +	else +		rate = PRO_RATE_DEFAULT; + +	if (snd_ice1712_chip_init(ice) < 0) { +		snd_card_disconnect(card); +		return -EIO; +	} + +	ice->cur_rate = rate; + +	if (ice->pm_resume) +		ice->pm_resume(ice); + +	if (ice->pm_saved_is_spdif_master) { +		/* switching to external clock via SPDIF */ +		spin_lock_irq(&ice->reg_lock); +		outb(inb(ICEMT(ice, RATE)) | ICE1712_SPDIF_MASTER, +			ICEMT(ice, RATE)); +		spin_unlock_irq(&ice->reg_lock); +		snd_ice1712_set_input_clock_source(ice, 1); +	} else { +		/* internal on-card clock */ +		snd_ice1712_set_pro_rate(ice, rate, 1); +		snd_ice1712_set_input_clock_source(ice, 0); +	} + +	outw(ice->pm_saved_spdif_ctrl, ICEMT(ice, ROUTE_SPDOUT)); +	outw(ice->pm_saved_route, ICEMT(ice, ROUTE_PSDOUT03)); + +	if (ice->ac97) +		snd_ac97_resume(ice->ac97); + +	snd_power_change_state(card, SNDRV_CTL_POWER_D0); +	return 0;  } -module_init(alsa_card_ice1712_init) -module_exit(alsa_card_ice1712_exit) +static SIMPLE_DEV_PM_OPS(snd_ice1712_pm, snd_ice1712_suspend, snd_ice1712_resume); +#define SND_VT1712_PM_OPS	&snd_ice1712_pm +#else +#define SND_VT1712_PM_OPS	NULL +#endif /* CONFIG_PM_SLEEP */ + +static struct pci_driver ice1712_driver = { +	.name = KBUILD_MODNAME, +	.id_table = snd_ice1712_ids, +	.probe = snd_ice1712_probe, +	.remove = snd_ice1712_remove, +	.driver = { +		.pm = SND_VT1712_PM_OPS, +	}, +}; + +module_pci_driver(ice1712_driver); diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h index 0da778a69ef..b209fc30b33 100644 --- a/sound/pci/ice1712/ice1712.h +++ b/sound/pci/ice1712/ice1712.h @@ -22,6 +22,7 @@   *   */ +#include <linux/io.h>  #include <sound/control.h>  #include <sound/ac97_codec.h>  #include <sound/rawmidi.h> @@ -288,6 +289,7 @@ struct snd_ice1712_spdif {  	} ops;  }; +struct snd_ice1712_card_info;  struct snd_ice1712 {  	unsigned long conp_dma_size; @@ -324,6 +326,7 @@ struct snd_ice1712 {  	struct snd_info_entry *proc_entry;  	struct snd_ice1712_eeprom eeprom; +	struct snd_ice1712_card_info *card_info;  	unsigned int pro_volumes[20];  	unsigned int omni:1;		/* Delta Omni I/O */ @@ -381,10 +384,10 @@ struct snd_ice1712 {  	unsigned char (*set_mclk)(struct snd_ice1712 *ice, unsigned int rate);  	int (*set_spdif_clock)(struct snd_ice1712 *ice, int type);  	int (*get_spdif_master_type)(struct snd_ice1712 *ice); -	char **ext_clock_names; +	const char * const *ext_clock_names;  	int ext_clock_count;  	void (*pro_open)(struct snd_ice1712 *, struct snd_pcm_substream *); -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP  	int (*pm_suspend)(struct snd_ice1712 *);  	int (*pm_resume)(struct snd_ice1712 *);  	unsigned int pm_suspend_enabled:1; @@ -513,10 +516,11 @@ static inline u8 snd_ice1712_read(struct snd_ice1712 *ice, u8 addr)  struct snd_ice1712_card_info {  	unsigned int subvendor; -	char *name; -	char *model; -	char *driver; +	const char *name; +	const char *model; +	const char *driver;  	int (*chip_init)(struct snd_ice1712 *); +	void (*chip_exit)(struct snd_ice1712 *);  	int (*build_controls)(struct snd_ice1712 *);  	unsigned int no_mpu401:1;  	unsigned int mpu401_1_info_flags; diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index c1498fa5545..5e7948f3efe 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c @@ -22,13 +22,12 @@   *   */ -#include <linux/io.h>  #include <linux/delay.h>  #include <linux/interrupt.h>  #include <linux/init.h>  #include <linux/pci.h>  #include <linux/slab.h> -#include <linux/moduleparam.h> +#include <linux/module.h>  #include <linux/mutex.h>  #include <sound/core.h>  #include <sound/info.h> @@ -54,6 +53,7 @@  #include "wtm.h"  #include "se.h"  #include "quartet.h" +#include "psc724.h"  MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");  MODULE_DESCRIPTION("VIA ICEnsemble ICE1724/1720 (Envy24HT/PT)"); @@ -80,7 +80,7 @@ MODULE_SUPPORTED_DEVICE("{"  static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */  static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;		/* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;		/* Enable this card */  static char *model[SNDRV_CARDS];  module_param_array(index, int, NULL, 0444); @@ -106,7 +106,7 @@ static int PRO_RATE_LOCKED;  static int PRO_RATE_RESET = 1;  static unsigned int PRO_RATE_DEFAULT = 44100; -static char *ext_clock_names[1] = { "IEC958 In" }; +static const char * const ext_clock_names[1] = { "IEC958 In" };  /*   *  Basic I/O @@ -146,7 +146,7 @@ static unsigned char snd_vt1724_ac97_ready(struct snd_ice1712 *ice)  			continue;  		return old_cmd;  	} -	snd_printd(KERN_ERR "snd_vt1724_ac97_ready: timeout\n"); +	dev_dbg(ice->card->dev, "snd_vt1724_ac97_ready: timeout\n");  	return old_cmd;  } @@ -156,7 +156,7 @@ static int snd_vt1724_ac97_wait_bit(struct snd_ice1712 *ice, unsigned char bit)  	for (tm = 0; tm < 0x10000; tm++)  		if ((inb(ICEMT1724(ice, AC97_CMD)) & bit) == 0)  			return 0; -	snd_printd(KERN_ERR "snd_vt1724_ac97_wait_bit: timeout\n"); +	dev_dbg(ice->card->dev, "snd_vt1724_ac97_wait_bit: timeout\n");  	return -EIO;  } @@ -430,10 +430,10 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id)  		spin_lock(&ice->reg_lock);  		if (++timeout > 10) {  			status = inb(ICEREG1724(ice, IRQSTAT)); -			printk(KERN_ERR "ice1724: Too long irq loop, " -			       "status = 0x%x\n", status); +			dev_err(ice->card->dev, +				"Too long irq loop, status = 0x%x\n", status);  			if (status & VT1724_IRQ_MPU_TX) { -				printk(KERN_ERR "ice1724: Disabling MPU_TX\n"); +				dev_err(ice->card->dev, "Disabling MPU_TX\n");  				enable_midi_irq(ice, VT1724_IRQ_MPU_TX, 0);  			}  			spin_unlock(&ice->reg_lock); @@ -801,7 +801,7 @@ static int snd_vt1724_playback_pro_prepare(struct snd_pcm_substream *substream)  	spin_unlock_irq(&ice->reg_lock);  	/* -	printk(KERN_DEBUG "pro prepare: ch = %d, addr = 0x%x, " +	dev_dbg(ice->card->dev, "pro prepare: ch = %d, addr = 0x%x, "  	       "buffer = 0x%x, period = 0x%x\n",  	       substream->runtime->channels,  	       (unsigned int)substream->runtime->dma_addr, @@ -821,13 +821,13 @@ static snd_pcm_uframes_t snd_vt1724_playback_pro_pointer(struct snd_pcm_substrea  #if 0 /* read PLAYBACK_ADDR */  	ptr = inl(ICEMT1724(ice, PLAYBACK_ADDR));  	if (ptr < substream->runtime->dma_addr) { -		snd_printd("ice1724: invalid negative ptr\n"); +		dev_dbg(ice->card->dev, "invalid negative ptr\n");  		return 0;  	}  	ptr -= substream->runtime->dma_addr;  	ptr = bytes_to_frames(substream->runtime, ptr);  	if (ptr >= substream->runtime->buffer_size) { -		snd_printd("ice1724: invalid ptr %d (size=%d)\n", +		dev_dbg(ice->card->dev, "invalid ptr %d (size=%d)\n",  			   (int)ptr, (int)substream->runtime->period_size);  		return 0;  	} @@ -840,7 +840,7 @@ static snd_pcm_uframes_t snd_vt1724_playback_pro_pointer(struct snd_pcm_substrea  	else if (ptr <= substream->runtime->buffer_size)  		ptr = substream->runtime->buffer_size - ptr;  	else { -		snd_printd("ice1724: invalid ptr %d (size=%d)\n", +		dev_dbg(ice->card->dev, "invalid ptr %d (size=%d)\n",  			   (int)ptr, (int)substream->runtime->buffer_size);  		ptr = 0;  	} @@ -884,7 +884,7 @@ static snd_pcm_uframes_t snd_vt1724_pcm_pointer(struct snd_pcm_substream *substr  	else if (ptr <= substream->runtime->buffer_size)  		ptr = substream->runtime->buffer_size - ptr;  	else { -		snd_printd("ice1724: invalid ptr %d (size=%d)\n", +		dev_dbg(ice->card->dev, "invalid ptr %d (size=%d)\n",  			   (int)ptr, (int)substream->runtime->buffer_size);  		ptr = 0;  	} @@ -1013,6 +1013,25 @@ static int set_rate_constraints(struct snd_ice1712 *ice,  					  ice->hw_rates);  } +/* if the card has the internal rate locked (is_pro_locked), limit runtime +   hw rates to the current internal rate only. +*/ +static void constrain_rate_if_locked(struct snd_pcm_substream *substream) +{ +	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); +	struct snd_pcm_runtime *runtime = substream->runtime; +	unsigned int rate; +	if (is_pro_rate_locked(ice)) { +		rate = ice->get_rate(ice); +		if (rate >= runtime->hw.rate_min +		    && rate <= runtime->hw.rate_max) { +			runtime->hw.rate_min = rate; +			runtime->hw.rate_max = rate; +		} +	} +} + +  /* multi-channel playback needs alignment 8x32bit regardless of the channels   * actually used   */ @@ -1046,6 +1065,7 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream)  				   VT1724_BUFFER_ALIGN);  	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,  				   VT1724_BUFFER_ALIGN); +	constrain_rate_if_locked(substream);  	if (ice->pro_open)  		ice->pro_open(ice, substream);  	return 0; @@ -1066,6 +1086,7 @@ static int snd_vt1724_capture_pro_open(struct snd_pcm_substream *substream)  				   VT1724_BUFFER_ALIGN);  	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,  				   VT1724_BUFFER_ALIGN); +	constrain_rate_if_locked(substream);  	if (ice->pro_open)  		ice->pro_open(ice, substream);  	return 0; @@ -1114,17 +1135,24 @@ static struct snd_pcm_ops snd_vt1724_capture_pro_ops = {  	.pointer =	snd_vt1724_pcm_pointer,  }; -static int __devinit snd_vt1724_pcm_profi(struct snd_ice1712 *ice, int device) +static int snd_vt1724_pcm_profi(struct snd_ice1712 *ice, int device)  {  	struct snd_pcm *pcm; -	int err; +	int capt, err; -	err = snd_pcm_new(ice->card, "ICE1724", device, 1, 1, &pcm); +	if ((ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_ADC_MASK) == +	    VT1724_CFG_ADC_NONE) +		capt = 0; +	else +		capt = 1; +	err = snd_pcm_new(ice->card, "ICE1724", device, 1, capt, &pcm);  	if (err < 0)  		return err;  	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_vt1724_playback_pro_ops); -	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_vt1724_capture_pro_ops); +	if (capt) +		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, +			&snd_vt1724_capture_pro_ops);  	pcm->private_data = ice;  	pcm->info_flags = 0; @@ -1208,6 +1236,7 @@ static int snd_vt1724_playback_spdif_open(struct snd_pcm_substream *substream)  				   VT1724_BUFFER_ALIGN);  	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,  				   VT1724_BUFFER_ALIGN); +	constrain_rate_if_locked(substream);  	if (ice->spdif.ops.open)  		ice->spdif.ops.open(ice, substream);  	return 0; @@ -1244,6 +1273,7 @@ static int snd_vt1724_capture_spdif_open(struct snd_pcm_substream *substream)  				   VT1724_BUFFER_ALIGN);  	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,  				   VT1724_BUFFER_ALIGN); +	constrain_rate_if_locked(substream);  	if (ice->spdif.ops.open)  		ice->spdif.ops.open(ice, substream);  	return 0; @@ -1285,7 +1315,7 @@ static struct snd_pcm_ops snd_vt1724_capture_spdif_ops = {  }; -static int __devinit snd_vt1724_pcm_spdif(struct snd_ice1712 *ice, int device) +static int snd_vt1724_pcm_spdif(struct snd_ice1712 *ice, int device)  {  	char *name;  	struct snd_pcm *pcm; @@ -1419,7 +1449,7 @@ static struct snd_pcm_ops snd_vt1724_playback_indep_ops = {  }; -static int __devinit snd_vt1724_pcm_indep(struct snd_ice1712 *ice, int device) +static int snd_vt1724_pcm_indep(struct snd_ice1712 *ice, int device)  {  	struct snd_pcm *pcm;  	int play; @@ -1454,7 +1484,7 @@ static int __devinit snd_vt1724_pcm_indep(struct snd_ice1712 *ice, int device)   *  Mixer section   */ -static int __devinit snd_vt1724_ac97_mixer(struct snd_ice1712 *ice) +static int snd_vt1724_ac97_mixer(struct snd_ice1712 *ice)  {  	int err; @@ -1478,7 +1508,8 @@ static int __devinit snd_vt1724_ac97_mixer(struct snd_ice1712 *ice)  		ac97.private_data = ice;  		err = snd_ac97_mixer(pbus, &ac97, &ice->ac97);  		if (err < 0) -			printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n"); +			dev_warn(ice->card->dev, +				 "cannot initialize pro ac97, skipped\n");  		else  			return 0;  	} @@ -1540,7 +1571,7 @@ static void snd_vt1724_proc_read(struct snd_info_entry *entry,  			    idx, inb(ice->profi_port+idx));  } -static void __devinit snd_vt1724_proc_init(struct snd_ice1712 *ice) +static void snd_vt1724_proc_init(struct snd_ice1712 *ice)  {  	struct snd_info_entry *entry; @@ -1569,7 +1600,7 @@ static int snd_vt1724_eeprom_get(struct snd_kcontrol *kcontrol,  	return 0;  } -static struct snd_kcontrol_new snd_vt1724_eeprom __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_eeprom = {  	.iface = SNDRV_CTL_ELEM_IFACE_CARD,  	.name = "ICE1724 EEPROM",  	.access = SNDRV_CTL_ELEM_ACCESS_READ, @@ -1682,7 +1713,7 @@ static int snd_vt1724_spdif_default_put(struct snd_kcontrol *kcontrol,  	return val != old;  } -static struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata = +static struct snd_kcontrol_new snd_vt1724_spdif_default =  {  	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,  	.name =         SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), @@ -1714,7 +1745,7 @@ static int snd_vt1724_spdif_maskp_get(struct snd_kcontrol *kcontrol,  	return 0;  } -static struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata = +static struct snd_kcontrol_new snd_vt1724_spdif_maskc =  {  	.access =	SNDRV_CTL_ELEM_ACCESS_READ,  	.iface =	SNDRV_CTL_ELEM_IFACE_PCM, @@ -1723,7 +1754,7 @@ static struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata =  	.get =		snd_vt1724_spdif_maskc_get,  }; -static struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata = +static struct snd_kcontrol_new snd_vt1724_spdif_maskp =  {  	.access =	SNDRV_CTL_ELEM_ACCESS_READ,  	.iface =	SNDRV_CTL_ELEM_IFACE_PCM, @@ -1760,7 +1791,7 @@ static int snd_vt1724_spdif_sw_put(struct snd_kcontrol *kcontrol,  	return old != val;  } -static struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata = +static struct snd_kcontrol_new snd_vt1724_spdif_switch =  {  	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,  	/* FIXME: the following conflict with IEC958 Playback Route */ @@ -1825,7 +1856,12 @@ static int snd_vt1724_pro_internal_clock_info(struct snd_kcontrol *kcontrol,  	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;  	uinfo->count = 1; -	uinfo->value.enumerated.items = hw_rates_count + ice->ext_clock_count; +	/* internal clocks */ +	uinfo->value.enumerated.items = hw_rates_count; +	/* external clocks */ +	if (ice->force_rdma1 || +	    (ice->eeprom.data[ICE_EEP2_SPDIF] & VT1724_CFG_SPDIF_IN)) +		uinfo->value.enumerated.items += ice->ext_clock_count;  	/* upper limit - keep at top */  	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)  		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; @@ -1930,7 +1966,7 @@ static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol,  	return old_rate != new_rate;  } -static struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_pro_internal_clock = {  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.name = "Multi Track Internal Clock",  	.info = snd_vt1724_pro_internal_clock_info, @@ -1961,7 +1997,7 @@ static int snd_vt1724_pro_rate_locking_put(struct snd_kcontrol *kcontrol,  	return change;  } -static struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_pro_rate_locking = {  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.name = "Multi Track Rate Locking",  	.info = snd_vt1724_pro_rate_locking_info, @@ -1992,7 +2028,7 @@ static int snd_vt1724_pro_rate_reset_put(struct snd_kcontrol *kcontrol,  	return change;  } -static struct snd_kcontrol_new snd_vt1724_pro_rate_reset __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_pro_rate_reset = {  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.name = "Multi Track Rate Reset",  	.info = snd_vt1724_pro_rate_reset_info, @@ -2007,7 +2043,7 @@ static struct snd_kcontrol_new snd_vt1724_pro_rate_reset __devinitdata = {  static int snd_vt1724_pro_route_info(struct snd_kcontrol *kcontrol,  				     struct snd_ctl_elem_info *uinfo)  { -	static char *texts[] = { +	static const char * const texts[] = {  		"PCM Out", /* 0 */  		"H/W In 0", "H/W In 1", /* 1-2 */  		"IEC958 In L", "IEC958 In R", /* 3-4 */ @@ -2114,7 +2150,7 @@ static int snd_vt1724_pro_route_spdif_put(struct snd_kcontrol *kcontrol,  					 digital_route_shift(idx));  } -static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata = +static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route =  {  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.name = "H/W Playback Route", @@ -2123,7 +2159,7 @@ static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata =  	.put = snd_vt1724_pro_route_analog_put,  }; -static struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route = {  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route",  	.info = snd_vt1724_pro_route_info, @@ -2159,7 +2195,7 @@ static int snd_vt1724_pro_peak_get(struct snd_kcontrol *kcontrol,  	return 0;  } -static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak = {  	.iface = SNDRV_CTL_ELEM_IFACE_PCM,  	.name = "Multi Track Peak",  	.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, @@ -2171,9 +2207,43 @@ static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = {   *   */ -static struct snd_ice1712_card_info no_matched __devinitdata; +static struct snd_ice1712_card_info no_matched; + -static struct snd_ice1712_card_info *card_tables[] __devinitdata = { +/* +  ooAoo cards with no controls +*/ +static unsigned char ooaoo_sq210_eeprom[] = { +	[ICE_EEP2_SYSCONF]     = 0x4c,	/* 49MHz crystal, no mpu401, no ADC, +					   1xDACs */ +	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */ +	[ICE_EEP2_I2S]         = 0x78,	/* no volume, 96k, 24bit, 192k */ +	[ICE_EEP2_SPDIF]       = 0xc1,	/* out-en, out-int, out-ext */ +	[ICE_EEP2_GPIO_DIR]    = 0x00,	/* no GPIOs are used */ +	[ICE_EEP2_GPIO_DIR1]   = 0x00, +	[ICE_EEP2_GPIO_DIR2]   = 0x00, +	[ICE_EEP2_GPIO_MASK]   = 0xff, +	[ICE_EEP2_GPIO_MASK1]  = 0xff, +	[ICE_EEP2_GPIO_MASK2]  = 0xff, + +	[ICE_EEP2_GPIO_STATE]  = 0x00, /* inputs */ +	[ICE_EEP2_GPIO_STATE1] = 0x00, /* all 1, but GPIO_CPLD_RW +					  and GPIO15 always zero */ +	[ICE_EEP2_GPIO_STATE2] = 0x00, /* inputs */ +}; + + +static struct snd_ice1712_card_info snd_vt1724_ooaoo_cards[] = { +	{ +		.name = "ooAoo SQ210a", +		.model = "sq210a", +		.eeprom_size = sizeof(ooaoo_sq210_eeprom), +		.eeprom_data = ooaoo_sq210_eeprom, +	}, +	{ } /* terminator */ +}; + +static struct snd_ice1712_card_info *card_tables[] = {  	snd_vt1724_revo_cards,  	snd_vt1724_amp_cards,  	snd_vt1724_aureon_cards, @@ -2187,6 +2257,8 @@ static struct snd_ice1712_card_info *card_tables[] __devinitdata = {  	snd_vt1724_wtm_cards,  	snd_vt1724_se_cards,  	snd_vt1724_qtet_cards, +	snd_vt1724_ooaoo_cards, +	snd_vt1724_psc724_cards,  	NULL,  }; @@ -2200,7 +2272,7 @@ static void wait_i2c_busy(struct snd_ice1712 *ice)  	while ((inb(ICEREG1724(ice, I2C_CTRL)) & VT1724_I2C_BUSY) && t--)  		;  	if (t == -1) -		printk(KERN_ERR "ice1724: i2c busy timeout\n"); +		dev_err(ice->card->dev, "i2c busy timeout\n");  }  unsigned char snd_vt1724_read_i2c(struct snd_ice1712 *ice, @@ -2216,7 +2288,7 @@ unsigned char snd_vt1724_read_i2c(struct snd_ice1712 *ice,  	val = inb(ICEREG1724(ice, I2C_DATA));  	mutex_unlock(&ice->i2c_mutex);  	/* -	printk(KERN_DEBUG "i2c_read: [0x%x,0x%x] = 0x%x\n", dev, addr, val); +	dev_dbg(ice->card->dev, "i2c_read: [0x%x,0x%x] = 0x%x\n", dev, addr, val);  	*/  	return val;  } @@ -2227,7 +2299,7 @@ void snd_vt1724_write_i2c(struct snd_ice1712 *ice,  	mutex_lock(&ice->i2c_mutex);  	wait_i2c_busy(ice);  	/* -	printk(KERN_DEBUG "i2c_write: [0x%x,0x%x] = 0x%x\n", dev, addr, data); +	dev_dbg(ice->card->dev, "i2c_write: [0x%x,0x%x] = 0x%x\n", dev, addr, data);  	*/  	outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR));  	outb(data, ICEREG1724(ice, I2C_DATA)); @@ -2236,8 +2308,8 @@ void snd_vt1724_write_i2c(struct snd_ice1712 *ice,  	mutex_unlock(&ice->i2c_mutex);  } -static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice, -					    const char *modelname) +static int snd_vt1724_read_eeprom(struct snd_ice1712 *ice, +				  const char *modelname)  {  	const int dev = 0xa0;		/* EEPROM device address */  	unsigned int i, size; @@ -2264,45 +2336,52 @@ static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice,  				((unsigned int)swab16(vendor) << 16) | swab16(device);  			if (ice->eeprom.subvendor == 0 ||  			    ice->eeprom.subvendor == (unsigned int)-1) { -				printk(KERN_ERR "ice1724: No valid ID is found\n"); +				dev_err(ice->card->dev, +					"No valid ID is found\n");  				return -ENXIO;  			}  		}  	}  	for (tbl = card_tables; *tbl; tbl++) { -		for (c = *tbl; c->subvendor; c++) { +		for (c = *tbl; c->name; c++) {  			if (modelname && c->model &&  			    !strcmp(modelname, c->model)) { -				printk(KERN_INFO "ice1724: Using board model %s\n", +				dev_info(ice->card->dev, +					 "Using board model %s\n",  				       c->name);  				ice->eeprom.subvendor = c->subvendor;  			} else if (c->subvendor != ice->eeprom.subvendor)  				continue; +			ice->card_info = c;  			if (!c->eeprom_size || !c->eeprom_data)  				goto found;  			/* if the EEPROM is given by the driver, use it */ -			snd_printdd("using the defined eeprom..\n"); +			dev_dbg(ice->card->dev, "using the defined eeprom..\n");  			ice->eeprom.version = 2;  			ice->eeprom.size = c->eeprom_size + 6;  			memcpy(ice->eeprom.data, c->eeprom_data, c->eeprom_size);  			goto read_skipped;  		}  	} -	printk(KERN_WARNING "ice1724: No matching model found for ID 0x%x\n", +	dev_warn(ice->card->dev, "No matching model found for ID 0x%x\n",  	       ice->eeprom.subvendor); +#ifdef CONFIG_PM_SLEEP +	/* assume AC97-only card which can suspend without additional code */ +	ice->pm_suspend_enabled = 1; +#endif   found:  	ice->eeprom.size = snd_vt1724_read_i2c(ice, dev, 0x04);  	if (ice->eeprom.size < 6)  		ice->eeprom.size = 32;  	else if (ice->eeprom.size > 32) { -		printk(KERN_ERR "ice1724: Invalid EEPROM (size = %i)\n", +		dev_err(ice->card->dev, "Invalid EEPROM (size = %i)\n",  		       ice->eeprom.size);  		return -EIO;  	}  	ice->eeprom.version = snd_vt1724_read_i2c(ice, dev, 0x05); -	if (ice->eeprom.version != 2) -		printk(KERN_WARNING "ice1724: Invalid EEPROM version %i\n", +	if (ice->eeprom.version != 1 && ice->eeprom.version != 2) +		dev_warn(ice->card->dev, "Invalid EEPROM version %i\n",  		       ice->eeprom.version);  	size = ice->eeprom.size - 6;  	for (i = 0; i < size; i++) @@ -2354,7 +2433,7 @@ static int snd_vt1724_chip_init(struct snd_ice1712 *ice)  	return 0;  } -static int __devinit snd_vt1724_spdif_build_controls(struct snd_ice1712 *ice) +static int snd_vt1724_spdif_build_controls(struct snd_ice1712 *ice)  {  	int err;  	struct snd_kcontrol *kctl; @@ -2396,7 +2475,7 @@ static int __devinit snd_vt1724_spdif_build_controls(struct snd_ice1712 *ice)  } -static int __devinit snd_vt1724_build_controls(struct snd_ice1712 *ice) +static int snd_vt1724_build_controls(struct snd_ice1712 *ice)  {  	int err; @@ -2456,10 +2535,10 @@ static int snd_vt1724_dev_free(struct snd_device *device)  	return snd_vt1724_free(ice);  } -static int __devinit snd_vt1724_create(struct snd_card *card, -				       struct pci_dev *pci, -				       const char *modelname, -				       struct snd_ice1712 **r_ice1712) +static int snd_vt1724_create(struct snd_card *card, +			     struct pci_dev *pci, +			     const char *modelname, +			     struct snd_ice1712 **r_ice1712)  {  	struct snd_ice1712 *ice;  	int err; @@ -2509,8 +2588,8 @@ static int __devinit snd_vt1724_create(struct snd_card *card,  	ice->profi_port = pci_resource_start(pci, 1);  	if (request_irq(pci->irq, snd_vt1724_interrupt, -			IRQF_SHARED, "ICE1724", ice)) { -		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); +			IRQF_SHARED, KBUILD_MODNAME, ice)) { +		dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);  		snd_vt1724_free(ice);  		return -EIO;  	} @@ -2533,8 +2612,6 @@ static int __devinit snd_vt1724_create(struct snd_card *card,  		return err;  	} -	snd_card_set_dev(card, &pci->dev); -  	*r_ice1712 = ice;  	return 0;  } @@ -2546,8 +2623,8 @@ static int __devinit snd_vt1724_create(struct snd_card *card,   *   */ -static int __devinit snd_vt1724_probe(struct pci_dev *pci, -				      const struct pci_device_id *pci_id) +static int snd_vt1724_probe(struct pci_dev *pci, +			    const struct pci_device_id *pci_id)  {  	static int dev;  	struct snd_card *card; @@ -2562,7 +2639,8 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,  		return -ENOENT;  	} -	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); +	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, +			   0, &card);  	if (err < 0)  		return err; @@ -2579,8 +2657,10 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,  	ice->ext_clock_count = 0;  	for (tbl = card_tables; *tbl; tbl++) { -		for (c = *tbl; c->subvendor; c++) { -			if (c->subvendor == ice->eeprom.subvendor) { +		for (c = *tbl; c->name; c++) { +			if ((model[dev] && c->model && +			     !strcmp(model[dev], c->model)) || +			    (c->subvendor == ice->eeprom.subvendor)) {  				strcpy(card->shortname, c->name);  				if (c->driver) /* specific driver? */  					strcpy(card->driver, c->driver); @@ -2714,16 +2794,21 @@ __found:  	return 0;  } -static void __devexit snd_vt1724_remove(struct pci_dev *pci) +static void snd_vt1724_remove(struct pci_dev *pci)  { -	snd_card_free(pci_get_drvdata(pci)); -	pci_set_drvdata(pci, NULL); +	struct snd_card *card = pci_get_drvdata(pci); +	struct snd_ice1712 *ice = card->private_data; + +	if (ice->card_info && ice->card_info->chip_exit) +		ice->card_info->chip_exit(ice); +	snd_card_free(card);  } -#ifdef CONFIG_PM -static int snd_vt1724_suspend(struct pci_dev *pci, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int snd_vt1724_suspend(struct device *dev)  { -	struct snd_card *card = pci_get_drvdata(pci); +	struct pci_dev *pci = to_pci_dev(dev); +	struct snd_card *card = dev_get_drvdata(dev);  	struct snd_ice1712 *ice = card->private_data;  	if (!ice->pm_suspend_enabled) @@ -2748,13 +2833,14 @@ static int snd_vt1724_suspend(struct pci_dev *pci, pm_message_t state)  	pci_disable_device(pci);  	pci_save_state(pci); -	pci_set_power_state(pci, pci_choose_state(pci, state)); +	pci_set_power_state(pci, PCI_D3hot);  	return 0;  } -static int snd_vt1724_resume(struct pci_dev *pci) +static int snd_vt1724_resume(struct device *dev)  { -	struct snd_card *card = pci_get_drvdata(pci); +	struct pci_dev *pci = to_pci_dev(dev); +	struct snd_card *card = dev_get_drvdata(dev);  	struct snd_ice1712 *ice = card->private_data;  	if (!ice->pm_suspend_enabled) @@ -2785,7 +2871,12 @@ static int snd_vt1724_resume(struct pci_dev *pci)  		ice->set_spdif_clock(ice, 0);  	} else {  		/* internal on-card clock */ -		snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 1); +		int rate; +		if (ice->cur_rate) +			rate = ice->cur_rate; +		else +			rate = ice->pro_rate_default; +		snd_vt1724_set_pro_rate(ice, rate, 1);  	}  	update_spdif_bits(ice, ice->pm_saved_spdif_ctrl); @@ -2799,28 +2890,21 @@ static int snd_vt1724_resume(struct pci_dev *pci)  	snd_power_change_state(card, SNDRV_CTL_POWER_D0);  	return 0;  } -#endif -static struct pci_driver driver = { -	.name = "ICE1724", +static SIMPLE_DEV_PM_OPS(snd_vt1724_pm, snd_vt1724_suspend, snd_vt1724_resume); +#define SND_VT1724_PM_OPS	&snd_vt1724_pm +#else +#define SND_VT1724_PM_OPS	NULL +#endif /* CONFIG_PM_SLEEP */ + +static struct pci_driver vt1724_driver = { +	.name = KBUILD_MODNAME,  	.id_table = snd_vt1724_ids,  	.probe = snd_vt1724_probe, -	.remove = __devexit_p(snd_vt1724_remove), -#ifdef CONFIG_PM -	.suspend = snd_vt1724_suspend, -	.resume = snd_vt1724_resume, -#endif +	.remove = snd_vt1724_remove, +	.driver = { +		.pm = SND_VT1724_PM_OPS, +	},  }; -static int __init alsa_card_ice1724_init(void) -{ -	return pci_register_driver(&driver); -} - -static void __exit alsa_card_ice1724_exit(void) -{ -	pci_unregister_driver(&driver); -} - -module_init(alsa_card_ice1724_init) -module_exit(alsa_card_ice1724_exit) +module_pci_driver(vt1724_driver); diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c index 98bc3b7681b..7a6c0786c55 100644 --- a/sound/pci/ice1712/juli.c +++ b/sound/pci/ice1712/juli.c @@ -23,7 +23,6 @@   *   */ -#include <asm/io.h>  #include <linux/delay.h>  #include <linux/interrupt.h>  #include <linux/init.h> @@ -245,7 +244,7 @@ static void juli_akm_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)  	/* AK5385 first, since it requires cold reset affecting both codecs */  	old_gpio = ice->gpio.get_data(ice);  	new_gpio =  (old_gpio & ~GPIO_AK5385A_MASK) | ak5385_pins; -	/* printk(KERN_DEBUG "JULI - ak5385 set_rate_val: new gpio 0x%x\n", +	/* dev_dbg(ice->card->dev, "JULI - ak5385 set_rate_val: new gpio 0x%x\n",  		new_gpio); */  	ice->gpio.set_data(ice, new_gpio); @@ -283,7 +282,7 @@ static const struct snd_akm4xxx_dac_channel juli_dac[] = {  }; -static struct snd_akm4xxx akm_juli_dac __devinitdata = { +static struct snd_akm4xxx akm_juli_dac = {  	.type = SND_AK4358,  	.num_dacs = 8,	/* DAC1 - analog out  			   DAC2 - analog in monitor @@ -345,7 +344,7 @@ static int juli_mute_put(struct snd_kcontrol *kcontrol,  			new_gpio =  old_gpio &  				~((unsigned int) kcontrol->private_value);  	} -	/* printk(KERN_DEBUG +	/* dev_dbg(ice->card->dev,  		"JULI - mute/unmute: control_value: 0x%x, old_gpio: 0x%x, "  		"new_gpio 0x%x\n",  		(unsigned int)ucontrol->value.integer.value[0], old_gpio, @@ -358,7 +357,7 @@ static int juli_mute_put(struct snd_kcontrol *kcontrol,  	return 0;  } -static struct snd_kcontrol_new juli_mute_controls[] __devinitdata = { +static struct snd_kcontrol_new juli_mute_controls[] = {  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "Master Playback Switch", @@ -412,7 +411,7 @@ static struct snd_kcontrol_new juli_mute_controls[] __devinitdata = {  	},  }; -static char *slave_vols[] __devinitdata = { +static char *slave_vols[] = {  	PCM_VOLUME,  	MONITOR_AN_IN_VOLUME,  	MONITOR_DIG_IN_VOLUME, @@ -420,11 +419,11 @@ static char *slave_vols[] __devinitdata = {  	NULL  }; -static __devinitdata +static  DECLARE_TLV_DB_SCALE(juli_master_db_scale, -6350, 50, 1); -static struct snd_kcontrol __devinit *ctl_find(struct snd_card *card, -		const char *name) +static struct snd_kcontrol *ctl_find(struct snd_card *card, +				     const char *name)  {  	struct snd_ctl_elem_id sid;  	memset(&sid, 0, sizeof(sid)); @@ -434,20 +433,21 @@ static struct snd_kcontrol __devinit *ctl_find(struct snd_card *card,  	return snd_ctl_find_id(card, &sid);  } -static void __devinit add_slaves(struct snd_card *card, -				 struct snd_kcontrol *master, char **list) +static void add_slaves(struct snd_card *card, +		       struct snd_kcontrol *master, +		       char * const *list)  {  	for (; *list; list++) {  		struct snd_kcontrol *slave = ctl_find(card, *list); -		/* printk(KERN_DEBUG "add_slaves - %s\n", *list); */ +		/* dev_dbg(card->dev, "add_slaves - %s\n", *list); */  		if (slave) { -			/* printk(KERN_DEBUG "slave %s found\n", *list); */ +			/* dev_dbg(card->dev, "slave %s found\n", *list); */  			snd_ctl_add_slave(master, slave);  		}  	}  } -static int __devinit juli_add_controls(struct snd_ice1712 *ice) +static int juli_add_controls(struct snd_ice1712 *ice)  {  	struct juli_spec *spec = ice->spec;  	int err; @@ -486,7 +486,7 @@ static int __devinit juli_add_controls(struct snd_ice1712 *ice)   * suspend/resume   * */ -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP  static int juli_resume(struct snd_ice1712 *ice)  {  	struct snd_akm4xxx *ak = ice->akm; @@ -536,7 +536,7 @@ static void juli_set_rate(struct snd_ice1712 *ice, unsigned int rate)  	old = ice->gpio.get_data(ice);  	new =  (old & ~GPIO_RATE_MASK) | get_gpio_val(rate); -	/* printk(KERN_DEBUG "JULI - set_rate: old %x, new %x\n", +	/* dev_dbg(ice->card->dev, "JULI - set_rate: old %x, new %x\n",  			old & GPIO_RATE_MASK,  			new & GPIO_RATE_MASK); */ @@ -573,13 +573,13 @@ static void juli_ak4114_change(struct ak4114 *ak4114, unsigned char c0,  	if (ice->is_spdif_master(ice) && c1) {  		/* only for SPDIF master mode, rate was changed */  		rate = snd_ak4114_external_rate(ak4114); -		/* printk(KERN_DEBUG "ak4114 - input rate changed to %d\n", +		/* dev_dbg(ice->card->dev, "ak4114 - input rate changed to %d\n",  				rate); */  		juli_akm_set_rate_val(ice->akm, rate);  	}  } -static int __devinit juli_init(struct snd_ice1712 *ice) +static int juli_init(struct snd_ice1712 *ice)  {  	static const unsigned char ak4114_init_vals[] = {  		/* AK4117_REG_PWRDN */	AK4114_RST | AK4114_PWN | @@ -628,7 +628,7 @@ static int __devinit juli_init(struct snd_ice1712 *ice)  #endif  	if (spec->analog) { -		printk(KERN_INFO "juli@: analog I/O detected\n"); +		dev_info(ice->card->dev, "juli@: analog I/O detected\n");  		ice->num_total_dacs = 2;  		ice->num_total_adcs = 2; @@ -652,7 +652,7 @@ static int __devinit juli_init(struct snd_ice1712 *ice)  	ice->spdif.ops.open = juli_spdif_in_open; -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP  	ice->pm_resume = juli_resume;  	ice->pm_suspend = juli_suspend;  	ice->pm_suspend_enabled = 1; @@ -667,7 +667,7 @@ static int __devinit juli_init(struct snd_ice1712 *ice)   * hence the driver needs to sets up it properly.   */ -static unsigned char juli_eeprom[] __devinitdata = { +static unsigned char juli_eeprom[] = {  	[ICE_EEP2_SYSCONF]     = 0x2b,	/* clock 512, mpu401, 1xADC, 1xDACs,  					   SPDIF in */  	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */ @@ -686,7 +686,7 @@ static unsigned char juli_eeprom[] __devinitdata = {  };  /* entry point */ -struct snd_ice1712_card_info snd_vt1724_juli_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_juli_cards[] = {  	{  		.subvendor = VT1724_SUBDEVICE_JULI,  		.name = "ESI Juli@", diff --git a/sound/pci/ice1712/maya44.c b/sound/pci/ice1712/maya44.c index 726fd4b92e1..63aa39f06f0 100644 --- a/sound/pci/ice1712/maya44.c +++ b/sound/pci/ice1712/maya44.c @@ -24,7 +24,6 @@  #include <linux/init.h>  #include <linux/slab.h> -#include <linux/io.h>  #include <sound/core.h>  #include <sound/control.h>  #include <sound/pcm.h> @@ -358,7 +357,7 @@ static void wm8776_select_input(struct snd_maya44 *chip, int idx, int line)  static int maya_rec_src_info(struct snd_kcontrol *kcontrol,  			     struct snd_ctl_elem_info *uinfo)  { -	static char *texts[] = { "Line", "Mic" }; +	static const char * const texts[] = { "Line", "Mic" };  	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;  	uinfo->count = 1; @@ -407,7 +406,7 @@ static int maya_rec_src_put(struct snd_kcontrol *kcontrol,  static int maya_pb_route_info(struct snd_kcontrol *kcontrol,  			      struct snd_ctl_elem_info *uinfo)  { -	static char *texts[] = { +	static const char * const texts[] = {  		"PCM Out", /* 0 */  		"Input 1", "Input 2", "Input 3", "Input 4"  	}; @@ -455,7 +454,7 @@ static int maya_pb_route_put(struct snd_kcontrol *kcontrol,   * controls to be added   */ -static struct snd_kcontrol_new maya_controls[] __devinitdata = { +static struct snd_kcontrol_new maya_controls[] = {  	{  		.name = "Crossmix Playback Volume",  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -545,7 +544,7 @@ static struct snd_kcontrol_new maya_controls[] __devinitdata = {  	},  }; -static int __devinit maya44_add_controls(struct snd_ice1712 *ice) +static int maya44_add_controls(struct snd_ice1712 *ice)  {  	int err, i; @@ -562,8 +561,8 @@ static int __devinit maya44_add_controls(struct snd_ice1712 *ice)  /*   * initialize a wm8776 chip   */ -static void __devinit wm8776_init(struct snd_ice1712 *ice, -				  struct snd_wm8776 *wm, unsigned int addr) +static void wm8776_init(struct snd_ice1712 *ice, +			struct snd_wm8776 *wm, unsigned int addr)  {  	static const unsigned short inits_wm8776[] = {  		0x02, 0x100, /* R2: headphone L+R muted + update */ @@ -693,14 +692,14 @@ static struct snd_pcm_hw_constraint_list dac_rates = {  /*   * chip addresses on I2C bus   */ -static unsigned char wm8776_addr[2] __devinitdata = { +static unsigned char wm8776_addr[2] = {  	0x34, 0x36, /* codec 0 & 1 */  };  /*   * initialize the chip   */ -static int __devinit maya44_init(struct snd_ice1712 *ice) +static int maya44_init(struct snd_ice1712 *ice)  {  	int i;  	struct snd_maya44 *chip; @@ -743,7 +742,7 @@ static int __devinit maya44_init(struct snd_ice1712 *ice)   * hence the driver needs to sets up it properly.   */ -static unsigned char maya44_eeprom[] __devinitdata = { +static unsigned char maya44_eeprom[] = {  	[ICE_EEP2_SYSCONF]     = 0x45,  		/* clock xin1=49.152MHz, mpu401, 2 stereo ADCs+DACs */  	[ICE_EEP2_ACLINK]      = 0x80, @@ -765,7 +764,7 @@ static unsigned char maya44_eeprom[] __devinitdata = {  };  /* entry point */ -struct snd_ice1712_card_info snd_vt1724_maya44_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_maya44_cards[] = {  	{  		.subvendor = VT1724_SUBDEVICE_MAYA44,  		.name = "ESI Maya44", diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c index de29be8c965..0011e04f36a 100644 --- a/sound/pci/ice1712/phase.c +++ b/sound/pci/ice1712/phase.c @@ -42,7 +42,6 @@   *   Digital receiver: CS8414-CS (supported in this release)   */ -#include <asm/io.h>  #include <linux/delay.h>  #include <linux/interrupt.h>  #include <linux/init.h> @@ -103,13 +102,13 @@ static const unsigned char wm_vol[256] = {  #define WM_VOL_MAX	(sizeof(wm_vol) - 1)  #define WM_VOL_MUTE	0x8000 -static struct snd_akm4xxx akm_phase22 __devinitdata = { +static struct snd_akm4xxx akm_phase22 = {  	.type = SND_AK4524,  	.num_dacs = 2,  	.num_adcs = 2,  }; -static struct snd_ak4xxx_private akm_phase22_priv __devinitdata = { +static struct snd_ak4xxx_private akm_phase22_priv = {  	.caddr =	2,  	.cif =		1,  	.data_mask =	1 << 4, @@ -121,7 +120,7 @@ static struct snd_ak4xxx_private akm_phase22_priv __devinitdata = {  	.mask_flags =	0,  }; -static int __devinit phase22_init(struct snd_ice1712 *ice) +static int phase22_init(struct snd_ice1712 *ice)  {  	struct snd_akm4xxx *ak;  	int err; @@ -158,7 +157,7 @@ static int __devinit phase22_init(struct snd_ice1712 *ice)  	return 0;  } -static int __devinit phase22_add_controls(struct snd_ice1712 *ice) +static int phase22_add_controls(struct snd_ice1712 *ice)  {  	int err = 0; @@ -172,7 +171,7 @@ static int __devinit phase22_add_controls(struct snd_ice1712 *ice)  	return 0;  } -static unsigned char phase22_eeprom[] __devinitdata = { +static unsigned char phase22_eeprom[] = {  	[ICE_EEP2_SYSCONF]     = 0x28,  /* clock 512, mpu 401,  					spdif-in/1xADC, 1xDACs */  	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */ @@ -189,7 +188,7 @@ static unsigned char phase22_eeprom[] __devinitdata = {  	[ICE_EEP2_GPIO_STATE2] = 0x00,  }; -static unsigned char phase28_eeprom[] __devinitdata = { +static unsigned char phase28_eeprom[] = {  	[ICE_EEP2_SYSCONF]     = 0x2b,  /* clock 512, mpu401,  					spdif-in/1xADC, 4xDACs */  	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */ @@ -379,7 +378,7 @@ static int wm_master_vol_put(struct snd_kcontrol *kcontrol,  	return change;  } -static int __devinit phase28_init(struct snd_ice1712 *ice) +static int phase28_init(struct snd_ice1712 *ice)  {  	static const unsigned short wm_inits_phase28[] = {  		/* These come first to reduce init pop noise */ @@ -722,7 +721,7 @@ static int phase28_deemp_put(struct snd_kcontrol *kcontrol,  static int phase28_oversampling_info(struct snd_kcontrol *k,  					struct snd_ctl_elem_info *uinfo)  { -	static char *texts[2] = { "128x", "64x"	}; +	static const char * const texts[2] = { "128x", "64x"	};  	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;  	uinfo->count = 1; @@ -770,7 +769,7 @@ static int phase28_oversampling_put(struct snd_kcontrol *kcontrol,  static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);  static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1); -static struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = { +static struct snd_kcontrol_new phase28_dac_controls[] = {  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "Master Playback Switch", @@ -885,7 +884,7 @@ static struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = {  	}  }; -static struct snd_kcontrol_new wm_controls[] __devinitdata = { +static struct snd_kcontrol_new wm_controls[] = {  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "PCM Playback Switch", @@ -919,7 +918,7 @@ static struct snd_kcontrol_new wm_controls[] __devinitdata = {  	}  }; -static int __devinit phase28_add_controls(struct snd_ice1712 *ice) +static int phase28_add_controls(struct snd_ice1712 *ice)  {  	unsigned int i, counts;  	int err; @@ -943,7 +942,7 @@ static int __devinit phase28_add_controls(struct snd_ice1712 *ice)  	return 0;  } -struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_phase_cards[] = {  	{  		.subvendor = VT1724_SUBDEVICE_PHASE22,  		.name = "Terratec PHASE 22", diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c index cdb873f5da5..5555eb4b240 100644 --- a/sound/pci/ice1712/pontis.c +++ b/sound/pci/ice1712/pontis.c @@ -21,7 +21,6 @@   *   */ -#include <asm/io.h>  #include <linux/delay.h>  #include <linux/interrupt.h>  #include <linux/init.h> @@ -550,7 +549,7 @@ static const DECLARE_TLV_DB_SCALE(db_scale_volume, -6400, 50, 1);   * mixers   */ -static struct snd_kcontrol_new pontis_controls[] __devinitdata = { +static struct snd_kcontrol_new pontis_controls[] = {  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | @@ -697,7 +696,7 @@ static void cs_proc_init(struct snd_ice1712 *ice)  } -static int __devinit pontis_add_controls(struct snd_ice1712 *ice) +static int pontis_add_controls(struct snd_ice1712 *ice)  {  	unsigned int i;  	int err; @@ -718,7 +717,7 @@ static int __devinit pontis_add_controls(struct snd_ice1712 *ice)  /*   * initialize the chip   */ -static int __devinit pontis_init(struct snd_ice1712 *ice) +static int pontis_init(struct snd_ice1712 *ice)  {  	static const unsigned short wm_inits[] = {  		/* These come first to reduce init pop noise */ @@ -768,7 +767,7 @@ static int __devinit pontis_init(struct snd_ice1712 *ice)  	ice->num_total_dacs = 2;  	ice->num_total_adcs = 2; -	/* to remeber the register values */ +	/* to remember the register values */  	ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);  	if (! ice->akm)  		return -ENOMEM; @@ -805,7 +804,7 @@ static int __devinit pontis_init(struct snd_ice1712 *ice)   * hence the driver needs to sets up it properly.   */ -static unsigned char pontis_eeprom[] __devinitdata = { +static unsigned char pontis_eeprom[] = {  	[ICE_EEP2_SYSCONF]     = 0x08,	/* clock 256, mpu401, spdif-in/ADC, 1DAC */  	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */  	[ICE_EEP2_I2S]         = 0xf8,	/* vol, 96k, 24bit, 192k */ @@ -822,7 +821,7 @@ static unsigned char pontis_eeprom[] __devinitdata = {  };  /* entry point */ -struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1720_pontis_cards[] = {  	{  		.subvendor = VT1720_SUBDEVICE_PONTIS_MS300,  		.name = "Pontis MS300", diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c index e36ddb94c38..f3b491aa3e2 100644 --- a/sound/pci/ice1712/prodigy192.c +++ b/sound/pci/ice1712/prodigy192.c @@ -54,7 +54,6 @@   *   */       -#include <asm/io.h>  #include <linux/delay.h>  #include <linux/interrupt.h>  #include <linux/init.h> @@ -99,7 +98,7 @@ static int stac9460_dac_mute(struct snd_ice1712 *ice, int idx,  	new = (~mute << 7 & 0x80) | (old & ~0x80);  	change = (new != old);  	if (change) -		/*printk ("Volume register 0x%02x: 0x%02x\n", idx, new);*/ +		/* dev_dbg(ice->card->dev, "Volume register 0x%02x: 0x%02x\n", idx, new);*/  		stac9460_put(ice, idx, new);  	return change;  } @@ -134,7 +133,7 @@ static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e  	/* due to possible conflicts with stac9460_set_rate_val, mutexing */  	mutex_lock(&spec->mute_mutex);  	/* -	printk(KERN_DEBUG "Mute put: reg 0x%02x, ctrl value: 0x%02x\n", idx, +	dev_dbg(ice->card->dev, "Mute put: reg 0x%02x, ctrl value: 0x%02x\n", idx,  	       ucontrol->value.integer.value[0]);  	*/  	change = stac9460_dac_mute(ice, idx, ucontrol->value.integer.value[0]); @@ -188,7 +187,7 @@ static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el  	if (change) {  		ovol =  (0x7f - nvol) | (tmp & 0x80);  		/* -		printk(KERN_DEBUG "DAC Volume: reg 0x%02x: 0x%02x\n", +		dev_dbg(ice->card->dev, "DAC Volume: reg 0x%02x: 0x%02x\n",  		       idx, ovol);  		*/  		stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80)); @@ -283,7 +282,7 @@ static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el  static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol,  	       			struct snd_ctl_elem_info *uinfo)  { -	static char *texts[2] = { "Line In", "Mic" }; +	static const char * const texts[2] = { "Line In", "Mic" };  	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;  	uinfo->count = 1; @@ -349,7 +348,7 @@ static void stac9460_set_rate_val(struct snd_ice1712 *ice, unsigned int rate)  	for (idx = 0; idx < 7 ; ++idx)  		changed[idx] = stac9460_dac_mute(ice,  				STAC946X_MASTER_VOLUME + idx, 0); -	/*printk(KERN_DEBUG "Rate change: %d, new MC: 0x%02x\n", rate, new);*/ +	/*dev_dbg(ice->card->dev, "Rate change: %d, new MC: 0x%02x\n", rate, new);*/  	stac9460_put(ice, STAC946X_MASTER_CLOCKING, new);  	udelay(10);  	/* unmuting - only originally unmuted dacs - @@ -369,7 +368,7 @@ static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0);   * mixers   */ -static struct snd_kcontrol_new stac_controls[] __devinitdata = { +static struct snd_kcontrol_new stac_controls[] = {  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "Master Playback Switch", @@ -562,7 +561,7 @@ static unsigned char prodigy192_ak4114_read(void *private_data,  static int ak4114_input_sw_info(struct snd_kcontrol *kcontrol,  	       			struct snd_ctl_elem_info *uinfo)  { -	static char *texts[2] = { "Toslink", "Coax" }; +	static const char * const texts[2] = { "Toslink", "Coax" };  	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;  	uinfo->count = 1; @@ -607,7 +606,7 @@ static int ak4114_input_sw_put(struct snd_kcontrol *kcontrol,  } -static struct snd_kcontrol_new ak4114_controls[] __devinitdata = { +static struct snd_kcontrol_new ak4114_controls[] = {  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "MIODIO IEC958 Capture Input", @@ -672,7 +671,7 @@ static void stac9460_proc_init(struct snd_ice1712 *ice)  } -static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice) +static int prodigy192_add_controls(struct snd_ice1712 *ice)  {  	struct prodigy192_spec *spec = ice->spec;  	unsigned int i; @@ -728,7 +727,7 @@ static int prodigy192_miodio_exists(struct snd_ice1712 *ice)  /*   * initialize the chip   */ -static int __devinit prodigy192_init(struct snd_ice1712 *ice) +static int prodigy192_init(struct snd_ice1712 *ice)  {  	static const unsigned short stac_inits_prodigy[] = {  		STAC946X_RESET, 0, @@ -769,9 +768,10 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice)  		/* from this moment if err = 0 then  		 * spec->ak4114 should not be null  		 */ -		snd_printdd("AK4114 initialized with status %d\n", err); +		dev_dbg(ice->card->dev, +			"AK4114 initialized with status %d\n", err);  	} else -		snd_printdd("AK4114 not found\n"); +		dev_dbg(ice->card->dev, "AK4114 not found\n");  	if (err < 0)  		return err; @@ -784,7 +784,7 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice)   * hence the driver needs to sets up it properly.   */ -static unsigned char prodigy71_eeprom[] __devinitdata = { +static unsigned char prodigy71_eeprom[] = {  	[ICE_EEP2_SYSCONF]     = 0x6a,	/* 49MHz crystal, mpu401,  					 * spdif-in+ 1 stereo ADC,  					 * 3 stereo DACs @@ -808,7 +808,7 @@ static unsigned char prodigy71_eeprom[] __devinitdata = {  /* entry point */ -struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] = {  	{  		.subvendor = VT1724_SUBDEVICE_PRODIGY192VE,  		.name = "Audiotrak Prodigy 192", diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c index 6a9fee3ee78..2261d1e4915 100644 --- a/sound/pci/ice1712/prodigy_hifi.c +++ b/sound/pci/ice1712/prodigy_hifi.c @@ -25,7 +25,6 @@   */ -#include <asm/io.h>  #include <linux/delay.h>  #include <linux/interrupt.h>  #include <linux/init.h> @@ -297,8 +296,9 @@ static int ak4396_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem  }  static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1); +static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); -static struct snd_kcontrol_new prodigy_hd2_controls[] __devinitdata = { +static struct snd_kcontrol_new prodigy_hd2_controls[] = {      {  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | @@ -307,7 +307,7 @@ static struct snd_kcontrol_new prodigy_hd2_controls[] __devinitdata = {  	.info = ak4396_dac_vol_info,  	.get = ak4396_dac_vol_get,  	.put = ak4396_dac_vol_put, -	.tlv = { .p = db_scale_wm_dac }, +	.tlv = { .p = ak4396_db_scale },      },  }; @@ -781,7 +781,7 @@ static int wm_chswap_put(struct snd_kcontrol *kcontrol,   * mixers   */ -static struct snd_kcontrol_new prodigy_hifi_controls[] __devinitdata = { +static struct snd_kcontrol_new prodigy_hifi_controls[] = {  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | @@ -938,7 +938,7 @@ static void wm_proc_init(struct snd_ice1712 *ice)  	}  } -static int __devinit prodigy_hifi_add_controls(struct snd_ice1712 *ice) +static int prodigy_hifi_add_controls(struct snd_ice1712 *ice)  {  	unsigned int i;  	int err; @@ -955,7 +955,7 @@ static int __devinit prodigy_hifi_add_controls(struct snd_ice1712 *ice)  	return 0;  } -static int __devinit prodigy_hd2_add_controls(struct snd_ice1712 *ice) +static int prodigy_hd2_add_controls(struct snd_ice1712 *ice)  {  	unsigned int i;  	int err; @@ -976,7 +976,7 @@ static int __devinit prodigy_hd2_add_controls(struct snd_ice1712 *ice)  /*   * initialize the chip   */ -static int __devinit prodigy_hifi_init(struct snd_ice1712 *ice) +static int prodigy_hifi_init(struct snd_ice1712 *ice)  {  	static unsigned short wm_inits[] = {  		/* These come first to reduce init pop noise */ @@ -1046,7 +1046,7 @@ static int __devinit prodigy_hifi_init(struct snd_ice1712 *ice)  	* don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten  	*/  	ice->gpio.saved[0] = 0; -	/* to remeber the register values */ +	/* to remember the register values */  	ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);  	if (! ice->akm) @@ -1099,7 +1099,7 @@ static void ak4396_init(struct snd_ice1712 *ice)  		ak4396_write(ice, ak4396_inits[i], ak4396_inits[i+1]);  } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP  static int prodigy_hd2_resume(struct snd_ice1712 *ice)  {  	/* initialize ak4396 codec and restore previous mixer volumes */ @@ -1114,7 +1114,7 @@ static int prodigy_hd2_resume(struct snd_ice1712 *ice)  }  #endif -static int __devinit prodigy_hd2_init(struct snd_ice1712 *ice) +static int prodigy_hd2_init(struct snd_ice1712 *ice)  {  	struct prodigy_hifi_spec *spec; @@ -1128,7 +1128,7 @@ static int __devinit prodigy_hd2_init(struct snd_ice1712 *ice)  	* don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten  	*/  	ice->gpio.saved[0] = 0; -	/* to remeber the register values */ +	/* to remember the register values */  	ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);  	if (! ice->akm) @@ -1140,7 +1140,7 @@ static int __devinit prodigy_hd2_init(struct snd_ice1712 *ice)  		return -ENOMEM;  	ice->spec = spec; -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP  	ice->pm_resume = &prodigy_hd2_resume;  	ice->pm_suspend_enabled = 1;  #endif @@ -1151,7 +1151,7 @@ static int __devinit prodigy_hd2_init(struct snd_ice1712 *ice)  } -static unsigned char prodigy71hifi_eeprom[] __devinitdata = { +static unsigned char prodigy71hifi_eeprom[] = {  	0x4b,   /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */  	0x80,   /* ACLINK: I2S */  	0xfc,   /* I2S: vol, 96k, 24bit, 192k */ @@ -1167,7 +1167,7 @@ static unsigned char prodigy71hifi_eeprom[] __devinitdata = {  	0x00,   /* GPIO_STATE2 */  }; -static unsigned char prodigyhd2_eeprom[] __devinitdata = { +static unsigned char prodigyhd2_eeprom[] = {  	0x4b,   /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */  	0x80,   /* ACLINK: I2S */  	0xfc,   /* I2S: vol, 96k, 24bit, 192k */ @@ -1183,7 +1183,7 @@ static unsigned char prodigyhd2_eeprom[] __devinitdata = {  	0x00,   /* GPIO_STATE2 */  }; -static unsigned char fortissimo4_eeprom[] __devinitdata = { +static unsigned char fortissimo4_eeprom[] = {  	0x43,   /* SYSCONF: clock 512, ADC, 4DACs */	  	0x80,   /* ACLINK: I2S */  	0xfc,   /* I2S: vol, 96k, 24bit, 192k */ @@ -1200,7 +1200,7 @@ static unsigned char fortissimo4_eeprom[] __devinitdata = {  };  /* entry point */ -struct snd_ice1712_card_info snd_vt1724_prodigy_hifi_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_prodigy_hifi_cards[] = {  	{  		.subvendor = VT1724_SUBDEVICE_PRODIGY_HIFI,  		.name = "Audiotrak Prodigy 7.1 HiFi", diff --git a/sound/pci/ice1712/psc724.c b/sound/pci/ice1712/psc724.c new file mode 100644 index 00000000000..4019cf27d11 --- /dev/null +++ b/sound/pci/ice1712/psc724.c @@ -0,0 +1,464 @@ +/* + *   ALSA driver for ICEnsemble VT1724 (Envy24HT) + * + *   Lowlevel functions for Philips PSC724 Ultimate Edge + * + *	Copyright (c) 2012 Ondrej Zary <linux@rainbow-software.org> + * + *   This program is free software; you can redistribute it and/or modify + *   it under the terms of the GNU General Public License as published by + *   the Free Software Foundation; either version 2 of the License, or + *   (at your option) any later version. + * + *   This program is distributed in the hope that it will be useful, + *   but WITHOUT ANY WARRANTY; without even the implied warranty of + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *   GNU General Public License for more details. + * + *   You should have received a copy of the GNU General Public License + *   along with this program; if not, write to the Free Software + *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA + * + */ + +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <sound/core.h> + +#include "ice1712.h" +#include "envy24ht.h" +#include "psc724.h" +#include "wm8766.h" +#include "wm8776.h" + +struct psc724_spec { +	struct snd_wm8766 wm8766; +	struct snd_wm8776 wm8776; +	bool mute_all, jack_detect; +	struct snd_ice1712 *ice; +	struct delayed_work hp_work; +	bool hp_connected; +}; + +/****************************************************************************/ +/*  PHILIPS PSC724 ULTIMATE EDGE                                            */ +/****************************************************************************/ +/* + *  VT1722 (Envy24GT) - 6 outputs, 4 inputs (only 2 used), 24-bit/96kHz + * + *  system configuration ICE_EEP2_SYSCONF=0x42 + *    XIN1 49.152MHz + *    no MPU401 + *    one stereo ADC, no S/PDIF receiver + *    three stereo DACs (FRONT, REAR, CENTER+LFE) + * + *  AC-Link configuration ICE_EEP2_ACLINK=0x80 + *    use I2S, not AC97 + * + *  I2S converters feature ICE_EEP2_I2S=0x30 + *    I2S codec has no volume/mute control feature (bug!) + *    I2S codec does not support 96KHz or 192KHz (bug!) + *    I2S codec 24bits + * + *  S/PDIF configuration ICE_EEP2_SPDIF=0xc1 + *    Enable integrated S/PDIF transmitter + *    internal S/PDIF out implemented + *    No S/PDIF input + *    External S/PDIF out implemented + * + * + * ** connected chips ** + * + *  WM8776 + *     2-channel DAC used for main output and stereo ADC (with 10-channel MUX) + *     AIN1: LINE IN, AIN2: CD/VIDEO, AIN3: AUX, AIN4: Front MIC, AIN5: Rear MIC + *     Controlled by I2C using VT1722 I2C interface: + *          MODE (pin16) -- GND + *          CE   (pin17) -- GND  I2C mode (address=0x34) + *          DI   (pin18) -- SDA  (VT1722 pin70) + *          CL   (pin19) -- SCLK (VT1722 pin71) + * + *  WM8766 + *      6-channel DAC used for rear & center/LFE outputs (only 4 channels used) + *      Controlled by SPI using VT1722 GPIO pins: + *          MODE   (pin 1) -- GPIO19 (VT1722 pin99) + *          ML/I2S (pin11) -- GPIO18 (VT1722 pin98) + *          MC/IWL (pin12) -- GPIO17 (VT1722 pin97) + *          MD/DM  (pin13) -- GPIO16 (VT1722 pin96) + *          MUTE   (pin14) -- GPIO20 (VT1722 pin101) + * + *  GPIO14 is used as input for headphone jack detection (1 = connected) + *  GPIO22 is used as MUTE ALL output, grounding all 6 channels + * + * ** output pins and device names ** + * + *   5.1ch name -- output connector color -- device (-D option) + * + *      FRONT 2ch                  -- green  -- plughw:0,0 + *      CENTER(Lch) SUBWOOFER(Rch) -- orange -- plughw:0,2,0 + *      REAR 2ch                   -- black  -- plughw:0,2,1 + */ + +/* codec access low-level functions */ + +#define GPIO_HP_JACK	(1 << 14) +#define GPIO_MUTE_SUR	(1 << 20) +#define GPIO_MUTE_ALL	(1 << 22) + +#define JACK_INTERVAL	1000 + +#define PSC724_SPI_DELAY 1 + +#define PSC724_SPI_DATA	(1 << 16) +#define PSC724_SPI_CLK	(1 << 17) +#define PSC724_SPI_LOAD	(1 << 18) +#define PSC724_SPI_MASK	(PSC724_SPI_DATA | PSC724_SPI_CLK | PSC724_SPI_LOAD) + +static void psc724_wm8766_write(struct snd_wm8766 *wm, u16 addr, u16 data) +{ +	struct psc724_spec *spec = container_of(wm, struct psc724_spec, wm8766); +	struct snd_ice1712 *ice = spec->ice; +	u32 st, bits; +	int i; + +	snd_ice1712_save_gpio_status(ice); + +	st = ((addr & 0x7f) << 9) | (data & 0x1ff); +	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction | PSC724_SPI_MASK); +	snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask & ~PSC724_SPI_MASK); +	bits = snd_ice1712_gpio_read(ice) & ~PSC724_SPI_MASK; +	snd_ice1712_gpio_write(ice, bits); + +	for (i = 0; i < 16; i++) { +		udelay(PSC724_SPI_DELAY); +		bits &= ~PSC724_SPI_CLK; +		/* MSB first */ +		st <<= 1; +		if (st & 0x10000) +			bits |= PSC724_SPI_DATA; +		else +			bits &= ~PSC724_SPI_DATA; +		snd_ice1712_gpio_write(ice, bits); +		/* CLOCK high */ +		udelay(PSC724_SPI_DELAY); +		bits |= PSC724_SPI_CLK; +		snd_ice1712_gpio_write(ice, bits); +	} +	/* LOAD high */ +	udelay(PSC724_SPI_DELAY); +	bits |= PSC724_SPI_LOAD; +	snd_ice1712_gpio_write(ice, bits); +	/* LOAD low, DATA and CLOCK high */ +	udelay(PSC724_SPI_DELAY); +	bits |= (PSC724_SPI_DATA | PSC724_SPI_CLK); +	snd_ice1712_gpio_write(ice, bits); + +	snd_ice1712_restore_gpio_status(ice); +} + +static void psc724_wm8776_write(struct snd_wm8776 *wm, u8 addr, u8 data) +{ +	struct psc724_spec *spec = container_of(wm, struct psc724_spec, wm8776); + +	snd_vt1724_write_i2c(spec->ice, 0x34, addr, data); +} + +/* mute all */ + +static void psc724_set_master_switch(struct snd_ice1712 *ice, bool on) +{ +	unsigned int bits = snd_ice1712_gpio_read(ice); +	struct psc724_spec *spec = ice->spec; + +	spec->mute_all = !on; +	if (on) +		bits &= ~(GPIO_MUTE_ALL | GPIO_MUTE_SUR); +	else +		bits |= GPIO_MUTE_ALL | GPIO_MUTE_SUR; +	snd_ice1712_gpio_write(ice, bits); +} + +static bool psc724_get_master_switch(struct snd_ice1712 *ice) +{ +	struct psc724_spec *spec = ice->spec; + +	return !spec->mute_all; +} + +/* jack detection */ + +static void psc724_set_jack_state(struct snd_ice1712 *ice, bool hp_connected) +{ +	struct psc724_spec *spec = ice->spec; +	struct snd_ctl_elem_id elem_id; +	struct snd_kcontrol *kctl; +	u16 power = spec->wm8776.regs[WM8776_REG_PWRDOWN] & ~WM8776_PWR_HPPD; + +	psc724_set_master_switch(ice, !hp_connected); +	if (!hp_connected) +		power |= WM8776_PWR_HPPD; +	snd_wm8776_set_power(&spec->wm8776, power); +	spec->hp_connected = hp_connected; +	/* notify about master speaker mute change */ +	memset(&elem_id, 0, sizeof(elem_id)); +	elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; +	strlcpy(elem_id.name, "Master Speakers Playback Switch", +						sizeof(elem_id.name)); +	kctl = snd_ctl_find_id(ice->card, &elem_id); +	snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); +	/* and headphone mute change */ +	strlcpy(elem_id.name, spec->wm8776.ctl[WM8776_CTL_HP_SW].name, +						sizeof(elem_id.name)); +	kctl = snd_ctl_find_id(ice->card, &elem_id); +	snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); +} + +static void psc724_update_hp_jack_state(struct work_struct *work) +{ +	struct psc724_spec *spec = container_of(work, struct psc724_spec, +						hp_work.work); +	struct snd_ice1712 *ice = spec->ice; +	bool hp_connected = snd_ice1712_gpio_read(ice) & GPIO_HP_JACK; + +	schedule_delayed_work(&spec->hp_work, msecs_to_jiffies(JACK_INTERVAL)); +	if (hp_connected == spec->hp_connected) +		return; +	psc724_set_jack_state(ice, hp_connected); +} + +static void psc724_set_jack_detection(struct snd_ice1712 *ice, bool on) +{ +	struct psc724_spec *spec = ice->spec; + +	if (spec->jack_detect == on) +		return; + +	spec->jack_detect = on; +	if (on) { +		bool hp_connected = snd_ice1712_gpio_read(ice) & GPIO_HP_JACK; +		psc724_set_jack_state(ice, hp_connected); +		schedule_delayed_work(&spec->hp_work, +					msecs_to_jiffies(JACK_INTERVAL)); +	} else +		cancel_delayed_work_sync(&spec->hp_work); +} + +static bool psc724_get_jack_detection(struct snd_ice1712 *ice) +{ +	struct psc724_spec *spec = ice->spec; + +	return spec->jack_detect; +} + +/* mixer controls */ + +struct psc724_control { +	const char *name; +	void (*set)(struct snd_ice1712 *ice, bool on); +	bool (*get)(struct snd_ice1712 *ice); +}; + +static const struct psc724_control psc724_cont[] = { +	{ +		.name = "Master Speakers Playback Switch", +		.set = psc724_set_master_switch, +		.get = psc724_get_master_switch, +	}, +	{ +		.name = "Headphone Jack Detection Playback Switch", +		.set = psc724_set_jack_detection, +		.get = psc724_get_jack_detection, +	}, +}; + +static int psc724_ctl_get(struct snd_kcontrol *kcontrol, +				  struct snd_ctl_elem_value *ucontrol) +{ +	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); +	int n = kcontrol->private_value; + +	ucontrol->value.integer.value[0] = psc724_cont[n].get(ice); + +	return 0; +} + +static int psc724_ctl_put(struct snd_kcontrol *kcontrol, +				  struct snd_ctl_elem_value *ucontrol) +{ +	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); +	int n = kcontrol->private_value; + +	psc724_cont[n].set(ice, ucontrol->value.integer.value[0]); + +	return 0; +} + +static const char *front_volume	= "Front Playback Volume"; +static const char *front_switch	= "Front Playback Switch"; +static const char *front_zc	= "Front Zero Cross Detect Playback Switch"; +static const char *front_izd	= "Front Infinite Zero Detect Playback Switch"; +static const char *front_phase	= "Front Phase Invert Playback Switch"; +static const char *front_deemph	= "Front Deemphasis Playback Switch"; +static const char *ain1_switch	= "Line Capture Switch"; +static const char *ain2_switch	= "CD Capture Switch"; +static const char *ain3_switch	= "AUX Capture Switch"; +static const char *ain4_switch	= "Front Mic Capture Switch"; +static const char *ain5_switch	= "Rear Mic Capture Switch"; +static const char *rear_volume	= "Surround Playback Volume"; +static const char *clfe_volume	= "CLFE Playback Volume"; +static const char *rear_switch	= "Surround Playback Switch"; +static const char *clfe_switch	= "CLFE Playback Switch"; +static const char *rear_phase	= "Surround Phase Invert Playback Switch"; +static const char *clfe_phase	= "CLFE Phase Invert Playback Switch"; +static const char *rear_deemph	= "Surround Deemphasis Playback Switch"; +static const char *clfe_deemph	= "CLFE Deemphasis Playback Switch"; +static const char *rear_clfe_izd = "Rear Infinite Zero Detect Playback Switch"; +static const char *rear_clfe_zc	= "Rear Zero Cross Detect Playback Switch"; + +static int psc724_add_controls(struct snd_ice1712 *ice) +{ +	struct snd_kcontrol_new cont; +	struct snd_kcontrol *ctl; +	int err, i; +	struct psc724_spec *spec = ice->spec; + +	spec->wm8776.ctl[WM8776_CTL_DAC_VOL].name = front_volume; +	spec->wm8776.ctl[WM8776_CTL_DAC_SW].name = front_switch; +	spec->wm8776.ctl[WM8776_CTL_DAC_ZC_SW].name = front_zc; +	spec->wm8776.ctl[WM8776_CTL_AUX_SW].name = NULL; +	spec->wm8776.ctl[WM8776_CTL_DAC_IZD_SW].name = front_izd; +	spec->wm8776.ctl[WM8776_CTL_PHASE_SW].name = front_phase; +	spec->wm8776.ctl[WM8776_CTL_DEEMPH_SW].name = front_deemph; +	spec->wm8776.ctl[WM8776_CTL_INPUT1_SW].name = ain1_switch; +	spec->wm8776.ctl[WM8776_CTL_INPUT2_SW].name = ain2_switch; +	spec->wm8776.ctl[WM8776_CTL_INPUT3_SW].name = ain3_switch; +	spec->wm8776.ctl[WM8776_CTL_INPUT4_SW].name = ain4_switch; +	spec->wm8776.ctl[WM8776_CTL_INPUT5_SW].name = ain5_switch; +	snd_wm8776_build_controls(&spec->wm8776); +	spec->wm8766.ctl[WM8766_CTL_CH1_VOL].name = rear_volume; +	spec->wm8766.ctl[WM8766_CTL_CH2_VOL].name = clfe_volume; +	spec->wm8766.ctl[WM8766_CTL_CH3_VOL].name = NULL; +	spec->wm8766.ctl[WM8766_CTL_CH1_SW].name = rear_switch; +	spec->wm8766.ctl[WM8766_CTL_CH2_SW].name = clfe_switch; +	spec->wm8766.ctl[WM8766_CTL_CH3_SW].name = NULL; +	spec->wm8766.ctl[WM8766_CTL_PHASE1_SW].name = rear_phase; +	spec->wm8766.ctl[WM8766_CTL_PHASE2_SW].name = clfe_phase; +	spec->wm8766.ctl[WM8766_CTL_PHASE3_SW].name = NULL; +	spec->wm8766.ctl[WM8766_CTL_DEEMPH1_SW].name = rear_deemph; +	spec->wm8766.ctl[WM8766_CTL_DEEMPH2_SW].name = clfe_deemph; +	spec->wm8766.ctl[WM8766_CTL_DEEMPH3_SW].name = NULL; +	spec->wm8766.ctl[WM8766_CTL_IZD_SW].name = rear_clfe_izd; +	spec->wm8766.ctl[WM8766_CTL_ZC_SW].name = rear_clfe_zc; +	snd_wm8766_build_controls(&spec->wm8766); + +	memset(&cont, 0, sizeof(cont)); +	cont.iface = SNDRV_CTL_ELEM_IFACE_MIXER; +	for (i = 0; i < ARRAY_SIZE(psc724_cont); i++) { +		cont.private_value = i; +		cont.name = psc724_cont[i].name; +		cont.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; +		cont.info = snd_ctl_boolean_mono_info; +		cont.get = psc724_ctl_get; +		cont.put = psc724_ctl_put; +		ctl = snd_ctl_new1(&cont, ice); +		if (!ctl) +			return -ENOMEM; +		err = snd_ctl_add(ice->card, ctl); +		if (err < 0) +			return err; +	} + +	return 0; +} + +static void psc724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate) +{ +	struct psc724_spec *spec = ice->spec; +	/* restore codec volume settings after rate change (PMCLK stop) */ +	snd_wm8776_volume_restore(&spec->wm8776); +	snd_wm8766_volume_restore(&spec->wm8766); +} + +/* power management */ + +#ifdef CONFIG_PM_SLEEP +static int psc724_resume(struct snd_ice1712 *ice) +{ +	struct psc724_spec *spec = ice->spec; + +	snd_wm8776_resume(&spec->wm8776); +	snd_wm8766_resume(&spec->wm8766); + +	return 0; +} +#endif + +/* init */ + +static int psc724_init(struct snd_ice1712 *ice) +{ +	struct psc724_spec *spec; + +	spec = kzalloc(sizeof(*spec), GFP_KERNEL); +	if (!spec) +		return -ENOMEM; +	ice->spec = spec; +	spec->ice = ice; + +	ice->num_total_dacs = 6; +	ice->num_total_adcs = 2; +	spec->wm8776.ops.write = psc724_wm8776_write; +	spec->wm8776.card = ice->card; +	snd_wm8776_init(&spec->wm8776); +	spec->wm8766.ops.write = psc724_wm8766_write; +	spec->wm8766.card = ice->card; +#ifdef CONFIG_PM_SLEEP +	ice->pm_resume = psc724_resume; +	ice->pm_suspend_enabled = 1; +#endif +	snd_wm8766_init(&spec->wm8766); +	snd_wm8766_set_if(&spec->wm8766, +			WM8766_IF_FMT_I2S | WM8766_IF_IWL_24BIT); +	ice->gpio.set_pro_rate = psc724_set_pro_rate; +	INIT_DELAYED_WORK(&spec->hp_work, psc724_update_hp_jack_state); +	psc724_set_jack_detection(ice, true); +	return 0; +} + +static void psc724_exit(struct snd_ice1712 *ice) +{ +	struct psc724_spec *spec = ice->spec; + +	cancel_delayed_work_sync(&spec->hp_work); +} + +/* PSC724 has buggy EEPROM (no 96&192kHz, all FFh GPIOs), so override it here */ +static unsigned char psc724_eeprom[] = { +	[ICE_EEP2_SYSCONF]	= 0x42,	/* 49.152MHz, 1 ADC, 3 DACs */ +	[ICE_EEP2_ACLINK]	= 0x80,	/* I2S */ +	[ICE_EEP2_I2S]		= 0xf0,	/* I2S volume, 96kHz, 24bit */ +	[ICE_EEP2_SPDIF]	= 0xc1,	/* spdif out-en, out-int, no input */ +	/* GPIO outputs */ +	[ICE_EEP2_GPIO_DIR2]	= 0x5f, /* MUTE_ALL,WM8766 MUTE/MODE/ML/MC/MD */ +	/* GPIO write enable */ +	[ICE_EEP2_GPIO_MASK]	= 0xff, /* read-only */ +	[ICE_EEP2_GPIO_MASK1]	= 0xff, /* read-only */ +	[ICE_EEP2_GPIO_MASK2]	= 0xa0, /* MUTE_ALL,WM8766 MUTE/MODE/ML/MC/MD */ +	/* GPIO initial state */ +	[ICE_EEP2_GPIO_STATE2]	= 0x20,	/* unmuted, all WM8766 pins low */ +}; + +struct snd_ice1712_card_info snd_vt1724_psc724_cards[] = { +	{ +		.subvendor = VT1724_SUBDEVICE_PSC724, +		.name = "Philips PSC724 Ultimate Edge", +		.model = "psc724", +		.chip_init = psc724_init, +		.chip_exit = psc724_exit, +		.build_controls = psc724_add_controls, +		.eeprom_size = sizeof(psc724_eeprom), +		.eeprom_data = psc724_eeprom, +	}, +	{} /*terminator*/ +}; diff --git a/sound/pci/ice1712/psc724.h b/sound/pci/ice1712/psc724.h new file mode 100644 index 00000000000..858e5fd0eeb --- /dev/null +++ b/sound/pci/ice1712/psc724.h @@ -0,0 +1,13 @@ +#ifndef __SOUND_PSC724_H +#define __SOUND_PSC724_H + +/* ID */ +#define PSC724_DEVICE_DESC	\ +		"{Philips,PSC724 Ultimate Edge}," + +#define VT1724_SUBDEVICE_PSC724		0xab170619 + +/* entry struct */ +extern struct snd_ice1712_card_info snd_vt1724_psc724_cards[]; + +#endif /* __SOUND_PSC724_H */ diff --git a/sound/pci/ice1712/quartet.c b/sound/pci/ice1712/quartet.c index 1948632787e..2c2df4b74e0 100644 --- a/sound/pci/ice1712/quartet.c +++ b/sound/pci/ice1712/quartet.c @@ -22,7 +22,6 @@   *   */ -#include <asm/io.h>  #include <linux/delay.h>  #include <linux/interrupt.h>  #include <linux/init.h> @@ -47,7 +46,7 @@ struct qtet_kcontrol_private {  	unsigned int bit;  	void (*set_register)(struct snd_ice1712 *ice, unsigned int val);  	unsigned int (*get_register)(struct snd_ice1712 *ice); -	unsigned char *texts[2]; +	unsigned char * const texts[2];  };  enum { @@ -63,7 +62,7 @@ enum {  	OUT34_MON12,  }; -static char *ext_clock_names[3] = {"IEC958 In", "Word Clock 1xFS", +static const char * const ext_clock_names[3] = {"IEC958 In", "Word Clock 1xFS",  	"Word Clock 256xFS"};  /* chip address on I2C bus */ @@ -204,6 +203,7 @@ static char *ext_clock_names[3] = {"IEC958 In", "Word Clock 1xFS",  #define AK4620_DEEMVOL_REG	0x03  #define AK4620_SMUTE		(1<<7) +#ifdef CONFIG_PROC_FS  /*   * Conversion from int value to its binary form. Used for debugging.   * The output buffer must be allocated prior to calling the function. @@ -228,6 +228,7 @@ static char *get_binary(char *buffer, int value)  	buffer[pos] = '\0';  	return buffer;  } +#endif /* CONFIG_PROC_FS */  /*   * Initial setup of the conversion array GPIO <-> rate @@ -279,7 +280,7 @@ static void qtet_akm_write(struct snd_akm4xxx *ak, int chip,  	if (snd_BUG_ON(chip < 0 || chip >= 4))  		return; -	/*printk(KERN_DEBUG "Writing to AK4620: chip=%d, addr=0x%x, +	/*dev_dbg(ice->card->dev, "Writing to AK4620: chip=%d, addr=0x%x,  	  data=0x%x\n", chip, addr, data);*/  	orig_dir = ice->gpio.get_dir(ice);  	ice->gpio.set_dir(ice, orig_dir | GPIO_SPI_ALL); @@ -387,7 +388,7 @@ static const struct snd_akm4xxx_adc_channel qtet_adc[] = {  	AK_CONTROL(PCM_34_CAPTURE_VOLUME, 2),  }; -static struct snd_akm4xxx akm_qtet_dac __devinitdata = { +static struct snd_akm4xxx akm_qtet_dac = {  	.type = SND_AK4620,  	.num_dacs = 4,	/* DAC1 - Output 12  	*/ @@ -551,7 +552,8 @@ static int qtet_mute_put(struct snd_kcontrol *kcontrol,  static int qtet_ain12_enum_info(struct snd_kcontrol *kcontrol,  		struct snd_ctl_elem_info *uinfo)  { -	static char *texts[3] = {"Line In 1/2", "Mic", "Mic + Low-cut"}; +	static const char * const texts[3] = +		{"Line In 1/2", "Mic", "Mic + Low-cut"};  	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;  	uinfo->count = 1;  	uinfo->value.enumerated.items = ARRAY_SIZE(texts); @@ -758,7 +760,7 @@ static int qtet_sw_put(struct snd_kcontrol *kcontrol,  	.put = qtet_sw_put,\  	.private_value = xpriv } -static struct snd_kcontrol_new qtet_controls[] __devinitdata = { +static struct snd_kcontrol_new qtet_controls[] = {  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "Master Playback Switch", @@ -795,17 +797,17 @@ static struct snd_kcontrol_new qtet_controls[] __devinitdata = {  	QTET_CONTROL("Output 3/4 to Monitor 1/2", sw, OUT34_MON12),  }; -static char *slave_vols[] __devinitdata = { +static char *slave_vols[] = {  	PCM_12_PLAYBACK_VOLUME,  	PCM_34_PLAYBACK_VOLUME,  	NULL  }; -static __devinitdata +static  DECLARE_TLV_DB_SCALE(qtet_master_db_scale, -6350, 50, 1); -static struct snd_kcontrol __devinit *ctl_find(struct snd_card *card, -		const char *name) +static struct snd_kcontrol *ctl_find(struct snd_card *card, +				     const char *name)  {  	struct snd_ctl_elem_id sid;  	memset(&sid, 0, sizeof(sid)); @@ -815,8 +817,8 @@ static struct snd_kcontrol __devinit *ctl_find(struct snd_card *card,  	return snd_ctl_find_id(card, &sid);  } -static void __devinit add_slaves(struct snd_card *card, -		struct snd_kcontrol *master, char **list) +static void add_slaves(struct snd_card *card, +		       struct snd_kcontrol *master, char * const *list)  {  	for (; *list; list++) {  		struct snd_kcontrol *slave = ctl_find(card, *list); @@ -825,7 +827,7 @@ static void __devinit add_slaves(struct snd_card *card,  	}  } -static int __devinit qtet_add_controls(struct snd_ice1712 *ice) +static int qtet_add_controls(struct snd_ice1712 *ice)  {  	struct qtet_spec *spec = ice->spec;  	int err, i; @@ -896,7 +898,7 @@ static void qtet_set_rate(struct snd_ice1712 *ice, unsigned int rate)  	new =  (get_cpld(ice) & ~CPLD_CKS_MASK) | get_cks_val(rate);  	/* switch to internal clock, drop CPLD_SYNC_SEL */  	new &= ~CPLD_SYNC_SEL; -	/* printk(KERN_DEBUG "QT - set_rate: old %x, new %x\n", +	/* dev_dbg(ice->card->dev, "QT - set_rate: old %x, new %x\n",  	   get_cpld(ice), new); */  	set_cpld(ice, new);  } @@ -976,7 +978,7 @@ static void qtet_ak4113_change(struct ak4113 *ak4113, unsigned char c0,  			c1) {  		/* only for SPDIF master mode, rate was changed */  		rate = snd_ak4113_external_rate(ak4113); -		/* printk(KERN_DEBUG "ak4113 - input rate changed to %d\n", +		/* dev_dbg(ice->card->dev, "ak4113 - input rate changed to %d\n",  		   rate); */  		qtet_akm_set_rate_val(ice->akm, rate);  	} @@ -1007,7 +1009,7 @@ static void qtet_spdif_in_open(struct snd_ice1712 *ice,  /*   * initialize the chip   */ -static int __devinit qtet_init(struct snd_ice1712 *ice) +static int qtet_init(struct snd_ice1712 *ice)  {  	static const unsigned char ak4113_init_vals[] = {  		/* AK4113_REG_PWRDN */	AK4113_RST | AK4113_PWN | @@ -1095,7 +1097,7 @@ static int __devinit qtet_init(struct snd_ice1712 *ice)  	return 0;  } -static unsigned char qtet_eeprom[] __devinitdata = { +static unsigned char qtet_eeprom[] = {  	[ICE_EEP2_SYSCONF]     = 0x28,	/* clock 256(24MHz), mpu401, 1xADC,  					   1xDACs, SPDIF in */  	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */ @@ -1116,7 +1118,7 @@ static unsigned char qtet_eeprom[] __devinitdata = {  };  /* entry point */ -struct snd_ice1712_card_info snd_vt1724_qtet_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_qtet_cards[] = {  	{  		.subvendor = VT1724_SUBDEVICE_QTET,  		.name = "Infrasonic Quartet", diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index b508bb360b9..1112ec1953b 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c @@ -21,7 +21,6 @@   *   */       -#include <asm/io.h>  #include <linux/delay.h>  #include <linux/interrupt.h>  #include <linux/init.h> @@ -36,6 +35,7 @@  struct revo51_spec {  	struct snd_i2c_device *dev;  	struct snd_pt2258 *pt2258; +	struct ak4114 *ak4114;  };  static void revo_i2s_mclk_changed(struct snd_ice1712 *ice) @@ -235,7 +235,7 @@ static const struct snd_akm4xxx_adc_channel revo51_adc[] = {  	},  }; -static struct snd_akm4xxx akm_revo_front __devinitdata = { +static struct snd_akm4xxx akm_revo_front = {  	.type = SND_AK4381,  	.num_dacs = 2,  	.ops = { @@ -244,7 +244,7 @@ static struct snd_akm4xxx akm_revo_front __devinitdata = {  	.dac_info = revo71_front,  }; -static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = { +static struct snd_ak4xxx_private akm_revo_front_priv = {  	.caddr = 1,  	.cif = 0,  	.data_mask = VT1724_REVO_CDOUT, @@ -256,7 +256,7 @@ static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = {  	.mask_flags = 0,  }; -static struct snd_akm4xxx akm_revo_surround __devinitdata = { +static struct snd_akm4xxx akm_revo_surround = {  	.type = SND_AK4355,  	.idx_offset = 1,  	.num_dacs = 6, @@ -266,7 +266,7 @@ static struct snd_akm4xxx akm_revo_surround __devinitdata = {  	.dac_info = revo71_surround,  }; -static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { +static struct snd_ak4xxx_private akm_revo_surround_priv = {  	.caddr = 3,  	.cif = 0,  	.data_mask = VT1724_REVO_CDOUT, @@ -278,7 +278,7 @@ static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = {  	.mask_flags = 0,  }; -static struct snd_akm4xxx akm_revo51 __devinitdata = { +static struct snd_akm4xxx akm_revo51 = {  	.type = SND_AK4358,  	.num_dacs = 8,  	.ops = { @@ -287,7 +287,7 @@ static struct snd_akm4xxx akm_revo51 __devinitdata = {  	.dac_info = revo51_dac,  }; -static struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { +static struct snd_ak4xxx_private akm_revo51_priv = {  	.caddr = 2,  	.cif = 0,  	.data_mask = VT1724_REVO_CDOUT, @@ -299,13 +299,13 @@ static struct snd_ak4xxx_private akm_revo51_priv __devinitdata = {  	.mask_flags = 0,  }; -static struct snd_akm4xxx akm_revo51_adc __devinitdata = { +static struct snd_akm4xxx akm_revo51_adc = {  	.type = SND_AK5365,  	.num_adcs = 2,  	.adc_info = revo51_adc,  }; -static struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = { +static struct snd_ak4xxx_private akm_revo51_adc_priv = {  	.caddr = 2,  	.cif = 0,  	.data_mask = VT1724_REVO_CDOUT, @@ -346,7 +346,7 @@ static const struct snd_akm4xxx_dac_channel ap192_dac[] = {  	AK_DAC("PCM Playback Volume", 2)  }; -static struct snd_akm4xxx akm_ap192 __devinitdata = { +static struct snd_akm4xxx akm_ap192 = {  	.type = SND_AK4358,  	.num_dacs = 2,  	.ops = { @@ -355,14 +355,14 @@ static struct snd_akm4xxx akm_ap192 __devinitdata = {  	.dac_info = ap192_dac,  }; -static struct snd_ak4xxx_private akm_ap192_priv __devinitdata = { +static struct snd_ak4xxx_private akm_ap192_priv = {  	.caddr = 2,  	.cif = 0,  	.data_mask = VT1724_REVO_CDOUT,  	.clk_mask = VT1724_REVO_CCLK, -	.cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1, -	.cs_addr = VT1724_REVO_CS1, -	.cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1, +	.cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS3, +	.cs_addr = VT1724_REVO_CS3, +	.cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS3,  	.add_flags = VT1724_REVO_CCLK, /* high at init */  	.mask_flags = 0,  }; @@ -373,7 +373,7 @@ static struct snd_ak4xxx_private akm_ap192_priv __devinitdata = {   * CCLK (pin 34) -- GPIO1 pin 51 (shared with AK4358)   * CSN  (pin 35) -- GPIO7 pin 59   */ -#define AK4114_ADDR	0x02 +#define AK4114_ADDR	0x00  static void write_data(struct snd_ice1712 *ice, unsigned int gpio,  		       unsigned int data, int idx) @@ -427,7 +427,7 @@ static unsigned int ap192_4wire_start(struct snd_ice1712 *ice)  	tmp = snd_ice1712_gpio_read(ice);  	tmp |= VT1724_REVO_CCLK; /* high at init */  	tmp |= VT1724_REVO_CS0; -	tmp &= ~VT1724_REVO_CS1; +	tmp &= ~VT1724_REVO_CS3;  	snd_ice1712_gpio_write(ice, tmp);  	udelay(1);  	return tmp; @@ -435,7 +435,7 @@ static unsigned int ap192_4wire_start(struct snd_ice1712 *ice)  static void ap192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp)  { -	tmp |= VT1724_REVO_CS1; +	tmp |= VT1724_REVO_CS3;  	tmp |= VT1724_REVO_CS0;  	snd_ice1712_gpio_write(ice, tmp);  	udelay(1); @@ -468,35 +468,40 @@ static unsigned char ap192_ak4114_read(void *private_data, unsigned char addr)  	return data;  } -static int __devinit ap192_ak4114_init(struct snd_ice1712 *ice) +static int ap192_ak4114_init(struct snd_ice1712 *ice)  {  	static const unsigned char ak4114_init_vals[] = { -		AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, +		AK4114_RST | AK4114_PWN | AK4114_OCKS0,  		AK4114_DIF_I24I2S,  		AK4114_TX1E, -		AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(1), +		AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(0),  		0,  		0  	};  	static const unsigned char ak4114_init_txcsb[] = {  		0x41, 0x02, 0x2c, 0x00, 0x00  	}; -	struct ak4114 *ak;  	int err; +	struct revo51_spec *spec; +	spec = kzalloc(sizeof(*spec), GFP_KERNEL); +	if (!spec) +		return -ENOMEM; +	ice->spec = spec; +  	err = snd_ak4114_create(ice->card,  				 ap192_ak4114_read,  				 ap192_ak4114_write,  				 ak4114_init_vals, ak4114_init_txcsb, -				 ice, &ak); +				 ice, &spec->ak4114);  	/* AK4114 in Revo cannot detect external rate correctly.  	 * No reason to stop capture stream due to incorrect checks */ -	ak->check_flags = AK4114_CHECK_NO_RATE; +	spec->ak4114->check_flags = AK4114_CHECK_NO_RATE;  	return 0; /* error ignored; it's no fatal error */  } -static int __devinit revo_init(struct snd_ice1712 *ice) +static int revo_init(struct snd_ice1712 *ice)  {  	struct snd_akm4xxx *ak;  	int err; @@ -563,6 +568,9 @@ static int __devinit revo_init(struct snd_ice1712 *ice)  					       ice);  		if (err < 0)  			return err; +		err = ap192_ak4114_init(ice); +		if (err < 0) +			return err;  		/* unmute all codecs */  		snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, @@ -574,9 +582,9 @@ static int __devinit revo_init(struct snd_ice1712 *ice)  } -static int __devinit revo_add_controls(struct snd_ice1712 *ice) +static int revo_add_controls(struct snd_ice1712 *ice)  { -	struct revo51_spec *spec; +	struct revo51_spec *spec = ice->spec;  	int err;  	switch (ice->eeprom.subvendor) { @@ -598,7 +606,9 @@ static int __devinit revo_add_controls(struct snd_ice1712 *ice)  		err = snd_ice1712_akm4xxx_build_controls(ice);  		if (err < 0)  			return err; -		err = ap192_ak4114_init(ice); +		/* only capture SPDIF over AK4114 */ +		err = snd_ak4114_build(spec->ak4114, NULL, +		   ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);  		if (err < 0)  			return err;  		break; @@ -607,7 +617,7 @@ static int __devinit revo_add_controls(struct snd_ice1712 *ice)  }  /* entry point */ -struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_revo_cards[] = {  	{  		.subvendor = VT1724_SUBDEVICE_REVOLUTION71,  		.name = "M Audio Revolution-7.1", diff --git a/sound/pci/ice1712/se.c b/sound/pci/ice1712/se.c index 69673b95869..ffd894bb450 100644 --- a/sound/pci/ice1712/se.c +++ b/sound/pci/ice1712/se.c @@ -22,7 +22,6 @@   *   */       -#include <asm/io.h>  #include <linux/delay.h>  #include <linux/interrupt.h>  #include <linux/init.h> @@ -114,7 +113,7 @@ struct se_spec {  /*  WM8740 interface                                                        */  /****************************************************************************/ -static void __devinit se200pci_WM8740_init(struct snd_ice1712 *ice) +static void se200pci_WM8740_init(struct snd_ice1712 *ice)  {  	/* nothing to do */  } @@ -196,7 +195,7 @@ static void se200pci_WM8766_set_volume(struct snd_ice1712 *ice, int ch,  	}  } -static void __devinit se200pci_WM8766_init(struct snd_ice1712 *ice) +static void se200pci_WM8766_init(struct snd_ice1712 *ice)  {  	se200pci_WM8766_write(ice, 0x1f, 0x000); /* RESET ALL */  	udelay(10); @@ -253,7 +252,7 @@ static void se200pci_WM8776_set_input_volume(struct snd_ice1712 *ice,  	se200pci_WM8776_write(ice, 0x0f, vol2 | 0x100);  } -static const char *se200pci_sel[] = { +static const char * const se200pci_sel[] = {  	"LINE-IN", "CD-IN", "MIC-IN", "ALL-MIX", NULL  }; @@ -278,7 +277,7 @@ static void se200pci_WM8776_set_afl(struct snd_ice1712 *ice, unsigned int afl)  		se200pci_WM8776_write(ice, 0x16, 0x001);  } -static const char *se200pci_agc[] = { +static const char * const se200pci_agc[] = {  	"Off", "LimiterMode", "ALCMode", NULL  }; @@ -300,10 +299,10 @@ static void se200pci_WM8776_set_agc(struct snd_ice1712 *ice, unsigned int agc)  	}  } -static void __devinit se200pci_WM8776_init(struct snd_ice1712 *ice) +static void se200pci_WM8776_init(struct snd_ice1712 *ice)  {  	int i; -	static unsigned short __devinitdata default_values[] = { +	static unsigned short default_values[] = {  		0x100, 0x100, 0x100,  		0x100, 0x100, 0x100,  		0x000, 0x090, 0x000, 0x000, @@ -352,7 +351,7 @@ static void se200pci_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate)  }  struct se200pci_control { -	char *name; +	const char *name;  	enum {  		WM8766,  		WM8776in, @@ -363,7 +362,7 @@ struct se200pci_control {  	} target;  	enum { VOLUME1, VOLUME2, BOOLEAN, ENUM } type;  	int ch; -	const char **member; +	const char * const *member;  	const char *comment;  }; @@ -421,7 +420,7 @@ static const struct se200pci_control se200pci_cont[] = {  static int se200pci_get_enum_count(int n)  { -	const char **member; +	const char * const *member;  	int c;  	member = se200pci_cont[n].member; @@ -600,7 +599,7 @@ static int se200pci_cont_enum_put(struct snd_kcontrol *kc,  static const DECLARE_TLV_DB_SCALE(db_scale_gain1, -12750, 50, 1);  static const DECLARE_TLV_DB_SCALE(db_scale_gain2, -10350, 50, 1); -static int __devinit se200pci_add_controls(struct snd_ice1712 *ice) +static int se200pci_add_controls(struct snd_ice1712 *ice)  {  	int i;  	struct snd_kcontrol_new cont; @@ -678,7 +677,7 @@ static int __devinit se200pci_add_controls(struct snd_ice1712 *ice)  /*  probe/initialize/setup                                                  */  /****************************************************************************/ -static int __devinit se_init(struct snd_ice1712 *ice) +static int se_init(struct snd_ice1712 *ice)  {  	struct se_spec *spec; @@ -706,7 +705,7 @@ static int __devinit se_init(struct snd_ice1712 *ice)  	return -ENOENT;  } -static int __devinit se_add_controls(struct snd_ice1712 *ice) +static int se_add_controls(struct snd_ice1712 *ice)  {  	int err; @@ -723,7 +722,7 @@ static int __devinit se_add_controls(struct snd_ice1712 *ice)  /*  entry point                                                             */  /****************************************************************************/ -static unsigned char se200pci_eeprom[] __devinitdata = { +static unsigned char se200pci_eeprom[] = {  	[ICE_EEP2_SYSCONF]	= 0x4b,	/* 49.152Hz, spdif-in/ADC, 4DACs */  	[ICE_EEP2_ACLINK]	= 0x80,	/* I2S */  	[ICE_EEP2_I2S]		= 0x78,	/* 96k-ok, 24bit, 192k-ok */ @@ -742,7 +741,7 @@ static unsigned char se200pci_eeprom[] __devinitdata = {  	[ICE_EEP2_GPIO_STATE2]	= 0x07, /* WM8766 ML/MC/MD */  }; -static unsigned char se90pci_eeprom[] __devinitdata = { +static unsigned char se90pci_eeprom[] = {  	[ICE_EEP2_SYSCONF]	= 0x4b,	/* 49.152Hz, spdif-in/ADC, 4DACs */  	[ICE_EEP2_ACLINK]	= 0x80,	/* I2S */  	[ICE_EEP2_I2S]		= 0x78,	/* 96k-ok, 24bit, 192k-ok */ @@ -751,7 +750,7 @@ static unsigned char se90pci_eeprom[] __devinitdata = {  	/* ALL GPIO bits are in input mode */  }; -struct snd_ice1712_card_info snd_vt1724_se_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_se_cards[] = {  	{  		.subvendor = VT1724_SUBDEVICE_SE200PCI,  		.name = "ONKYO SE200PCI", diff --git a/sound/pci/ice1712/vt1720_mobo.c b/sound/pci/ice1712/vt1720_mobo.c index 4c551e147c0..5dbb867e642 100644 --- a/sound/pci/ice1712/vt1720_mobo.c +++ b/sound/pci/ice1712/vt1720_mobo.c @@ -21,7 +21,6 @@   *   */       -#include <asm/io.h>  #include <linux/delay.h>  #include <linux/interrupt.h>  #include <linux/init.h> @@ -32,7 +31,7 @@  #include "vt1720_mobo.h" -static int __devinit k8x800_init(struct snd_ice1712 *ice) +static int k8x800_init(struct snd_ice1712 *ice)  {  	ice->vt1720 = 1; @@ -46,7 +45,7 @@ static int __devinit k8x800_init(struct snd_ice1712 *ice)  	return 0;  } -static int __devinit k8x800_add_controls(struct snd_ice1712 *ice) +static int k8x800_add_controls(struct snd_ice1712 *ice)  {  	/* FIXME: needs some quirks for VT1616? */  	return 0; @@ -54,7 +53,7 @@ static int __devinit k8x800_add_controls(struct snd_ice1712 *ice)  /* EEPROM image */ -static unsigned char k8x800_eeprom[] __devinitdata = { +static unsigned char k8x800_eeprom[] = {  	[ICE_EEP2_SYSCONF]     = 0x01,	/* clock 256, 1ADC, 2DACs */  	[ICE_EEP2_ACLINK]      = 0x02,	/* ACLINK, packed */  	[ICE_EEP2_I2S]         = 0x00,	/* - */ @@ -70,7 +69,7 @@ static unsigned char k8x800_eeprom[] __devinitdata = {  	[ICE_EEP2_GPIO_STATE2] = 0x00,	/* - */  }; -static unsigned char sn25p_eeprom[] __devinitdata = { +static unsigned char sn25p_eeprom[] = {  	[ICE_EEP2_SYSCONF]     = 0x01,	/* clock 256, 1ADC, 2DACs */  	[ICE_EEP2_ACLINK]      = 0x02,	/* ACLINK, packed */  	[ICE_EEP2_I2S]         = 0x00,	/* - */ @@ -88,7 +87,7 @@ static unsigned char sn25p_eeprom[] __devinitdata = {  /* entry point */ -struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1720_mobo_cards[] = {  	{  		.subvendor = VT1720_SUBDEVICE_K8X800,  		.name = "Albatron K8X800 Pro II", diff --git a/sound/pci/ice1712/wm8766.c b/sound/pci/ice1712/wm8766.c new file mode 100644 index 00000000000..21b373b2e26 --- /dev/null +++ b/sound/pci/ice1712/wm8766.c @@ -0,0 +1,362 @@ +/* + *   ALSA driver for ICEnsemble VT17xx + * + *   Lowlevel functions for WM8766 codec + * + *	Copyright (c) 2012 Ondrej Zary <linux@rainbow-software.org> + * + *   This program is free software; you can redistribute it and/or modify + *   it under the terms of the GNU General Public License as published by + *   the Free Software Foundation; either version 2 of the License, or + *   (at your option) any later version. + * + *   This program is distributed in the hope that it will be useful, + *   but WITHOUT ANY WARRANTY; without even the implied warranty of + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *   GNU General Public License for more details. + * + *   You should have received a copy of the GNU General Public License + *   along with this program; if not, write to the Free Software + *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA + * + */ + +#include <linux/delay.h> +#include <sound/core.h> +#include <sound/control.h> +#include <sound/tlv.h> +#include "wm8766.h" + +/* low-level access */ + +static void snd_wm8766_write(struct snd_wm8766 *wm, u16 addr, u16 data) +{ +	if (addr < WM8766_REG_COUNT) +		wm->regs[addr] = data; +	wm->ops.write(wm, addr, data); +} + +/* mixer controls */ + +static const DECLARE_TLV_DB_SCALE(wm8766_tlv, -12750, 50, 1); + +static struct snd_wm8766_ctl snd_wm8766_default_ctl[WM8766_CTL_COUNT] = { +	[WM8766_CTL_CH1_VOL] = { +		.name = "Channel 1 Playback Volume", +		.type = SNDRV_CTL_ELEM_TYPE_INTEGER, +		.tlv = wm8766_tlv, +		.reg1 = WM8766_REG_DACL1, +		.reg2 = WM8766_REG_DACR1, +		.mask1 = WM8766_VOL_MASK, +		.mask2 = WM8766_VOL_MASK, +		.max = 0xff, +		.flags = WM8766_FLAG_STEREO | WM8766_FLAG_VOL_UPDATE, +	}, +	[WM8766_CTL_CH2_VOL] = { +		.name = "Channel 2 Playback Volume", +		.type = SNDRV_CTL_ELEM_TYPE_INTEGER, +		.tlv = wm8766_tlv, +		.reg1 = WM8766_REG_DACL2, +		.reg2 = WM8766_REG_DACR2, +		.mask1 = WM8766_VOL_MASK, +		.mask2 = WM8766_VOL_MASK, +		.max = 0xff, +		.flags = WM8766_FLAG_STEREO | WM8766_FLAG_VOL_UPDATE, +	}, +	[WM8766_CTL_CH3_VOL] = { +		.name = "Channel 3 Playback Volume", +		.type = SNDRV_CTL_ELEM_TYPE_INTEGER, +		.tlv = wm8766_tlv, +		.reg1 = WM8766_REG_DACL3, +		.reg2 = WM8766_REG_DACR3, +		.mask1 = WM8766_VOL_MASK, +		.mask2 = WM8766_VOL_MASK, +		.max = 0xff, +		.flags = WM8766_FLAG_STEREO | WM8766_FLAG_VOL_UPDATE, +	}, +	[WM8766_CTL_CH1_SW] = { +		.name = "Channel 1 Playback Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8766_REG_DACCTRL2, +		.mask1 = WM8766_DAC2_MUTE1, +		.flags = WM8766_FLAG_INVERT, +	}, +	[WM8766_CTL_CH2_SW] = { +		.name = "Channel 2 Playback Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8766_REG_DACCTRL2, +		.mask1 = WM8766_DAC2_MUTE2, +		.flags = WM8766_FLAG_INVERT, +	}, +	[WM8766_CTL_CH3_SW] = { +		.name = "Channel 3 Playback Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8766_REG_DACCTRL2, +		.mask1 = WM8766_DAC2_MUTE3, +		.flags = WM8766_FLAG_INVERT, +	}, +	[WM8766_CTL_PHASE1_SW] = { +		.name = "Channel 1 Phase Invert Playback Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8766_REG_IFCTRL, +		.mask1 = WM8766_PHASE_INVERT1, +	}, +	[WM8766_CTL_PHASE2_SW] = { +		.name = "Channel 2 Phase Invert Playback Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8766_REG_IFCTRL, +		.mask1 = WM8766_PHASE_INVERT2, +	}, +	[WM8766_CTL_PHASE3_SW] = { +		.name = "Channel 3 Phase Invert Playback Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8766_REG_IFCTRL, +		.mask1 = WM8766_PHASE_INVERT3, +	}, +	[WM8766_CTL_DEEMPH1_SW] = { +		.name = "Channel 1 Deemphasis Playback Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8766_REG_DACCTRL2, +		.mask1 = WM8766_DAC2_DEEMP1, +	}, +	[WM8766_CTL_DEEMPH2_SW] = { +		.name = "Channel 2 Deemphasis Playback Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8766_REG_DACCTRL2, +		.mask1 = WM8766_DAC2_DEEMP2, +	}, +	[WM8766_CTL_DEEMPH3_SW] = { +		.name = "Channel 3 Deemphasis Playback Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8766_REG_DACCTRL2, +		.mask1 = WM8766_DAC2_DEEMP3, +	}, +	[WM8766_CTL_IZD_SW] = { +		.name = "Infinite Zero Detect Playback Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8766_REG_DACCTRL1, +		.mask1 = WM8766_DAC_IZD, +	}, +	[WM8766_CTL_ZC_SW] = { +		.name = "Zero Cross Detect Playback Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8766_REG_DACCTRL2, +		.mask1 = WM8766_DAC2_ZCD, +		.flags = WM8766_FLAG_INVERT, +	}, +}; + +/* exported functions */ + +void snd_wm8766_init(struct snd_wm8766 *wm) +{ +	int i; +	static const u16 default_values[] = { +		0x000, 0x100, +		0x120, 0x000, +		0x000, 0x100, 0x000, 0x100, 0x000, +		0x000, 0x080, +	}; + +	memcpy(wm->ctl, snd_wm8766_default_ctl, sizeof(wm->ctl)); + +	snd_wm8766_write(wm, WM8766_REG_RESET, 0x00); /* reset */ +	udelay(10); +	/* load defaults */ +	for (i = 0; i < ARRAY_SIZE(default_values); i++) +		snd_wm8766_write(wm, i, default_values[i]); +} + +void snd_wm8766_resume(struct snd_wm8766 *wm) +{ +	int i; + +	for (i = 0; i < WM8766_REG_COUNT; i++) +		snd_wm8766_write(wm, i, wm->regs[i]); +} + +void snd_wm8766_set_if(struct snd_wm8766 *wm, u16 dac) +{ +	u16 val = wm->regs[WM8766_REG_IFCTRL] & ~WM8766_IF_MASK; + +	dac &= WM8766_IF_MASK; +	snd_wm8766_write(wm, WM8766_REG_IFCTRL, val | dac); +} + +void snd_wm8766_set_master_mode(struct snd_wm8766 *wm, u16 mode) +{ +	u16 val = wm->regs[WM8766_REG_DACCTRL3] & ~WM8766_DAC3_MSTR_MASK; + +	mode &= WM8766_DAC3_MSTR_MASK; +	snd_wm8766_write(wm, WM8766_REG_DACCTRL3, val | mode); +} + +void snd_wm8766_set_power(struct snd_wm8766 *wm, u16 power) +{ +	u16 val = wm->regs[WM8766_REG_DACCTRL3] & ~WM8766_DAC3_POWER_MASK; + +	power &= WM8766_DAC3_POWER_MASK; +	snd_wm8766_write(wm, WM8766_REG_DACCTRL3, val | power); +} + +void snd_wm8766_volume_restore(struct snd_wm8766 *wm) +{ +	u16 val = wm->regs[WM8766_REG_DACR1]; +	/* restore volume after MCLK stopped */ +	snd_wm8766_write(wm, WM8766_REG_DACR1, val | WM8766_VOL_UPDATE); +} + +/* mixer callbacks */ + +static int snd_wm8766_volume_info(struct snd_kcontrol *kcontrol, +				   struct snd_ctl_elem_info *uinfo) +{ +	struct snd_wm8766 *wm = snd_kcontrol_chip(kcontrol); +	int n = kcontrol->private_value; + +	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; +	uinfo->count = (wm->ctl[n].flags & WM8766_FLAG_STEREO) ? 2 : 1; +	uinfo->value.integer.min = wm->ctl[n].min; +	uinfo->value.integer.max = wm->ctl[n].max; + +	return 0; +} + +static int snd_wm8766_enum_info(struct snd_kcontrol *kcontrol, +				      struct snd_ctl_elem_info *uinfo) +{ +	struct snd_wm8766 *wm = snd_kcontrol_chip(kcontrol); +	int n = kcontrol->private_value; + +	return snd_ctl_enum_info(uinfo, 1, wm->ctl[n].max, +						wm->ctl[n].enum_names); +} + +static int snd_wm8766_ctl_get(struct snd_kcontrol *kcontrol, +				  struct snd_ctl_elem_value *ucontrol) +{ +	struct snd_wm8766 *wm = snd_kcontrol_chip(kcontrol); +	int n = kcontrol->private_value; +	u16 val1, val2; + +	if (wm->ctl[n].get) +		wm->ctl[n].get(wm, &val1, &val2); +	else { +		val1 = wm->regs[wm->ctl[n].reg1] & wm->ctl[n].mask1; +		val1 >>= __ffs(wm->ctl[n].mask1); +		if (wm->ctl[n].flags & WM8766_FLAG_STEREO) { +			val2 = wm->regs[wm->ctl[n].reg2] & wm->ctl[n].mask2; +			val2 >>= __ffs(wm->ctl[n].mask2); +			if (wm->ctl[n].flags & WM8766_FLAG_VOL_UPDATE) +				val2 &= ~WM8766_VOL_UPDATE; +		} +	} +	if (wm->ctl[n].flags & WM8766_FLAG_INVERT) { +		val1 = wm->ctl[n].max - (val1 - wm->ctl[n].min); +		if (wm->ctl[n].flags & WM8766_FLAG_STEREO) +			val2 = wm->ctl[n].max - (val2 - wm->ctl[n].min); +	} +	ucontrol->value.integer.value[0] = val1; +	if (wm->ctl[n].flags & WM8766_FLAG_STEREO) +		ucontrol->value.integer.value[1] = val2; + +	return 0; +} + +static int snd_wm8766_ctl_put(struct snd_kcontrol *kcontrol, +				  struct snd_ctl_elem_value *ucontrol) +{ +	struct snd_wm8766 *wm = snd_kcontrol_chip(kcontrol); +	int n = kcontrol->private_value; +	u16 val, regval1, regval2; + +	/* this also works for enum because value is an union */ +	regval1 = ucontrol->value.integer.value[0]; +	regval2 = ucontrol->value.integer.value[1]; +	if (wm->ctl[n].flags & WM8766_FLAG_INVERT) { +		regval1 = wm->ctl[n].max - (regval1 - wm->ctl[n].min); +		regval2 = wm->ctl[n].max - (regval2 - wm->ctl[n].min); +	} +	if (wm->ctl[n].set) +		wm->ctl[n].set(wm, regval1, regval2); +	else { +		val = wm->regs[wm->ctl[n].reg1] & ~wm->ctl[n].mask1; +		val |= regval1 << __ffs(wm->ctl[n].mask1); +		/* both stereo controls in one register */ +		if (wm->ctl[n].flags & WM8766_FLAG_STEREO && +				wm->ctl[n].reg1 == wm->ctl[n].reg2) { +			val &= ~wm->ctl[n].mask2; +			val |= regval2 << __ffs(wm->ctl[n].mask2); +		} +		snd_wm8766_write(wm, wm->ctl[n].reg1, val); +		/* stereo controls in different registers */ +		if (wm->ctl[n].flags & WM8766_FLAG_STEREO && +				wm->ctl[n].reg1 != wm->ctl[n].reg2) { +			val = wm->regs[wm->ctl[n].reg2] & ~wm->ctl[n].mask2; +			val |= regval2 << __ffs(wm->ctl[n].mask2); +			if (wm->ctl[n].flags & WM8766_FLAG_VOL_UPDATE) +				val |= WM8766_VOL_UPDATE; +			snd_wm8766_write(wm, wm->ctl[n].reg2, val); +		} +	} + +	return 0; +} + +static int snd_wm8766_add_control(struct snd_wm8766 *wm, int num) +{ +	struct snd_kcontrol_new cont; +	struct snd_kcontrol *ctl; + +	memset(&cont, 0, sizeof(cont)); +	cont.iface = SNDRV_CTL_ELEM_IFACE_MIXER; +	cont.private_value = num; +	cont.name = wm->ctl[num].name; +	cont.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; +	if (wm->ctl[num].flags & WM8766_FLAG_LIM || +	    wm->ctl[num].flags & WM8766_FLAG_ALC) +		cont.access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; +	cont.tlv.p = NULL; +	cont.get = snd_wm8766_ctl_get; +	cont.put = snd_wm8766_ctl_put; + +	switch (wm->ctl[num].type) { +	case SNDRV_CTL_ELEM_TYPE_INTEGER: +		cont.info = snd_wm8766_volume_info; +		cont.access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; +		cont.tlv.p = wm->ctl[num].tlv; +		break; +	case SNDRV_CTL_ELEM_TYPE_BOOLEAN: +		wm->ctl[num].max = 1; +		if (wm->ctl[num].flags & WM8766_FLAG_STEREO) +			cont.info = snd_ctl_boolean_stereo_info; +		else +			cont.info = snd_ctl_boolean_mono_info; +		break; +	case SNDRV_CTL_ELEM_TYPE_ENUMERATED: +		cont.info = snd_wm8766_enum_info; +		break; +	default: +		return -EINVAL; +	} +	ctl = snd_ctl_new1(&cont, wm); +	if (!ctl) +		return -ENOMEM; +	wm->ctl[num].kctl = ctl; + +	return snd_ctl_add(wm->card, ctl); +} + +int snd_wm8766_build_controls(struct snd_wm8766 *wm) +{ +	int err, i; + +	for (i = 0; i < WM8766_CTL_COUNT; i++) +		if (wm->ctl[i].name) { +			err = snd_wm8766_add_control(wm, i); +			if (err < 0) +				return err; +		} + +	return 0; +} diff --git a/sound/pci/ice1712/wm8766.h b/sound/pci/ice1712/wm8766.h new file mode 100644 index 00000000000..c119f84bd2c --- /dev/null +++ b/sound/pci/ice1712/wm8766.h @@ -0,0 +1,163 @@ +#ifndef __SOUND_WM8766_H +#define __SOUND_WM8766_H + +/* + *   ALSA driver for ICEnsemble VT17xx + * + *   Lowlevel functions for WM8766 codec + * + *	Copyright (c) 2012 Ondrej Zary <linux@rainbow-software.org> + * + *   This program is free software; you can redistribute it and/or modify + *   it under the terms of the GNU General Public License as published by + *   the Free Software Foundation; either version 2 of the License, or + *   (at your option) any later version. + * + *   This program is distributed in the hope that it will be useful, + *   but WITHOUT ANY WARRANTY; without even the implied warranty of + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *   GNU General Public License for more details. + * + *   You should have received a copy of the GNU General Public License + *   along with this program; if not, write to the Free Software + *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA + * + */ + +#define WM8766_REG_DACL1	0x00 +#define WM8766_REG_DACR1	0x01 +#define WM8766_VOL_MASK			0x1ff		/* incl. update bit */ +#define WM8766_VOL_UPDATE		(1 << 8)	/* update volume */ +#define WM8766_REG_DACCTRL1	0x02 +#define WM8766_DAC_MUTEALL		(1 << 0) +#define WM8766_DAC_DEEMPALL		(1 << 1) +#define WM8766_DAC_PDWN			(1 << 2) +#define WM8766_DAC_ATC			(1 << 3) +#define WM8766_DAC_IZD			(1 << 4) +#define WM8766_DAC_PL_MASK		0x1e0 +#define WM8766_DAC_PL_LL		(1 << 5)	/* L chan: L signal */ +#define WM8766_DAC_PL_LR		(2 << 5)	/* L chan: R signal */ +#define WM8766_DAC_PL_LB		(3 << 5)	/* L chan: both */ +#define WM8766_DAC_PL_RL		(1 << 7)	/* R chan: L signal */ +#define WM8766_DAC_PL_RR		(2 << 7)	/* R chan: R signal */ +#define WM8766_DAC_PL_RB		(3 << 7)	/* R chan: both */ +#define WM8766_REG_IFCTRL	0x03 +#define WM8766_IF_FMT_RIGHTJ		(0 << 0) +#define WM8766_IF_FMT_LEFTJ		(1 << 0) +#define WM8766_IF_FMT_I2S		(2 << 0) +#define WM8766_IF_FMT_DSP		(3 << 0) +#define WM8766_IF_DSP_LATE		(1 << 2)	/* in DSP mode */ +#define WM8766_IF_LRC_INVERTED		(1 << 2)	/* in other modes */ +#define WM8766_IF_BCLK_INVERTED		(1 << 3) +#define WM8766_IF_IWL_16BIT		(0 << 4) +#define WM8766_IF_IWL_20BIT		(1 << 4) +#define WM8766_IF_IWL_24BIT		(2 << 4) +#define WM8766_IF_IWL_32BIT		(3 << 4) +#define WM8766_IF_MASK			0x3f +#define WM8766_PHASE_INVERT1		(1 << 6) +#define WM8766_PHASE_INVERT2		(1 << 7) +#define WM8766_PHASE_INVERT3		(1 << 8) +#define WM8766_REG_DACL2	0x04 +#define WM8766_REG_DACR2	0x05 +#define WM8766_REG_DACL3	0x06 +#define WM8766_REG_DACR3	0x07 +#define WM8766_REG_MASTDA	0x08 +#define WM8766_REG_DACCTRL2	0x09 +#define WM8766_DAC2_ZCD			(1 << 0) +#define WM8766_DAC2_ZFLAG_ALL		(0 << 1) +#define WM8766_DAC2_ZFLAG_1		(1 << 1) +#define WM8766_DAC2_ZFLAG_2		(2 << 1) +#define WM8766_DAC2_ZFLAG_3		(3 << 1) +#define WM8766_DAC2_MUTE1		(1 << 3) +#define WM8766_DAC2_MUTE2		(1 << 4) +#define WM8766_DAC2_MUTE3		(1 << 5) +#define WM8766_DAC2_DEEMP1		(1 << 6) +#define WM8766_DAC2_DEEMP2		(1 << 7) +#define WM8766_DAC2_DEEMP3		(1 << 8) +#define WM8766_REG_DACCTRL3	0x0a +#define WM8766_DAC3_DACPD1		(1 << 1) +#define WM8766_DAC3_DACPD2		(1 << 2) +#define WM8766_DAC3_DACPD3		(1 << 3) +#define WM8766_DAC3_PWRDNALL		(1 << 4) +#define WM8766_DAC3_POWER_MASK		0x1e +#define WM8766_DAC3_MASTER		(1 << 5) +#define WM8766_DAC3_DAC128FS		(0 << 6) +#define WM8766_DAC3_DAC192FS		(1 << 6) +#define WM8766_DAC3_DAC256FS		(2 << 6) +#define WM8766_DAC3_DAC384FS		(3 << 6) +#define WM8766_DAC3_DAC512FS		(4 << 6) +#define WM8766_DAC3_DAC768FS		(5 << 6) +#define WM8766_DAC3_MSTR_MASK		0x1e0 +#define WM8766_REG_MUTE1	0x0c +#define WM8766_MUTE1_MPD		(1 << 6) +#define WM8766_REG_MUTE2	0x0f +#define WM8766_MUTE2_MPD		(1 << 5) +#define WM8766_REG_RESET	0x1f + +#define WM8766_REG_COUNT	0x10	/* don't cache the RESET register */ + +struct snd_wm8766; + +struct snd_wm8766_ops { +	void (*write)(struct snd_wm8766 *wm, u16 addr, u16 data); +}; + +enum snd_wm8766_ctl_id { +	WM8766_CTL_CH1_VOL, +	WM8766_CTL_CH2_VOL, +	WM8766_CTL_CH3_VOL, +	WM8766_CTL_CH1_SW, +	WM8766_CTL_CH2_SW, +	WM8766_CTL_CH3_SW, +	WM8766_CTL_PHASE1_SW, +	WM8766_CTL_PHASE2_SW, +	WM8766_CTL_PHASE3_SW, +	WM8766_CTL_DEEMPH1_SW, +	WM8766_CTL_DEEMPH2_SW, +	WM8766_CTL_DEEMPH3_SW, +	WM8766_CTL_IZD_SW, +	WM8766_CTL_ZC_SW, + +	WM8766_CTL_COUNT, +}; + +#define WM8766_ENUM_MAX		16 + +#define WM8766_FLAG_STEREO	(1 << 0) +#define WM8766_FLAG_VOL_UPDATE	(1 << 1) +#define WM8766_FLAG_INVERT	(1 << 2) +#define WM8766_FLAG_LIM		(1 << 3) +#define WM8766_FLAG_ALC		(1 << 4) + +struct snd_wm8766_ctl { +	struct snd_kcontrol *kctl; +	const char *name; +	snd_ctl_elem_type_t type; +	const char *const enum_names[WM8766_ENUM_MAX]; +	const unsigned int *tlv; +	u16 reg1, reg2, mask1, mask2, min, max, flags; +	void (*set)(struct snd_wm8766 *wm, u16 ch1, u16 ch2); +	void (*get)(struct snd_wm8766 *wm, u16 *ch1, u16 *ch2); +}; + +enum snd_wm8766_agc_mode { WM8766_AGC_OFF, WM8766_AGC_LIM, WM8766_AGC_ALC }; + +struct snd_wm8766 { +	struct snd_card *card; +	struct snd_wm8766_ctl ctl[WM8766_CTL_COUNT]; +	enum snd_wm8766_agc_mode agc_mode; +	struct snd_wm8766_ops ops; +	u16 regs[WM8766_REG_COUNT];	/* 9-bit registers */ +}; + + + +void snd_wm8766_init(struct snd_wm8766 *wm); +void snd_wm8766_resume(struct snd_wm8766 *wm); +void snd_wm8766_set_if(struct snd_wm8766 *wm, u16 dac); +void snd_wm8766_set_master_mode(struct snd_wm8766 *wm, u16 mode); +void snd_wm8766_set_power(struct snd_wm8766 *wm, u16 power); +void snd_wm8766_volume_restore(struct snd_wm8766 *wm); +int snd_wm8766_build_controls(struct snd_wm8766 *wm); + +#endif /* __SOUND_WM8766_H */ diff --git a/sound/pci/ice1712/wm8776.c b/sound/pci/ice1712/wm8776.c new file mode 100644 index 00000000000..e66c0da6201 --- /dev/null +++ b/sound/pci/ice1712/wm8776.c @@ -0,0 +1,634 @@ +/* + *   ALSA driver for ICEnsemble VT17xx + * + *   Lowlevel functions for WM8776 codec + * + *	Copyright (c) 2012 Ondrej Zary <linux@rainbow-software.org> + * + *   This program is free software; you can redistribute it and/or modify + *   it under the terms of the GNU General Public License as published by + *   the Free Software Foundation; either version 2 of the License, or + *   (at your option) any later version. + * + *   This program is distributed in the hope that it will be useful, + *   but WITHOUT ANY WARRANTY; without even the implied warranty of + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *   GNU General Public License for more details. + * + *   You should have received a copy of the GNU General Public License + *   along with this program; if not, write to the Free Software + *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA + * + */ + +#include <linux/delay.h> +#include <sound/core.h> +#include <sound/control.h> +#include <sound/tlv.h> +#include "wm8776.h" + +/* low-level access */ + +static void snd_wm8776_write(struct snd_wm8776 *wm, u16 addr, u16 data) +{ +	u8 bus_addr = addr << 1 | data >> 8;	/* addr + 9th data bit */ +	u8 bus_data = data & 0xff;		/* remaining 8 data bits */ + +	if (addr < WM8776_REG_RESET) +		wm->regs[addr] = data; +	wm->ops.write(wm, bus_addr, bus_data); +} + +/* register-level functions */ + +static void snd_wm8776_activate_ctl(struct snd_wm8776 *wm, +				    const char *ctl_name, +				    bool active) +{ +	struct snd_card *card = wm->card; +	struct snd_kcontrol *kctl; +	struct snd_kcontrol_volatile *vd; +	struct snd_ctl_elem_id elem_id; +	unsigned int index_offset; + +	memset(&elem_id, 0, sizeof(elem_id)); +	strlcpy(elem_id.name, ctl_name, sizeof(elem_id.name)); +	elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; +	kctl = snd_ctl_find_id(card, &elem_id); +	if (!kctl) +		return; +	index_offset = snd_ctl_get_ioff(kctl, &kctl->id); +	vd = &kctl->vd[index_offset]; +	if (active) +		vd->access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; +	else +		vd->access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; +	snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id); +} + +static void snd_wm8776_update_agc_ctl(struct snd_wm8776 *wm) +{ +	int i, flags_on = 0, flags_off = 0; + +	switch (wm->agc_mode) { +	case WM8776_AGC_OFF: +		flags_off = WM8776_FLAG_LIM | WM8776_FLAG_ALC; +		break; +	case WM8776_AGC_LIM: +		flags_off = WM8776_FLAG_ALC; +		flags_on = WM8776_FLAG_LIM; +		break; +	case WM8776_AGC_ALC_R: +	case WM8776_AGC_ALC_L: +	case WM8776_AGC_ALC_STEREO: +		flags_off = WM8776_FLAG_LIM; +		flags_on = WM8776_FLAG_ALC; +		break; +	} + +	for (i = 0; i < WM8776_CTL_COUNT; i++) +		if (wm->ctl[i].flags & flags_off) +			snd_wm8776_activate_ctl(wm, wm->ctl[i].name, false); +		else if (wm->ctl[i].flags & flags_on) +			snd_wm8776_activate_ctl(wm, wm->ctl[i].name, true); +} + +static void snd_wm8776_set_agc(struct snd_wm8776 *wm, u16 agc, u16 nothing) +{ +	u16 alc1 = wm->regs[WM8776_REG_ALCCTRL1] & ~WM8776_ALC1_LCT_MASK; +	u16 alc2 = wm->regs[WM8776_REG_ALCCTRL2] & ~WM8776_ALC2_LCEN; + +	switch (agc) { +	case 0:	/* Off */ +		wm->agc_mode = WM8776_AGC_OFF; +		break; +	case 1: /* Limiter */ +		alc2 |= WM8776_ALC2_LCEN; +		wm->agc_mode = WM8776_AGC_LIM; +		break; +	case 2: /* ALC Right */ +		alc1 |= WM8776_ALC1_LCSEL_ALCR; +		alc2 |= WM8776_ALC2_LCEN; +		wm->agc_mode = WM8776_AGC_ALC_R; +		break; +	case 3: /* ALC Left */ +		alc1 |= WM8776_ALC1_LCSEL_ALCL; +		alc2 |= WM8776_ALC2_LCEN; +		wm->agc_mode = WM8776_AGC_ALC_L; +		break; +	case 4: /* ALC Stereo */ +		alc1 |= WM8776_ALC1_LCSEL_ALCSTEREO; +		alc2 |= WM8776_ALC2_LCEN; +		wm->agc_mode = WM8776_AGC_ALC_STEREO; +		break; +	} +	snd_wm8776_write(wm, WM8776_REG_ALCCTRL1, alc1); +	snd_wm8776_write(wm, WM8776_REG_ALCCTRL2, alc2); +	snd_wm8776_update_agc_ctl(wm); +} + +static void snd_wm8776_get_agc(struct snd_wm8776 *wm, u16 *mode, u16 *nothing) +{ +	*mode = wm->agc_mode; +} + +/* mixer controls */ + +static const DECLARE_TLV_DB_SCALE(wm8776_hp_tlv, -7400, 100, 1); +static const DECLARE_TLV_DB_SCALE(wm8776_dac_tlv, -12750, 50, 1); +static const DECLARE_TLV_DB_SCALE(wm8776_adc_tlv, -10350, 50, 1); +static const DECLARE_TLV_DB_SCALE(wm8776_lct_tlv, -1600, 100, 0); +static const DECLARE_TLV_DB_SCALE(wm8776_maxgain_tlv, 0, 400, 0); +static const DECLARE_TLV_DB_SCALE(wm8776_ngth_tlv, -7800, 600, 0); +static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_lim_tlv, -1200, 100, 0); +static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_alc_tlv, -2100, 400, 0); + +static struct snd_wm8776_ctl snd_wm8776_default_ctl[WM8776_CTL_COUNT] = { +	[WM8776_CTL_DAC_VOL] = { +		.name = "Master Playback Volume", +		.type = SNDRV_CTL_ELEM_TYPE_INTEGER, +		.tlv = wm8776_dac_tlv, +		.reg1 = WM8776_REG_DACLVOL, +		.reg2 = WM8776_REG_DACRVOL, +		.mask1 = WM8776_DACVOL_MASK, +		.mask2 = WM8776_DACVOL_MASK, +		.max = 0xff, +		.flags = WM8776_FLAG_STEREO | WM8776_FLAG_VOL_UPDATE, +	}, +	[WM8776_CTL_DAC_SW] = { +		.name = "Master Playback Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8776_REG_DACCTRL1, +		.reg2 = WM8776_REG_DACCTRL1, +		.mask1 = WM8776_DAC_PL_LL, +		.mask2 = WM8776_DAC_PL_RR, +		.flags = WM8776_FLAG_STEREO, +	}, +	[WM8776_CTL_DAC_ZC_SW] = { +		.name = "Master Zero Cross Detect Playback Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8776_REG_DACCTRL1, +		.mask1 = WM8776_DAC_DZCEN, +	}, +	[WM8776_CTL_HP_VOL] = { +		.name = "Headphone Playback Volume", +		.type = SNDRV_CTL_ELEM_TYPE_INTEGER, +		.tlv = wm8776_hp_tlv, +		.reg1 = WM8776_REG_HPLVOL, +		.reg2 = WM8776_REG_HPRVOL, +		.mask1 = WM8776_HPVOL_MASK, +		.mask2 = WM8776_HPVOL_MASK, +		.min = 0x2f, +		.max = 0x7f, +		.flags = WM8776_FLAG_STEREO | WM8776_FLAG_VOL_UPDATE, +	}, +	[WM8776_CTL_HP_SW] = { +		.name = "Headphone Playback Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8776_REG_PWRDOWN, +		.mask1 = WM8776_PWR_HPPD, +		.flags = WM8776_FLAG_INVERT, +	}, +	[WM8776_CTL_HP_ZC_SW] = { +		.name = "Headphone Zero Cross Detect Playback Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8776_REG_HPLVOL, +		.reg2 = WM8776_REG_HPRVOL, +		.mask1 = WM8776_VOL_HPZCEN, +		.mask2 = WM8776_VOL_HPZCEN, +		.flags = WM8776_FLAG_STEREO, +	}, +	[WM8776_CTL_AUX_SW] = { +		.name = "AUX Playback Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8776_REG_OUTMUX, +		.mask1 = WM8776_OUTMUX_AUX, +	}, +	[WM8776_CTL_BYPASS_SW] = { +		.name = "Bypass Playback Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8776_REG_OUTMUX, +		.mask1 = WM8776_OUTMUX_BYPASS, +	}, +	[WM8776_CTL_DAC_IZD_SW] = { +		.name = "Infinite Zero Detect Playback Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8776_REG_DACCTRL1, +		.mask1 = WM8776_DAC_IZD, +	}, +	[WM8776_CTL_PHASE_SW] = { +		.name = "Phase Invert Playback Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8776_REG_PHASESWAP, +		.reg2 = WM8776_REG_PHASESWAP, +		.mask1 = WM8776_PHASE_INVERTL, +		.mask2 = WM8776_PHASE_INVERTR, +		.flags = WM8776_FLAG_STEREO, +	}, +	[WM8776_CTL_DEEMPH_SW] = { +		.name = "Deemphasis Playback Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8776_REG_DACCTRL2, +		.mask1 = WM8776_DAC2_DEEMPH, +	}, +	[WM8776_CTL_ADC_VOL] = { +		.name = "Input Capture Volume", +		.type = SNDRV_CTL_ELEM_TYPE_INTEGER, +		.tlv = wm8776_adc_tlv, +		.reg1 = WM8776_REG_ADCLVOL, +		.reg2 = WM8776_REG_ADCRVOL, +		.mask1 = WM8776_ADC_GAIN_MASK, +		.mask2 = WM8776_ADC_GAIN_MASK, +		.max = 0xff, +		.flags = WM8776_FLAG_STEREO | WM8776_FLAG_VOL_UPDATE, +	}, +	[WM8776_CTL_ADC_SW] = { +		.name = "Input Capture Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8776_REG_ADCMUX, +		.reg2 = WM8776_REG_ADCMUX, +		.mask1 = WM8776_ADC_MUTEL, +		.mask2 = WM8776_ADC_MUTER, +		.flags = WM8776_FLAG_STEREO | WM8776_FLAG_INVERT, +	}, +	[WM8776_CTL_INPUT1_SW] = { +		.name = "AIN1 Capture Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8776_REG_ADCMUX, +		.mask1 = WM8776_ADC_MUX_AIN1, +	}, +	[WM8776_CTL_INPUT2_SW] = { +		.name = "AIN2 Capture Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8776_REG_ADCMUX, +		.mask1 = WM8776_ADC_MUX_AIN2, +	}, +	[WM8776_CTL_INPUT3_SW] = { +		.name = "AIN3 Capture Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8776_REG_ADCMUX, +		.mask1 = WM8776_ADC_MUX_AIN3, +	}, +	[WM8776_CTL_INPUT4_SW] = { +		.name = "AIN4 Capture Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8776_REG_ADCMUX, +		.mask1 = WM8776_ADC_MUX_AIN4, +	}, +	[WM8776_CTL_INPUT5_SW] = { +		.name = "AIN5 Capture Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8776_REG_ADCMUX, +		.mask1 = WM8776_ADC_MUX_AIN5, +	}, +	[WM8776_CTL_AGC_SEL] = { +		.name = "AGC Select Capture Enum", +		.type = SNDRV_CTL_ELEM_TYPE_ENUMERATED, +		.enum_names = { "Off", "Limiter", "ALC Right", "ALC Left", +				"ALC Stereo" }, +		.max = 5,	/* .enum_names item count */ +		.set = snd_wm8776_set_agc, +		.get = snd_wm8776_get_agc, +	}, +	[WM8776_CTL_LIM_THR] = { +		.name = "Limiter Threshold Capture Volume", +		.type = SNDRV_CTL_ELEM_TYPE_INTEGER, +		.tlv = wm8776_lct_tlv, +		.reg1 = WM8776_REG_ALCCTRL1, +		.mask1 = WM8776_ALC1_LCT_MASK, +		.max = 15, +		.flags = WM8776_FLAG_LIM, +	}, +	[WM8776_CTL_LIM_ATK] = { +		.name = "Limiter Attack Time Capture Enum", +		.type = SNDRV_CTL_ELEM_TYPE_ENUMERATED, +		.enum_names = { "0.25 ms", "0.5 ms", "1 ms", "2 ms", "4 ms", +			"8 ms", "16 ms", "32 ms", "64 ms", "128 ms", "256 ms" }, +		.max = 11,	/* .enum_names item count */ +		.reg1 = WM8776_REG_ALCCTRL3, +		.mask1 = WM8776_ALC3_ATK_MASK, +		.flags = WM8776_FLAG_LIM, +	}, +	[WM8776_CTL_LIM_DCY] = { +		.name = "Limiter Decay Time Capture Enum", +		.type = SNDRV_CTL_ELEM_TYPE_ENUMERATED, +		.enum_names = {	"1.2 ms", "2.4 ms", "4.8 ms", "9.6 ms", +			"19.2 ms", "38.4 ms", "76.8 ms", "154 ms", "307 ms", +			"614 ms", "1.23 s" }, +		.max = 11,	/* .enum_names item count */ +		.reg1 = WM8776_REG_ALCCTRL3, +		.mask1 = WM8776_ALC3_DCY_MASK, +		.flags = WM8776_FLAG_LIM, +	}, +	[WM8776_CTL_LIM_TRANWIN] = { +		.name = "Limiter Transient Window Capture Enum", +		.type = SNDRV_CTL_ELEM_TYPE_ENUMERATED, +		.enum_names = {	"0 us", "62.5 us", "125 us", "250 us", "500 us", +			"1 ms", "2 ms", "4 ms" }, +		.max = 8,	/* .enum_names item count */ +		.reg1 = WM8776_REG_LIMITER, +		.mask1 = WM8776_LIM_TRANWIN_MASK, +		.flags = WM8776_FLAG_LIM, +	}, +	[WM8776_CTL_LIM_MAXATTN] = { +		.name = "Limiter Maximum Attenuation Capture Volume", +		.type = SNDRV_CTL_ELEM_TYPE_INTEGER, +		.tlv = wm8776_maxatten_lim_tlv, +		.reg1 = WM8776_REG_LIMITER, +		.mask1 = WM8776_LIM_MAXATTEN_MASK, +		.min = 3, +		.max = 12, +		.flags = WM8776_FLAG_LIM | WM8776_FLAG_INVERT, +	}, +	[WM8776_CTL_ALC_TGT] = { +		.name = "ALC Target Level Capture Volume", +		.type = SNDRV_CTL_ELEM_TYPE_INTEGER, +		.tlv = wm8776_lct_tlv, +		.reg1 = WM8776_REG_ALCCTRL1, +		.mask1 = WM8776_ALC1_LCT_MASK, +		.max = 15, +		.flags = WM8776_FLAG_ALC, +	}, +	[WM8776_CTL_ALC_ATK] = { +		.name = "ALC Attack Time Capture Enum", +		.type = SNDRV_CTL_ELEM_TYPE_ENUMERATED, +		.enum_names = { "8.40 ms", "16.8 ms", "33.6 ms", "67.2 ms", +			"134 ms", "269 ms", "538 ms", "1.08 s",	"2.15 s", +			"4.3 s", "8.6 s" }, +		.max = 11,	/* .enum_names item count */ +		.reg1 = WM8776_REG_ALCCTRL3, +		.mask1 = WM8776_ALC3_ATK_MASK, +		.flags = WM8776_FLAG_ALC, +	}, +	[WM8776_CTL_ALC_DCY] = { +		.name = "ALC Decay Time Capture Enum", +		.type = SNDRV_CTL_ELEM_TYPE_ENUMERATED, +		.enum_names = {	"33.5 ms", "67.0 ms", "134 ms", "268 ms", +			"536 ms", "1.07 s", "2.14 s", "4.29 s",	"8.58 s", +			"17.2 s", "34.3 s" }, +		.max = 11,	/* .enum_names item count */ +		.reg1 = WM8776_REG_ALCCTRL3, +		.mask1 = WM8776_ALC3_DCY_MASK, +		.flags = WM8776_FLAG_ALC, +	}, +	[WM8776_CTL_ALC_MAXGAIN] = { +		.name = "ALC Maximum Gain Capture Volume", +		.type = SNDRV_CTL_ELEM_TYPE_INTEGER, +		.tlv = wm8776_maxgain_tlv, +		.reg1 = WM8776_REG_ALCCTRL1, +		.mask1 = WM8776_ALC1_MAXGAIN_MASK, +		.min = 1, +		.max = 7, +		.flags = WM8776_FLAG_ALC, +	}, +	[WM8776_CTL_ALC_MAXATTN] = { +		.name = "ALC Maximum Attenuation Capture Volume", +		.type = SNDRV_CTL_ELEM_TYPE_INTEGER, +		.tlv = wm8776_maxatten_alc_tlv, +		.reg1 = WM8776_REG_LIMITER, +		.mask1 = WM8776_LIM_MAXATTEN_MASK, +		.min = 10, +		.max = 15, +		.flags = WM8776_FLAG_ALC | WM8776_FLAG_INVERT, +	}, +	[WM8776_CTL_ALC_HLD] = { +		.name = "ALC Hold Time Capture Enum", +		.type = SNDRV_CTL_ELEM_TYPE_ENUMERATED, +		.enum_names = {	"0 ms", "2.67 ms", "5.33 ms", "10.6 ms", +			"21.3 ms", "42.7 ms", "85.3 ms", "171 ms", "341 ms", +			"683 ms", "1.37 s", "2.73 s", "5.46 s", "10.9 s", +			"21.8 s", "43.7 s" }, +		.max = 16,	/* .enum_names item count */ +		.reg1 = WM8776_REG_ALCCTRL2, +		.mask1 = WM8776_ALC2_HOLD_MASK, +		.flags = WM8776_FLAG_ALC, +	}, +	[WM8776_CTL_NGT_SW] = { +		.name = "Noise Gate Capture Switch", +		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, +		.reg1 = WM8776_REG_NOISEGATE, +		.mask1 = WM8776_NGAT_ENABLE, +		.flags = WM8776_FLAG_ALC, +	}, +	[WM8776_CTL_NGT_THR] = { +		.name = "Noise Gate Threshold Capture Volume", +		.type = SNDRV_CTL_ELEM_TYPE_INTEGER, +		.tlv = wm8776_ngth_tlv, +		.reg1 = WM8776_REG_NOISEGATE, +		.mask1 = WM8776_NGAT_THR_MASK, +		.max = 7, +		.flags = WM8776_FLAG_ALC, +	}, +}; + +/* exported functions */ + +void snd_wm8776_init(struct snd_wm8776 *wm) +{ +	int i; +	static const u16 default_values[] = { +		0x000, 0x100, 0x000, +		0x000, 0x100, 0x000, +		0x000, 0x090, 0x000, 0x000, +		0x022, 0x022, 0x022, +		0x008, 0x0cf, 0x0cf, 0x07b, 0x000, +		0x032, 0x000, 0x0a6, 0x001, 0x001 +	}; + +	memcpy(wm->ctl, snd_wm8776_default_ctl, sizeof(wm->ctl)); + +	snd_wm8776_write(wm, WM8776_REG_RESET, 0x00); /* reset */ +	udelay(10); +	/* load defaults */ +	for (i = 0; i < ARRAY_SIZE(default_values); i++) +		snd_wm8776_write(wm, i, default_values[i]); +} + +void snd_wm8776_resume(struct snd_wm8776 *wm) +{ +	int i; + +	for (i = 0; i < WM8776_REG_COUNT; i++) +		snd_wm8776_write(wm, i, wm->regs[i]); +} + +void snd_wm8776_set_dac_if(struct snd_wm8776 *wm, u16 dac) +{ +	snd_wm8776_write(wm, WM8776_REG_DACIFCTRL, dac); +} + +void snd_wm8776_set_adc_if(struct snd_wm8776 *wm, u16 adc) +{ +	snd_wm8776_write(wm, WM8776_REG_ADCIFCTRL, adc); +} + +void snd_wm8776_set_master_mode(struct snd_wm8776 *wm, u16 mode) +{ +	snd_wm8776_write(wm, WM8776_REG_MSTRCTRL, mode); +} + +void snd_wm8776_set_power(struct snd_wm8776 *wm, u16 power) +{ +	snd_wm8776_write(wm, WM8776_REG_PWRDOWN, power); +} + +void snd_wm8776_volume_restore(struct snd_wm8776 *wm) +{ +	u16 val = wm->regs[WM8776_REG_DACRVOL]; +	/* restore volume after MCLK stopped */ +	snd_wm8776_write(wm, WM8776_REG_DACRVOL, val | WM8776_VOL_UPDATE); +} + +/* mixer callbacks */ + +static int snd_wm8776_volume_info(struct snd_kcontrol *kcontrol, +				   struct snd_ctl_elem_info *uinfo) +{ +	struct snd_wm8776 *wm = snd_kcontrol_chip(kcontrol); +	int n = kcontrol->private_value; + +	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; +	uinfo->count = (wm->ctl[n].flags & WM8776_FLAG_STEREO) ? 2 : 1; +	uinfo->value.integer.min = wm->ctl[n].min; +	uinfo->value.integer.max = wm->ctl[n].max; + +	return 0; +} + +static int snd_wm8776_enum_info(struct snd_kcontrol *kcontrol, +				      struct snd_ctl_elem_info *uinfo) +{ +	struct snd_wm8776 *wm = snd_kcontrol_chip(kcontrol); +	int n = kcontrol->private_value; + +	return snd_ctl_enum_info(uinfo, 1, wm->ctl[n].max, +						wm->ctl[n].enum_names); +} + +static int snd_wm8776_ctl_get(struct snd_kcontrol *kcontrol, +				  struct snd_ctl_elem_value *ucontrol) +{ +	struct snd_wm8776 *wm = snd_kcontrol_chip(kcontrol); +	int n = kcontrol->private_value; +	u16 val1, val2; + +	if (wm->ctl[n].get) +		wm->ctl[n].get(wm, &val1, &val2); +	else { +		val1 = wm->regs[wm->ctl[n].reg1] & wm->ctl[n].mask1; +		val1 >>= __ffs(wm->ctl[n].mask1); +		if (wm->ctl[n].flags & WM8776_FLAG_STEREO) { +			val2 = wm->regs[wm->ctl[n].reg2] & wm->ctl[n].mask2; +			val2 >>= __ffs(wm->ctl[n].mask2); +			if (wm->ctl[n].flags & WM8776_FLAG_VOL_UPDATE) +				val2 &= ~WM8776_VOL_UPDATE; +		} +	} +	if (wm->ctl[n].flags & WM8776_FLAG_INVERT) { +		val1 = wm->ctl[n].max - (val1 - wm->ctl[n].min); +		if (wm->ctl[n].flags & WM8776_FLAG_STEREO) +			val2 = wm->ctl[n].max - (val2 - wm->ctl[n].min); +	} +	ucontrol->value.integer.value[0] = val1; +	if (wm->ctl[n].flags & WM8776_FLAG_STEREO) +		ucontrol->value.integer.value[1] = val2; + +	return 0; +} + +static int snd_wm8776_ctl_put(struct snd_kcontrol *kcontrol, +				  struct snd_ctl_elem_value *ucontrol) +{ +	struct snd_wm8776 *wm = snd_kcontrol_chip(kcontrol); +	int n = kcontrol->private_value; +	u16 val, regval1, regval2; + +	/* this also works for enum because value is an union */ +	regval1 = ucontrol->value.integer.value[0]; +	regval2 = ucontrol->value.integer.value[1]; +	if (wm->ctl[n].flags & WM8776_FLAG_INVERT) { +		regval1 = wm->ctl[n].max - (regval1 - wm->ctl[n].min); +		regval2 = wm->ctl[n].max - (regval2 - wm->ctl[n].min); +	} +	if (wm->ctl[n].set) +		wm->ctl[n].set(wm, regval1, regval2); +	else { +		val = wm->regs[wm->ctl[n].reg1] & ~wm->ctl[n].mask1; +		val |= regval1 << __ffs(wm->ctl[n].mask1); +		/* both stereo controls in one register */ +		if (wm->ctl[n].flags & WM8776_FLAG_STEREO && +				wm->ctl[n].reg1 == wm->ctl[n].reg2) { +			val &= ~wm->ctl[n].mask2; +			val |= regval2 << __ffs(wm->ctl[n].mask2); +		} +		snd_wm8776_write(wm, wm->ctl[n].reg1, val); +		/* stereo controls in different registers */ +		if (wm->ctl[n].flags & WM8776_FLAG_STEREO && +				wm->ctl[n].reg1 != wm->ctl[n].reg2) { +			val = wm->regs[wm->ctl[n].reg2] & ~wm->ctl[n].mask2; +			val |= regval2 << __ffs(wm->ctl[n].mask2); +			if (wm->ctl[n].flags & WM8776_FLAG_VOL_UPDATE) +				val |= WM8776_VOL_UPDATE; +			snd_wm8776_write(wm, wm->ctl[n].reg2, val); +		} +	} + +	return 0; +} + +static int snd_wm8776_add_control(struct snd_wm8776 *wm, int num) +{ +	struct snd_kcontrol_new cont; +	struct snd_kcontrol *ctl; + +	memset(&cont, 0, sizeof(cont)); +	cont.iface = SNDRV_CTL_ELEM_IFACE_MIXER; +	cont.private_value = num; +	cont.name = wm->ctl[num].name; +	cont.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; +	if (wm->ctl[num].flags & WM8776_FLAG_LIM || +	    wm->ctl[num].flags & WM8776_FLAG_ALC) +		cont.access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; +	cont.tlv.p = NULL; +	cont.get = snd_wm8776_ctl_get; +	cont.put = snd_wm8776_ctl_put; + +	switch (wm->ctl[num].type) { +	case SNDRV_CTL_ELEM_TYPE_INTEGER: +		cont.info = snd_wm8776_volume_info; +		cont.access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; +		cont.tlv.p = wm->ctl[num].tlv; +		break; +	case SNDRV_CTL_ELEM_TYPE_BOOLEAN: +		wm->ctl[num].max = 1; +		if (wm->ctl[num].flags & WM8776_FLAG_STEREO) +			cont.info = snd_ctl_boolean_stereo_info; +		else +			cont.info = snd_ctl_boolean_mono_info; +		break; +	case SNDRV_CTL_ELEM_TYPE_ENUMERATED: +		cont.info = snd_wm8776_enum_info; +		break; +	default: +		return -EINVAL; +	} +	ctl = snd_ctl_new1(&cont, wm); +	if (!ctl) +		return -ENOMEM; + +	return snd_ctl_add(wm->card, ctl); +} + +int snd_wm8776_build_controls(struct snd_wm8776 *wm) +{ +	int err, i; + +	for (i = 0; i < WM8776_CTL_COUNT; i++) +		if (wm->ctl[i].name) { +			err = snd_wm8776_add_control(wm, i); +			if (err < 0) +				return err; +		} + +	return 0; +} diff --git a/sound/pci/ice1712/wm8776.h b/sound/pci/ice1712/wm8776.h new file mode 100644 index 00000000000..93a2d697115 --- /dev/null +++ b/sound/pci/ice1712/wm8776.h @@ -0,0 +1,226 @@ +#ifndef __SOUND_WM8776_H +#define __SOUND_WM8776_H + +/* + *   ALSA driver for ICEnsemble VT17xx + * + *   Lowlevel functions for WM8776 codec + * + *	Copyright (c) 2012 Ondrej Zary <linux@rainbow-software.org> + * + *   This program is free software; you can redistribute it and/or modify + *   it under the terms of the GNU General Public License as published by + *   the Free Software Foundation; either version 2 of the License, or + *   (at your option) any later version. + * + *   This program is distributed in the hope that it will be useful, + *   but WITHOUT ANY WARRANTY; without even the implied warranty of + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *   GNU General Public License for more details. + * + *   You should have received a copy of the GNU General Public License + *   along with this program; if not, write to the Free Software + *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA + * + */ + +#define WM8776_REG_HPLVOL	0x00 +#define WM8776_REG_HPRVOL	0x01 +#define WM8776_REG_HPMASTER	0x02 +#define WM8776_HPVOL_MASK		0x17f		/* incl. update bit */ +#define WM8776_VOL_HPZCEN		(1 << 7)	/* zero cross detect */ +#define WM8776_VOL_UPDATE		(1 << 8)	/* update volume */ +#define WM8776_REG_DACLVOL	0x03 +#define WM8776_REG_DACRVOL	0x04 +#define WM8776_REG_DACMASTER	0x05 +#define WM8776_DACVOL_MASK		0x1ff		/* incl. update bit */ +#define WM8776_REG_PHASESWAP	0x06 +#define WM8776_PHASE_INVERTL		(1 << 0) +#define WM8776_PHASE_INVERTR		(1 << 1) +#define WM8776_REG_DACCTRL1	0x07 +#define WM8776_DAC_DZCEN		(1 << 0) +#define WM8776_DAC_ATC			(1 << 1) +#define WM8776_DAC_IZD			(1 << 2) +#define WM8776_DAC_TOD			(1 << 3) +#define WM8776_DAC_PL_MASK		0xf0 +#define WM8776_DAC_PL_LL		(1 << 4)	/* L chan: L signal */ +#define WM8776_DAC_PL_LR		(2 << 4)	/* L chan: R signal */ +#define WM8776_DAC_PL_LB		(3 << 4)	/* L chan: both */ +#define WM8776_DAC_PL_RL		(1 << 6)	/* R chan: L signal */ +#define WM8776_DAC_PL_RR		(2 << 6)	/* R chan: R signal */ +#define WM8776_DAC_PL_RB		(3 << 6)	/* R chan: both */ +#define WM8776_REG_DACMUTE	0x08 +#define WM8776_DACMUTE			(1 << 0) +#define WM8776_REG_DACCTRL2	0x09 +#define WM8776_DAC2_DEEMPH		(1 << 0) +#define WM8776_DAC2_ZFLAG_DISABLE	(0 << 1) +#define WM8776_DAC2_ZFLAG_OWN		(1 << 1) +#define WM8776_DAC2_ZFLAG_BOTH		(2 << 1) +#define WM8776_DAC2_ZFLAG_EITHER	(3 << 1) +#define WM8776_REG_DACIFCTRL	0x0a +#define WM8776_FMT_RIGHTJ		(0 << 0) +#define WM8776_FMT_LEFTJ		(1 << 0) +#define WM8776_FMT_I2S			(2 << 0) +#define WM8776_FMT_DSP			(3 << 0) +#define WM8776_FMT_DSP_LATE		(1 << 2)	/* in DSP mode */ +#define WM8776_FMT_LRC_INVERTED		(1 << 2)	/* in other modes */ +#define WM8776_FMT_BCLK_INVERTED	(1 << 3) +#define WM8776_FMT_16BIT		(0 << 4) +#define WM8776_FMT_20BIT		(1 << 4) +#define WM8776_FMT_24BIT		(2 << 4) +#define WM8776_FMT_32BIT		(3 << 4) +#define WM8776_REG_ADCIFCTRL	0x0b +#define WM8776_FMT_ADCMCLK_INVERTED	(1 << 6) +#define WM8776_FMT_ADCHPD		(1 << 8) +#define WM8776_REG_MSTRCTRL	0x0c +#define WM8776_IF_ADC256FS		(2 << 0) +#define WM8776_IF_ADC384FS		(3 << 0) +#define WM8776_IF_ADC512FS		(4 << 0) +#define WM8776_IF_ADC768FS		(5 << 0) +#define WM8776_IF_OVERSAMP64		(1 << 3) +#define WM8776_IF_DAC128FS		(0 << 4) +#define WM8776_IF_DAC192FS		(1 << 4) +#define WM8776_IF_DAC256FS		(2 << 4) +#define WM8776_IF_DAC384FS		(3 << 4) +#define WM8776_IF_DAC512FS		(4 << 4) +#define WM8776_IF_DAC768FS		(5 << 4) +#define WM8776_IF_DAC_MASTER		(1 << 7) +#define WM8776_IF_ADC_MASTER		(1 << 8) +#define WM8776_REG_PWRDOWN	0x0d +#define WM8776_PWR_PDWN			(1 << 0) +#define WM8776_PWR_ADCPD		(1 << 1) +#define WM8776_PWR_DACPD		(1 << 2) +#define WM8776_PWR_HPPD			(1 << 3) +#define WM8776_PWR_AINPD		(1 << 6) +#define WM8776_REG_ADCLVOL	0x0e +#define WM8776_REG_ADCRVOL	0x0f +#define WM8776_ADC_GAIN_MASK		0xff +#define WM8776_ADC_ZCEN			(1 << 8) +#define WM8776_REG_ALCCTRL1	0x10 +#define WM8776_ALC1_LCT_MASK		0x0f	/* 0=-16dB, 1=-15dB..15=-1dB */ +#define WM8776_ALC1_MAXGAIN_MASK	0x70	/* 0,1=0dB, 2=+4dB...7=+24dB */ +#define WM8776_ALC1_LCSEL_MASK		0x180 +#define WM8776_ALC1_LCSEL_LIMITER	(0 << 7) +#define WM8776_ALC1_LCSEL_ALCR		(1 << 7) +#define WM8776_ALC1_LCSEL_ALCL		(2 << 7) +#define WM8776_ALC1_LCSEL_ALCSTEREO	(3 << 7) +#define WM8776_REG_ALCCTRL2	0x11 +#define WM8776_ALC2_HOLD_MASK		0x0f	/*0=0ms, 1=2.67ms, 2=5.33ms.. */ +#define WM8776_ALC2_ZCEN		(1 << 7) +#define WM8776_ALC2_LCEN		(1 << 8) +#define WM8776_REG_ALCCTRL3	0x12 +#define WM8776_ALC3_ATK_MASK		0x0f +#define WM8776_ALC3_DCY_MASK		0xf0 +#define WM8776_ALC3_FDECAY		(1 << 8) +#define WM8776_REG_NOISEGATE	0x13 +#define WM8776_NGAT_ENABLE		(1 << 0) +#define WM8776_NGAT_THR_MASK		0x1c	/*0=-78dB, 1=-72dB...7=-36dB */ +#define WM8776_REG_LIMITER	0x14 +#define WM8776_LIM_MAXATTEN_MASK	0x0f +#define WM8776_LIM_TRANWIN_MASK		0x70	/*0=0us, 1=62.5us, 2=125us.. */ +#define WM8776_REG_ADCMUX	0x15 +#define WM8776_ADC_MUX_AIN1		(1 << 0) +#define WM8776_ADC_MUX_AIN2		(1 << 1) +#define WM8776_ADC_MUX_AIN3		(1 << 2) +#define WM8776_ADC_MUX_AIN4		(1 << 3) +#define WM8776_ADC_MUX_AIN5		(1 << 4) +#define WM8776_ADC_MUTER		(1 << 6) +#define WM8776_ADC_MUTEL		(1 << 7) +#define WM8776_ADC_LRBOTH		(1 << 8) +#define WM8776_REG_OUTMUX	0x16 +#define WM8776_OUTMUX_DAC		(1 << 0) +#define WM8776_OUTMUX_AUX		(1 << 1) +#define WM8776_OUTMUX_BYPASS		(1 << 2) +#define WM8776_REG_RESET	0x17 + +#define WM8776_REG_COUNT	0x17	/* don't cache the RESET register */ + +struct snd_wm8776; + +struct snd_wm8776_ops { +	void (*write)(struct snd_wm8776 *wm, u8 addr, u8 data); +}; + +enum snd_wm8776_ctl_id { +	WM8776_CTL_DAC_VOL, +	WM8776_CTL_DAC_SW, +	WM8776_CTL_DAC_ZC_SW, +	WM8776_CTL_HP_VOL, +	WM8776_CTL_HP_SW, +	WM8776_CTL_HP_ZC_SW, +	WM8776_CTL_AUX_SW, +	WM8776_CTL_BYPASS_SW, +	WM8776_CTL_DAC_IZD_SW, +	WM8776_CTL_PHASE_SW, +	WM8776_CTL_DEEMPH_SW, +	WM8776_CTL_ADC_VOL, +	WM8776_CTL_ADC_SW, +	WM8776_CTL_INPUT1_SW, +	WM8776_CTL_INPUT2_SW, +	WM8776_CTL_INPUT3_SW, +	WM8776_CTL_INPUT4_SW, +	WM8776_CTL_INPUT5_SW, +	WM8776_CTL_AGC_SEL, +	WM8776_CTL_LIM_THR, +	WM8776_CTL_LIM_ATK, +	WM8776_CTL_LIM_DCY, +	WM8776_CTL_LIM_TRANWIN, +	WM8776_CTL_LIM_MAXATTN, +	WM8776_CTL_ALC_TGT, +	WM8776_CTL_ALC_ATK, +	WM8776_CTL_ALC_DCY, +	WM8776_CTL_ALC_MAXGAIN, +	WM8776_CTL_ALC_MAXATTN, +	WM8776_CTL_ALC_HLD, +	WM8776_CTL_NGT_SW, +	WM8776_CTL_NGT_THR, + +	WM8776_CTL_COUNT, +}; + +#define WM8776_ENUM_MAX		16 + +#define WM8776_FLAG_STEREO	(1 << 0) +#define WM8776_FLAG_VOL_UPDATE	(1 << 1) +#define WM8776_FLAG_INVERT	(1 << 2) +#define WM8776_FLAG_LIM		(1 << 3) +#define WM8776_FLAG_ALC		(1 << 4) + +struct snd_wm8776_ctl { +	const char *name; +	snd_ctl_elem_type_t type; +	const char *const enum_names[WM8776_ENUM_MAX]; +	const unsigned int *tlv; +	u16 reg1, reg2, mask1, mask2, min, max, flags; +	void (*set)(struct snd_wm8776 *wm, u16 ch1, u16 ch2); +	void (*get)(struct snd_wm8776 *wm, u16 *ch1, u16 *ch2); +}; + +enum snd_wm8776_agc_mode { +	WM8776_AGC_OFF, +	WM8776_AGC_LIM, +	WM8776_AGC_ALC_R, +	WM8776_AGC_ALC_L, +	WM8776_AGC_ALC_STEREO +}; + +struct snd_wm8776 { +	struct snd_card *card; +	struct snd_wm8776_ctl ctl[WM8776_CTL_COUNT]; +	enum snd_wm8776_agc_mode agc_mode; +	struct snd_wm8776_ops ops; +	u16 regs[WM8776_REG_COUNT];	/* 9-bit registers */ +}; + + + +void snd_wm8776_init(struct snd_wm8776 *wm); +void snd_wm8776_resume(struct snd_wm8776 *wm); +void snd_wm8776_set_dac_if(struct snd_wm8776 *wm, u16 dac); +void snd_wm8776_set_adc_if(struct snd_wm8776 *wm, u16 adc); +void snd_wm8776_set_master_mode(struct snd_wm8776 *wm, u16 mode); +void snd_wm8776_set_power(struct snd_wm8776 *wm, u16 power); +void snd_wm8776_volume_restore(struct snd_wm8776 *wm); +int snd_wm8776_build_controls(struct snd_wm8776 *wm); + +#endif /* __SOUND_WM8776_H */ diff --git a/sound/pci/ice1712/wtm.c b/sound/pci/ice1712/wtm.c index e618f789026..bcf30a387b8 100644 --- a/sound/pci/ice1712/wtm.c +++ b/sound/pci/ice1712/wtm.c @@ -25,7 +25,6 @@ -#include <linux/io.h>  #include <linux/delay.h>  #include <linux/interrupt.h>  #include <linux/init.h> @@ -384,7 +383,7 @@ static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol,  /*   * Control tabs   */ -static struct snd_kcontrol_new stac9640_controls[] __devinitdata = { +static struct snd_kcontrol_new stac9640_controls[] = {  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "Master Playback Switch", @@ -448,7 +447,7 @@ static struct snd_kcontrol_new stac9640_controls[] __devinitdata = {  /*INIT*/ -static int __devinit wtm_add_controls(struct snd_ice1712 *ice) +static int wtm_add_controls(struct snd_ice1712 *ice)  {  	unsigned int i;  	int err; @@ -462,7 +461,7 @@ static int __devinit wtm_add_controls(struct snd_ice1712 *ice)  	return 0;  } -static int __devinit wtm_init(struct snd_ice1712 *ice) +static int wtm_init(struct snd_ice1712 *ice)  {  	static unsigned short stac_inits_prodigy[] = {  		STAC946X_RESET, 0, @@ -485,7 +484,7 @@ static int __devinit wtm_init(struct snd_ice1712 *ice)  } -static unsigned char wtm_eeprom[] __devinitdata = { +static unsigned char wtm_eeprom[] = {  	0x47,	/*SYSCONF: clock 192KHz, 4ADC, 8DAC */  	0x80,	/* ACLINK : I2S */  	0xf8,	/* I2S: vol; 96k, 24bit, 192k */ @@ -503,7 +502,7 @@ static unsigned char wtm_eeprom[] __devinitdata = {  /*entry point*/ -struct snd_ice1712_card_info snd_vt1724_wtm_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_wtm_cards[] = {  	{  		.subvendor = VT1724_SUBDEVICE_WTM,  		.name = "ESI Waveterminal 192M",  | 
