Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7cda8ba9 authored by Takashi Iwai's avatar Takashi Iwai Committed by Jaroslav Kysela
Browse files

[ALSA] ice1712, ice1724 - Code clean up



Clean up ice1712/ice1724 codes.  The board-specific data is allocated
locally in each code instead of having an ungly union in struct ice1712.
Also, fix coding issues in prodigy_hifi.c.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarJaroslav Kysela <perex@perex.cz>
parent 797760ab
Loading
Loading
Loading
Loading
+74 −39
Original line number Diff line number Diff line
@@ -61,6 +61,15 @@
#include "aureon.h"
#include <sound/tlv.h>

/* AC97 register cache for Aureon */
struct aureon_spec {
	unsigned short stac9744[64];
	unsigned int cs8415_mux;
	unsigned short master[2];
	unsigned short vol[8];
	unsigned char pca9554_out;
};

/* WM8770 registers */
#define WM_DAC_ATTEN		0x00	/* DAC1-8 analog attenuation */
#define WM_DAC_MASTER_ATTEN	0x08	/* DAC master analog attenuation */
@@ -204,7 +213,8 @@ static int aureon_universe_inmux_get(struct snd_kcontrol *kcontrol,
				     struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	ucontrol->value.enumerated.item[0] = ice->spec.aureon.pca9554_out;
	struct aureon_spec *spec = ice->spec;
	ucontrol->value.enumerated.item[0] = spec->pca9554_out;
	return 0;
}

@@ -212,6 +222,7 @@ static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol,
				     struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	struct aureon_spec *spec = ice->spec;
	unsigned char oval, nval;
	int change;

@@ -219,10 +230,10 @@ static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol,
	if (nval >= 3)
		return -EINVAL;
	snd_ice1712_save_gpio_status(ice);
	oval = ice->spec.aureon.pca9554_out;
	oval = spec->pca9554_out;
	if ((change = (oval != nval))) {
		aureon_pca9554_write(ice, PCA9554_OUT, nval);
		ice->spec.aureon.pca9554_out = nval;
		spec->pca9554_out = nval;
	}
	snd_ice1712_restore_gpio_status(ice);
	
@@ -233,6 +244,7 @@ static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol,
static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
			      unsigned short val)
{
	struct aureon_spec *spec = ice->spec;
	unsigned int tmp;

	/* Send address to XILINX chip */
@@ -280,12 +292,13 @@ static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
	udelay(10);
	
	/* Store the data in out private buffer */
	ice->spec.aureon.stac9744[(reg & 0x7F) >> 1] = val;
	spec->stac9744[(reg & 0x7F) >> 1] = val;
}

static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short reg)
{
       return ice->spec.aureon.stac9744[(reg & 0x7F) >> 1];
	struct aureon_spec *spec = ice->spec;
	return spec->stac9744[(reg & 0x7F) >> 1];
}

/*
@@ -293,6 +306,7 @@ static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short r
 */
static int aureon_ac97_init (struct snd_ice1712 *ice)
{
	struct aureon_spec *spec = ice->spec;
	int i;
	static const unsigned short ac97_defaults[] = {
		0x00, 0x9640,
@@ -330,9 +344,9 @@ static int aureon_ac97_init (struct snd_ice1712 *ice)
	snd_ice1712_gpio_write(ice, tmp);
	udelay(3);
	
	memset(&ice->spec.aureon.stac9744, 0, sizeof(ice->spec.aureon.stac9744));
	memset(&spec->stac9744, 0, sizeof(spec->stac9744));
	for (i=0; ac97_defaults[i] != (unsigned short)-1; i+=2)
		ice->spec.aureon.stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1];
		spec->stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1];
		
	aureon_ac97_write(ice, AC97_MASTER, 0x0000); // Unmute AC'97 master volume permanently - muting is done by WM8770

@@ -744,15 +758,18 @@ static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	struct aureon_spec *spec = ice->spec;
	int i;
	for (i=0; i<2; i++)
		ucontrol->value.integer.value[i] = ice->spec.aureon.master[i] & ~WM_VOL_MUTE;
		ucontrol->value.integer.value[i] =
			spec->master[i] & ~WM_VOL_MUTE;
	return 0;
}

static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	struct aureon_spec *spec = ice->spec;
	int ch, change = 0;

	snd_ice1712_save_gpio_status(ice);
