Skip to content

Commit 6098524

Browse files
ossilatortiwai
authored andcommitted
ALSA: emu10k1: make available E-MU clock sources card-specific
The actually available clock sources depend on the available audio input ports and dedicated clock input ports. This includes refactoring the code to be data-driven to remain manageable. Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> Link: https://lore.kernel.org/r/20230612191325.1315854-3-oswald.buddenhagen@gmx.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent 1359886 commit 6098524

4 files changed

Lines changed: 107 additions & 75 deletions

File tree

include/sound/emu10k1.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1668,6 +1668,7 @@ struct snd_emu1010 {
16681668
unsigned char input_source[NUM_INPUT_DESTS];
16691669
unsigned int adc_pads; /* bit mask */
16701670
unsigned int dac_pads; /* bit mask */
1671+
unsigned int wclock; /* Cached register value */
16711672
unsigned int clock_source;
16721673
unsigned int clock_fallback;
16731674
unsigned int optical_in; /* 0:SPDIF, 1:ADAT */
@@ -1824,6 +1825,7 @@ void snd_emu1010_fpga_write(struct snd_emu10k1 *emu, u32 reg, u32 value);
18241825
void snd_emu1010_fpga_read(struct snd_emu10k1 *emu, u32 reg, u32 *value);
18251826
void snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 *emu, u32 dst, u32 src);
18261827
u32 snd_emu1010_fpga_link_dst_src_read(struct snd_emu10k1 *emu, u32 dst);
1828+
void snd_emu1010_update_clock(struct snd_emu10k1 *emu);
18271829
unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc);
18281830
void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb);
18291831
void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb);

sound/pci/emu10k1/emu10k1_main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -905,10 +905,10 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
905905
/* Default WCLK set to 48kHz. */
906906
snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_48K);
907907
/* Word Clock source, Internal 48kHz x1 */
908+
emu->emu1010.wclock = EMU_HANA_WCLOCK_INT_48K;
908909
snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K);
909910
/* snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X); */
910-
/* Audio Dock LEDs. */
911-
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, EMU_HANA_DOCK_LEDS_2_LOCK | EMU_HANA_DOCK_LEDS_2_48K);
911+
snd_emu1010_update_clock(emu);
912912

913913
// The routes are all set to EMU_SRC_SILENCE due to the reset,
914914
// so it is safe to simply enable the outputs.

sound/pci/emu10k1/emumixer.c

Lines changed: 80 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -887,15 +887,79 @@ static const struct snd_emu1010_pads_info emu1010_pads_info[] = {
887887
},
888888
};
889889

890+
static const char * const emu1010_clock_texts[] = {
891+
"44100", "48000", "SPDIF", "ADAT", "Dock", "BNC"
892+
};
893+
894+
static const u8 emu1010_clock_vals[] = {
895+
EMU_HANA_WCLOCK_INT_44_1K,
896+
EMU_HANA_WCLOCK_INT_48K,
897+
EMU_HANA_WCLOCK_HANA_SPDIF_IN,
898+
EMU_HANA_WCLOCK_HANA_ADAT_IN,
899+
EMU_HANA_WCLOCK_2ND_HANA,
900+
EMU_HANA_WCLOCK_SYNC_BNC,
901+
};
902+
903+
static const char * const emu0404_clock_texts[] = {
904+
"44100", "48000", "SPDIF", "BNC"
905+
};
906+
907+
static const u8 emu0404_clock_vals[] = {
908+
EMU_HANA_WCLOCK_INT_44_1K,
909+
EMU_HANA_WCLOCK_INT_48K,
910+
EMU_HANA_WCLOCK_HANA_SPDIF_IN,
911+
EMU_HANA_WCLOCK_SYNC_BNC,
912+
};
913+
914+
struct snd_emu1010_clock_info {
915+
const char * const *texts;
916+
const u8 *vals;
917+
unsigned num;
918+
};
919+
920+
static const struct snd_emu1010_clock_info emu1010_clock_info[] = {
921+
{
922+
// rev1 1010
923+
.texts = emu1010_clock_texts,
924+
.vals = emu1010_clock_vals,
925+
.num = ARRAY_SIZE(emu1010_clock_vals),
926+
},
927+
{
928+
// rev2 1010
929+
.texts = emu1010_clock_texts,
930+
.vals = emu1010_clock_vals,
931+
.num = ARRAY_SIZE(emu1010_clock_vals) - 1,
932+
},
933+
{
934+
// 1616(m) CardBus
935+
.texts = emu1010_clock_texts,
936+
// TODO: determine what is actually available.
937+
// Pedantically, *every* source comes from the 2nd FPGA, as the
938+
// card itself has no own (digital) audio ports. The user manual
939+
// claims that ADAT and S/PDIF clock sources are separate, which
940+
// can mean two things: either E-MU mapped the dock's sources to
941+
// the primary ones, or they determine the meaning of the "Dock"
942+
// source depending on how the ports are actually configured
943+
// (which the 2nd FPGA must be doing anyway).
944+
.vals = emu1010_clock_vals,
945+
.num = ARRAY_SIZE(emu1010_clock_vals),
946+
},
947+
{
948+
// 0404
949+
.texts = emu0404_clock_texts,
950+
.vals = emu0404_clock_vals,
951+
.num = ARRAY_SIZE(emu0404_clock_vals),
952+
},
953+
};
890954

