aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/oxygen/virtuoso.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/oxygen/virtuoso.c')
-rw-r--r--sound/pci/oxygen/virtuoso.c252
1 files changed, 145 insertions, 107 deletions
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 7f84fa5deca2..9a2c16bf94e0 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -79,7 +79,7 @@
79 79
80MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 80MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
81MODULE_DESCRIPTION("Asus AVx00 driver"); 81MODULE_DESCRIPTION("Asus AVx00 driver");
82MODULE_LICENSE("GPL"); 82MODULE_LICENSE("GPL v2");
83MODULE_SUPPORTED_DEVICE("{{Asus,AV100},{Asus,AV200}}"); 83MODULE_SUPPORTED_DEVICE("{{Asus,AV100},{Asus,AV200}}");
84 84
85static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 85static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
@@ -132,6 +132,9 @@ struct xonar_data {
132 u8 ext_power_int_reg; 132 u8 ext_power_int_reg;
133 u8 ext_power_bit; 133 u8 ext_power_bit;
134 u8 has_power; 134 u8 has_power;
135 u8 pcm1796_oversampling;
136 u8 cs4398_fm;
137 u8 cs4362a_fm;
135}; 138};
136 139
137static void pcm1796_write(struct oxygen *chip, unsigned int codec, 140static void pcm1796_write(struct oxygen *chip, unsigned int codec,
@@ -159,6 +162,14 @@ static void cs4362a_write(struct oxygen *chip, u8 reg, u8 value)
159 oxygen_write_i2c(chip, I2C_DEVICE_CS4362A, reg, value); 162 oxygen_write_i2c(chip, I2C_DEVICE_CS4362A, reg, value);
160} 163}
161 164
165static void xonar_enable_output(struct oxygen *chip)
166{
167 struct xonar_data *data = chip->model_data;
168
169 msleep(data->anti_pop_delay);
170 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);
171}
172
162static void xonar_common_init(struct oxygen *chip) 173static void xonar_common_init(struct oxygen *chip)
163{ 174{
164 struct xonar_data *data = chip->model_data; 175 struct xonar_data *data = chip->model_data;
@@ -170,32 +181,59 @@ static void xonar_common_init(struct oxygen *chip)
170 data->has_power = !!(oxygen_read8(chip, data->ext_power_reg) 181 data->has_power = !!(oxygen_read8(chip, data->ext_power_reg)
171 & data->ext_power_bit); 182 & data->ext_power_bit);
172 } 183 }
173 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CS53x1_M_MASK); 184 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
185 GPIO_CS53x1_M_MASK | data->output_enable_bit);
174 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, 186 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
175 GPIO_CS53x1_M_SINGLE, GPIO_CS53x1_M_MASK); 187 GPIO_CS53x1_M_SINGLE, GPIO_CS53x1_M_MASK);
176 oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC); 188 oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC);
177 msleep(data->anti_pop_delay); 189 xonar_enable_output(chip);
178 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, data->output_enable_bit);
179 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);
180} 190}
181 191
182static void xonar_d2_init(struct oxygen *chip) 192static void update_pcm1796_volume(struct oxygen *chip)
183{ 193{
184 struct xonar_data *data = chip->model_data;
185 unsigned int i; 194 unsigned int i;
186 195
187 data->anti_pop_delay = 300; 196 for (i = 0; i < 4; ++i) {
188 data->output_enable_bit = GPIO_D2_OUTPUT_ENABLE; 197 pcm1796_write(chip, i, 16, chip->dac_volume[i * 2]);
198 pcm1796_write(chip, i, 17, chip->dac_volume[i * 2 + 1]);
199 }
200}
201
202static void update_pcm1796_mute(struct oxygen *chip)
203{
204 unsigned int i;
205 u8 value;
206
207 value = PCM1796_DMF_DISABLED | PCM1796_FMT_24_LJUST | PCM1796_ATLD;
208 if (chip->dac_mute)
209 value |= PCM1796_MUTE;
210 for (i = 0; i < 4; ++i)
211 pcm1796_write(chip, i, 18, value);
212}
213
214static void pcm1796_init(struct oxygen *chip)
215{
216 struct xonar_data *data = chip->model_data;
217 unsigned int i;
189 218
190 for (i = 0; i < 4; ++i) { 219 for (i = 0; i < 4; ++i) {
191 pcm1796_write(chip, i, 18, PCM1796_MUTE | PCM1796_DMF_DISABLED |
192 PCM1796_FMT_24_LJUST | PCM1796_ATLD);
193 pcm1796_write(chip, i, 19, PCM1796_FLT_SHARP | PCM1796_ATS_1); 220 pcm1796_write(chip, i, 19, PCM1796_FLT_SHARP | PCM1796_ATS_1);
194 pcm1796_write(chip, i, 20, PCM1796_OS_64); 221 pcm1796_write(chip, i, 20, data->pcm1796_oversampling);
195 pcm1796_write(chip, i, 21, 0); 222 pcm1796_write(chip, i, 21, 0);
196 pcm1796_write(chip, i, 16, 0x0f); /* set ATL/ATR after ATLD */
197 pcm1796_write(chip, i, 17, 0x0f);
198 } 223 }
224 update_pcm1796_mute(chip); /* set ATLD before ATL/ATR */
225 update_pcm1796_volume(chip);
226}
227
228static void xonar_d2_init(struct oxygen *chip)
229{
230 struct xonar_data *data = chip->model_data;
231
232 data->anti_pop_delay = 300;
233 data->output_enable_bit = GPIO_D2_OUTPUT_ENABLE;
234 data->pcm1796_oversampling = PCM1796_OS_64;
235
236 pcm1796_init(chip);
199 237
200 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2_ALT); 238 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2_ALT);
201 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_D2_ALT); 239 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_D2_ALT);
@@ -217,31 +255,47 @@ static void xonar_d2x_init(struct oxygen *chip)
217 xonar_d2_init(chip); 255 xonar_d2_init(chip);
218} 256}
219 257
220static void xonar_dx_init(struct oxygen *chip) 258static void update_cs4362a_volumes(struct oxygen *chip)
221{ 259{
222 struct xonar_data *data = chip->model_data; 260 u8 mute;
223 261
224 data->anti_pop_delay = 800; 262 mute = chip->dac_mute ? CS4362A_MUTE : 0;
225 data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE; 263 cs4362a_write(chip, 7, (127 - chip->dac_volume[2]) | mute);
226 data->ext_power_reg = OXYGEN_GPI_DATA; 264 cs4362a_write(chip, 8, (127 - chip->dac_volume[3]) | mute);
227 data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; 265 cs4362a_write(chip, 10, (127 - chip->dac_volume[4]) | mute);
228 data->ext_power_bit = GPI_DX_EXT_POWER; 266 cs4362a_write(chip, 11, (127 - chip->dac_volume[5]) | mute);
267 cs4362a_write(chip, 13, (127 - chip->dac_volume[6]) | mute);
268 cs4362a_write(chip, 14, (127 - chip->dac_volume[7]) | mute);
269}
229 270
230 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, 271static void update_cs43xx_volume(struct oxygen *chip)
231 OXYGEN_2WIRE_LENGTH_8 | 272{
232 OXYGEN_2WIRE_INTERRUPT_MASK | 273 cs4398_write(chip, 5, (127 - chip->dac_volume[0]) * 2);
233 OXYGEN_2WIRE_SPEED_FAST); 274 cs4398_write(chip, 6, (127 - chip->dac_volume[1]) * 2);
275 update_cs4362a_volumes(chip);
276}
277
278static void update_cs43xx_mute(struct oxygen *chip)
279{
280 u8 reg;
281
282 reg = CS4398_MUTEP_LOW | CS4398_PAMUTE;
283 if (chip->dac_mute)
284 reg |= CS4398_MUTE_B | CS4398_MUTE_A;
285 cs4398_write(chip, 4, reg);
286 update_cs4362a_volumes(chip);
287}
288
289static void cs43xx_init(struct oxygen *chip)
290{
291 struct xonar_data *data = chip->model_data;
234 292
235 /* set CPEN (control port mode) and power down */ 293 /* set CPEN (control port mode) and power down */
236 cs4398_write(chip, 8, CS4398_CPEN | CS4398_PDN); 294 cs4398_write(chip, 8, CS4398_CPEN | CS4398_PDN);
237 cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN); 295 cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN);
238 /* configure */ 296 /* configure */
239 cs4398_write(chip, 2, CS4398_FM_SINGLE | 297 cs4398_write(chip, 2, data->cs4398_fm);
240 CS4398_DEM_NONE | CS4398_DIF_LJUST);
241 cs4398_write(chip, 3, CS4398_ATAPI_B_R | CS4398_ATAPI_A_L); 298 cs4398_write(chip, 3, CS4398_ATAPI_B_R | CS4398_ATAPI_A_L);
242 cs4398_write(chip, 4, CS4398_MUTEP_LOW | CS4398_PAMUTE);
243 cs4398_write(chip, 5, 0xfe);
244 cs4398_write(chip, 6, 0xfe);
245 cs4398_write(chip, 7, CS4398_RMP_DN | CS4398_RMP_UP | 299 cs4398_write(chip, 7, CS4398_RMP_DN | CS4398_RMP_UP |
246 CS4398_ZERO_CROSS | CS4398_SOFT_RAMP); 300 CS4398_ZERO_CROSS | CS4398_SOFT_RAMP);
247 cs4362a_write(chip, 0x02, CS4362A_DIF_LJUST); 301 cs4362a_write(chip, 0x02, CS4362A_DIF_LJUST);
@@ -249,21 +303,35 @@ static void xonar_dx_init(struct oxygen *chip)
249 CS4362A_RMP_UP | CS4362A_ZERO_CROSS | CS4362A_SOFT_RAMP); 303 CS4362A_RMP_UP | CS4362A_ZERO_CROSS | CS4362A_SOFT_RAMP);
250 cs4362a_write(chip, 0x04, CS4362A_RMP_DN | CS4362A_DEM_NONE); 304 cs4362a_write(chip, 0x04, CS4362A_RMP_DN | CS4362A_DEM_NONE);
251 cs4362a_write(chip, 0x05, 0); 305 cs4362a_write(chip, 0x05, 0);
252 cs4362a_write(chip, 0x06, CS4362A_FM_SINGLE | 306 cs4362a_write(chip, 0x06, data->cs4362a_fm);
253 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L); 307 cs4362a_write(chip, 0x09, data->cs4362a_fm);
254 cs4362a_write(chip, 0x07, 0x7f | CS4362A_MUTE); 308 cs4362a_write(chip, 0x0c, data->cs4362a_fm);
255 cs4362a_write(chip, 0x08, 0x7f | CS4362A_MUTE); 309 update_cs43xx_volume(chip);
256 cs4362a_write(chip, 0x09, CS4362A_FM_SINGLE | 310 update_cs43xx_mute(chip);
257 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L);
258 cs4362a_write(chip, 0x0a, 0x7f | CS4362A_MUTE);
259 cs4362a_write(chip, 0x0b, 0x7f | CS4362A_MUTE);
260 cs4362a_write(chip, 0x0c, CS4362A_FM_SINGLE |
261 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L);
262 cs4362a_write(chip, 0x0d, 0x7f | CS4362A_MUTE);
263 cs4362a_write(chip, 0x0e, 0x7f | CS4362A_MUTE);
264 /* clear power down */ 311 /* clear power down */
265 cs4398_write(chip, 8, CS4398_CPEN); 312 cs4398_write(chip, 8, CS4398_CPEN);
266 cs4362a_write(chip, 0x01, CS4362A_CPEN); 313 cs4362a_write(chip, 0x01, CS4362A_CPEN);
314}
315
316static void xonar_dx_init(struct oxygen *chip)
317{
318 struct xonar_data *data = chip->model_data;
319
320 data->anti_pop_delay = 800;
321 data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE;
322 data->ext_power_reg = OXYGEN_GPI_DATA;
323 data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
324 data->ext_power_bit = GPI_DX_EXT_POWER;
325 data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST;
326 data->cs4362a_fm = CS4362A_FM_SINGLE |
327 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
328
329 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
330 OXYGEN_2WIRE_LENGTH_8 |
331 OXYGEN_2WIRE_INTERRUPT_MASK |
332 OXYGEN_2WIRE_SPEED_FAST);
333
334 cs43xx_init(chip);
267 335
268 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 336 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
269 GPIO_DX_FRONT_PANEL | GPIO_DX_INPUT_ROUTE); 337 GPIO_DX_FRONT_PANEL | GPIO_DX_INPUT_ROUTE);
@@ -291,37 +359,28 @@ static void xonar_dx_cleanup(struct oxygen *chip)
291 oxygen_clear_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC); 359 oxygen_clear_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC);
292} 360}
293 361
294static void set_pcm1796_params(struct oxygen *chip, 362static void xonar_d2_resume(struct oxygen *chip)
295 struct snd_pcm_hw_params *params)
296{ 363{
297 unsigned int i; 364 pcm1796_init(chip);
298 u8 value; 365 xonar_enable_output(chip);
299
300 value = params_rate(params) >= 96000 ? PCM1796_OS_32 : PCM1796_OS_64;
301 for (i = 0; i < 4; ++i)
302 pcm1796_write(chip, i, 20, value);
303} 366}
304 367
305static void update_pcm1796_volume(struct oxygen *chip) 368static void xonar_dx_resume(struct oxygen *chip)
306{ 369{
307 unsigned int i; 370 cs43xx_init(chip);
308 371 xonar_enable_output(chip);
309 for (i = 0; i < 4; ++i) {
310 pcm1796_write(chip, i, 16, chip->dac_volume[i * 2]);
311 pcm1796_write(chip, i, 17, chip->dac_volume[i * 2 + 1]);
312 }
313} 372}
314 373
315static void update_pcm1796_mute(struct oxygen *chip) 374static void set_pcm1796_params(struct oxygen *chip,
375 struct snd_pcm_hw_params *params)
316{ 376{
377 struct xonar_data *data = chip->model_data;
317 unsigned int i; 378 unsigned int i;
318 u8 value;
319 379
320 value = PCM1796_FMT_24_LJUST | PCM1796_ATLD; 380 data->pcm1796_oversampling =
321 if (chip->dac_mute) 381 params_rate(params) >= 96000 ? PCM1796_OS_32 : PCM1796_OS_64;
322 value |= PCM1796_MUTE;
323 for (i = 0; i < 4; ++i) 382 for (i = 0; i < 4; ++i)
324 pcm1796_write(chip, i, 18, value); 383 pcm1796_write(chip, i, 20, data->pcm1796_oversampling);
325} 384}
326 385
327static void set_cs53x1_params(struct oxygen *chip, 386static void set_cs53x1_params(struct oxygen *chip,
@@ -342,55 +401,24 @@ static void set_cs53x1_params(struct oxygen *chip,
342static void set_cs43xx_params(struct oxygen *chip, 401static void set_cs43xx_params(struct oxygen *chip,
343 struct snd_pcm_hw_params *params) 402 struct snd_pcm_hw_params *params)
344{ 403{
345 u8 fm_cs4398, fm_cs4362a; 404 struct xonar_data *data = chip->model_data;
346 405
347 fm_cs4398 = CS4398_DEM_NONE | CS4398_DIF_LJUST; 406 data->cs4398_fm = CS4398_DEM_NONE | CS4398_DIF_LJUST;
348 fm_cs4362a = CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L; 407 data->cs4362a_fm = CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
349 if (params_rate(params) <= 50000) { 408 if (params_rate(params) <= 50000) {
350 fm_cs4398 |= CS4398_FM_SINGLE; 409 data->cs4398_fm |= CS4398_FM_SINGLE;
351 fm_cs4362a |= CS4362A_FM_SINGLE; 410 data->cs4362a_fm |= CS4362A_FM_SINGLE;
352 } else if (params_rate(params) <= 100000) { 411 } else if (params_rate(params) <= 100000) {
353 fm_cs4398 |= CS4398_FM_DOUBLE; 412 data->cs4398_fm |= CS4398_FM_DOUBLE;
354 fm_cs4362a |= CS4362A_FM_DOUBLE; 413 data->cs4362a_fm |= CS4362A_FM_DOUBLE;
355 } else { 414 } else {
356 fm_cs4398 |= CS4398_FM_QUAD; 415 data->cs4398_fm |= CS4398_FM_QUAD;
357 fm_cs4362a |= CS4362A_FM_QUAD; 416 data->cs4362a_fm |= CS4362A_FM_QUAD;
358 } 417 }
359 cs4398_write(chip, 2, fm_cs4398); 418 cs4398_write(chip, 2, data->cs4398_fm);
360 cs4362a_write(chip, 0x06, fm_cs4362a); 419 cs4362a_write(chip, 0x06, data->cs4362a_fm);
361 cs4362a_write(chip, 0x09, fm_cs4362a); 420 cs4362a_write(chip, 0x09, data->cs4362a_fm);
362 cs4362a_write(chip, 0x0c, fm_cs4362a); 421 cs4362a_write(chip, 0x0c, data->cs4362a_fm);
363}
364
365static void update_cs4362a_volumes(struct oxygen *chip)
366{
367 u8 mute;
368
369 mute = chip->dac_mute ? CS4362A_MUTE : 0;
370 cs4362a_write(chip, 7, (127 - chip->dac_volume[2]) | mute);
371 cs4362a_write(chip, 8, (127 - chip->dac_volume[3]) | mute);
372 cs4362a_write(chip, 10, (127 - chip->dac_volume[4]) | mute);
373 cs4362a_write(chip, 11, (127 - chip->dac_volume[5]) | mute);
374 cs4362a_write(chip, 13, (127 - chip->dac_volume[6]) | mute);
375 cs4362a_write(chip, 14, (127 - chip->dac_volume[7]) | mute);
376}
377
378static void update_cs43xx_volume(struct oxygen *chip)
379{
380 cs4398_write(chip, 5, (127 - chip->dac_volume[0]) * 2);
381 cs4398_write(chip, 6, (127 - chip->dac_volume[1]) * 2);
382 update_cs4362a_volumes(chip);
383}
384
385static void update_cs43xx_mute(struct oxygen *chip)
386{
387 u8 reg;
388
389 reg = CS4398_MUTEP_LOW | CS4398_PAMUTE;
390 if (chip->dac_mute)
391 reg |= CS4398_MUTE_B | CS4398_MUTE_A;
392 cs4398_write(chip, 4, reg);
393 update_cs4362a_volumes(chip);
394} 422}
395 423
396static void xonar_gpio_changed(struct oxygen *chip) 424static void xonar_gpio_changed(struct oxygen *chip)
@@ -535,6 +563,8 @@ static const struct oxygen_model xonar_models[] = {
535 .control_filter = xonar_d2_control_filter, 563 .control_filter = xonar_d2_control_filter,
536 .mixer_init = xonar_mixer_init, 564 .mixer_init = xonar_mixer_init,
537 .cleanup = xonar_cleanup, 565 .cleanup = xonar_cleanup,
566 .suspend = xonar_cleanup,
567 .resume = xonar_d2_resume,
538 .set_dac_params = set_pcm1796_params, 568 .set_dac_params = set_pcm1796_params,
539 .set_adc_params = set_cs53x1_params, 569 .set_adc_params = set_cs53x1_params,
540 .update_dac_volume = update_pcm1796_volume, 570 .update_dac_volume = update_pcm1796_volume,
@@ -563,6 +593,8 @@ static const struct oxygen_model xonar_models[] = {
563 .control_filter = xonar_d2_control_filter, 593 .control_filter = xonar_d2_control_filter,
564 .mixer_init = xonar_mixer_init, 594 .mixer_init = xonar_mixer_init,
565 .cleanup = xonar_cleanup, 595 .cleanup = xonar_cleanup,
596 .suspend = xonar_cleanup,
597 .resume = xonar_d2_resume,
566 .set_dac_params = set_pcm1796_params, 598 .set_dac_params = set_pcm1796_params,
567 .set_adc_params = set_cs53x1_params, 599 .set_adc_params = set_cs53x1_params,
568 .update_dac_volume = update_pcm1796_volume, 600 .update_dac_volume = update_pcm1796_volume,
@@ -592,6 +624,8 @@ static const struct oxygen_model xonar_models[] = {
592 .control_filter = xonar_dx_control_filter, 624 .control_filter = xonar_dx_control_filter,
593 .mixer_init = xonar_dx_mixer_init, 625 .mixer_init = xonar_dx_mixer_init,
594 .cleanup = xonar_dx_cleanup, 626 .cleanup = xonar_dx_cleanup,
627 .suspend = xonar_dx_cleanup,
628 .resume = xonar_dx_resume,
595 .set_dac_params = set_cs43xx_params, 629 .set_dac_params = set_cs43xx_params,
596 .set_adc_params = set_cs53x1_params, 630 .set_adc_params = set_cs53x1_params,
597 .update_dac_volume = update_cs43xx_volume, 631 .update_dac_volume = update_cs43xx_volume,
@@ -636,6 +670,10 @@ static struct pci_driver xonar_driver = {
636 .id_table = xonar_ids, 670 .id_table = xonar_ids,
637 .probe = xonar_probe, 671 .probe = xonar_probe,
638 .remove = __devexit_p(oxygen_pci_remove), 672 .remove = __devexit_p(oxygen_pci_remove),
673#ifdef CONFIG_PM
674 .suspend = oxygen_pci_suspend,
675 .resume = oxygen_pci_resume,
676#endif
639}; 677};
640 678
641static int __init alsa_card_xonar_init(void) 679static int __init alsa_card_xonar_init(void)