@@ -760,14 +777,14 @@ static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
		unsigned int vol = ucontrol->value.integer.value[ch];
		if (vol > WM_VOL_MAX)
			continue;
		vol |= ice->spec.aureon.master[ch] & WM_VOL_MUTE;
		if (vol != ice->spec.aureon.master[ch]) {
		vol |= spec->master[ch] & WM_VOL_MUTE;
		if (vol != spec->master[ch]) {
			int dac;
			ice->spec.aureon.master[ch] = vol;
			spec->master[ch] = vol;
			for (dac = 0; dac < ice->num_total_dacs; dac += 2)
				wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
					   ice->spec.aureon.vol[dac + ch],
					   ice->spec.aureon.master[ch]);
					   spec->vol[dac + ch],
					   spec->master[ch]);
			change = 1;
		}
	}
@@ -791,18 +808,21 @@ static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *
static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	struct aureon_spec *spec = ice->spec;
	int i, ofs, voices;

	voices = kcontrol->private_value >> 8;
	ofs = kcontrol->private_value & 0xff;
	for (i = 0; i < voices; i++)
		ucontrol->value.integer.value[i] = ice->spec.aureon.vol[ofs+i] & ~WM_VOL_MUTE;
		ucontrol->value.integer.value[i] =
			spec->vol[ofs+i] & ~WM_VOL_MUTE;
	return 0;
}

static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	struct aureon_spec *spec = ice->spec;
	int i, idx, ofs, voices;
	int change = 0;

@@ -813,12 +833,12 @@ static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *
		unsigned int vol = ucontrol->value.integer.value[i];
		if (vol > 0x7f)
			continue;
		vol |= ice->spec.aureon.vol[ofs+i];
		if (vol != ice->spec.aureon.vol[ofs+i]) {
			ice->spec.aureon.vol[ofs+i] = vol;
		vol |= spec->vol[ofs+i];
		if (vol != spec->vol[ofs+i]) {
			spec->vol[ofs+i] = vol;
			idx  = WM_DAC_ATTEN + ofs + i;
			wm_set_vol(ice, idx, ice->spec.aureon.vol[ofs+i],
				   ice->spec.aureon.master[i]);
			wm_set_vol(ice, idx, spec->vol[ofs + i],
				   spec->master[i]);
			change = 1;
		}
	}
@@ -840,19 +860,22 @@ static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info
static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	struct aureon_spec *spec = ice->spec;
	int voices, ofs, i;
	
	voices = kcontrol->private_value >> 8;
	ofs = kcontrol->private_value & 0xFF;

	for (i = 0; i < voices; i++)
		ucontrol->value.integer.value[i] = (ice->spec.aureon.vol[ofs+i] & WM_VOL_MUTE) ? 0 : 1;
		ucontrol->value.integer.value[i] =
			(spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
	return 0;
}

static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	struct aureon_spec *spec = ice->spec;
	int change = 0, voices, ofs, i;

	voices = kcontrol->private_value >> 8;
@@ -860,13 +883,13 @@ static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value

	snd_ice1712_save_gpio_status(ice);
	for (i = 0; i < voices; i++) {
		int val = (ice->spec.aureon.vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
		int val = (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
		if (ucontrol->value.integer.value[i] != val) {
			ice->spec.aureon.vol[ofs + i] &= ~WM_VOL_MUTE;
			ice->spec.aureon.vol[ofs + i] |=
			spec->vol[ofs + i] &= ~WM_VOL_MUTE;
			spec->vol[ofs + i] |=
				ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
			wm_set_vol(ice, ofs + i, ice->spec.aureon.vol[ofs + i],
				   ice->spec.aureon.master[i]);
			wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
				   spec->master[i]);
			change = 1;
		}
	}
@@ -883,29 +906,33 @@ static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	struct aureon_spec *spec = ice->spec;
	
	ucontrol->value.integer.value[0] = (ice->spec.aureon.master[0] & WM_VOL_MUTE) ? 0 : 1;
	ucontrol->value.integer.value[1] = (ice->spec.aureon.master[1] & WM_VOL_MUTE) ? 0 : 1;
	ucontrol->value.integer.value[0] =
		(spec->master[0] & WM_VOL_MUTE) ? 0 : 1;
	ucontrol->value.integer.value[1] =
		(spec->master[1] & WM_VOL_MUTE) ? 0 : 1;
	return 0;
}