891955
static int snd_emu1010_clock_source_info(struct snd_kcontrol *kcontrol,
892956
struct snd_ctl_elem_info *uinfo)
893957
{
894-
static const char * const texts[4] = {
895-
"44100", "48000", "SPDIF", "ADAT"
896-
};
958+
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
959+
const struct snd_emu1010_clock_info *emu_ci =
960+
&emu1010_clock_info[emu1010_idx(emu)];
897961

898-
return snd_ctl_enum_info(uinfo, 1, 4, texts);
962+
return snd_ctl_enum_info(uinfo, 1, emu_ci->num, emu_ci->texts);
899963
}
900964

901965
static int snd_emu1010_clock_source_get(struct snd_kcontrol *kcontrol,
@@ -911,84 +975,27 @@ static int snd_emu1010_clock_source_put(struct snd_kcontrol *kcontrol,
911975
struct snd_ctl_elem_value *ucontrol)
912976
{
913977
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
978+
const struct snd_emu1010_clock_info *emu_ci =
979+
&emu1010_clock_info[emu1010_idx(emu)];
914980
unsigned int val;
915981
int change = 0;
916982

917983
val = ucontrol->value.enumerated.item[0] ;
918-
/* Limit: uinfo->value.enumerated.items = 4; */
919-
if (val >= 4)
984+
if (val >= emu_ci->num)
920985
return -EINVAL;
921986
change = (emu->emu1010.clock_source != val);
922987
if (change) {
923988
emu->emu1010.clock_source = val;
924-
switch (val) {
925-
case 0:
926-
/* 44100 */
927-
/* Mute all */
928-
snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE );
929-
/* Word Clock source, Internal 44.1kHz x1 */
930-
snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK,
931-
EMU_HANA_WCLOCK_INT_44_1K | EMU_HANA_WCLOCK_1X );
932-
/* Set LEDs on Audio Dock */
933-
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2,
934-
EMU_HANA_DOCK_LEDS_2_44K | EMU_HANA_DOCK_LEDS_2_LOCK );
935-
/* Allow DLL to settle */
936-
msleep(10);
937-
/* Unmute all */
938-
snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE );
939-
break;
940-
case 1:
941-
/* 48000 */
942-
/* Mute all */
943-
snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE );
944-
/* Word Clock source, Internal 48kHz x1 */
945-
snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK,
946-
EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_1X );
947-
/* Set LEDs on Audio Dock */
948-
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2,
949-
EMU_HANA_DOCK_LEDS_2_48K | EMU_HANA_DOCK_LEDS_2_LOCK );
950-
/* Allow DLL to settle */
951-
msleep(10);
952-
/* Unmute all */
953-
snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE );
954-
break;
955-
956-
case 2: /* Take clock from S/PDIF IN */
957-
/* Mute all */
958-
snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE );
959-
/* Word Clock source, sync to S/PDIF input */
960-
snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK,
961-
EMU_HANA_WCLOCK_HANA_SPDIF_IN | EMU_HANA_WCLOCK_1X );
962-
/* Set LEDs on Audio Dock */
963-
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2,
964-
EMU_HANA_DOCK_LEDS_2_EXT | EMU_HANA_DOCK_LEDS_2_LOCK );
965-
/* FIXME: We should set EMU_HANA_DOCK_LEDS_2_LOCK only when clock signal is present and valid */
966-
/* Allow DLL to settle */
967-
msleep(10);
968-
/* Unmute all */
969-
snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE );
970-
break;
971-
972-
case 3:
973-
/* Take clock from ADAT IN */
974-
/* Mute all */
975-
snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE );
976-
/* Word Clock source, sync to ADAT input */
977-
snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK,
978-
EMU_HANA_WCLOCK_HANA_ADAT_IN | EMU_HANA_WCLOCK_1X );
979-
/* Set LEDs on Audio Dock */
980-
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, EMU_HANA_DOCK_LEDS_2_EXT | EMU_HANA_DOCK_LEDS_2_LOCK );
981-
/* FIXME: We should set EMU_HANA_DOCK_LEDS_2_LOCK only when clock signal is present and valid */
982-
/* Allow DLL to settle */
983-
msleep(10);
984-
/* Unmute all */
985-
snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE );
986-
987-
988-
break;
989-
}
989+
emu->emu1010.wclock = emu_ci->vals[val];
990+
991+
snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE);
992+
snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, emu->emu1010.wclock);
993+
msleep(10); // Allow DLL to settle
994+
snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE);
995+
996+
snd_emu1010_update_clock(emu);
990997
}
991-
return change;
998+
return change;
992999
}
9931000

9941001
static const struct snd_kcontrol_new snd_emu1010_clock_source =

sound/pci/emu10k1/io.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,29 @@ u32 snd_emu1010_fpga_link_dst_src_read(struct snd_emu10k1 *emu, u32 dst)
357357
return (hi << 8) | lo;
358358
}
359359

360+
void snd_emu1010_update_clock(struct snd_emu10k1 *emu)
361+
{
362+
u32 leds;
363+
364+
switch (emu->emu1010.wclock) {
365+
case EMU_HANA_WCLOCK_INT_44_1K | EMU_HANA_WCLOCK_1X:
366+
leds = EMU_HANA_DOCK_LEDS_2_44K;
367+
break;
368+
case EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_1X:
369+
leds = EMU_HANA_DOCK_LEDS_2_48K;
370+
break;
371+
default:
372+
leds = EMU_HANA_DOCK_LEDS_2_EXT;
373+
break;
374+
}
375+
376+
// FIXME: this should probably represent the AND of all currently
377+
// used sources' lock status. But we don't know how to get that ...
378+
leds |= EMU_HANA_DOCK_LEDS_2_LOCK;
379+
380+
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, leds);
381+
}
382+
360383
void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
361384
{
362385
unsigned long flags;

0 commit comments

Comments
 (0)