diff options
author | James Courtier-Dutton <James@superbug.co.uk> | 2006-10-10 13:08:45 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2007-02-09 03:00:40 -0500 |
commit | b0dbdaea55d55c05be972cd2a040acfa073b0509 (patch) | |
tree | d1bcb3f75e87dd524832a43935c4c6569ca2f76a /sound/pci | |
parent | 0f71e8b98506252db22a0c4fcfecb0aadcf393cc (diff) |
[ALSA] snd-emu10k1: Add emu1010 internal clock rate control for 44100 or 48000.
Signed-off-by: James Courtier-Dutton <James@superbug.co.uk>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/emu10k1/emu10k1_main.c | 1 | ||||
-rw-r--r-- | sound/pci/emu10k1/emumixer.c | 92 | ||||
-rw-r--r-- | sound/pci/emu10k1/emupcm.c | 28 |
3 files changed, 115 insertions, 6 deletions
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 341a2775d286..711e819e4a0b 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c | |||
@@ -1014,6 +1014,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) | |||
1014 | /* Word Clock source, Internal 48kHz x1 */ | 1014 | /* Word Clock source, Internal 48kHz x1 */ |
1015 | snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K ); | 1015 | snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K ); |
1016 | //snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X ); | 1016 | //snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X ); |
1017 | emu->emu1010.internal_clock = 1; /* 48000 */ | ||
1017 | snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12);/* Set LEDs on Audio Dock */ | 1018 | snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12);/* Set LEDs on Audio Dock */ |
1018 | snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x1); /* Unmute all */ | 1019 | snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x1); /* Unmute all */ |
1019 | //snd_emu1010_fpga_write(emu, 0x7, 0x0); /* Mute all */ | 1020 | //snd_emu1010_fpga_write(emu, 0x7, 0x0); /* Mute all */ |
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index 2edf92a4f065..a118fee11cdd 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <sound/core.h> | 36 | #include <sound/core.h> |
37 | #include <sound/emu10k1.h> | 37 | #include <sound/emu10k1.h> |
38 | #include <linux/delay.h> | ||
38 | 39 | ||
39 | #define AC97_ID_STAC9758 0x83847658 | 40 | #define AC97_ID_STAC9758 0x83847658 |
40 | 41 | ||
@@ -490,6 +491,94 @@ static struct snd_kcontrol_new snd_emu1010_dac_pads[] __devinitdata = { | |||
490 | EMU1010_DAC_PADS("DAC1 0202 14dB PAD Playback Switch", EMU_HANA_0202_DAC_PAD1), | 491 | EMU1010_DAC_PADS("DAC1 0202 14dB PAD Playback Switch", EMU_HANA_0202_DAC_PAD1), |
491 | }; | 492 | }; |
492 | 493 | ||
494 | |||
495 | static int snd_emu1010_internal_clock_info(struct snd_kcontrol *kcontrol, | ||
496 | struct snd_ctl_elem_info *uinfo) | ||
497 | { | ||
498 | static char *texts[2] = { | ||
499 | "44100", "48000" | ||
500 | }; | ||
501 | |||
502 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
503 | uinfo->count = 1; | ||
504 | uinfo->value.enumerated.items = 2; | ||
505 | if (uinfo->value.enumerated.item > 1) | ||
506 | uinfo->value.enumerated.item = 1; | ||
507 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
508 | return 0; | ||
509 | } | ||
510 | |||
511 | static int snd_emu1010_internal_clock_get(struct snd_kcontrol *kcontrol, | ||
512 | struct snd_ctl_elem_value *ucontrol) | ||
513 | { | ||
514 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); | ||
515 | |||
516 | ucontrol->value.enumerated.item[0] = emu->emu1010.internal_clock; | ||
517 | return 0; | ||
518 | } | ||
519 | |||
520 | static int snd_emu1010_internal_clock_put(struct snd_kcontrol *kcontrol, | ||
521 | struct snd_ctl_elem_value *ucontrol) | ||
522 | { | ||
523 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); | ||
524 | unsigned int val; | ||
525 | int change = 0; | ||
526 | |||
527 | val = ucontrol->value.enumerated.item[0] ; | ||
528 | change = (emu->emu1010.internal_clock != val); | ||
529 | if (change) { | ||
530 | emu->emu1010.internal_clock = val; | ||
531 | switch (val) { | ||
532 | case 0: | ||
533 | /* 44100 */ | ||
534 | /* Mute all */ | ||
535 | snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE ); | ||
536 | /* Default fallback clock 48kHz */ | ||
537 | snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_44_1K ); | ||
538 | /* Word Clock source, Internal 44.1kHz x1 */ | ||
539 | snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, | ||
540 | EMU_HANA_WCLOCK_INT_44_1K | EMU_HANA_WCLOCK_1X ); | ||
541 | /* Set LEDs on Audio Dock */ | ||
542 | snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, | ||
543 | EMU_HANA_DOCK_LEDS_2_44K | EMU_HANA_DOCK_LEDS_2_LOCK ); | ||
544 | /* Allow DLL to settle */ | ||
545 | udelay(10000); | ||
546 | /* Unmute all */ | ||
547 | snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE ); | ||
548 | break; | ||
549 | case 1: | ||
550 | /* 48000 */ | ||
551 | /* Mute all */ | ||
552 | snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE ); | ||
553 | /* Default fallback clock 48kHz */ | ||
554 | snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_48K ); | ||
555 | /* Word Clock source, Internal 48kHz x1 */ | ||
556 | snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, | ||
557 | EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_1X ); | ||
558 | /* Set LEDs on Audio Dock */ | ||
559 | snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, | ||
560 | EMU_HANA_DOCK_LEDS_2_48K | EMU_HANA_DOCK_LEDS_2_LOCK ); | ||
561 | /* Allow DLL to settle */ | ||
562 | udelay(10000); | ||
563 | /* Unmute all */ | ||
564 | snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE ); | ||
565 | break; | ||
566 | } | ||
567 | } | ||
568 | return change; | ||
569 | } | ||
570 | |||
571 | static struct snd_kcontrol_new snd_emu1010_internal_clock = | ||
572 | { | ||
573 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
574 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
575 | .name = "Clock Internal Rate", | ||
576 | .count = 1, | ||
577 | .info = snd_emu1010_internal_clock_info, | ||
578 | .get = snd_emu1010_internal_clock_get, | ||
579 | .put = snd_emu1010_internal_clock_put | ||
580 | }; | ||
581 | |||
493 | #if 0 | 582 | #if 0 |
494 | static int snd_audigy_spdif_output_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 583 | static int snd_audigy_spdif_output_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
495 | { | 584 | { |
@@ -1491,6 +1580,9 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu, | |||
1491 | if (err < 0) | 1580 | if (err < 0) |
1492 | return err; | 1581 | return err; |
1493 | } | 1582 | } |
1583 | err = snd_ctl_add(card, snd_ctl_new1(&snd_emu1010_internal_clock, emu)); | ||
1584 | if (err < 0) | ||
1585 | return err; | ||
1494 | } | 1586 | } |
1495 | 1587 | ||
1496 | return 0; | 1588 | return 0; |
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index 44d098ac86d5..ab4f5df5241b 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c | |||
@@ -358,7 +358,10 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu, | |||
358 | snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]); | 358 | snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]); |
359 | snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24)); | 359 | snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24)); |
360 | snd_emu10k1_ptr_write(emu, PSST, voice, start_addr | (send_amount[2] << 24)); | 360 | snd_emu10k1_ptr_write(emu, PSST, voice, start_addr | (send_amount[2] << 24)); |
361 | pitch_target = emu10k1_calc_pitch_target(runtime->rate); | 361 | if (emu->card_capabilities->emu1010) |
362 | pitch_target = PITCH_48000; /* Disable interpolators on emu1010 card */ | ||
363 | else | ||
364 | pitch_target = emu10k1_calc_pitch_target(runtime->rate); | ||
362 | if (extra) | 365 | if (extra) |
363 | snd_emu10k1_ptr_write(emu, CCCA, voice, start_addr | | 366 | snd_emu10k1_ptr_write(emu, CCCA, voice, start_addr | |
364 | emu10k1_select_interprom(pitch_target) | | 367 | emu10k1_select_interprom(pitch_target) | |
@@ -698,7 +701,10 @@ static void snd_emu10k1_playback_trigger_voice(struct snd_emu10k1 *emu, struct s | |||
698 | voice = evoice->number; | 701 | voice = evoice->number; |
699 | 702 | ||
700 | pitch = snd_emu10k1_rate_to_pitch(runtime->rate) >> 8; | 703 | pitch = snd_emu10k1_rate_to_pitch(runtime->rate) >> 8; |
701 | pitch_target = emu10k1_calc_pitch_target(runtime->rate); | 704 | if (emu->card_capabilities->emu1010) |
705 | pitch_target = PITCH_48000; /* Disable interpolators on emu1010 card */ | ||
706 | else | ||
707 | pitch_target = emu10k1_calc_pitch_target(runtime->rate); | ||
702 | snd_emu10k1_ptr_write(emu, PTRX_PITCHTARGET, voice, pitch_target); | 708 | snd_emu10k1_ptr_write(emu, PTRX_PITCHTARGET, voice, pitch_target); |
703 | if (master || evoice->epcm->type == PLAYBACK_EFX) | 709 | if (master || evoice->epcm->type == PLAYBACK_EFX) |
704 | snd_emu10k1_ptr_write(emu, CPF_CURRENTPITCH, voice, pitch_target); | 710 | snd_emu10k1_ptr_write(emu, CPF_CURRENTPITCH, voice, pitch_target); |
@@ -1247,10 +1253,20 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream) | |||
1247 | * for 192kHz 24bit, one has 2 channels | 1253 | * for 192kHz 24bit, one has 2 channels |
1248 | */ | 1254 | */ |
1249 | #if 1 | 1255 | #if 1 |
1250 | /* For 48kHz */ | 1256 | switch (emu->emu1010.internal_clock) { |
1251 | runtime->hw.rates = SNDRV_PCM_RATE_48000; | 1257 | case 0: |
1252 | runtime->hw.rate_min = runtime->hw.rate_max = 48000; | 1258 | /* For 44.1kHz */ |
1253 | runtime->hw.channels_min = runtime->hw.channels_max = 8; | 1259 | runtime->hw.rates = SNDRV_PCM_RATE_44100; |
1260 | runtime->hw.rate_min = runtime->hw.rate_max = 44100; | ||
1261 | runtime->hw.channels_min = runtime->hw.channels_max = 8; | ||
1262 | break; | ||
1263 | case 1: | ||
1264 | /* For 48kHz */ | ||
1265 | runtime->hw.rates = SNDRV_PCM_RATE_48000; | ||
1266 | runtime->hw.rate_min = runtime->hw.rate_max = 48000; | ||
1267 | runtime->hw.channels_min = runtime->hw.channels_max = 8; | ||
1268 | break; | ||
1269 | }; | ||
1254 | #endif | 1270 | #endif |
1255 | #if 0 | 1271 | #if 0 |
1256 | /* For 96kHz */ | 1272 | /* For 96kHz */ |