static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	struct aureon_spec *spec = ice->spec;
	int change = 0, i;

	snd_ice1712_save_gpio_status(ice);
	for (i = 0; i < 2; i++) {
		int val = (ice->spec.aureon.master[i] & WM_VOL_MUTE) ? 0 : 1;
		int val = (spec->master[i] & WM_VOL_MUTE) ? 0 : 1;
		if (ucontrol->value.integer.value[i] != val) {
			int dac;
			ice->spec.aureon.master[i] &= ~WM_VOL_MUTE;
			ice->spec.aureon.master[i] |=
			spec->master[i] &= ~WM_VOL_MUTE;
			spec->master[i] |=
				ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
			for (dac = 0; dac < ice->num_total_dacs; dac += 2)
				wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
					   ice->spec.aureon.vol[dac + i],
					   ice->spec.aureon.master[i]);
					   spec->vol[dac + i],
					   spec->master[i]);
			change = 1;
		}
	}
@@ -1151,10 +1178,11 @@ static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	struct aureon_spec *spec = ice->spec;

	//snd_ice1712_save_gpio_status(ice);
	//val = aureon_cs8415_get(ice, CS8415_CTRL2);
	ucontrol->value.enumerated.item[0] = ice->spec.aureon.cs8415_mux;
	ucontrol->value.enumerated.item[0] = spec->cs8415_mux;
	//snd_ice1712_restore_gpio_status(ice);
	return 0;
}
@@ -1162,6 +1190,7 @@ static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	struct aureon_spec *spec = ice->spec;
	unsigned short oval, nval;
	int change;

@@ -1173,7 +1202,7 @@ static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
	if (change)
		aureon_cs8415_put(ice, CS8415_CTRL2, nval);
	snd_ice1712_restore_gpio_status(ice);
	ice->spec.aureon.cs8415_mux = ucontrol->value.enumerated.item[0];
	spec->cs8415_mux = ucontrol->value.enumerated.item[0];
	return change;
}

@@ -2009,10 +2038,16 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
		0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
		(unsigned short)-1
	};
	struct aureon_spec *spec;
	unsigned int tmp;
	const unsigned short *p;
	int err, i;

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

	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
		ice->num_total_dacs = 6;
		ice->num_total_adcs = 2;
@@ -2063,7 +2098,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
	    ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
		for (p = cs_inits; *p != (unsigned short)-1; p++)
			aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24);
		ice->spec.aureon.cs8415_mux = 1;
		spec->cs8415_mux = 1;

		aureon_set_headphone_amp(ice, 1);
	}
@@ -2074,11 +2109,11 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
	aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
	aureon_pca9554_write(ice, PCA9554_OUT, 0x00);   /* internal AUX */
	
	ice->spec.aureon.master[0] = WM_VOL_MUTE;
	ice->spec.aureon.master[1] = WM_VOL_MUTE;
	spec->master[0] = WM_VOL_MUTE;
	spec->master[1] = WM_VOL_MUTE;
	for (i = 0; i < ice->num_total_dacs; i++) {
		ice->spec.aureon.vol[i] = WM_VOL_MUTE;
		wm_set_vol(ice, i, ice->spec.aureon.vol[i], ice->spec.aureon.master[i % 2]);
		spec->vol[i] = WM_VOL_MUTE;
		wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
	}

	return 0;
+68 −23
Original line number Diff line number Diff line
@@ -44,6 +44,11 @@ enum {
};
	

/* additional i2c devices for EWS boards */
struct ews_spec {
	struct snd_i2c_device *i2cdevs[3];
};

/*
 * access via i2c mode (for EWX 24/96, EWS 88MT&D)
 */
@@ -141,15 +146,17 @@ static struct snd_i2c_bit_ops snd_ice1712_ewx_cs8427_bit_ops = {
/* AK4524 chip select; address 0x48 bit 0-3 */
static int snd_ice1712_ews88mt_chip_select(struct snd_ice1712 *ice, int chip_mask)
{
	struct ews_spec *spec = ice->spec;
	unsigned char data, ndata;

	snd_assert(chip_mask >= 0 && chip_mask <= 0x0f, return -EINVAL);
	snd_i2c_lock(ice->i2c);
	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &data, 1) != 1)
	if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF2], &data, 1) != 1)
		goto __error;
	ndata = (data & 0xf0) | chip_mask;
	if (ndata != data)
		if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &ndata, 1) != 1)
		if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_PCF2], &ndata, 1)
		    != 1)
			goto __error;
	snd_i2c_unlock(ice->i2c);
	return 0;
