-/* 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)
-{