diff options
Diffstat (limited to 'sound/pci/ice1712/delta.c')
| -rw-r--r-- | sound/pci/ice1712/delta.c | 155 | 
1 files changed, 131 insertions, 24 deletions
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",  | 