@@ -223,6 +230,7 @@ static void dmx6fire_ak4524_lock(struct snd_akm4xxx *ak, int chip)

static void snd_ice1712_ews_cs8404_spdif_write(struct snd_ice1712 *ice, unsigned char bits)
{
	struct ews_spec *spec = ice->spec;
	unsigned char bytes[2];

	snd_i2c_lock(ice->i2c);
@@ -230,15 +238,18 @@ static void snd_ice1712_ews_cs8404_spdif_write(struct snd_ice1712 *ice, unsigned
	case ICE1712_SUBDEVICE_EWS88MT:
	case ICE1712_SUBDEVICE_EWS88MT_NEW:
	case ICE1712_SUBDEVICE_PHASE88:
		if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_CS8404], &bits, 1) != 1)
		if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_CS8404], &bits, 1)
		    != 1)
			goto _error;
		break;
	case ICE1712_SUBDEVICE_EWS88D:
		if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_88D], bytes, 2) != 2)
		if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_88D], bytes, 2)
		    != 2)
			goto _error;
		if (bits != bytes[1]) {
			bytes[1] = bits;
			if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_88D], bytes, 2) != 2)
			if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_88D],
					      bytes, 2) != 2)
				goto _error;
		}
		break;
@@ -411,6 +422,7 @@ static int __devinit snd_ice1712_ews_init(struct snd_ice1712 *ice)
{
	int err;
	struct snd_akm4xxx *ak;
	struct ews_spec *spec;

	/* set the analog DACs */
	switch (ice->eeprom.subvendor) {
@@ -435,6 +447,11 @@ static int __devinit snd_ice1712_ews_init(struct snd_ice1712 *ice)
		break;
	}

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

	/* 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");
@@ -446,7 +463,10 @@ static int __devinit snd_ice1712_ews_init(struct snd_ice1712 *ice)
	/* create i2c devices */
	switch (ice->eeprom.subvendor) {
	case ICE1712_SUBDEVICE_DMX6FIRE:
		if ((err = snd_i2c_device_create(ice->i2c, "PCF9554", ICE1712_6FIRE_PCF9554_ADDR, &ice->spec.i2cdevs[EWS_I2C_6FIRE])) < 0) {
		err = snd_i2c_device_create(ice->i2c, "PCF9554",
					    ICE1712_6FIRE_PCF9554_ADDR,
					    &spec->i2cdevs[EWS_I2C_6FIRE]);
		if (err < 0) {
			snd_printk(KERN_ERR "PCF9554 initialization failed\n");
			return err;
		}
@@ -455,18 +475,30 @@ static int __devinit snd_ice1712_ews_init(struct snd_ice1712 *ice)
	case ICE1712_SUBDEVICE_EWS88MT:
	case ICE1712_SUBDEVICE_EWS88MT_NEW:
	case ICE1712_SUBDEVICE_PHASE88:
		if ((err = snd_i2c_device_create(ice->i2c, "CS8404", ICE1712_EWS88MT_CS8404_ADDR, &ice->spec.i2cdevs[EWS_I2C_CS8404])) < 0)
		err = snd_i2c_device_create(ice->i2c, "CS8404",
					    ICE1712_EWS88MT_CS8404_ADDR,
					    &spec->i2cdevs[EWS_I2C_CS8404]);
		if (err < 0)
			return err;
		if ((err = snd_i2c_device_create(ice->i2c, "PCF8574 (1st)", ICE1712_EWS88MT_INPUT_ADDR, &ice->spec.i2cdevs[EWS_I2C_PCF1])) < 0)
		err = snd_i2c_device_create(ice->i2c, "PCF8574 (1st)",
					    ICE1712_EWS88MT_INPUT_ADDR,
					    &spec->i2cdevs[EWS_I2C_PCF1]);
		if (err < 0)
			return err;
		if ((err = snd_i2c_device_create(ice->i2c, "PCF8574 (2nd)", ICE1712_EWS88MT_OUTPUT_ADDR, &ice->spec.i2cdevs[EWS_I2C_PCF2])) < 0)
		err = snd_i2c_device_create(ice->i2c, "PCF8574 (2nd)",
					    ICE1712_EWS88MT_OUTPUT_ADDR,
					    &spec->i2cdevs[EWS_I2C_PCF2]);
		if (err < 0)
			return err;
		/* Check if the front module is connected */
		if ((err = snd_ice1712_ews88mt_chip_select(ice, 0x0f)) < 0)
			return err;
		break;
	case ICE1712_SUBDEVICE_EWS88D:
		if ((err = snd_i2c_device_create(ice->i2c, "PCF8575", ICE1712_EWS88D_PCF_ADDR, &ice->spec.i2cdevs[EWS_I2C_88D])) < 0)
		err = snd_i2c_device_create(ice->i2c, "PCF8575",
					    ICE1712_EWS88D_PCF_ADDR,
					    &spec->i2cdevs[EWS_I2C_88D]);
		if (err < 0)
			return err;
		break;
	}
@@ -506,7 +538,7 @@ static int __devinit snd_ice1712_ews_init(struct snd_ice1712 *ice)
	}

	/* analog section */
	ak = ice->akm = kmalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
	ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
	if (! ak)
		return -ENOMEM;
	ice->akm_codecs = 1;
@@ -604,10 +636,11 @@ static struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = {
static int snd_ice1712_ews88mt_output_sense_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	struct ews_spec *spec = ice->spec;
	unsigned char data;

	snd_i2c_lock(ice->i2c);
	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) {
	if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) {
		snd_i2c_unlock(ice->i2c);
		return -EIO;
	}
@@ -620,15 +653,17 @@ static int snd_ice1712_ews88mt_output_sense_get(struct snd_kcontrol *kcontrol, s
static int snd_ice1712_ews88mt_output_sense_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	struct ews_spec *spec = ice->spec;
	unsigned char data, ndata;

	snd_i2c_lock(ice->i2c);
	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) {
	if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) {
		snd_i2c_unlock(ice->i2c);
		return -EIO;
	}
	ndata = (data & ~ICE1712_EWS88MT_OUTPUT_SENSE) | (ucontrol->value.enumerated.item[0] ? ICE1712_EWS88MT_OUTPUT_SENSE : 0);
	if (ndata != data && snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &ndata, 1) != 1) {
	if (ndata != data && snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_PCF2],
					       &ndata, 1) != 1) {
		snd_i2c_unlock(ice->i2c);
		return -EIO;
	}
