aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/oxygen/virtuoso.c77
1 files changed, 51 insertions, 26 deletions
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 1627197f1689..95c229acf855 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -79,11 +79,16 @@ MODULE_DEVICE_TABLE(pci, xonar_ids);
79#define GPIO_CS53x1_M_DOUBLE 0x0004 79#define GPIO_CS53x1_M_DOUBLE 0x0004
80#define GPIO_CS53x1_M_QUAD 0x0008 80#define GPIO_CS53x1_M_QUAD 0x0008
81 81
82#define GPIO_EXT_POWER 0x0020 82#define GPIO_D2X_EXT_POWER 0x0020
83#define GPIO_ALT 0x0080 83#define GPIO_D2_ALT 0x0080
84#define GPIO_OUTPUT_ENABLE 0x0100 84#define GPIO_D2_OUTPUT_ENABLE 0x0100
85 85
86struct xonar_data { 86struct xonar_data {
87 unsigned int anti_pop_delay;
88 u16 output_enable_bit;
89 u8 ext_power_reg;
90 u8 ext_power_int_reg;
91 u8 ext_power_bit;
87 u8 has_power; 92 u8 has_power;
88}; 93};
89 94
@@ -102,10 +107,34 @@ static void pcm1796_write(struct oxygen *chip, unsigned int codec,
102 (reg << 8) | value); 107 (reg << 8) | value);
103} 108}
104 109
110static void xonar_common_init(struct oxygen *chip)
111{
112 struct xonar_data *data = chip->model_data;
113
114 if (data->ext_power_reg) {
115 oxygen_set_bits8(chip, data->ext_power_int_reg,
116 data->ext_power_bit);
117 chip->interrupt_mask |= OXYGEN_INT_GPIO;
118 data->has_power = !!(oxygen_read8(chip, data->ext_power_reg)
119 & data->ext_power_bit);
120 }
121 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CS53x1_M_MASK);
122 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
123 GPIO_CS53x1_M_SINGLE, GPIO_CS53x1_M_MASK);
124 oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC);
125 msleep(data->anti_pop_delay);
126 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, data->output_enable_bit);
127 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);
128}
129
105static void xonar_d2_init(struct oxygen *chip) 130static void xonar_d2_init(struct oxygen *chip)
106{ 131{
132 struct xonar_data *data = chip->model_data;
107 unsigned int i; 133 unsigned int i;
108 134
135 data->anti_pop_delay = 300;
136 data->output_enable_bit = GPIO_D2_OUTPUT_ENABLE;
137
109 for (i = 0; i < 4; ++i) { 138 for (i = 0; i < 4; ++i) {
110 pcm1796_write(chip, i, 18, PCM1796_FMT_24_LJUST | PCM1796_ATLD); 139 pcm1796_write(chip, i, 18, PCM1796_FMT_24_LJUST | PCM1796_ATLD);
111 pcm1796_write(chip, i, 19, PCM1796_FLT_SHARP | PCM1796_ATS_1); 140 pcm1796_write(chip, i, 19, PCM1796_FLT_SHARP | PCM1796_ATS_1);
@@ -115,15 +144,10 @@ static void xonar_d2_init(struct oxygen *chip)
115 pcm1796_write(chip, i, 17, 0xff); 144 pcm1796_write(chip, i, 17, 0xff);
116 } 145 }
117 146
118 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 147 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2_ALT);
119 GPIO_CS53x1_M_MASK | GPIO_ALT); 148 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_D2_ALT);
120 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, 149
121 GPIO_CS53x1_M_SINGLE, 150 xonar_common_init(chip);
122 GPIO_CS53x1_M_MASK | GPIO_ALT);
123 oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC);
124 msleep(300);
125 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_OUTPUT_ENABLE);
126 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE);
127 151
128 snd_component_add(chip->card, "PCM1796"); 152 snd_component_add(chip->card, "PCM1796");
129 snd_component_add(chip->card, "CS5381"); 153 snd_component_add(chip->card, "CS5381");
@@ -133,17 +157,18 @@ static void xonar_d2x_init(struct oxygen *chip)
133{ 157{
134 struct xonar_data *data = chip->model_data; 158 struct xonar_data *data = chip->model_data;
135 159
160 data->ext_power_reg = OXYGEN_GPIO_DATA;
161 data->ext_power_int_reg = OXYGEN_GPIO_INTERRUPT_MASK;
162 data->ext_power_bit = GPIO_D2X_EXT_POWER;
163 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2X_EXT_POWER);
136 xonar_d2_init(chip); 164 xonar_d2_init(chip);
137 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_EXT_POWER);
138 oxygen_set_bits16(chip, OXYGEN_GPIO_INTERRUPT_MASK, GPIO_EXT_POWER);
139 chip->interrupt_mask |= OXYGEN_INT_GPIO;
140 data->has_power = !!(oxygen_read16(chip, OXYGEN_GPIO_DATA)
141 & GPIO_EXT_POWER);
142} 165}
143 166
144static void xonar_cleanup(struct oxygen *chip) 167static void xonar_cleanup(struct oxygen *chip)
145{ 168{
146 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE); 169 struct xonar_data *data = chip->model_data;
170
171 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);
147} 172}
148 173
149static void set_pcm1796_params(struct oxygen *chip, 174static void set_pcm1796_params(struct oxygen *chip,
@@ -201,8 +226,8 @@ static void xonar_gpio_changed(struct oxygen *chip)
201 struct xonar_data *data = chip->model_data; 226 struct xonar_data *data = chip->model_data;
202 u8 has_power; 227 u8 has_power;
203 228
204 has_power = !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) 229 has_power = !!(oxygen_read8(chip, data->ext_power_reg)
205 & GPIO_EXT_POWER); 230 & data->ext_power_bit);
206 if (has_power != data->has_power) { 231 if (has_power != data->has_power) {
207 data->has_power = has_power; 232 data->has_power = has_power;
208 if (has_power) { 233 if (has_power) {
@@ -231,7 +256,7 @@ static int alt_switch_get(struct snd_kcontrol *ctl,
231 struct oxygen *chip = ctl->private_data; 256 struct oxygen *chip = ctl->private_data;
232 257
233 value->value.integer.value[0] = 258 value->value.integer.value[0] =
234 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & GPIO_ALT); 259 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & GPIO_D2_ALT);
235 return 0; 260 return 0;
236} 261}
237 262
@@ -245,9 +270,9 @@ static int alt_switch_put(struct snd_kcontrol *ctl,
245 spin_lock_irq(&chip->reg_lock); 270 spin_lock_irq(&chip->reg_lock);
246 old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA); 271 old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA);
247 if (value->value.integer.value[0]) 272 if (value->value.integer.value[0])
248 new_bits = old_bits | GPIO_ALT; 273 new_bits = old_bits | GPIO_D2_ALT;
249 else 274 else
250 new_bits = old_bits & ~GPIO_ALT; 275 new_bits = old_bits & ~GPIO_D2_ALT;
251 changed = new_bits != old_bits; 276 changed = new_bits != old_bits;
252 if (changed) 277 if (changed)
253 oxygen_write16(chip, OXYGEN_GPIO_DATA, new_bits); 278 oxygen_write16(chip, OXYGEN_GPIO_DATA, new_bits);
@@ -265,7 +290,7 @@ static const struct snd_kcontrol_new alt_switch = {
265 290
266static const DECLARE_TLV_DB_SCALE(pcm1796_db_scale, -12000, 50, 0); 291static const DECLARE_TLV_DB_SCALE(pcm1796_db_scale, -12000, 50, 0);
267 292
268static int xonar_control_filter(struct snd_kcontrol_new *template) 293static int xonar_d2_control_filter(struct snd_kcontrol_new *template)
269{ 294{
270 if (!strcmp(template->name, "Master Playback Volume")) { 295 if (!strcmp(template->name, "Master Playback Volume")) {
271 template->access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; 296 template->access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
@@ -290,7 +315,7 @@ static const struct oxygen_model xonar_models[] = {
290 .chip = "AV200", 315 .chip = "AV200",
291 .owner = THIS_MODULE, 316 .owner = THIS_MODULE,
292 .init = xonar_d2_init, 317 .init = xonar_d2_init,
293 .control_filter = xonar_control_filter, 318 .control_filter = xonar_d2_control_filter,
294 .mixer_init = xonar_mixer_init, 319 .mixer_init = xonar_mixer_init,
295 .cleanup = xonar_cleanup, 320 .cleanup = xonar_cleanup,
296 .set_dac_params = set_pcm1796_params, 321 .set_dac_params = set_pcm1796_params,
@@ -315,7 +340,7 @@ static const struct oxygen_model xonar_models[] = {
315 .chip = "AV200", 340 .chip = "AV200",
316 .owner = THIS_MODULE, 341 .owner = THIS_MODULE,
317 .init = xonar_d2x_init, 342 .init = xonar_d2x_init,
318 .control_filter = xonar_control_filter, 343 .control_filter = xonar_d2_control_filter,
319 .mixer_init = xonar_mixer_init, 344 .mixer_init = xonar_mixer_init,
320 .cleanup = xonar_cleanup, 345 .cleanup = xonar_cleanup,
321 .set_dac_params = set_pcm1796_params, 346 .set_dac_params = set_pcm1796_params,