[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: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
797760ab14
commit
7cda8ba9f4
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,12 @@
|
|||
#include "ice1712.h"
|
||||
#include "hoontech.h"
|
||||
|
||||
/* Hoontech-specific setting */
|
||||
struct hoontech_spec {
|
||||
unsigned char boxbits[4];
|
||||
unsigned int config;
|
||||
unsigned short boxconfig[4];
|
||||
};
|
||||
|
||||
static void __devinit snd_ice1712_stdsp24_gpio_write(struct snd_ice1712 *ice, unsigned char byte)
|
||||
{
|
||||
|
@ -49,169 +55,182 @@ static void __devinit snd_ice1712_stdsp24_gpio_write(struct snd_ice1712 *ice, un
|
|||
|
||||
static void __devinit snd_ice1712_stdsp24_darear(struct snd_ice1712 *ice, int activate)
|
||||
{
|
||||
struct hoontech_spec *spec = ice->spec;
|
||||
mutex_lock(&ice->gpio_mutex);
|
||||
ICE1712_STDSP24_0_DAREAR(ice->spec.hoontech.boxbits, activate);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[0]);
|
||||
ICE1712_STDSP24_0_DAREAR(spec->boxbits, activate);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]);
|
||||
mutex_unlock(&ice->gpio_mutex);
|
||||
}
|
||||
|
||||
static void __devinit snd_ice1712_stdsp24_mute(struct snd_ice1712 *ice, int activate)
|
||||
{
|
||||
struct hoontech_spec *spec = ice->spec;
|
||||
mutex_lock(&ice->gpio_mutex);
|
||||
ICE1712_STDSP24_3_MUTE(ice->spec.hoontech.boxbits, activate);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
|
||||
ICE1712_STDSP24_3_MUTE(spec->boxbits, activate);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
|
||||
mutex_unlock(&ice->gpio_mutex);
|
||||
}
|
||||
|
||||
static void __devinit snd_ice1712_stdsp24_insel(struct snd_ice1712 *ice, int activate)
|
||||
{
|
||||
struct hoontech_spec *spec = ice->spec;
|
||||
mutex_lock(&ice->gpio_mutex);
|
||||
ICE1712_STDSP24_3_INSEL(ice->spec.hoontech.boxbits, activate);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
|
||||
ICE1712_STDSP24_3_INSEL(spec->boxbits, activate);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
|
||||
mutex_unlock(&ice->gpio_mutex);
|
||||
}
|
||||
|
||||
static void __devinit snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, int box, int chn, int activate)
|
||||
{
|
||||
struct hoontech_spec *spec = ice->spec;
|
||||
|
||||
mutex_lock(&ice->gpio_mutex);
|
||||
|
||||
/* select box */
|
||||
ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, box);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[0]);
|
||||
ICE1712_STDSP24_0_BOX(spec->boxbits, box);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]);
|
||||
|
||||
/* prepare for write */
|
||||
if (chn == 3)
|
||||
ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 0);
|
||||
ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, activate);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
|
||||
ICE1712_STDSP24_2_CHN4(spec->boxbits, 0);
|
||||
ICE1712_STDSP24_2_MIDI1(spec->boxbits, activate);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
|
||||
|
||||
ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 1);
|
||||
ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 1);
|
||||
ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 1);
|
||||
ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 1);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[1]);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
|
||||
ICE1712_STDSP24_1_CHN1(spec->boxbits, 1);
|
||||
ICE1712_STDSP24_1_CHN2(spec->boxbits, 1);
|
||||
ICE1712_STDSP24_1_CHN3(spec->boxbits, 1);
|
||||
ICE1712_STDSP24_2_CHN4(spec->boxbits, 1);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
|
||||
udelay(100);
|
||||
if (chn == 3) {
|
||||
ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 0);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
|
||||
ICE1712_STDSP24_2_CHN4(spec->boxbits, 0);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
|
||||
} else {
|
||||
switch (chn) {
|
||||
case 0: ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 0); break;
|
||||
case 1: ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 0); break;
|
||||
case 2: ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 0); break;
|
||||
case 0: ICE1712_STDSP24_1_CHN1(spec->boxbits, 0); break;
|
||||
case 1: ICE1712_STDSP24_1_CHN2(spec->boxbits, 0); break;
|
||||
case 2: ICE1712_STDSP24_1_CHN3(spec->boxbits, 0); break;
|
||||
}
|
||||
snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[1]);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]);
|
||||
}
|
||||
udelay(100);
|
||||
ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 1);
|
||||
ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 1);
|
||||
ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 1);
|
||||
ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 1);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[1]);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
|
||||
ICE1712_STDSP24_1_CHN1(spec->boxbits, 1);
|
||||
ICE1712_STDSP24_1_CHN2(spec->boxbits, 1);
|
||||
ICE1712_STDSP24_1_CHN3(spec->boxbits, 1);
|
||||
ICE1712_STDSP24_2_CHN4(spec->boxbits, 1);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
|
||||
udelay(100);
|
||||
|
||||
ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, 0);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
|
||||
ICE1712_STDSP24_2_MIDI1(spec->boxbits, 0);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
|
||||
|
||||
mutex_unlock(&ice->gpio_mutex);
|
||||
}
|
||||
|
||||
static void __devinit snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int box, int master)
|
||||
{
|
||||
struct hoontech_spec *spec = ice->spec;
|
||||
|
||||
mutex_lock(&ice->gpio_mutex);
|
||||
|
||||
/* select box */
|
||||
ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, box);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[0]);
|
||||
ICE1712_STDSP24_0_BOX(spec->boxbits, box);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]);
|
||||
|
||||
ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 1);
|
||||
ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, master);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
|
||||
ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1);
|
||||
ICE1712_STDSP24_2_MIDI1(spec->boxbits, master);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
|
||||
|
||||
udelay(100);
|
||||
|
||||
ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 0);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
|
||||
ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 0);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
|
||||
|
||||
mdelay(10);
|
||||
|
||||
ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 1);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
|
||||
ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
|
||||
|
||||
mutex_unlock(&ice->gpio_mutex);
|
||||
}
|
||||
|
||||
static void __devinit snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int activate)
|
||||
{
|
||||
struct hoontech_spec *spec = ice->spec;
|
||||
mutex_lock(&ice->gpio_mutex);
|
||||
ICE1712_STDSP24_3_MIDI2(ice->spec.hoontech.boxbits, activate);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
|
||||
ICE1712_STDSP24_3_MIDI2(spec->boxbits, activate);
|
||||
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
|
||||
mutex_unlock(&ice->gpio_mutex);
|
||||
}
|
||||
|
||||
static int __devinit snd_ice1712_hoontech_init(struct snd_ice1712 *ice)
|
||||
{
|
||||
struct hoontech_spec *spec;
|
||||
int box, chn;
|
||||
|
||||
ice->num_total_dacs = 8;
|
||||
ice->num_total_adcs = 8;
|
||||
|
||||
ice->spec.hoontech.boxbits[0] =
|
||||
ice->spec.hoontech.boxbits[1] =
|
||||
ice->spec.hoontech.boxbits[2] =
|
||||
ice->spec.hoontech.boxbits[3] = 0; /* should be already */
|
||||
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
||||
if (!spec)
|
||||
return -ENOMEM;
|
||||
ice->spec = spec;
|
||||
|
||||
ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 0);
|
||||
ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 0, 1);
|
||||
ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, 0);
|
||||
ICE1712_STDSP24_0_DAREAR(ice->spec.hoontech.boxbits, 0);
|
||||
ICE1712_STDSP24_SET_ADDR(spec->boxbits, 0);
|
||||
ICE1712_STDSP24_CLOCK(spec->boxbits, 0, 1);
|
||||
ICE1712_STDSP24_0_BOX(spec->boxbits, 0);
|
||||
ICE1712_STDSP24_0_DAREAR(spec->boxbits, 0);
|
||||
|
||||
ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 1);
|
||||
ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 1, 1);
|
||||
ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 1);
|
||||
ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 1);
|
||||
ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 1);
|
||||
ICE1712_STDSP24_SET_ADDR(spec->boxbits, 1);
|
||||
ICE1712_STDSP24_CLOCK(spec->boxbits, 1, 1);
|
||||
ICE1712_STDSP24_1_CHN1(spec->boxbits, 1);
|
||||
ICE1712_STDSP24_1_CHN2(spec->boxbits, 1);
|
||||
ICE1712_STDSP24_1_CHN3(spec->boxbits, 1);
|
||||
|
||||
ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 2);
|
||||
ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 2, 1);
|
||||
ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 1);
|
||||
ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 1);
|
||||
ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, 0);
|
||||
ICE1712_STDSP24_SET_ADDR(spec->boxbits, 2);
|
||||
ICE1712_STDSP24_CLOCK(spec->boxbits, 2, 1);
|
||||
ICE1712_STDSP24_2_CHN4(spec->boxbits, 1);
|
||||
ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1);
|
||||
ICE1712_STDSP24_2_MIDI1(spec->boxbits, 0);
|
||||
|
||||
ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 3);
|
||||
ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 3, 1);
|
||||
ICE1712_STDSP24_3_MIDI2(ice->spec.hoontech.boxbits, 0);
|
||||
ICE1712_STDSP24_3_MUTE(ice->spec.hoontech.boxbits, 1);
|
||||
ICE1712_STDSP24_3_INSEL(ice->spec.hoontech.boxbits, 0);
|
||||
ICE1712_STDSP24_SET_ADDR(spec->boxbits, 3);
|
||||
ICE1712_STDSP24_CLOCK(spec->boxbits, 3, 1);
|
||||
ICE1712_STDSP24_3_MIDI2(spec->boxbits, 0);
|
||||
ICE1712_STDSP24_3_MUTE(spec->boxbits, 1);
|
||||
ICE1712_STDSP24_3_INSEL(spec->boxbits, 0);
|
||||
|
||||
/* let's go - activate only functions in first box */
|
||||
ice->spec.hoontech.config = 0;
|
||||
spec->config = 0;
|
||||
/* ICE1712_STDSP24_MUTE |
|
||||
ICE1712_STDSP24_INSEL |
|
||||
ICE1712_STDSP24_DAREAR; */
|
||||
ice->spec.hoontech.boxconfig[0] = ICE1712_STDSP24_BOX_CHN1 |
|
||||
spec->boxconfig[0] = ICE1712_STDSP24_BOX_CHN1 |
|
||||
ICE1712_STDSP24_BOX_CHN2 |
|
||||
ICE1712_STDSP24_BOX_CHN3 |
|
||||
ICE1712_STDSP24_BOX_CHN4 |
|
||||
ICE1712_STDSP24_BOX_MIDI1 |
|
||||
ICE1712_STDSP24_BOX_MIDI2;
|
||||
ice->spec.hoontech.boxconfig[1] =
|
||||
ice->spec.hoontech.boxconfig[2] =
|
||||
ice->spec.hoontech.boxconfig[3] = 0;
|
||||
snd_ice1712_stdsp24_darear(ice, (ice->spec.hoontech.config & ICE1712_STDSP24_DAREAR) ? 1 : 0);
|
||||
snd_ice1712_stdsp24_mute(ice, (ice->spec.hoontech.config & ICE1712_STDSP24_MUTE) ? 1 : 0);
|
||||
snd_ice1712_stdsp24_insel(ice, (ice->spec.hoontech.config & ICE1712_STDSP24_INSEL) ? 1 : 0);
|
||||
spec->boxconfig[1] =
|
||||
spec->boxconfig[2] =
|
||||
spec->boxconfig[3] = 0;
|
||||
snd_ice1712_stdsp24_darear(ice,
|
||||
(spec->config & ICE1712_STDSP24_DAREAR) ? 1 : 0);
|
||||
snd_ice1712_stdsp24_mute(ice,
|
||||
(spec->config & ICE1712_STDSP24_MUTE) ? 1 : 0);
|
||||
snd_ice1712_stdsp24_insel(ice,
|
||||
(spec->config & ICE1712_STDSP24_INSEL) ? 1 : 0);
|
||||
for (box = 0; box < 1; box++) {
|
||||
if (ice->spec.hoontech.boxconfig[box] & ICE1712_STDSP24_BOX_MIDI2)
|
||||
if (spec->boxconfig[box] & ICE1712_STDSP24_BOX_MIDI2)
|
||||
snd_ice1712_stdsp24_midi2(ice, 1);
|
||||
for (chn = 0; chn < 4; chn++)
|
||||
snd_ice1712_stdsp24_box_channel(ice, box, chn, (ice->spec.hoontech.boxconfig[box] & (1 << chn)) ? 1 : 0);
|
||||
snd_ice1712_stdsp24_box_channel(ice, box, chn,
|
||||
(spec->boxconfig[box] & (1 << chn)) ? 1 : 0);
|
||||
snd_ice1712_stdsp24_box_midi(ice, box,
|
||||
(ice->spec.hoontech.boxconfig[box] & ICE1712_STDSP24_BOX_MIDI1) ? 1 : 0);
|
||||
(spec->boxconfig[box] & ICE1712_STDSP24_BOX_MIDI1) ? 1 : 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -2176,6 +2176,7 @@ static int snd_vt1724_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;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,11 @@
|
|||
#include "envy24ht.h"
|
||||
#include "juli.h"
|
||||
|
||||
struct juli_spec {
|
||||
struct ak4114 *ak4114;
|
||||
unsigned int analog: 1;
|
||||
};
|
||||
|
||||
/*
|
||||
* chip addresses on I2C bus
|
||||
*/
|
||||
|
@ -137,12 +142,13 @@ static struct snd_akm4xxx akm_juli_dac __devinitdata = {
|
|||
|
||||
static int __devinit juli_add_controls(struct snd_ice1712 *ice)
|
||||
{
|
||||
struct juli_spec *spec = ice->spec;
|
||||
int err;
|
||||
err = snd_ice1712_akm4xxx_build_controls(ice);
|
||||
if (err < 0)
|
||||
return err;
|
||||
/* only capture SPDIF over AK4114 */
|
||||
err = snd_ak4114_build(ice->spec.juli.ak4114, NULL,
|
||||
err = snd_ak4114_build(spec->ak4114, NULL,
|
||||
ice->pcm_pro->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
@ -166,13 +172,19 @@ static int __devinit juli_init(struct snd_ice1712 *ice)
|
|||
0x41, 0x02, 0x2c, 0x00, 0x00
|
||||
};
|
||||
int err;
|
||||
struct juli_spec *spec;
|
||||
struct snd_akm4xxx *ak;
|
||||
|
||||
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
||||
if (!spec)
|
||||
return -ENOMEM;
|
||||
ice->spec = spec;
|
||||
|
||||
err = snd_ak4114_create(ice->card,
|
||||
juli_ak4114_read,
|
||||
juli_ak4114_write,
|
||||
ak4114_init_vals, ak4114_init_txcsb,
|
||||
ice, &ice->spec.juli.ak4114);
|
||||
ice, &spec->ak4114);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -180,12 +192,12 @@ static int __devinit juli_init(struct snd_ice1712 *ice)
|
|||
/* it seems that the analog doughter board detection does not work
|
||||
reliably, so force the analog flag; it should be very rare
|
||||
to use Juli@ without the analog doughter board */
|
||||
ice->spec.juli.analog = (ice->gpio.get_data(ice) & GPIO_ANALOG_PRESENT) ? 0 : 1;
|
||||
spec->analog = (ice->gpio.get_data(ice) & GPIO_ANALOG_PRESENT) ? 0 : 1;
|
||||
#else
|
||||
ice->spec.juli.analog = 1;
|
||||
spec->analog = 1;
|
||||
#endif
|
||||
|
||||
if (ice->spec.juli.analog) {
|
||||
if (spec->analog) {
|
||||
printk(KERN_INFO "juli@: analog I/O detected\n");
|
||||
ice->num_total_dacs = 2;
|
||||
ice->num_total_adcs = 2;
|
||||
|
|
|
@ -47,6 +47,12 @@
|
|||
#include "phase.h"
|
||||
#include <sound/tlv.h>
|
||||
|
||||
/* AC97 register cache for Phase28 */
|
||||
struct phase28_spec {
|
||||
unsigned short master[2];
|
||||
unsigned short vol[8];
|
||||
} phase28;
|
||||
|
||||
/* WM8770 registers */
|
||||
#define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */
|
||||
#define WM_DAC_MASTER_ATTEN 0x08 /* DAC master analog attenuation */
|
||||
|
@ -312,15 +318,17 @@ 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 phase28_spec *spec = ice->spec;
|
||||
int i;
|
||||
for (i=0; i<2; i++)
|
||||
ucontrol->value.integer.value[i] = ice->spec.phase28.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 phase28_spec *spec = ice->spec;
|
||||
int ch, change = 0;
|
||||
|
||||
snd_ice1712_save_gpio_status(ice);
|
||||
|
@ -328,14 +336,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.phase28.master[ch] & WM_VOL_MUTE;
|
||||
if (vol != ice->spec.phase28.master[ch]) {
|
||||
vol |= spec->master[ch] & WM_VOL_MUTE;
|
||||
if (vol != spec->master[ch]) {
|
||||
int dac;
|
||||
ice->spec.phase28.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.phase28.vol[dac + ch],
|
||||
ice->spec.phase28.master[ch]);
|
||||
spec->vol[dac + ch],
|
||||
spec->master[ch]);
|
||||
change = 1;
|
||||
}
|
||||
}
|
||||
|
@ -384,12 +392,18 @@ static int __devinit phase28_init(struct snd_ice1712 *ice)
|
|||
|
||||
unsigned int tmp;
|
||||
struct snd_akm4xxx *ak;
|
||||
struct phase28_spec *spec;
|
||||
const unsigned short *p;
|
||||
int i;
|
||||
|
||||
ice->num_total_dacs = 8;
|
||||
ice->num_total_adcs = 2;
|
||||
|
||||
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
||||
if (!spec)
|
||||
return -ENOMEM;
|
||||
ice->spec = spec;
|
||||
|
||||
// Initialize analog chips
|
||||
ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
|
||||
if (!ak)
|
||||
|
@ -419,11 +433,11 @@ static int __devinit phase28_init(struct snd_ice1712 *ice)
|
|||
|
||||
snd_ice1712_restore_gpio_status(ice);
|
||||
|
||||
ice->spec.phase28.master[0] = WM_VOL_MUTE;
|
||||
ice->spec.phase28.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.phase28.vol[i] = WM_VOL_MUTE;
|
||||
wm_set_vol(ice, i, ice->spec.phase28.vol[i], ice->spec.phase28.master[i % 2]);
|
||||
spec->vol[i] = WM_VOL_MUTE;
|
||||
wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -445,18 +459,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 phase28_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.phase28.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 phase28_spec *spec = ice->spec;
|
||||
int i, idx, ofs, voices;
|
||||
int change = 0;
|
||||
|
||||
|
@ -468,12 +485,12 @@ static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *
|
|||
vol = ucontrol->value.integer.value[i];
|
||||
if (vol > 0x7f)
|
||||
continue;
|
||||
vol |= ice->spec.phase28.vol[ofs+i] & WM_VOL_MUTE;
|
||||
if (vol != ice->spec.phase28.vol[ofs+i]) {
|
||||
ice->spec.phase28.vol[ofs+i] = vol;
|
||||
vol |= spec->vol[ofs+i] & WM_VOL_MUTE;
|
||||
if (vol != spec->vol[ofs+i]) {
|
||||
spec->vol[ofs+i] = vol;
|
||||
idx = WM_DAC_ATTEN + ofs + i;
|
||||
wm_set_vol(ice, idx, ice->spec.phase28.vol[ofs+i],
|
||||
ice->spec.phase28.master[i]);
|
||||
wm_set_vol(ice, idx, spec->vol[ofs+i],
|
||||
spec->master[i]);
|
||||
change = 1;
|
||||
}
|
||||
}
|
||||
|
@ -495,19 +512,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 phase28_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.phase28.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 phase28_spec *spec = ice->spec;
|
||||
int change = 0, voices, ofs, i;
|
||||
|
||||
voices = kcontrol->private_value >> 8;
|
||||
|
@ -515,13 +535,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.phase28.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.phase28.vol[ofs + i] &= ~WM_VOL_MUTE;
|
||||
ice->spec.phase28.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.phase28.vol[ofs + i],
|
||||
ice->spec.phase28.master[i]);
|
||||
wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
|
||||
spec->master[i]);
|
||||
change = 1;
|
||||
}
|
||||
}
|
||||
|
@ -538,29 +558,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 phase28_spec *spec = ice->spec;
|
||||
|
||||
ucontrol->value.integer.value[0] = (ice->spec.phase28.master[0] & WM_VOL_MUTE) ? 0 : 1;
|
||||
ucontrol->value.integer.value[1] = (ice->spec.phase28.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 phase28_spec *spec = ice->spec;
|
||||
int change = 0, i;
|
||||
|
||||
snd_ice1712_save_gpio_status(ice);
|
||||
for (i = 0; i < 2; i++) {
|
||||
int val = (ice->spec.phase28.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.phase28.master[i] &= ~WM_VOL_MUTE;
|
||||
ice->spec.phase28.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.phase28.vol[dac + i],
|
||||
ice->spec.phase28.master[i]);
|
||||
spec->vol[dac + i],
|
||||
spec->master[i]);
|
||||
change = 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,6 +67,12 @@
|
|||
#include "stac946x.h"
|
||||
#include <sound/tlv.h>
|
||||
|
||||
struct prodigy192_spec {
|
||||
struct ak4114 *ak4114;
|
||||
/* rate change needs atomic mute/unmute of all dacs*/
|
||||
struct mutex mute_mutex;
|
||||
};
|
||||
|
||||
static inline void stac9460_put(struct snd_ice1712 *ice, int reg, unsigned char val)
|
||||
{
|
||||
snd_vt1724_write_i2c(ice, PRODIGY192_STAC9460_ADDR, reg, val);
|
||||
|
@ -118,6 +124,7 @@ static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
|
|||
static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
|
||||
struct prodigy192_spec *spec = ice->spec;
|
||||
int idx, change;
|
||||
|
||||
if (kcontrol->private_value)
|
||||
|
@ -125,11 +132,11 @@ static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
|
|||
else
|
||||
idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
|
||||
/* due to possible conflicts with stac9460_set_rate_val, mutexing */
|
||||
mutex_lock(&ice->spec.prodigy192.mute_mutex);
|
||||
mutex_lock(&spec->mute_mutex);
|
||||
/*printk("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]);
|
||||
mutex_unlock(&ice->spec.prodigy192.mute_mutex);
|
||||
mutex_unlock(&spec->mute_mutex);
|
||||
return change;
|
||||
}
|
||||
|
||||
|
@ -318,6 +325,7 @@ static void stac9460_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
|
|||
int idx;
|
||||
unsigned char changed[7];
|
||||
struct snd_ice1712 *ice = ak->private_data[0];
|
||||
struct prodigy192_spec *spec = ice->spec;
|
||||
|
||||
if (rate == 0) /* no hint - S/PDIF input is master, simply return */
|
||||
return;
|
||||
|
@ -332,7 +340,7 @@ static void stac9460_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
|
|||
return;
|
||||
/* change detected, setting master clock, muting first */
|
||||
/* due to possible conflicts with mute controls - mutexing */
|
||||
mutex_lock(&ice->spec.prodigy192.mute_mutex);
|
||||
mutex_lock(&spec->mute_mutex);
|
||||
/* we have to remember current mute status for each DAC */
|
||||
for (idx = 0; idx < 7 ; ++idx)
|
||||
changed[idx] = stac9460_dac_mute(ice,
|
||||
|
@ -346,7 +354,7 @@ static void stac9460_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
|
|||
if (changed[idx])
|
||||
stac9460_dac_mute(ice, STAC946X_MASTER_VOLUME + idx, 1);
|
||||
}
|
||||
mutex_unlock(&ice->spec.prodigy192.mute_mutex);
|
||||
mutex_unlock(&spec->mute_mutex);
|
||||
}
|
||||
|
||||
/* using akm infrastructure for setting rate of the codec */
|
||||
|
@ -633,12 +641,13 @@ static int prodigy192_ak4114_init(struct snd_ice1712 *ice)
|
|||
static const unsigned char ak4114_init_txcsb[] = {
|
||||
0x41, 0x02, 0x2c, 0x00, 0x00
|
||||
};
|
||||
struct prodigy192_spec *spec = ice->spec;
|
||||
|
||||
return snd_ak4114_create(ice->card,
|
||||
prodigy192_ak4114_read,
|
||||
prodigy192_ak4114_write,
|
||||
ak4114_init_vals, ak4114_init_txcsb,
|
||||
ice, &ice->spec.prodigy192.ak4114);
|
||||
ice, &spec->ak4114);
|
||||
}
|
||||
|
||||
static void stac9460_proc_regs_read(struct snd_info_entry *entry,
|
||||
|
@ -664,6 +673,7 @@ static void stac9460_proc_init(struct snd_ice1712 *ice)
|
|||
|
||||
static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice)
|
||||
{
|
||||
struct prodigy192_spec *spec = ice->spec;
|
||||
unsigned int i;
|
||||
int err;
|
||||
|
||||
|
@ -673,7 +683,7 @@ static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice)
|
|||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
if (ice->spec.prodigy192.ak4114) {
|
||||
if (spec->ak4114) {
|
||||
/* ak4114 is connected */
|
||||
for (i = 0; i < ARRAY_SIZE(ak4114_controls); i++) {
|
||||
err = snd_ctl_add(ice->card,
|
||||
|
@ -682,7 +692,7 @@ static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice)
|
|||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
err = snd_ak4114_build(ice->spec.prodigy192.ak4114,
|
||||
err = snd_ak4114_build(spec->ak4114,
|
||||
NULL, /* ak4114 in MIO/DI/O handles no IEC958 output */
|
||||
ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
|
||||
if (err < 0)
|
||||
|
@ -734,12 +744,19 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice)
|
|||
const unsigned short *p;
|
||||
int err = 0;
|
||||
struct snd_akm4xxx *ak;
|
||||
struct prodigy192_spec *spec;
|
||||
|
||||
/* prodigy 192 */
|
||||
ice->num_total_dacs = 6;
|
||||
ice->num_total_adcs = 2;
|
||||
ice->vt1720 = 0; /* ice1724, e.g. 23 GPIOs */
|
||||
|
||||
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
||||
if (!spec)
|
||||
return -ENOMEM;
|
||||
ice->spec = spec;
|
||||
mutex_init(&spec->mute_mutex);
|
||||
|
||||
/* initialize codec */
|
||||
p = stac_inits_prodigy;
|
||||
for (; *p != (unsigned short)-1; p += 2)
|
||||
|
@ -758,7 +775,7 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice)
|
|||
if (prodigy192_miodio_exists(ice)) {
|
||||
err = prodigy192_ak4114_init(ice);
|
||||
/* from this moment if err = 0 then
|
||||
* ice->spec.prodigy192.ak4114 should not be null
|
||||
* spec->ak4114 should not be null
|
||||
*/
|
||||
snd_printdd("AK4114 initialized with status %d\n", err);
|
||||
} else
|
||||
|
@ -766,8 +783,6 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice)
|
|||
if (err < 0)
|
||||
return err;
|
||||
|
||||
mutex_init(&ice->spec.prodigy192.mute_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,11 @@
|
|||
#include "envy24ht.h"
|
||||
#include "prodigy_hifi.h"
|
||||
|
||||
struct prodigy_hifi_spec {
|
||||
unsigned short master[2];
|
||||
unsigned short vol[8];
|
||||
};
|
||||
|
||||
/* I2C addresses */
|
||||
#define WM_DEV 0x34
|
||||
|
||||
|
@ -177,7 +182,8 @@ static void wm8766_spi_send_word(struct snd_ice1712 *ice, unsigned int data)
|
|||
}
|
||||
}
|
||||
|
||||
static void wm8766_spi_write(struct snd_ice1712 *ice, unsigned int reg, unsigned int data)
|
||||
static void wm8766_spi_write(struct snd_ice1712 *ice, unsigned int reg,
|
||||
unsigned int data)
|
||||
{
|
||||
unsigned int block;
|
||||
|
||||
|
@ -216,7 +222,8 @@ static void ak4396_send_word(struct snd_ice1712 *ice, unsigned int data)
|
|||
}
|
||||
}
|
||||
|
||||
static void ak4396_write(struct snd_ice1712 *ice, unsigned int reg, unsigned int data)
|
||||
static void ak4396_write(struct snd_ice1712 *ice, unsigned int reg,
|
||||
unsigned int data)
|
||||
{
|
||||
unsigned int block;
|
||||
|
||||
|
@ -246,7 +253,8 @@ static void ak4396_write(struct snd_ice1712 *ice, unsigned int reg, unsigned int
|
|||
* DAC volume attenuation mixer control (-64dB to 0dB)
|
||||
*/
|
||||
|
||||
static int ak4396_dac_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
|
||||
static int ak4396_dac_vol_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
|
||||
uinfo->count = 2;
|
||||
|
@ -255,31 +263,32 @@ static int ak4396_dac_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ak4396_dac_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
static int ak4396_dac_vol_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
|
||||
struct prodigy_hifi_spec *spec = ice->spec;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
ucontrol->value.integer.value[i] =ice->spec.prodigy_hd2.vol[i];
|
||||
}
|
||||
for (i = 0; i < 2; i++)
|
||||
ucontrol->value.integer.value[i] = spec->vol[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ak4396_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
|
||||
struct prodigy_hifi_spec *spec = ice->spec;
|
||||
int i;
|
||||
int change = 0;
|
||||
|
||||
mutex_lock(&ice->gpio_mutex);
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (ucontrol->value.integer.value[i] !=
|
||||
ice->spec.prodigy_hd2.vol[i]) {
|
||||
ice->spec.prodigy_hd2.vol[i] =
|
||||
ucontrol->value.integer.value[i];
|
||||
if (ucontrol->value.integer.value[i] != spec->vol[i]) {
|
||||
spec->vol[i] = ucontrol->value.integer.value[i];
|
||||
ak4396_write(ice, AK4396_LCH_ATT + i,
|
||||
(ice->spec.prodigy_hd2.vol[i] & 0xff));
|
||||
spec->vol[i] & 0xff);
|
||||
change = 1;
|
||||
}
|
||||
}
|
||||
|
@ -333,7 +342,8 @@ static const unsigned char wm_vol[256] = {
|
|||
#define DAC_MIN (DAC_0dB - DAC_RES)
|
||||
|
||||
|
||||
static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
|
||||
static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index,
|
||||
unsigned short vol, unsigned short master)
|
||||
{
|
||||
unsigned char nvol;
|
||||
|
||||
|
@ -349,7 +359,8 @@ static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned sho
|
|||
wm_put_nocache(ice, index, 0x100 | nvol);
|
||||
}
|
||||
|
||||
static void wm8766_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
|
||||
static void wm8766_set_vol(struct snd_ice1712 *ice, unsigned int index,
|
||||
unsigned short vol, unsigned short master)
|
||||
{
|
||||
unsigned char nvol;
|
||||
|
||||
|
@ -361,7 +372,6 @@ static void wm8766_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned
|
|||
nvol = (nvol ? (nvol + DAC_MIN) : 0) & 0xff;
|
||||
}
|
||||
|
||||
|
||||
wm8766_spi_write(ice, index, (0x0100 | nvol));
|
||||
}
|
||||
|
||||
|
@ -370,7 +380,8 @@ static void wm8766_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned
|
|||
* DAC volume attenuation mixer control (-64dB to 0dB)
|
||||
*/
|
||||
|
||||
static int wm_dac_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
|
||||
static int wm_dac_vol_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
|
||||
uinfo->count = 2;
|
||||
|
@ -379,33 +390,32 @@ static int wm_dac_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_in
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int wm_dac_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
static int wm_dac_vol_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
|
||||
struct prodigy_hifi_spec *spec = ice->spec;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (i = 0; i < 2; i++)
|
||||
ucontrol->value.integer.value[i] =
|
||||
ice->spec.prodigy_hifi.vol[2+i] & ~WM_VOL_MUTE;
|
||||
}
|
||||
spec->vol[2 + i] & ~WM_VOL_MUTE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
|
||||
struct prodigy_hifi_spec *spec = ice->spec;
|
||||
int i, idx, change = 0;
|
||||
|
||||
mutex_lock(&ice->gpio_mutex);
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (ucontrol->value.integer.value[i] !=
|
||||
ice->spec.prodigy_hifi.vol[2+i]) {
|
||||
if (ucontrol->value.integer.value[i] != spec->vol[2 + i]) {
|
||||
idx = WM_DAC_ATTEN_L + i;
|
||||
ice->spec.prodigy_hifi.vol[2+i] &= WM_VOL_MUTE;
|
||||
ice->spec.prodigy_hifi.vol[2+i] |=
|
||||
ucontrol->value.integer.value[i];
|
||||
wm_set_vol(ice, idx, ice->spec.prodigy_hifi.vol[2+i],
|
||||
ice->spec.prodigy_hifi.master[i]);
|
||||
spec->vol[2 + i] &= WM_VOL_MUTE;
|
||||
spec->vol[2 + i] |= ucontrol->value.integer.value[i];
|
||||
wm_set_vol(ice, idx, spec->vol[2 + i], spec->master[i]);
|
||||
change = 1;
|
||||
}
|
||||
}
|
||||
|
@ -417,7 +427,8 @@ static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
|
|||
/*
|
||||
* WM8766 DAC volume attenuation mixer control
|
||||
*/
|
||||
static int wm8766_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
|
||||
static int wm8766_vol_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
int voices = kcontrol->private_value >> 8;
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
|
||||
|
@ -427,22 +438,24 @@ static int wm8766_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_in
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int wm8766_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
static int wm8766_vol_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
|
||||
struct prodigy_hifi_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.prodigy_hifi.vol[ofs+i];
|
||||
ucontrol->value.integer.value[i] = spec->vol[ofs + i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wm8766_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
|
||||
struct prodigy_hifi_spec *spec = ice->spec;
|
||||
int i, idx, ofs, voices;
|
||||
int change = 0;
|
||||
|
||||
|
@ -450,15 +463,12 @@ static int wm8766_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
|
|||
ofs = kcontrol->private_value & 0xff;
|
||||
mutex_lock(&ice->gpio_mutex);
|
||||
for (i = 0; i < voices; i++) {
|
||||
if (ucontrol->value.integer.value[i] !=
|
||||
ice->spec.prodigy_hifi.vol[ofs+i]) {
|
||||
if (ucontrol->value.integer.value[i] != spec->vol[ofs + i]) {
|
||||
idx = WM8766_LDA1 + ofs + i;
|
||||
ice->spec.prodigy_hifi.vol[ofs+i] &= WM_VOL_MUTE;
|
||||
ice->spec.prodigy_hifi.vol[ofs+i] |=
|
||||
ucontrol->value.integer.value[i];
|
||||
spec->vol[ofs + i] &= WM_VOL_MUTE;
|
||||
spec->vol[ofs + i] |= ucontrol->value.integer.value[i];
|
||||
wm8766_set_vol(ice, idx,
|
||||
ice->spec.prodigy_hifi.vol[ofs+i],
|
||||
ice->spec.prodigy_hifi.master[i]);
|
||||
spec->vol[ofs + i], spec->master[i]);
|
||||
change = 1;
|
||||
}
|
||||
}
|
||||
|
@ -469,7 +479,8 @@ static int wm8766_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
|
|||
/*
|
||||
* Master volume attenuation mixer control / applied to WM8776+WM8766
|
||||
*/
|
||||
static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
|
||||
static int wm_master_vol_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
|
||||
uinfo->count = 2;
|
||||
|
@ -478,45 +489,41 @@ static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
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 prodigy_hifi_spec *spec = ice->spec;
|
||||
int i;
|
||||
for (i = 0; i < 2; i++)
|
||||
ucontrol->value.integer.value[i] =
|
||||
ice->spec.prodigy_hifi.master[i];
|
||||
ucontrol->value.integer.value[i] = spec->master[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
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 prodigy_hifi_spec *spec = ice->spec;
|
||||
int ch, change = 0;
|
||||
|
||||
mutex_lock(&ice->gpio_mutex);
|
||||
for (ch = 0; ch < 2; ch++) {
|
||||
if (ucontrol->value.integer.value[ch] !=
|
||||
ice->spec.prodigy_hifi.master[ch]) {
|
||||
ice->spec.prodigy_hifi.master[ch] &= 0x00;
|
||||
ice->spec.prodigy_hifi.master[ch] |=
|
||||
ucontrol->value.integer.value[ch];
|
||||
if (ucontrol->value.integer.value[ch] != spec->master[ch]) {
|
||||
spec->master[ch] = ucontrol->value.integer.value[ch];
|
||||
|
||||
/* Apply to front DAC */
|
||||
wm_set_vol(ice, WM_DAC_ATTEN_L + ch,
|
||||
ice->spec.prodigy_hifi.vol[2 + ch],
|
||||
ice->spec.prodigy_hifi.master[ch]);
|
||||
spec->vol[2 + ch], spec->master[ch]);
|
||||
|
||||
wm8766_set_vol(ice, WM8766_LDA1 + ch,
|
||||
ice->spec.prodigy_hifi.vol[0 + ch],
|
||||
ice->spec.prodigy_hifi.master[ch]);
|
||||
spec->vol[0 + ch], spec->master[ch]);
|
||||
|
||||
wm8766_set_vol(ice, WM8766_LDA2 + ch,
|
||||
ice->spec.prodigy_hifi.vol[4 + ch],
|
||||
ice->spec.prodigy_hifi.master[ch]);
|
||||
spec->vol[4 + ch], spec->master[ch]);
|
||||
|
||||
wm8766_set_vol(ice, WM8766_LDA3 + ch,
|
||||
ice->spec.prodigy_hifi.vol[6 + ch],
|
||||
ice->spec.prodigy_hifi.master[ch]);
|
||||
spec->vol[6 + ch], spec->master[ch]);
|
||||
change = 1;
|
||||
}
|
||||
}
|
||||
|
@ -525,12 +532,13 @@ static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
|
|||
}
|
||||
|
||||
|
||||
|
||||
/* KONSTI */
|
||||
|
||||
static int wm_adc_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
|
||||
static int wm_adc_mux_enum_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
static char* texts[32] = {"NULL", WM_AIN1, WM_AIN2, WM_AIN1 "+" WM_AIN2,
|
||||
static char* texts[32] = {
|
||||
"NULL", WM_AIN1, WM_AIN2, WM_AIN1 "+" WM_AIN2,
|
||||
WM_AIN3, WM_AIN1 "+" WM_AIN3, WM_AIN2 "+" WM_AIN3,
|
||||
WM_AIN1 "+" WM_AIN2 "+" WM_AIN3,
|
||||
WM_AIN4, WM_AIN1 "+" WM_AIN4, WM_AIN2 "+" WM_AIN4,
|
||||
|
@ -549,18 +557,21 @@ static int wm_adc_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_el
|
|||
WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
|
||||
WM_AIN1 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
|
||||
WM_AIN2 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
|
||||
WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5};
|
||||
WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5
|
||||
};
|
||||
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
|
||||
uinfo->count = 1;
|
||||
uinfo->value.enumerated.items = 32;
|
||||
if (uinfo->value.enumerated.item > 31)
|
||||
uinfo->value.enumerated.item = 31;
|
||||
strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
|
||||
strcpy(uinfo->value.enumerated.name,
|
||||
texts[uinfo->value.enumerated.item]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wm_adc_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
static int wm_adc_mux_enum_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
|
||||
|
||||
|
@ -570,19 +581,22 @@ static int wm_adc_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int wm_adc_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
static int wm_adc_mux_enum_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
|
||||
unsigned short oval, nval;
|
||||
int change = 0;
|
||||
|
||||
mutex_lock(&ice->gpio_mutex);
|
||||
oval = wm_get(ice, WM_ADC_MUX);
|
||||
nval = (oval & 0xe0) | ucontrol->value.integer.value[0];
|
||||
if (nval != oval) {
|
||||
wm_put(ice, WM_ADC_MUX, nval);
|
||||
change = 1;
|
||||
}
|
||||
mutex_unlock(&ice->gpio_mutex);
|
||||
return 0;
|
||||
return change;
|
||||
}
|
||||
|
||||
/* KONSTI */
|
||||
|
@ -595,7 +609,8 @@ static int wm_adc_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
|
|||
#define ADC_RES 128
|
||||
#define ADC_MIN (ADC_0dB - ADC_RES)
|
||||
|
||||
static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
|
||||
static int wm_adc_vol_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
|
||||
uinfo->count = 2;
|
||||
|
@ -604,7 +619,8 @@ static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_in
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
static int wm_adc_vol_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
|
||||
unsigned short val;
|
||||
|
@ -620,7 +636,8 @@ static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
static int wm_adc_vol_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
|
||||
unsigned short ovol, nvol;
|
||||
|
@ -644,27 +661,23 @@ static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
|
|||
/*
|
||||
* ADC input mux mixer control
|
||||
*/
|
||||
static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
|
||||
uinfo->count = 1;
|
||||
uinfo->value.integer.min = 0;
|
||||
uinfo->value.integer.max = 1;
|
||||
return 0;
|
||||
}
|
||||
#define wm_adc_mux_info snd_ctl_boolean_mono_info
|
||||
|
||||
static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
static int wm_adc_mux_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
|
||||
int bit = kcontrol->private_value;
|
||||
|
||||
mutex_lock(&ice->gpio_mutex);
|
||||
ucontrol->value.integer.value[0] = (wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0;
|
||||
ucontrol->value.integer.value[0] =
|
||||
(wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0;
|
||||
mutex_unlock(&ice->gpio_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
static int wm_adc_mux_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
|
||||
int bit = kcontrol->private_value;
|
||||
|
@ -688,26 +701,22 @@ static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
|
|||
/*
|
||||
* Analog bypass (In -> Out)
|
||||
*/
|
||||
static int wm_bypass_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
|
||||
uinfo->count = 1;
|
||||
uinfo->value.integer.min = 0;
|
||||
uinfo->value.integer.max = 1;
|
||||
return 0;
|
||||
}
|
||||
#define wm_bypass_info snd_ctl_boolean_mono_info
|
||||
|
||||
static int wm_bypass_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
static int wm_bypass_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
|
||||
|
||||
mutex_lock(&ice->gpio_mutex);
|
||||
ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0;
|
||||
ucontrol->value.integer.value[0] =
|
||||
(wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0;
|
||||
mutex_unlock(&ice->gpio_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wm_bypass_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
static int wm_bypass_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
|
||||
unsigned short val, oval;
|
||||
|
@ -730,16 +739,10 @@ static int wm_bypass_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu
|
|||
/*
|
||||
* Left/Right swap
|
||||
*/
|
||||
static int wm_chswap_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
|
||||
uinfo->count = 1;
|
||||
uinfo->value.integer.min = 0;
|
||||
uinfo->value.integer.max = 1;
|
||||
return 0;
|
||||
}
|
||||
#define wm_chswap_info snd_ctl_boolean_mono_info
|
||||
|
||||
static int wm_chswap_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
static int wm_chswap_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
|
||||
|
||||
|
@ -750,7 +753,8 @@ static int wm_chswap_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int wm_chswap_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
static int wm_chswap_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
|
||||
unsigned short val, oval;
|
||||
|
@ -894,9 +898,10 @@ static struct snd_kcontrol_new prodigy_hifi_controls[] __devinitdata = {
|
|||
/*
|
||||
* WM codec registers
|
||||
*/
|
||||
static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
|
||||
static void wm_proc_regs_write(struct snd_info_entry *entry,
|
||||
struct snd_info_buffer *buffer)
|
||||
{
|
||||
struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data;
|
||||
struct snd_ice1712 *ice = entry->private_data;
|
||||
char line[64];
|
||||
unsigned int reg, val;
|
||||
mutex_lock(&ice->gpio_mutex);
|
||||
|
@ -909,9 +914,10 @@ static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buf
|
|||
mutex_unlock(&ice->gpio_mutex);
|
||||
}
|
||||
|
||||
static void wm_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
|
||||
static void wm_proc_regs_read(struct snd_info_entry *entry,
|
||||
struct snd_info_buffer *buffer)
|
||||
{
|
||||
struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data;
|
||||
struct snd_ice1712 *ice = entry->private_data;
|
||||
int reg, val;
|
||||
|
||||
mutex_lock(&ice->gpio_mutex);
|
||||
|
@ -938,7 +944,8 @@ static int __devinit prodigy_hifi_add_controls(struct snd_ice1712 *ice)
|
|||
int err;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(prodigy_hifi_controls); i++) {
|
||||
err = snd_ctl_add(ice->card, snd_ctl_new1(&prodigy_hifi_controls[i], ice));
|
||||
err = snd_ctl_add(ice->card,
|
||||
snd_ctl_new1(&prodigy_hifi_controls[i], ice));
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
@ -954,7 +961,8 @@ static int __devinit prodigy_hd2_add_controls(struct snd_ice1712 *ice)
|
|||
int err;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(prodigy_hd2_controls); i++) {
|
||||
err = snd_ctl_add(ice->card, snd_ctl_new1(&prodigy_hd2_controls[i], ice));
|
||||
err = snd_ctl_add(ice->card,
|
||||
snd_ctl_new1(&prodigy_hd2_controls[i], ice));
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
@ -1025,7 +1033,7 @@ static int __devinit prodigy_hifi_init(struct snd_ice1712 *ice)
|
|||
WM8766_MUTE2, 0x0000,
|
||||
};
|
||||
|
||||
|
||||
struct prodigy_hifi_spec *spec;
|
||||
unsigned int i;
|
||||
|
||||
ice->vt1720 = 0;
|
||||
|
@ -1033,7 +1041,6 @@ static int __devinit prodigy_hifi_init(struct snd_ice1712 *ice)
|
|||
|
||||
ice->num_total_dacs = 8;
|
||||
ice->num_total_adcs = 1;
|
||||
ice->akm_codecs = 2;
|
||||
|
||||
/* HACK - use this as the SPDIF source.
|
||||
* don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
|
||||
|
@ -1046,6 +1053,11 @@ static int __devinit prodigy_hifi_init(struct snd_ice1712 *ice)
|
|||
return -ENOMEM;
|
||||
ice->akm_codecs = 1;
|
||||
|
||||
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
||||
if (!spec)
|
||||
return -ENOMEM;
|
||||
ice->spec = spec;
|
||||
|
||||
/* initialize WM8776 codec */
|
||||
for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
|
||||
wm_put(ice, wm_inits[i], wm_inits[i+1]);
|
||||
|
@ -1054,7 +1066,6 @@ static int __devinit prodigy_hifi_init(struct snd_ice1712 *ice)
|
|||
wm_put(ice, wm_inits2[i], wm_inits2[i+1]);
|
||||
|
||||
/* initialize WM8766 codec */
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(wm8766_inits); i += 2)
|
||||
wm8766_spi_write(ice, wm8766_inits[i], wm8766_inits[i+1]);
|
||||
|
||||
|
@ -1076,7 +1087,7 @@ static int __devinit prodigy_hd2_init(struct snd_ice1712 *ice)
|
|||
AK4396_RCH_ATT, 0x00,
|
||||
};
|
||||
|
||||
|
||||
struct prodigy_hifi_spec *spec;
|
||||
unsigned int i;
|
||||
|
||||
ice->vt1720 = 0;
|
||||
|
@ -1084,7 +1095,6 @@ static int __devinit prodigy_hd2_init(struct snd_ice1712 *ice)
|
|||
|
||||
ice->num_total_dacs = 1;
|
||||
ice->num_total_adcs = 1;
|
||||
ice->akm_codecs = 1;
|
||||
|
||||
/* HACK - use this as the SPDIF source.
|
||||
* don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
|
||||
|
@ -1097,6 +1107,11 @@ static int __devinit prodigy_hd2_init(struct snd_ice1712 *ice)
|
|||
return -ENOMEM;
|
||||
ice->akm_codecs = 1;
|
||||
|
||||
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
||||
if (!spec)
|
||||
return -ENOMEM;
|
||||
ice->spec = spec;
|
||||
|
||||
/* initialize ak4396 codec */
|
||||
/* reset codec */
|
||||
ak4396_write(ice, AK4396_CTRL1, 0x86);
|
||||
|
|
|
@ -32,6 +32,12 @@
|
|||
#include "envy24ht.h"
|
||||
#include "revo.h"
|
||||
|
||||
/* a non-standard I2C device for revo51 */
|
||||
struct revo51_spec {
|
||||
struct snd_i2c_device *dev;
|
||||
struct snd_pt2258 *pt2258;
|
||||
} revo51;
|
||||
|
||||
static void revo_i2s_mclk_changed(struct snd_ice1712 *ice)
|
||||
{
|
||||
/* assert PRST# to converters; MT05 bit 7 */
|
||||
|
@ -152,8 +158,14 @@ static struct snd_i2c_bit_ops revo51_bit_ops = {
|
|||
static int revo51_i2c_init(struct snd_ice1712 *ice,
|
||||
struct snd_pt2258 *pt)
|
||||
{
|
||||
struct revo51_spec *spec;
|
||||
int err;
|
||||
|
||||
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
||||
if (!spec)
|
||||
return -ENOMEM;
|
||||
ice->spec = spec;
|
||||
|
||||
/* create the I2C bus */
|
||||
err = snd_i2c_bus_create(ice->card, "ICE1724 GPIO6", NULL, &ice->i2c);
|
||||
if (err < 0)
|
||||
|
@ -163,15 +175,14 @@ static int revo51_i2c_init(struct snd_ice1712 *ice,
|
|||
ice->i2c->hw_ops.bit = &revo51_bit_ops;
|
||||
|
||||
/* create the I2C device */
|
||||
err = snd_i2c_device_create(ice->i2c, "PT2258", 0x40,
|
||||
&ice->spec.revo51.dev);
|
||||
err = snd_i2c_device_create(ice->i2c, "PT2258", 0x40, &spec->dev);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
pt->card = ice->card;
|
||||
pt->i2c_bus = ice->i2c;
|
||||
pt->i2c_dev = ice->spec.revo51.dev;
|
||||
ice->spec.revo51.pt2258 = pt;
|
||||
pt->i2c_dev = spec->dev;
|
||||
spec->pt2258 = pt;
|
||||
|
||||
snd_pt2258_reset(pt);
|
||||
|
||||
|
@ -555,6 +566,7 @@ static int __devinit revo_init(struct snd_ice1712 *ice)
|
|||
|
||||
static int __devinit revo_add_controls(struct snd_ice1712 *ice)
|
||||
{
|
||||
struct revo51_spec *spec;
|
||||
int err;
|
||||
|
||||
switch (ice->eeprom.subvendor) {
|
||||
|
@ -567,7 +579,8 @@ static int __devinit revo_add_controls(struct snd_ice1712 *ice)
|
|||
err = snd_ice1712_akm4xxx_build_controls(ice);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = snd_pt2258_build_controls(ice->spec.revo51.pt2258);
|
||||
spec = ice->spec;
|
||||
err = snd_pt2258_build_controls(spec->pt2258);
|
||||
if (err < 0)
|
||||
return err;
|
||||
break;
|
||||
|
|
|
@ -34,6 +34,11 @@
|
|||
#include "envy24ht.h"
|
||||
#include "se.h"
|
||||
|
||||
struct se_spec {
|
||||
struct {
|
||||
unsigned char ch1, ch2;
|
||||
} vol[8];
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
/* ONKYO WAVIO SE-200PCI */
|
||||
|
@ -462,9 +467,10 @@ static int se200pci_cont_volume_get(struct snd_kcontrol *kc,
|
|||
struct snd_ctl_elem_value *uc)
|
||||
{
|
||||
struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
|
||||
struct se_spec *spec = ice->spec;
|
||||
int n = kc->private_value;
|
||||
uc->value.integer.value[0] = ice->spec.se.vol[n].ch1;
|
||||
uc->value.integer.value[1] = ice->spec.se.vol[n].ch2;
|
||||
uc->value.integer.value[0] = spec->vol[n].ch1;
|
||||
uc->value.integer.value[1] = spec->vol[n].ch2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -472,8 +478,9 @@ static int se200pci_cont_boolean_get(struct snd_kcontrol *kc,
|
|||
struct snd_ctl_elem_value *uc)
|
||||
{
|
||||
struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
|
||||
struct se_spec *spec = ice->spec;
|
||||
int n = kc->private_value;
|
||||
uc->value.integer.value[0] = ice->spec.se.vol[n].ch1;
|
||||
uc->value.integer.value[0] = spec->vol[n].ch1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -481,44 +488,46 @@ static int se200pci_cont_enum_get(struct snd_kcontrol *kc,
|
|||
struct snd_ctl_elem_value *uc)
|
||||
{
|
||||
struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
|
||||
struct se_spec *spec = ice->spec;
|
||||
int n = kc->private_value;
|
||||
uc->value.enumerated.item[0] = ice->spec.se.vol[n].ch1;
|
||||
uc->value.enumerated.item[0] = spec->vol[n].ch1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void se200pci_cont_update(struct snd_ice1712 *ice, int n)
|
||||
{
|
||||
struct se_spec *spec = ice->spec;
|
||||
switch (se200pci_cont[n].target) {
|
||||
case WM8766:
|
||||
se200pci_WM8766_set_volume(ice,
|
||||
se200pci_cont[n].ch,
|
||||
ice->spec.se.vol[n].ch1,
|
||||
ice->spec.se.vol[n].ch2);
|
||||
spec->vol[n].ch1,
|
||||
spec->vol[n].ch2);
|
||||
break;
|
||||
|
||||
case WM8776in:
|
||||
se200pci_WM8776_set_input_volume(ice,
|
||||
ice->spec.se.vol[n].ch1,
|
||||
ice->spec.se.vol[n].ch2);
|
||||
spec->vol[n].ch1,
|
||||
spec->vol[n].ch2);
|
||||
break;
|
||||
|
||||
case WM8776out:
|
||||
se200pci_WM8776_set_output_volume(ice,
|
||||
ice->spec.se.vol[n].ch1,
|
||||
ice->spec.se.vol[n].ch2);
|
||||
spec->vol[n].ch1,
|
||||
spec->vol[n].ch2);
|
||||
break;
|
||||
|
||||
case WM8776sel:
|
||||
se200pci_WM8776_set_input_selector(ice,
|
||||
ice->spec.se.vol[n].ch1);
|
||||
spec->vol[n].ch1);
|
||||
break;
|
||||
|
||||
case WM8776agc:
|
||||
se200pci_WM8776_set_agc(ice, ice->spec.se.vol[n].ch1);
|
||||
se200pci_WM8776_set_agc(ice, spec->vol[n].ch1);
|
||||
break;
|
||||
|
||||
case WM8776afl:
|
||||
se200pci_WM8776_set_afl(ice, ice->spec.se.vol[n].ch1);
|
||||
se200pci_WM8776_set_afl(ice, spec->vol[n].ch1);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -530,6 +539,7 @@ static int se200pci_cont_volume_put(struct snd_kcontrol *kc,
|
|||
struct snd_ctl_elem_value *uc)
|
||||
{
|
||||
struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
|
||||
struct se_spec *spec = ice->spec;
|
||||
int n = kc->private_value;
|
||||
unsigned int vol1, vol2;
|
||||
int changed;
|
||||
|
@ -537,12 +547,12 @@ static int se200pci_cont_volume_put(struct snd_kcontrol *kc,
|
|||
changed = 0;
|
||||
vol1 = uc->value.integer.value[0] & 0xff;
|
||||
vol2 = uc->value.integer.value[1] & 0xff;
|
||||
if (ice->spec.se.vol[n].ch1 != vol1) {
|
||||
ice->spec.se.vol[n].ch1 = vol1;
|
||||
if (spec->vol[n].ch1 != vol1) {
|
||||
spec->vol[n].ch1 = vol1;
|
||||
changed = 1;
|
||||
}
|
||||
if (ice->spec.se.vol[n].ch2 != vol2) {
|
||||
ice->spec.se.vol[n].ch2 = vol2;
|
||||
if (spec->vol[n].ch2 != vol2) {
|
||||
spec->vol[n].ch2 = vol2;
|
||||
changed = 1;
|
||||
}
|
||||
if (changed)
|
||||
|
@ -555,12 +565,13 @@ static int se200pci_cont_boolean_put(struct snd_kcontrol *kc,
|
|||
struct snd_ctl_elem_value *uc)
|
||||
{
|
||||
struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
|
||||
struct se_spec *spec = ice->spec;
|
||||
int n = kc->private_value;
|
||||
unsigned int vol1;
|
||||
|
||||
vol1 = !!uc->value.integer.value[0];
|
||||
if (ice->spec.se.vol[n].ch1 != vol1) {
|
||||
ice->spec.se.vol[n].ch1 = vol1;
|
||||
if (spec->vol[n].ch1 != vol1) {
|
||||
spec->vol[n].ch1 = vol1;
|
||||
se200pci_cont_update(ice, n);
|
||||
return 1;
|
||||
}
|
||||
|
@ -571,14 +582,15 @@ static int se200pci_cont_enum_put(struct snd_kcontrol *kc,
|
|||
struct snd_ctl_elem_value *uc)
|
||||
{
|
||||
struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
|
||||
struct se_spec *spec = ice->spec;
|
||||
int n = kc->private_value;
|
||||
unsigned int vol1;
|
||||
|
||||
vol1 = uc->value.enumerated.item[0];
|
||||
if (vol1 >= se200pci_get_enum_count(n))
|
||||
return -EINVAL;
|
||||
if (ice->spec.se.vol[n].ch1 != vol1) {
|
||||
ice->spec.se.vol[n].ch1 = vol1;
|
||||
if (spec->vol[n].ch1 != vol1) {
|
||||
spec->vol[n].ch1 = vol1;
|
||||
se200pci_cont_update(ice, n);
|
||||
return 1;
|
||||
}
|
||||
|
@ -668,6 +680,13 @@ static int __devinit se200pci_add_controls(struct snd_ice1712 *ice)
|
|||
|
||||
static int __devinit se_init(struct snd_ice1712 *ice)
|
||||
{
|
||||
struct se_spec *spec;
|
||||
|
||||
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
||||
if (!spec)
|
||||
return -ENOMEM;
|
||||
ice->spec = spec;
|
||||
|
||||
if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE90PCI) {
|
||||
ice->num_total_dacs = 2;
|
||||
ice->num_total_adcs = 0;
|
||||
|
|
Loading…
Reference in a new issue