@@ -640,12 +675,13 @@ static int snd_ice1712_ews88mt_output_sense_put(struct snd_kcontrol *kcontrol, s
static int snd_ice1712_ews88mt_input_sense_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	struct ews_spec *spec = ice->spec;
	int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
	unsigned char data;

	snd_assert(channel >= 0 && channel <= 7, return 0);
	snd_i2c_lock(ice->i2c);
	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
	if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
		snd_i2c_unlock(ice->i2c);
		return -EIO;
	}
@@ -659,17 +695,19 @@ static int snd_ice1712_ews88mt_input_sense_get(struct snd_kcontrol *kcontrol, st
static int snd_ice1712_ews88mt_input_sense_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	struct ews_spec *spec = ice->spec;
	int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
	unsigned char data, ndata;

	snd_assert(channel >= 0 && channel <= 7, return 0);
	snd_i2c_lock(ice->i2c);
	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
	if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
		snd_i2c_unlock(ice->i2c);
		return -EIO;
	}
	ndata = (data & ~(1 << channel)) | (ucontrol->value.enumerated.item[0] ? 0 : (1 << channel));
	if (ndata != data && snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_PCF1], &ndata, 1) != 1) {
	if (ndata != data && snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_PCF1],
					       &ndata, 1) != 1) {
		snd_i2c_unlock(ice->i2c);
		return -EIO;
	}
@@ -704,12 +742,13 @@ static struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata =
static int snd_ice1712_ews88d_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	struct ews_spec *spec = ice->spec;
	int shift = kcontrol->private_value & 0xff;
	int invert = (kcontrol->private_value >> 8) & 1;
	unsigned char data[2];
	
	snd_i2c_lock(ice->i2c);
	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_88D], data, 2) != 2) {
	if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_88D], data, 2) != 2) {
		snd_i2c_unlock(ice->i2c);
		return -EIO;
	}
