@@ -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
891955static 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
901965static 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
9941001static const struct snd_kcontrol_new snd_emu1010_clock_source =
0 commit comments