aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2011-01-10 10:11:05 -0500
committerTakashi Iwai <tiwai@suse.de>2011-01-10 10:46:24 -0500
commitc97e2dc48457642e2f1c6183b986549b7fa0113a (patch)
treeaac3279f466e147b78bf5da8872ed90b7e063e17 /sound
parent00b8dd7dd71ef129176731d5fa24f5e298797599 (diff)
ALSA: virtuoso: handle DAC oversampling automatically
Remove the DAC Oversampling mixer control because this setting does not make much sense. For cards with the H6 daughterboard, 128x oversampling was disabled anyway because these high MCLK frequency would not be compatible with the connector cable. For cards without the H6 daughterboard, 128x gives a slightly higher output quality; there is no reason to reduce it to 64x except for saving power, but then these cards have not been designed to be power efficient anyway (the D2's blinkenlights cannot be disabled). Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/oxygen/xonar_pcm179x.c100
1 files changed, 21 insertions, 79 deletions
diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c
index 2a50a55cbbb1..2d0a634a7239 100644
--- a/sound/pci/oxygen/xonar_pcm179x.c
+++ b/sound/pci/oxygen/xonar_pcm179x.c
@@ -223,7 +223,6 @@ struct xonar_pcm179x {
223 unsigned int dacs; 223 unsigned int dacs;
224 u8 pcm1796_regs[4][5]; 224 u8 pcm1796_regs[4][5];
225 unsigned int current_rate; 225 unsigned int current_rate;
226 bool os_128;
227 bool h6; 226 bool h6;
228 bool hp_active; 227 bool hp_active;
229 s8 hp_gain_offset; 228 s8 hp_gain_offset;
@@ -331,9 +330,14 @@ static void pcm1796_init(struct oxygen *chip)
331 PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD; 330 PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD;
332 data->pcm1796_regs[0][19 - PCM1796_REG_BASE] = 331 data->pcm1796_regs[0][19 - PCM1796_REG_BASE] =
333 PCM1796_FLT_SHARP | PCM1796_ATS_1; 332 PCM1796_FLT_SHARP | PCM1796_ATS_1;
334 data->pcm1796_regs[0][20 - PCM1796_REG_BASE] = PCM1796_OS_64; 333 data->pcm1796_regs[0][20 - PCM1796_REG_BASE] =
334 data->h6 ? PCM1796_OS_64 : PCM1796_OS_128;
335 pcm1796_registers_init(chip); 335 pcm1796_registers_init(chip);
336 data->current_rate = 48000; 336 data->current_rate = 48000;
337 if (!data->h6)
338 oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
339 OXYGEN_I2S_MCLK_512,
340 OXYGEN_I2S_MCLK_MASK);
337} 341}
338 342
339static void xonar_d2_init(struct oxygen *chip) 343static void xonar_d2_init(struct oxygen *chip)
@@ -469,9 +473,12 @@ static void xonar_st_init(struct oxygen *chip)
469 data->broken_i2c = true; 473 data->broken_i2c = true;
470 474
471 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, 475 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
472 OXYGEN_RATE_48000 | OXYGEN_I2S_FORMAT_I2S | 476 OXYGEN_RATE_48000 |
473 OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | 477 OXYGEN_I2S_FORMAT_I2S |
474 OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); 478 (data->h6 ? OXYGEN_I2S_MCLK_256 : OXYGEN_I2S_MCLK_512) |
479 OXYGEN_I2S_BITS_16 |
480 OXYGEN_I2S_MASTER |
481 OXYGEN_I2S_BCLK_64);
475 482
476 xonar_st_init_i2c(chip); 483 xonar_st_init_i2c(chip);
477 cs2000_registers_init(chip); 484 cs2000_registers_init(chip);
@@ -556,11 +563,8 @@ static unsigned int mclk_from_rate(struct oxygen *chip, unsigned int rate)
556{ 563{
557 struct xonar_pcm179x *data = chip->model_data; 564 struct xonar_pcm179x *data = chip->model_data;
558 565
559 if (rate <= 32000) 566 if (rate <= 48000)
560 return data->h6 ? OXYGEN_I2S_MCLK_256 : OXYGEN_I2S_MCLK_512; 567 return data->h6 ? OXYGEN_I2S_MCLK_256 : OXYGEN_I2S_MCLK_512;
561 else if (rate <= 48000)
562 return data->os_128 && !data->h6
563 ? OXYGEN_I2S_MCLK_512 : OXYGEN_I2S_MCLK_256;
564 else 568 else
565 return OXYGEN_I2S_MCLK_128; 569 return OXYGEN_I2S_MCLK_128;
566} 570}
@@ -581,14 +585,10 @@ static void update_pcm1796_oversampling(struct oxygen *chip)
581 unsigned int i; 585 unsigned int i;
582 u8 reg; 586 u8 reg;
583 587
584 if (data->current_rate <= 32000 && !data->h6) 588 if (data->current_rate <= 48000 && !data->h6)
585 reg = PCM1796_OS_128; 589 reg = PCM1796_OS_128;
586 else if (data->current_rate <= 48000 && data->os_128 && !data->h6)
587 reg = PCM1796_OS_128;
588 else if (data->current_rate <= 96000 || data->os_128)
589 reg = PCM1796_OS_64;
590 else 590 else
591 reg = PCM1796_OS_32; 591 reg = PCM1796_OS_64;
592 for (i = 0; i < data->dacs; ++i) 592 for (i = 0; i < data->dacs; ++i)
593 pcm1796_write_cached(chip, i, 20, reg); 593 pcm1796_write_cached(chip, i, 20, reg);
594} 594}
@@ -644,16 +644,16 @@ static void update_cs2000_rate(struct oxygen *chip, unsigned int rate)
644 rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_512; 644 rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_512;
645 break; 645 break;
646 case 44100: 646 case 44100:
647 if (data->os_128 && !data->h6) 647 if (data->h6)
648 rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_512;
649 else
650 rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256; 648 rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256;
649 else
650 rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_512;
651 break; 651 break;
652 default: /* 48000 */ 652 default: /* 48000 */
653 if (data->os_128 && !data->h6) 653 if (data->h6)
654 rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_512;
655 else
656 rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256; 654 rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256;
655 else
656 rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_512;
657 break; 657 break;
658 case 64000: 658 case 64000:
659 rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_256; 659 rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_256;
@@ -767,60 +767,6 @@ static const struct snd_kcontrol_new rolloff_control = {
767 .put = rolloff_put, 767 .put = rolloff_put,
768}; 768};
769 769
770static int os_128_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
771{
772 static const char *const names[2] = { "64x", "128x" };
773
774 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
775 info->count = 1;
776 info->value.enumerated.items = 2;
777 if (info->value.enumerated.item >= 2)
778 info->value.enumerated.item = 1;
779 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
780 return 0;
781}
782
783static int os_128_get(struct snd_kcontrol *ctl,
784 struct snd_ctl_elem_value *value)
785{
786 struct oxygen *chip = ctl->private_data;
787 struct xonar_pcm179x *data = chip->model_data;
788
789 value->value.enumerated.item[0] = data->os_128;
790 return 0;
791}
792
793static int os_128_put(struct snd_kcontrol *ctl,
794 struct snd_ctl_elem_value *value)
795{
796 struct oxygen *chip = ctl->private_data;
797 struct xonar_pcm179x *data = chip->model_data;
798 int changed;
799
800 mutex_lock(&chip->mutex);
801 changed = value->value.enumerated.item[0] != data->os_128;
802 if (changed) {
803 data->os_128 = value->value.enumerated.item[0];
804 if (data->has_cs2000)
805 update_cs2000_rate(chip, data->current_rate);
806 oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
807 mclk_from_rate(chip, data->current_rate),
808 OXYGEN_I2S_MCLK_MASK);
809 msleep(1);
810 update_pcm1796_oversampling(chip);
811 }
812 mutex_unlock(&chip->mutex);
813 return changed;
814}
815
816static const struct snd_kcontrol_new os_128_control = {
817 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
818 .name = "DAC Oversampling Playback Enum",
819 .info = os_128_info,
820 .get = os_128_get,
821 .put = os_128_put,
822};
823
824static const struct snd_kcontrol_new hdav_hdmi_control = { 770static const struct snd_kcontrol_new hdav_hdmi_control = {
825 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 771 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
826 .name = "HDMI Playback Switch", 772 .name = "HDMI Playback Switch",
@@ -1004,10 +950,6 @@ static int add_pcm1796_controls(struct oxygen *chip)
1004 snd_ctl_new1(&rolloff_control, chip)); 950 snd_ctl_new1(&rolloff_control, chip));
1005 if (err < 0) 951 if (err < 0)
1006 return err; 952 return err;
1007 err = snd_ctl_add(chip->card,
1008 snd_ctl_new1(&os_128_control, chip));
1009 if (err < 0)
1010 return err;
1011 } 953 }
1012 return 0; 954 return 0;
1013} 955}