@@ -724,13 +763,14 @@ static int snd_ice1712_ews88d_control_get(struct snd_kcontrol *kcontrol, struct
static int snd_ice1712_ews88d_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	struct ews_spec *spec = ice->spec;
	int shift = kcontrol->private_value & 0xff;
	int invert = (kcontrol->private_value >> 8) & 1;
	unsigned char data[2], ndata[2];
	int change;

	snd_i2c_lock(ice->i2c);
	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_88D], data, 2) != 2) {
	if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_88D], data, 2) != 2) {
		snd_i2c_unlock(ice->i2c);
		return -EIO;
	}
@@ -743,7 +783,8 @@ static int snd_ice1712_ews88d_control_put(struct snd_kcontrol *kcontrol, struct
			ndata[shift >> 3] |= (1 << (shift & 7));
	}
	change = (data[shift >> 3] != ndata[shift >> 3]);
	if (change && snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_88D], data, 2) != 2) {
	if (change &&
	    snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_88D], data, 2) != 2) {
		snd_i2c_unlock(ice->i2c);
		return -EIO;
	}
@@ -777,11 +818,13 @@ static struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = {
static int snd_ice1712_6fire_read_pca(struct snd_ice1712 *ice, unsigned char reg)
{
	unsigned char byte;
	struct ews_spec *spec = ice->spec;

	snd_i2c_lock(ice->i2c);
	byte = reg;
	snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], &byte, 1);
	snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_6FIRE], &byte, 1);
	byte = 0;
	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], &byte, 1) != 1) {
	if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_6FIRE], &byte, 1) != 1) {
		snd_i2c_unlock(ice->i2c);
		printk(KERN_ERR "cannot read pca\n");
		return -EIO;
@@ -793,10 +836,12 @@ static int snd_ice1712_6fire_read_pca(struct snd_ice1712 *ice, unsigned char reg
static int snd_ice1712_6fire_write_pca(struct snd_ice1712 *ice, unsigned char reg, unsigned char data)
{
	unsigned char bytes[2];
	struct ews_spec *spec = ice->spec;

	snd_i2c_lock(ice->i2c);
	bytes[0] = reg;
	bytes[1] = data;
	if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], bytes, 2) != 2) {
	if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_6FIRE], bytes, 2) != 2) {
		snd_i2c_unlock(ice->i2c);
		return -EIO;
	}
+101 −82

File changed.

Preview size limit exceeded, changes collapsed.

+1 −0
Original line number Diff line number Diff line
@@ -2490,6 +2490,7 @@ static int snd_ice1712_free(struct snd_ice1712 *ice)
		pci_release_regions(ice->pci);
	snd_ice1712_akm4xxx_free(ice);
	pci_disable_device(ice->pci);
	kfree(ice->spec);
	kfree(ice);
	return 0;
}
+1 −50
Original line number Diff line number Diff line
@@ -366,56 +366,7 @@ struct snd_ice1712 {
	struct mutex gpio_mutex;

	/* other board-specific data */
	union {
		/* additional i2c devices for EWS boards */
		struct snd_i2c_device *i2cdevs[3];
		/* AC97 register cache for Aureon */
		struct aureon_spec {
			unsigned short stac9744[64];
			unsigned int cs8415_mux;
			unsigned short master[2];
			unsigned short vol[8];
			unsigned char pca9554_out;
		} aureon;
		/* AC97 register cache for Phase28 */
		struct phase28_spec {
			unsigned short master[2];
			unsigned short vol[8];
		} phase28;
		/* a non-standard I2C device for revo51 */
		struct revo51_spec {
			struct snd_i2c_device *dev;
			struct snd_pt2258 *pt2258;
		} revo51;
		/* Hoontech-specific setting */
		struct hoontech_spec {
			unsigned char boxbits[4];
			unsigned int config;
			unsigned short boxconfig[4];
		} hoontech;
		struct {
			struct ak4114 *ak4114;
			unsigned int analog: 1;
		} juli;
		struct {
			struct ak4114 *ak4114;
			/* rate change needs atomic mute/unmute of all dacs*/
			struct mutex mute_mutex;
		} prodigy192;
		struct {
			struct {
				unsigned char ch1, ch2;
			} vol[8];
		} se;
		struct prodigy_hifi_spec {
			unsigned short master[2];
			unsigned short vol[8];
		} prodigy_hifi;
		struct prodigy_hd2_spec {
			unsigned short vol[2];
		} prodigy_hd2;
	} spec;

	void *spec;
};


Loading