diff options
| -rw-r--r-- | sound/pci/ice1712/aureon.c | 163 | ||||
| -rw-r--r-- | sound/pci/ice1712/ice1712.h | 1 |
2 files changed, 161 insertions, 3 deletions
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c index 7e6608b14abc..336dc489aee1 100644 --- a/sound/pci/ice1712/aureon.c +++ b/sound/pci/ice1712/aureon.c | |||
| @@ -87,7 +87,151 @@ | |||
| 87 | #define CS8415_C_BUFFER 0x20 | 87 | #define CS8415_C_BUFFER 0x20 |
| 88 | #define CS8415_ID 0x7F | 88 | #define CS8415_ID 0x7F |
| 89 | 89 | ||
| 90 | static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg, unsigned short val) { | 90 | /* PCA9554 registers */ |
| 91 | #define PCA9554_DEV 0x40 /* I2C device address */ | ||
| 92 | #define PCA9554_IN 0x00 /* input port */ | ||
| 93 | #define PCA9554_OUT 0x01 /* output port */ | ||
| 94 | #define PCA9554_INVERT 0x02 /* input invert */ | ||
| 95 | #define PCA9554_DIR 0x03 /* port directions */ | ||
| 96 | |||
| 97 | /* | ||
| 98 | * Aureon Universe additional controls using PCA9554 | ||
| 99 | */ | ||
| 100 | |||
| 101 | /* | ||
| 102 | * Send data to pca9554 | ||
| 103 | */ | ||
| 104 | static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg, | ||
| 105 | unsigned char data) | ||
| 106 | { | ||
| 107 | unsigned int tmp; | ||
| 108 | int i, j; | ||
| 109 | unsigned char dev = PCA9554_DEV; /* ID 0100000, write */ | ||
| 110 | unsigned char val = 0; | ||
| 111 | |||
| 112 | tmp = snd_ice1712_gpio_read(ice); | ||
| 113 | |||
| 114 | snd_ice1712_gpio_set_mask(ice, ~(AUREON_SPI_MOSI|AUREON_SPI_CLK| | ||
| 115 | AUREON_WM_RW|AUREON_WM_CS| | ||
| 116 | AUREON_CS8415_CS)); | ||
| 117 | tmp |= AUREON_WM_RW; | ||
| 118 | tmp |= AUREON_CS8415_CS | AUREON_WM_CS; /* disable SPI devices */ | ||
| 119 | |||
| 120 | tmp &= ~AUREON_SPI_MOSI; | ||
| 121 | tmp &= ~AUREON_SPI_CLK; | ||
| 122 | snd_ice1712_gpio_write(ice, tmp); | ||
| 123 | udelay(50); | ||
| 124 | |||
| 125 | /* | ||
| 126 | * send i2c stop condition and start condition | ||
| 127 | * to obtain sane state | ||
| 128 | */ | ||
| 129 | tmp |= AUREON_SPI_CLK; | ||
| 130 | snd_ice1712_gpio_write(ice, tmp); | ||
| 131 | udelay(50); | ||
| 132 | tmp |= AUREON_SPI_MOSI; | ||
| 133 | snd_ice1712_gpio_write(ice, tmp); | ||
| 134 | udelay(100); | ||
| 135 | tmp &= ~AUREON_SPI_MOSI; | ||
| 136 | snd_ice1712_gpio_write(ice, tmp); | ||
| 137 | udelay(50); | ||
| 138 | tmp &= ~AUREON_SPI_CLK; | ||
| 139 | snd_ice1712_gpio_write(ice, tmp); | ||
| 140 | udelay(100); | ||
| 141 | /* | ||
| 142 | * send device address, command and value, | ||
| 143 | * skipping ack cycles inbetween | ||
| 144 | */ | ||
| 145 | for (j = 0; j < 3; j++) { | ||
| 146 | switch(j) { | ||
| 147 | case 0: val = dev; break; | ||
| 148 | case 1: val = reg; break; | ||
| 149 | case 2: val = data; break; | ||
| 150 | } | ||
| 151 | for (i = 7; i >= 0; i--) { | ||
| 152 | tmp &= ~AUREON_SPI_CLK; | ||
| 153 | snd_ice1712_gpio_write(ice, tmp); | ||
| 154 | udelay(40); | ||
| 155 | if (val & (1 << i)) | ||
| 156 | tmp |= AUREON_SPI_MOSI; | ||
| 157 | else | ||
| 158 | tmp &= ~AUREON_SPI_MOSI; | ||
| 159 | snd_ice1712_gpio_write(ice, tmp); | ||
| 160 | udelay(40); | ||
| 161 | tmp |= AUREON_SPI_CLK; | ||
| 162 | snd_ice1712_gpio_write(ice, tmp); | ||
| 163 | udelay(40); | ||
| 164 | } | ||
| 165 | tmp &= ~AUREON_SPI_CLK; | ||
| 166 | snd_ice1712_gpio_write(ice, tmp); | ||
| 167 | udelay(40); | ||
| 168 | tmp |= AUREON_SPI_CLK; | ||
| 169 | snd_ice1712_gpio_write(ice, tmp); | ||
| 170 | udelay(40); | ||
| 171 | tmp &= ~AUREON_SPI_CLK; | ||
| 172 | snd_ice1712_gpio_write(ice, tmp); | ||
| 173 | udelay(40); | ||
| 174 | } | ||
| 175 | tmp &= ~AUREON_SPI_CLK; | ||
| 176 | snd_ice1712_gpio_write(ice, tmp); | ||
| 177 | udelay(40); | ||
| 178 | tmp &= ~AUREON_SPI_MOSI; | ||
| 179 | snd_ice1712_gpio_write(ice, tmp); | ||
| 180 | udelay(40); | ||
| 181 | tmp |= AUREON_SPI_CLK; | ||
| 182 | snd_ice1712_gpio_write(ice, tmp); | ||
| 183 | udelay(50); | ||
| 184 | tmp |= AUREON_SPI_MOSI; | ||
| 185 | snd_ice1712_gpio_write(ice, tmp); | ||
| 186 | udelay(100); | ||
| 187 | } | ||
| 188 | |||
| 189 | static int aureon_universe_inmux_info(struct snd_kcontrol *kcontrol, | ||
| 190 | struct snd_ctl_elem_info *uinfo) | ||
| 191 | { | ||
| 192 | char *texts[3] = {"Internal Aux", "Wavetable", "Rear Line-In"}; | ||
| 193 | |||
| 194 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
| 195 | uinfo->count = 1; | ||
| 196 | uinfo->value.enumerated.items = 3; | ||
| 197 | if(uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
| 198 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
| 199 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
| 200 | return 0; | ||
| 201 | } | ||
| 202 | |||
| 203 | static int aureon_universe_inmux_get(struct snd_kcontrol *kcontrol, | ||
| 204 | struct snd_ctl_elem_value *ucontrol) | ||
| 205 | { | ||
| 206 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | ||
| 207 | ucontrol->value.integer.value[0] = ice->spec.aureon.pca9554_out; | ||
| 208 | return 0; | ||
| 209 | } | ||
| 210 | |||
| 211 | static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol, | ||
| 212 | struct snd_ctl_elem_value *ucontrol) | ||
| 213 | { | ||
| 214 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | ||
| 215 | unsigned char oval, nval; | ||
| 216 | int change; | ||
| 217 | |||
| 218 | snd_ice1712_save_gpio_status(ice); | ||
| 219 | |||
| 220 | oval = ice->spec.aureon.pca9554_out; | ||
| 221 | nval = ucontrol->value.integer.value[0]; | ||
| 222 | if ((change = (oval != nval))) { | ||
| 223 | aureon_pca9554_write(ice, PCA9554_OUT, nval); | ||
| 224 | ice->spec.aureon.pca9554_out = nval; | ||
| 225 | } | ||
| 226 | snd_ice1712_restore_gpio_status(ice); | ||
| 227 | |||
| 228 | return change; | ||
| 229 | } | ||
| 230 | |||
| 231 | |||
| 232 | static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg, | ||
| 233 | unsigned short val) | ||
| 234 | { | ||
| 91 | unsigned int tmp; | 235 | unsigned int tmp; |
| 92 | 236 | ||
| 93 | /* Send address to XILINX chip */ | 237 | /* Send address to XILINX chip */ |
| @@ -146,7 +290,8 @@ static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short r | |||
| 146 | /* | 290 | /* |
| 147 | * Initialize STAC9744 chip | 291 | * Initialize STAC9744 chip |
| 148 | */ | 292 | */ |
| 149 | static int aureon_ac97_init (struct snd_ice1712 *ice) { | 293 | static int aureon_ac97_init (struct snd_ice1712 *ice) |
| 294 | { | ||
| 150 | int i; | 295 | int i; |
| 151 | static unsigned short ac97_defaults[] = { | 296 | static unsigned short ac97_defaults[] = { |
| 152 | 0x00, 0x9640, | 297 | 0x00, 0x9640, |
| @@ -1598,7 +1743,15 @@ static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = { | |||
| 1598 | .get = aureon_ac97_vol_get, | 1743 | .get = aureon_ac97_vol_get, |
| 1599 | .put = aureon_ac97_vol_put, | 1744 | .put = aureon_ac97_vol_put, |
| 1600 | .private_value = AC97_VIDEO|AUREON_AC97_STEREO | 1745 | .private_value = AC97_VIDEO|AUREON_AC97_STEREO |
| 1601 | } | 1746 | }, |
| 1747 | { | ||
| 1748 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 1749 | .name = "Aux Source", | ||
| 1750 | .info = aureon_universe_inmux_info, | ||
| 1751 | .get = aureon_universe_inmux_get, | ||
| 1752 | .put = aureon_universe_inmux_put | ||
| 1753 | } | ||
| 1754 | |||
| 1602 | }; | 1755 | }; |
| 1603 | 1756 | ||
| 1604 | 1757 | ||
| @@ -1856,6 +2009,10 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) | |||
| 1856 | } | 2009 | } |
| 1857 | 2010 | ||
| 1858 | snd_ice1712_restore_gpio_status(ice); | 2011 | snd_ice1712_restore_gpio_status(ice); |
| 2012 | |||
| 2013 | /* initialize PCA9554 pin directions & set default input*/ | ||
| 2014 | aureon_pca9554_write(ice, PCA9554_DIR, 0x00); | ||
| 2015 | aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */ | ||
| 1859 | 2016 | ||
| 1860 | ice->spec.aureon.master[0] = WM_VOL_MUTE; | 2017 | ice->spec.aureon.master[0] = WM_VOL_MUTE; |
| 1861 | ice->spec.aureon.master[1] = WM_VOL_MUTE; | 2018 | ice->spec.aureon.master[1] = WM_VOL_MUTE; |
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h index f9b22d4a3932..053f8e56fd68 100644 --- a/sound/pci/ice1712/ice1712.h +++ b/sound/pci/ice1712/ice1712.h | |||
| @@ -373,6 +373,7 @@ struct snd_ice1712 { | |||
| 373 | unsigned int cs8415_mux; | 373 | unsigned int cs8415_mux; |
| 374 | unsigned short master[2]; | 374 | unsigned short master[2]; |
| 375 | unsigned short vol[8]; | 375 | unsigned short vol[8]; |
| 376 | unsigned char pca9554_out; | ||
| 376 | } aureon; | 377 | } aureon; |
| 377 | /* AC97 register cache for Phase28 */ | 378 | /* AC97 register cache for Phase28 */ |
| 378 | struct phase28_spec { | 379 | struct phase28_spec { |
