diff options
author | Jonas Petersen <jnsptrsn1@gmail.com> | 2013-02-23 17:38:43 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-02-25 03:52:07 -0500 |
commit | c2d3703cdd4954836f348515b802a5dc4c17710e (patch) | |
tree | ae1c1e4c0a00ffe92bc709b4bcd0f5981951bd0e /sound | |
parent | aacfddfdadb3540651d263245069631f341e953a (diff) |
ALSA: ice1724: M-Audio Audiophile192: Fix SPDIF input
This patch fixes initialization of the AK4114 chip so spdif capture is working properly.
Worked out together with Pavel Hofman.
Signed-off-by: Jonas Petersen <jnsptrsn1@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/ice1712/revo.c | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index 7641080a9b5d..1112ec1953be 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c | |||
@@ -35,6 +35,7 @@ | |||
35 | struct revo51_spec { | 35 | struct revo51_spec { |
36 | struct snd_i2c_device *dev; | 36 | struct snd_i2c_device *dev; |
37 | struct snd_pt2258 *pt2258; | 37 | struct snd_pt2258 *pt2258; |
38 | struct ak4114 *ak4114; | ||
38 | }; | 39 | }; |
39 | 40 | ||
40 | static void revo_i2s_mclk_changed(struct snd_ice1712 *ice) | 41 | static void revo_i2s_mclk_changed(struct snd_ice1712 *ice) |
@@ -359,9 +360,9 @@ static struct snd_ak4xxx_private akm_ap192_priv = { | |||
359 | .cif = 0, | 360 | .cif = 0, |
360 | .data_mask = VT1724_REVO_CDOUT, | 361 | .data_mask = VT1724_REVO_CDOUT, |
361 | .clk_mask = VT1724_REVO_CCLK, | 362 | .clk_mask = VT1724_REVO_CCLK, |
362 | .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1, | 363 | .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS3, |
363 | .cs_addr = VT1724_REVO_CS1, | 364 | .cs_addr = VT1724_REVO_CS3, |
364 | .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1, | 365 | .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS3, |
365 | .add_flags = VT1724_REVO_CCLK, /* high at init */ | 366 | .add_flags = VT1724_REVO_CCLK, /* high at init */ |
366 | .mask_flags = 0, | 367 | .mask_flags = 0, |
367 | }; | 368 | }; |
@@ -372,7 +373,7 @@ static struct snd_ak4xxx_private akm_ap192_priv = { | |||
372 | * CCLK (pin 34) -- GPIO1 pin 51 (shared with AK4358) | 373 | * CCLK (pin 34) -- GPIO1 pin 51 (shared with AK4358) |
373 | * CSN (pin 35) -- GPIO7 pin 59 | 374 | * CSN (pin 35) -- GPIO7 pin 59 |
374 | */ | 375 | */ |
375 | #define AK4114_ADDR 0x02 | 376 | #define AK4114_ADDR 0x00 |
376 | 377 | ||
377 | static void write_data(struct snd_ice1712 *ice, unsigned int gpio, | 378 | static void write_data(struct snd_ice1712 *ice, unsigned int gpio, |
378 | unsigned int data, int idx) | 379 | unsigned int data, int idx) |
@@ -426,7 +427,7 @@ static unsigned int ap192_4wire_start(struct snd_ice1712 *ice) | |||
426 | tmp = snd_ice1712_gpio_read(ice); | 427 | tmp = snd_ice1712_gpio_read(ice); |
427 | tmp |= VT1724_REVO_CCLK; /* high at init */ | 428 | tmp |= VT1724_REVO_CCLK; /* high at init */ |
428 | tmp |= VT1724_REVO_CS0; | 429 | tmp |= VT1724_REVO_CS0; |
429 | tmp &= ~VT1724_REVO_CS1; | 430 | tmp &= ~VT1724_REVO_CS3; |
430 | snd_ice1712_gpio_write(ice, tmp); | 431 | snd_ice1712_gpio_write(ice, tmp); |
431 | udelay(1); | 432 | udelay(1); |
432 | return tmp; | 433 | return tmp; |
@@ -434,7 +435,7 @@ static unsigned int ap192_4wire_start(struct snd_ice1712 *ice) | |||
434 | 435 | ||
435 | static void ap192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp) | 436 | static void ap192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp) |
436 | { | 437 | { |
437 | tmp |= VT1724_REVO_CS1; | 438 | tmp |= VT1724_REVO_CS3; |
438 | tmp |= VT1724_REVO_CS0; | 439 | tmp |= VT1724_REVO_CS0; |
439 | snd_ice1712_gpio_write(ice, tmp); | 440 | snd_ice1712_gpio_write(ice, tmp); |
440 | udelay(1); | 441 | udelay(1); |
@@ -470,27 +471,32 @@ static unsigned char ap192_ak4114_read(void *private_data, unsigned char addr) | |||
470 | static int ap192_ak4114_init(struct snd_ice1712 *ice) | 471 | static int ap192_ak4114_init(struct snd_ice1712 *ice) |
471 | { | 472 | { |
472 | static const unsigned char ak4114_init_vals[] = { | 473 | static const unsigned char ak4114_init_vals[] = { |
473 | AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, | 474 | AK4114_RST | AK4114_PWN | AK4114_OCKS0, |
474 | AK4114_DIF_I24I2S, | 475 | AK4114_DIF_I24I2S, |
475 | AK4114_TX1E, | 476 | AK4114_TX1E, |
476 | AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(1), | 477 | AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(0), |
477 | 0, | 478 | 0, |
478 | 0 | 479 | 0 |
479 | }; | 480 | }; |
480 | static const unsigned char ak4114_init_txcsb[] = { | 481 | static const unsigned char ak4114_init_txcsb[] = { |
481 | 0x41, 0x02, 0x2c, 0x00, 0x00 | 482 | 0x41, 0x02, 0x2c, 0x00, 0x00 |
482 | }; | 483 | }; |
483 | struct ak4114 *ak; | ||
484 | int err; | 484 | int err; |
485 | 485 | ||
486 | struct revo51_spec *spec; | ||
487 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
488 | if (!spec) | ||
489 | return -ENOMEM; | ||
490 | ice->spec = spec; | ||
491 | |||
486 | err = snd_ak4114_create(ice->card, | 492 | err = snd_ak4114_create(ice->card, |
487 | ap192_ak4114_read, | 493 | ap192_ak4114_read, |
488 | ap192_ak4114_write, | 494 | ap192_ak4114_write, |
489 | ak4114_init_vals, ak4114_init_txcsb, | 495 | ak4114_init_vals, ak4114_init_txcsb, |
490 | ice, &ak); | 496 | ice, &spec->ak4114); |
491 | /* AK4114 in Revo cannot detect external rate correctly. | 497 | /* AK4114 in Revo cannot detect external rate correctly. |
492 | * No reason to stop capture stream due to incorrect checks */ | 498 | * No reason to stop capture stream due to incorrect checks */ |
493 | ak->check_flags = AK4114_CHECK_NO_RATE; | 499 | spec->ak4114->check_flags = AK4114_CHECK_NO_RATE; |
494 | 500 | ||
495 | return 0; /* error ignored; it's no fatal error */ | 501 | return 0; /* error ignored; it's no fatal error */ |
496 | } | 502 | } |
@@ -562,6 +568,9 @@ static int revo_init(struct snd_ice1712 *ice) | |||
562 | ice); | 568 | ice); |
563 | if (err < 0) | 569 | if (err < 0) |
564 | return err; | 570 | return err; |
571 | err = ap192_ak4114_init(ice); | ||
572 | if (err < 0) | ||
573 | return err; | ||
565 | 574 | ||
566 | /* unmute all codecs */ | 575 | /* unmute all codecs */ |
567 | snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, | 576 | snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, |
@@ -575,7 +584,7 @@ static int revo_init(struct snd_ice1712 *ice) | |||
575 | 584 | ||
576 | static int revo_add_controls(struct snd_ice1712 *ice) | 585 | static int revo_add_controls(struct snd_ice1712 *ice) |
577 | { | 586 | { |
578 | struct revo51_spec *spec; | 587 | struct revo51_spec *spec = ice->spec; |
579 | int err; | 588 | int err; |
580 | 589 | ||
581 | switch (ice->eeprom.subvendor) { | 590 | switch (ice->eeprom.subvendor) { |
@@ -597,7 +606,9 @@ static int revo_add_controls(struct snd_ice1712 *ice) | |||
597 | err = snd_ice1712_akm4xxx_build_controls(ice); | 606 | err = snd_ice1712_akm4xxx_build_controls(ice); |
598 | if (err < 0) | 607 | if (err < 0) |
599 | return err; | 608 | return err; |
600 | err = ap192_ak4114_init(ice); | 609 | /* only capture SPDIF over AK4114 */ |
610 | err = snd_ak4114_build(spec->ak4114, NULL, | ||
611 | ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream); | ||
601 | if (err < 0) | 612 | if (err < 0) |
602 | return err; | 613 | return err; |
603 | break; | 614 | break; |