diff options
| author | Takashi Iwai <tiwai@suse.de> | 2006-11-09 10:47:26 -0500 |
|---|---|---|
| committer | Jaroslav Kysela <perex@suse.cz> | 2007-02-09 03:01:23 -0500 |
| commit | 56255060ea51984e728223d8056b3faaba0dadf6 (patch) | |
| tree | e5a68da414caec33bc6e0e4a950c97b5e331f403 | |
| parent | bd903b6ed7fb107e122682db5ac8aaa323ab84c9 (diff) | |
[ALSA] ice1724 - Add support of M-Audio Audiophile 192
Added the (experimental) support of M-Audio Audiophile 192 board.
Currently, the analog and the digital playbacks seem working fine.
The inputs seem not working as far as I've tested yet.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
| -rw-r--r-- | Documentation/sound/alsa/ALSA-Configuration.txt | 3 | ||||
| -rw-r--r-- | sound/pci/ice1712/revo.c | 204 | ||||
| -rw-r--r-- | sound/pci/ice1712/revo.h | 5 |
3 files changed, 210 insertions, 2 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 8a254e2fe315..3f5f6900bbf9 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt | |||
| @@ -982,6 +982,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
| 982 | Module for Envy24HT (VT/ICE1724), Envy24PT (VT1720) based PCI sound cards. | 982 | Module for Envy24HT (VT/ICE1724), Envy24PT (VT1720) based PCI sound cards. |
| 983 | * MidiMan M Audio Revolution 5.1 | 983 | * MidiMan M Audio Revolution 5.1 |
| 984 | * MidiMan M Audio Revolution 7.1 | 984 | * MidiMan M Audio Revolution 7.1 |
| 985 | * MidiMan M Audio Audiophile 192 | ||
| 985 | * AMP Ltd AUDIO2000 | 986 | * AMP Ltd AUDIO2000 |
| 986 | * TerraTec Aureon 5.1 Sky | 987 | * TerraTec Aureon 5.1 Sky |
| 987 | * TerraTec Aureon 7.1 Space | 988 | * TerraTec Aureon 7.1 Space |
| @@ -1001,7 +1002,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
| 1001 | 1002 | ||
| 1002 | model - Use the given board model, one of the following: | 1003 | model - Use the given board model, one of the following: |
| 1003 | revo51, revo71, amp2000, prodigy71, prodigy71lt, | 1004 | revo51, revo71, amp2000, prodigy71, prodigy71lt, |
| 1004 | prodigy192, aureon51, aureon71, universe, | 1005 | prodigy192, aureon51, aureon71, universe, ap192, |
| 1005 | k8x800, phase22, phase28, ms300, av710 | 1006 | k8x800, phase22, phase28, ms300, av710 |
| 1006 | 1007 | ||
| 1007 | This module supports multiple cards and autoprobe. | 1008 | This module supports multiple cards and autoprobe. |
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index 233e9a5a2e70..0e578aa38af2 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c | |||
| @@ -303,6 +303,181 @@ static struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = { | |||
| 303 | 303 | ||
| 304 | static struct snd_pt2258 ptc_revo51_volume; | 304 | static struct snd_pt2258 ptc_revo51_volume; |
| 305 | 305 | ||
| 306 | /* AK4358 for AP192 DAC, AK5385A for ADC */ | ||
| 307 | static void ap192_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) | ||
| 308 | { | ||
| 309 | struct snd_ice1712 *ice = ak->private_data[0]; | ||
| 310 | |||
| 311 | revo_set_rate_val(ak, rate); | ||
| 312 | |||
| 313 | #if 1 /* FIXME: do we need this procedure? */ | ||
| 314 | /* reset DFS pin of AK5385A for ADC, too */ | ||
| 315 | /* DFS0 (pin 18) -- GPIO10 pin 77 */ | ||
| 316 | snd_ice1712_save_gpio_status(ice); | ||
| 317 | snd_ice1712_gpio_write_bits(ice, 1 << 10, | ||
| 318 | rate > 48000 ? (1 << 10) : 0); | ||
| 319 | snd_ice1712_restore_gpio_status(ice); | ||
| 320 | #endif | ||
| 321 | } | ||
| 322 | |||
| 323 | static struct snd_akm4xxx_dac_channel ap192_dac[] = { | ||
| 324 | AK_DAC("PCM Playback Volume", 2) | ||
| 325 | }; | ||
| 326 | |||
| 327 | static struct snd_akm4xxx akm_ap192 __devinitdata = { | ||
| 328 | .type = SND_AK4358, | ||
| 329 | .num_dacs = 2, | ||
| 330 | .ops = { | ||
| 331 | .set_rate_val = ap192_set_rate_val | ||
| 332 | }, | ||
| 333 | .dac_info = ap192_dac, | ||
| 334 | }; | ||
| 335 | |||
| 336 | static struct snd_ak4xxx_private akm_ap192_priv __devinitdata = { | ||
| 337 | .caddr = 2, | ||
| 338 | .cif = 0, | ||
| 339 | .data_mask = VT1724_REVO_CDOUT, | ||
| 340 | .clk_mask = VT1724_REVO_CCLK, | ||
| 341 | .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS3, | ||
| 342 | .cs_addr = VT1724_REVO_CS3, | ||
| 343 | .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS3, | ||
| 344 | .add_flags = VT1724_REVO_CCLK, /* high at init */ | ||
| 345 | .mask_flags = 0, | ||
| 346 | }; | ||
| 347 | |||
| 348 | #if 0 | ||
| 349 | /* FIXME: ak4114 makes the sound much lower due to some confliction, | ||
| 350 | * so let's disable it right now... | ||
| 351 | */ | ||
| 352 | #define BUILD_AK4114_AP192 | ||
| 353 | #endif | ||
| 354 | |||
| 355 | #ifdef BUILD_AK4114_AP192 | ||
| 356 | /* AK4114 support on Audiophile 192 */ | ||
| 357 | /* CDTO (pin 32) -- GPIO2 pin 52 | ||
| 358 | * CDTI (pin 33) -- GPIO3 pin 53 (shared with AK4358) | ||
| 359 | * CCLK (pin 34) -- GPIO1 pin 51 (shared with AK4358) | ||
| 360 | * CSN (pin 35) -- GPIO7 pin 59 | ||
| 361 | */ | ||
| 362 | #define AK4114_ADDR 0x00 | ||
| 363 | |||
| 364 | static void write_data(struct snd_ice1712 *ice, unsigned int gpio, | ||
| 365 | unsigned int data, int idx) | ||
| 366 | { | ||
| 367 | for (; idx >= 0; idx--) { | ||
| 368 | /* drop clock */ | ||
| 369 | gpio &= ~VT1724_REVO_CCLK; | ||
| 370 | snd_ice1712_gpio_write(ice, gpio); | ||
| 371 | udelay(1); | ||
| 372 | /* set data */ | ||
| 373 | if (data & (1 << idx)) | ||
| 374 | gpio |= VT1724_REVO_CDOUT; | ||
| 375 | else | ||
| 376 | gpio &= ~VT1724_REVO_CDOUT; | ||
| 377 | snd_ice1712_gpio_write(ice, gpio); | ||
| 378 | udelay(1); | ||
| 379 | /* raise clock */ | ||
| 380 | gpio |= VT1724_REVO_CCLK; | ||
| 381 | snd_ice1712_gpio_write(ice, gpio); | ||
| 382 | udelay(1); | ||
| 383 | } | ||
| 384 | } | ||
| 385 | |||
| 386 | static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio, | ||
| 387 | int idx) | ||
| 388 | { | ||
| 389 | unsigned char data = 0; | ||
| 390 | |||
| 391 | for (; idx >= 0; idx--) { | ||
| 392 | /* drop clock */ | ||
| 393 | gpio &= ~VT1724_REVO_CCLK; | ||
| 394 | snd_ice1712_gpio_write(ice, gpio); | ||
| 395 | udelay(1); | ||
| 396 | /* read data */ | ||
| 397 | if (snd_ice1712_gpio_read(ice) & VT1724_REVO_CDIN) | ||
| 398 | data |= (1 << idx); | ||
| 399 | udelay(1); | ||
| 400 | /* raise clock */ | ||
| 401 | gpio |= VT1724_REVO_CCLK; | ||
| 402 | snd_ice1712_gpio_write(ice, gpio); | ||
| 403 | udelay(1); | ||
| 404 | } | ||
| 405 | return data; | ||
| 406 | } | ||
| 407 | |||
| 408 | static unsigned char ap192_4wire_start(struct snd_ice1712 *ice) | ||
| 409 | { | ||
| 410 | unsigned int tmp; | ||
| 411 | |||
| 412 | snd_ice1712_save_gpio_status(ice); | ||
| 413 | tmp = snd_ice1712_gpio_read(ice); | ||
| 414 | tmp |= VT1724_REVO_CCLK; /* high at init */ | ||
| 415 | tmp |= VT1724_REVO_CS0; | ||
| 416 | tmp &= ~VT1724_REVO_CS3; | ||
| 417 | snd_ice1712_gpio_write(ice, tmp); | ||
| 418 | udelay(1); | ||
| 419 | return tmp; | ||
| 420 | } | ||
| 421 | |||
| 422 | static void ap192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp) | ||
| 423 | { | ||
| 424 | tmp |= VT1724_REVO_CS3; | ||
| 425 | tmp |= VT1724_REVO_CS0; | ||
| 426 | snd_ice1712_gpio_write(ice, tmp); | ||
| 427 | udelay(1); | ||
| 428 | snd_ice1712_restore_gpio_status(ice); | ||
| 429 | } | ||
| 430 | |||
| 431 | static void ap192_ak4114_write(void *private_data, unsigned char addr, | ||
| 432 | unsigned char data) | ||
| 433 | { | ||
| 434 | struct snd_ice1712 *ice = private_data; | ||
| 435 | unsigned int tmp, addrdata; | ||
| 436 | |||
| 437 | tmp = ap192_4wire_start(ice); | ||
| 438 | addrdata = (AK4114_ADDR << 6) | 0x20 | (addr & 0x1f); | ||
| 439 | addrdata = (addrdata << 8) | data; | ||
| 440 | write_data(ice, tmp, addrdata, 15); | ||
| 441 | ap192_4wire_finish(ice, tmp); | ||
| 442 | } | ||
| 443 | |||
| 444 | static unsigned char ap192_ak4114_read(void *private_data, unsigned char addr) | ||
| 445 | { | ||
| 446 | struct snd_ice1712 *ice = private_data; | ||
| 447 | unsigned int tmp; | ||
| 448 | unsigned char data; | ||
| 449 | |||
| 450 | tmp = ap192_4wire_start(ice); | ||
| 451 | write_data(ice, tmp, (AK4114_ADDR << 6) | (addr & 0x1f), 7); | ||
| 452 | data = read_data(ice, tmp, 7); | ||
| 453 | ap192_4wire_finish(ice, tmp); | ||
| 454 | return data; | ||
| 455 | } | ||
| 456 | |||
| 457 | static int ap192_ak4114_init(struct snd_ice1712 *ice) | ||
| 458 | { | ||
| 459 | static unsigned char ak4114_init_vals[] = { | ||
| 460 | AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, | ||
| 461 | AK4114_DIF_I24I2S, | ||
| 462 | AK4114_TX1E, | ||
| 463 | AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(1), | ||
| 464 | 0, | ||
| 465 | 0 | ||
| 466 | }; | ||
| 467 | static unsigned char ak4114_init_txcsb[] = { | ||
| 468 | 0x41, 0x02, 0x2c, 0x00, 0x00 | ||
| 469 | }; | ||
| 470 | struct ak4114 *ak; | ||
| 471 | int err; | ||
| 472 | |||
| 473 | return snd_ak4114_create(ice->card, | ||
| 474 | ap192_ak4114_read, | ||
| 475 | ap192_ak4114_write, | ||
| 476 | ak4114_init_vals, ak4114_init_txcsb, | ||
| 477 | ice, &ak); | ||
| 478 | } | ||
| 479 | #endif /* BUILD_AK4114_AP192 */ | ||
| 480 | |||
| 306 | static int __devinit revo_init(struct snd_ice1712 *ice) | 481 | static int __devinit revo_init(struct snd_ice1712 *ice) |
| 307 | { | 482 | { |
| 308 | struct snd_akm4xxx *ak; | 483 | struct snd_akm4xxx *ak; |
| @@ -319,6 +494,10 @@ static int __devinit revo_init(struct snd_ice1712 *ice) | |||
| 319 | ice->num_total_dacs = 6; | 494 | ice->num_total_dacs = 6; |
| 320 | ice->num_total_adcs = 2; | 495 | ice->num_total_adcs = 2; |
| 321 | break; | 496 | break; |
| 497 | case VT1724_SUBDEVICE_AUDIOPHILE192: | ||
| 498 | ice->num_total_dacs = 2; | ||
| 499 | ice->num_total_adcs = 2; | ||
| 500 | break; | ||
| 322 | default: | 501 | default: |
| 323 | snd_BUG(); | 502 | snd_BUG(); |
| 324 | return -EINVAL; | 503 | return -EINVAL; |
| @@ -356,6 +535,14 @@ static int __devinit revo_init(struct snd_ice1712 *ice) | |||
| 356 | snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, | 535 | snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, |
| 357 | VT1724_REVO_MUTE); | 536 | VT1724_REVO_MUTE); |
| 358 | break; | 537 | break; |
| 538 | case VT1724_SUBDEVICE_AUDIOPHILE192: | ||
| 539 | ice->akm_codecs = 1; | ||
| 540 | err = snd_ice1712_akm4xxx_init(ak, &akm_ap192, &akm_ap192_priv, | ||
| 541 | ice); | ||
| 542 | if (err < 0) | ||
| 543 | return err; | ||
| 544 | |||
| 545 | break; | ||
| 359 | } | 546 | } |
| 360 | 547 | ||
| 361 | return 0; | 548 | return 0; |
| @@ -380,6 +567,16 @@ static int __devinit revo_add_controls(struct snd_ice1712 *ice) | |||
| 380 | if (err < 0) | 567 | if (err < 0) |
| 381 | return err; | 568 | return err; |
| 382 | break; | 569 | break; |
| 570 | case VT1724_SUBDEVICE_AUDIOPHILE192: | ||
| 571 | err = snd_ice1712_akm4xxx_build_controls(ice); | ||
| 572 | if (err < 0) | ||
| 573 | return err; | ||
| 574 | #ifdef BUILD_AK4114_AP192 | ||
| 575 | err = ap192_ak4114_init(ice); | ||
| 576 | if (err < 0) | ||
| 577 | return err; | ||
| 578 | #endif | ||
| 579 | break; | ||
| 383 | } | 580 | } |
| 384 | return 0; | 581 | return 0; |
| 385 | } | 582 | } |
| @@ -400,5 +597,12 @@ struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = { | |||
| 400 | .chip_init = revo_init, | 597 | .chip_init = revo_init, |
| 401 | .build_controls = revo_add_controls, | 598 | .build_controls = revo_add_controls, |
| 402 | }, | 599 | }, |
| 600 | { | ||
| 601 | .subvendor = VT1724_SUBDEVICE_AUDIOPHILE192, | ||
| 602 | .name = "M Audio Audiophile192", | ||
| 603 | .model = "ap192", | ||
| 604 | .chip_init = revo_init, | ||
| 605 | .build_controls = revo_add_controls, | ||
| 606 | }, | ||
| 403 | { } /* terminator */ | 607 | { } /* terminator */ |
| 404 | }; | 608 | }; |
diff --git a/sound/pci/ice1712/revo.h b/sound/pci/ice1712/revo.h index c70adaf017c1..a3ba425911cc 100644 --- a/sound/pci/ice1712/revo.h +++ b/sound/pci/ice1712/revo.h | |||
| @@ -26,10 +26,12 @@ | |||
| 26 | 26 | ||
| 27 | #define REVO_DEVICE_DESC \ | 27 | #define REVO_DEVICE_DESC \ |
| 28 | "{MidiMan M Audio,Revolution 7.1},"\ | 28 | "{MidiMan M Audio,Revolution 7.1},"\ |
| 29 | "{MidiMan M Audio,Revolution 5.1}," | 29 | "{MidiMan M Audio,Revolution 5.1},"\ |
| 30 | "{MidiMan M Audio,Audiophile 192}," | ||
| 30 | 31 | ||
| 31 | #define VT1724_SUBDEVICE_REVOLUTION71 0x12143036 | 32 | #define VT1724_SUBDEVICE_REVOLUTION71 0x12143036 |
| 32 | #define VT1724_SUBDEVICE_REVOLUTION51 0x12143136 | 33 | #define VT1724_SUBDEVICE_REVOLUTION51 0x12143136 |
| 34 | #define VT1724_SUBDEVICE_AUDIOPHILE192 0x12143236 | ||
| 33 | 35 | ||
| 34 | /* entry point */ | 36 | /* entry point */ |
| 35 | extern struct snd_ice1712_card_info snd_vt1724_revo_cards[]; | 37 | extern struct snd_ice1712_card_info snd_vt1724_revo_cards[]; |
| @@ -47,6 +49,7 @@ extern struct snd_ice1712_card_info snd_vt1724_revo_cards[]; | |||
| 47 | #define VT1724_REVO_CS2 0x40 /* surround AKM4355 CS (revo71) */ | 49 | #define VT1724_REVO_CS2 0x40 /* surround AKM4355 CS (revo71) */ |
| 48 | #define VT1724_REVO_I2C_DATA 0x40 /* I2C: PT 2258 SDA (on revo51) */ | 50 | #define VT1724_REVO_I2C_DATA 0x40 /* I2C: PT 2258 SDA (on revo51) */ |
| 49 | #define VT1724_REVO_I2C_CLOCK 0x80 /* I2C: PT 2258 SCL (on revo51) */ | 51 | #define VT1724_REVO_I2C_CLOCK 0x80 /* I2C: PT 2258 SCL (on revo51) */ |
| 52 | #define VT1724_REVO_CS3 0x80 /* AK4114 for AP192 */ | ||
| 50 | #define VT1724_REVO_MUTE (1<<22) /* 0 = all mute, 1 = normal operation */ | 53 | #define VT1724_REVO_MUTE (1<<22) /* 0 = all mute, 1 = normal operation */ |
| 51 | 54 | ||
| 52 | #endif /* __SOUND_REVO_H */ | 55 | #endif /* __SOUND_REVO_H */ |
