#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/slab.h>
-#include <linux/mutex.h>
-
#include <sound/core.h>
#include "ice1712.h"
#define CS8415_C_BUFFER 0x20
#define CS8415_ID 0x7F
-/* PCA9554 registers */
-#define PCA9554_DEV 0x40 /* I2C device address */
-#define PCA9554_IN 0x00 /* input port */
-#define PCA9554_OUT 0x01 /* output port */
-#define PCA9554_INVERT 0x02 /* input invert */
-#define PCA9554_DIR 0x03 /* port directions */
-
-/*
- * Aureon Universe additional controls using PCA9554
- */
-
-/*
- * Send data to pca9554
- */
-static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg,
- unsigned char data)
-{
- unsigned int tmp;
- int i, j;
- unsigned char dev = PCA9554_DEV; /* ID 0100000, write */
- unsigned char val = 0;
-
- tmp = snd_ice1712_gpio_read(ice);
-
- snd_ice1712_gpio_set_mask(ice, ~(AUREON_SPI_MOSI|AUREON_SPI_CLK|
- AUREON_WM_RW|AUREON_WM_CS|
- AUREON_CS8415_CS));
- tmp |= AUREON_WM_RW;
- tmp |= AUREON_CS8415_CS | AUREON_WM_CS; /* disable SPI devices */
-
- tmp &= ~AUREON_SPI_MOSI;
- tmp &= ~AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(50);
-
- /*
- * send i2c stop condition and start condition
- * to obtain sane state
- */
- tmp |= AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(50);
- tmp |= AUREON_SPI_MOSI;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(100);
- tmp &= ~AUREON_SPI_MOSI;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(50);
- tmp &= ~AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(100);
- /*
- * send device address, command and value,
- * skipping ack cycles inbetween
- */
- for (j = 0; j < 3; j++) {
- switch(j) {
- case 0: val = dev; break;
- case 1: val = reg; break;
- case 2: val = data; break;
- }
- for (i = 7; i >= 0; i--) {
- tmp &= ~AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(40);
- if (val & (1 << i))
- tmp |= AUREON_SPI_MOSI;
- else
- tmp &= ~AUREON_SPI_MOSI;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(40);
- tmp |= AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(40);
- }
- tmp &= ~AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(40);
- tmp |= AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(40);
- tmp &= ~AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(40);
- }
- tmp &= ~AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(40);
- tmp &= ~AUREON_SPI_MOSI;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(40);
- tmp |= AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(50);
- tmp |= AUREON_SPI_MOSI;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(100);
-}
-
-static int aureon_universe_inmux_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- char *texts[3] = {"Internal Aux", "Wavetable", "Rear Line-In"};
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- if(uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-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.integer.value[0] = ice->spec.aureon.pca9554_out;
- return 0;
-}
-
-static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned char oval, nval;
- int change;
-
- snd_ice1712_save_gpio_status(ice);
-
- oval = ice->spec.aureon.pca9554_out;
- nval = ucontrol->value.integer.value[0];
- if ((change = (oval != nval))) {
- aureon_pca9554_write(ice, PCA9554_OUT, nval);
- ice->spec.aureon.pca9554_out = nval;
- }
- snd_ice1712_restore_gpio_status(ice);
-
- return change;
-}
-
-
-static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
- unsigned short val)
-{
+static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg, unsigned short val) {
unsigned int tmp;
/* Send address to XILINX chip */
/*
* Initialize STAC9744 chip
*/
-static int aureon_ac97_init (struct snd_ice1712 *ice)
-{
+static int aureon_ac97_init (struct snd_ice1712 *ice) {
int i;
static unsigned short ac97_defaults[] = {
0x00, 0x9640,
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned short vol;
- mutex_lock(&ice->gpio_mutex);
+ down(&ice->gpio_mutex);
vol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
ucontrol->value.integer.value[0] = 0x1F - (vol & 0x1F);
if (kcontrol->private_value & AUREON_AC97_STEREO)
ucontrol->value.integer.value[1] = 0x1F - ((vol >> 8) & 0x1F);
- mutex_unlock(&ice->gpio_mutex);
+ up(&ice->gpio_mutex);
return 0;
}
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- mutex_lock(&ice->gpio_mutex);
+ down(&ice->gpio_mutex);
ucontrol->value.integer.value[0] = aureon_ac97_read(ice, kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1;
- mutex_unlock(&ice->gpio_mutex);
+ up(&ice->gpio_mutex);
return 0;
}
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- mutex_lock(&ice->gpio_mutex);
+ down(&ice->gpio_mutex);
ucontrol->value.integer.value[0] = aureon_ac97_read(ice, AC97_MIC) & 0x0020 ? 0 : 1;
- mutex_unlock(&ice->gpio_mutex);
+ up(&ice->gpio_mutex);
return 0;
}
{
unsigned int tmp;
int i;
- unsigned int mosi, clk;
tmp = snd_ice1712_gpio_read(ice);
- if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT) {
- snd_ice1712_gpio_set_mask(ice, ~(PRODIGY_SPI_MOSI|PRODIGY_SPI_CLK|PRODIGY_WM_CS));
- mosi = PRODIGY_SPI_MOSI;
- clk = PRODIGY_SPI_CLK;
- }
- else {
- snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK|
- AUREON_WM_CS|AUREON_CS8415_CS));
- mosi = AUREON_SPI_MOSI;
- clk = AUREON_SPI_CLK;
-
- tmp |= AUREON_WM_RW;
- }
-
+ snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK|
+ AUREON_WM_CS|AUREON_CS8415_CS));
+ tmp |= AUREON_WM_RW;
tmp &= ~cs;
snd_ice1712_gpio_write(ice, tmp);
udelay(1);
for (i = bits - 1; i >= 0; i--) {
- tmp &= ~clk;
+ tmp &= ~AUREON_SPI_CLK;
snd_ice1712_gpio_write(ice, tmp);
udelay(1);
if (data & (1 << i))
- tmp |= mosi;
+ tmp |= AUREON_SPI_MOSI;
else
- tmp &= ~mosi;
+ tmp &= ~AUREON_SPI_MOSI;
snd_ice1712_gpio_write(ice, tmp);
udelay(1);
- tmp |= clk;
+ tmp |= AUREON_SPI_CLK;
snd_ice1712_gpio_write(ice, tmp);
udelay(1);
}
- tmp &= ~clk;
+ tmp &= ~AUREON_SPI_CLK;
tmp |= cs;
snd_ice1712_gpio_write(ice, tmp);
udelay(1);
- tmp |= clk;
+ tmp |= AUREON_SPI_CLK;
snd_ice1712_gpio_write(ice, tmp);
udelay(1);
}
*/
static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
{
- aureon_spi_write(ice,
- (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ? PRODIGY_WM_CS : AUREON_WM_CS),
- (reg << 9) | (val & 0x1ff), 16);
+ aureon_spi_write(ice, AUREON_WM_CS, (reg << 9) | (val & 0x1ff), 16);
}
/*
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- mutex_lock(&ice->gpio_mutex);
+ down(&ice->gpio_mutex);
ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX1) >> 1) & 0x01;
- mutex_unlock(&ice->gpio_mutex);
+ up(&ice->gpio_mutex);
return 0;
}
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- mutex_lock(&ice->gpio_mutex);
+ down(&ice->gpio_mutex);
ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1;
- mutex_unlock(&ice->gpio_mutex);
+ up(&ice->gpio_mutex);
return 0;
}
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned short val;
- mutex_lock(&ice->gpio_mutex);
+ down(&ice->gpio_mutex);
val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
val = val > PCM_MIN ? (val - PCM_MIN) : 0;
ucontrol->value.integer.value[0] = val;
- mutex_unlock(&ice->gpio_mutex);
+ up(&ice->gpio_mutex);
return 0;
}
unsigned short val;
int i;
- mutex_lock(&ice->gpio_mutex);
+ down(&ice->gpio_mutex);
for (i = 0; i < 2; i++) {
val = wm_get(ice, WM_ADC_GAIN + i);
ucontrol->value.integer.value[i] = ~val>>5 & 0x1;
}
- mutex_unlock(&ice->gpio_mutex);
+ up(&ice->gpio_mutex);
return 0;
}
int i, idx;
unsigned short vol;
- mutex_lock(&ice->gpio_mutex);
+ down(&ice->gpio_mutex);
for (i = 0; i < 2; i++) {
idx = WM_ADC_GAIN + i;
vol = wm_get(ice, idx) & 0x1f;
ucontrol->value.integer.value[i] = vol;
}
- mutex_unlock(&ice->gpio_mutex);
+ up(&ice->gpio_mutex);
return 0;
}
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned short val;
- mutex_lock(&ice->gpio_mutex);
+ down(&ice->gpio_mutex);
val = wm_get(ice, WM_ADC_MUX);
- ucontrol->value.enumerated.item[0] = val & 7;
- ucontrol->value.enumerated.item[1] = (val >> 4) & 7;
- mutex_unlock(&ice->gpio_mutex);
+ ucontrol->value.integer.value[0] = val & 7;
+ ucontrol->value.integer.value[1] = (val >> 4) & 7;
+ up(&ice->gpio_mutex);
return 0;
}
snd_ice1712_save_gpio_status(ice);
oval = wm_get(ice, WM_ADC_MUX);
nval = oval & ~0x77;
- nval |= ucontrol->value.enumerated.item[0] & 7;
- nval |= (ucontrol->value.enumerated.item[1] & 7) << 4;
+ nval |= ucontrol->value.integer.value[0] & 7;
+ nval |= (ucontrol->value.integer.value[1] & 7) << 4;
change = (oval != nval);
if (change)
wm_put(ice, WM_ADC_MUX, nval);
//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.integer.value[0] = ice->spec.aureon.cs8415_mux;
//snd_ice1712_restore_gpio_status(ice);
return 0;
}
snd_ice1712_save_gpio_status(ice);
oval = aureon_cs8415_get(ice, CS8415_CTRL2);
nval = oval & ~0x07;
- nval |= ucontrol->value.enumerated.item[0] & 7;
+ nval |= ucontrol->value.integer.value[0] & 7;
change = (oval != nval);
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];
+ ice->spec.aureon.cs8415_mux = ucontrol->value.integer.value[0];
return change;
}
tmp2 = tmp = snd_ice1712_gpio_read(ice);
if (enable)
- if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT)
- tmp |= AUREON_HP_SEL;
- else
- tmp |= PRODIGY_HP_SEL;
+ tmp |= AUREON_HP_SEL;
else
- if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT)
- tmp &= ~ AUREON_HP_SEL;
- else
- tmp &= ~ PRODIGY_HP_SEL;
+ tmp &= ~ AUREON_HP_SEL;
if (tmp != tmp2) {
snd_ice1712_gpio_write(ice, tmp);
return 1;
.get = aureon_ac97_vol_get,
.put = aureon_ac97_vol_put,
.private_value = AC97_VIDEO|AUREON_AC97_STEREO
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Aux Source",
- .info = aureon_universe_inmux_info,
- .get = aureon_universe_inmux_get,
- .put = aureon_universe_inmux_put
- }
-
+ }
};
return err;
}
}
- else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) {
+ else {
for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
if (err < 0)
}
}
- if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) {
+ {
unsigned char id;
snd_ice1712_save_gpio_status(ice);
id = aureon_cs8415_get(ice, CS8415_ID);
udelay(1);
/* initialize WM8770 codec */
- if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 ||
- ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT)
+ if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
p = wm_inits_prodigy;
else
p = wm_inits_aureon;
wm_put(ice, p[0], p[1]);
/* initialize CS8415A codec */
- if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) {
- 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;
+ 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;
- aureon_set_headphone_amp(ice, 1);
- }
+ aureon_set_headphone_amp(ice, 1);
snd_ice1712_restore_gpio_status(ice);
-
- /* initialize PCA9554 pin directions & set default input*/
- 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;
0x00, /* GPIO_STATE2 */
};
-static unsigned char prodigy71lt_eeprom[] __devinitdata = {
- 0x4b, /* SYSCINF: clock 512, spdif-in/ADC, 4DACs */
- 0x80, /* ACLINK: I2S */
- 0xfc, /* I2S: vol, 96k, 24bit, 192k */
- 0xc3, /* SPDIF: out-en, out-int, spdif-in */
- 0xff, /* GPIO_DIR */
- 0xff, /* GPIO_DIR1 */
- 0x5f, /* GPIO_DIR2 */
- 0x00, /* GPIO_MASK */
- 0x00, /* GPIO_MASK1 */
- 0x00, /* GPIO_MASK2 */
- 0x00, /* GPIO_STATE */
- 0x00, /* GPIO_STATE1 */
- 0x00, /* GPIO_STATE2 */
-};
-
-
/* entry point */
struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
{
.build_controls = aureon_add_controls,
.eeprom_size = sizeof(aureon71_eeprom),
.eeprom_data = aureon71_eeprom,
- .driver = "Aureon71Univ", /* keep in 15 letters */
+ .driver = "Aureon71Universe",
},
{
.subvendor = VT1724_SUBDEVICE_PRODIGY71,
.eeprom_data = prodigy71_eeprom,
.driver = "Prodigy71", /* should be identical with Aureon71 */
},
- {
- .subvendor = VT1724_SUBDEVICE_PRODIGY71LT,
- .name = "Audiotrak Prodigy 7.1 LT",
- .model = "prodigy71lt",
- .chip_init = aureon_init,
- .build_controls = aureon_add_controls,
- .eeprom_size = sizeof(prodigy71lt_eeprom),
- .eeprom_data = prodigy71lt_eeprom,
- .driver = "Prodigy71LT",
- },
{ } /* terminator */
};