^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * ALSA driver for RME Hammerfall DSP MADI audio interface(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2003 Winfried Ritsch (IEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * code based on hdsp.c Paul Davis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Marcus Andersson
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Thomas Charbonnel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Modified 2006-06-01 for AES32 support by Remy Bruno
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * <remy.bruno@trinnov.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Modified 2009-04-13 for proper metering by Florian Faber
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * <faber@faberman.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Modified 2009-04-14 for native float support by Florian Faber
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * <faber@faberman.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Modified 2009-04-26 fixed bug in rms metering by Florian Faber
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * <faber@faberman.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * Modified 2009-04-30 added hw serial number support by Florian Faber
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Modified 2011-01-14 added S/PDIF input on RayDATs by Adrian Knoth
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * Modified 2011-01-25 variable period sizes on RayDAT/AIO by Adrian Knoth
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * Modified 2019-05-23 fix AIO single speed ADAT capture and playback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * by Philippe.Bekaert@uhasselt.be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /* ************* Register Documentation *******************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * Work in progress! Documentation is based on the code in this file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * --------- HDSPM_controlRegister ---------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * :7654.3210:7654.3210:7654.3210:7654.3210: bit number per byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * :||||.||||:||||.||||:||||.||||:||||.||||:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * :3322.2222:2222.1111:1111.1100:0000.0000: bit number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * :1098.7654:3210.9876:5432.1098:7654.3210: 0..31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * :||||.||||:||||.||||:||||.||||:||||.||||:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * :8421.8421:8421.8421:8421.8421:8421.8421: hex digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * : . : . : . : x . : HDSPM_AudioInterruptEnable \_ setting both bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * : . : . : . : . x: HDSPM_Start / enables audio IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * : . : . : . : x. : HDSPM_ClockModeMaster - 1: Master, 0: Slave
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * : . : . : . : .210 : HDSPM_LatencyMask - 3 Bit value for latency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * : . : . : . : . : 0:64, 1:128, 2:256, 3:512,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * : . : . : . : . : 4:1024, 5:2048, 6:4096, 7:8192
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * :x . : . : . x:xx . : HDSPM_FrequencyMask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * : . : . : . :10 . : HDSPM_Frequency1|HDSPM_Frequency0: 1=32K,2=44.1K,3=48K,0=??
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * : . : . : . x: . : <MADI> HDSPM_DoubleSpeed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * :x . : . : . : . : <MADI> HDSPM_QuadSpeed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * : . 3 : . 10: 2 . : . : HDSPM_SyncRefMask :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * : . : . x: . : . : HDSPM_SyncRef0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * : . : . x : . : . : HDSPM_SyncRef1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * : . : . : x . : . : <AES32> HDSPM_SyncRef2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * : . x : . : . : . : <AES32> HDSPM_SyncRef3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * : . : . 10: . : . : <MADI> sync ref: 0:WC, 1:Madi, 2:TCO, 3:SyncIn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * : . 3 : . 10: 2 . : . : <AES32> 0:WC, 1:AES1 ... 8:AES8, 9: TCO, 10:SyncIn?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * : . x : . : . : . : <MADIe> HDSPe_FLOAT_FORMAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * : . : . : x . : . : <MADI> HDSPM_InputSelect0 : 0=optical,1=coax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * : . : . :x . : . : <MADI> HDSPM_InputSelect1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * : . : .x : . : . : <MADI> HDSPM_clr_tms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * : . : . : . x : . : <MADI> HDSPM_TX_64ch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * : . : . : . x : . : <AES32> HDSPM_Emphasis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * : . : . : .x : . : <MADI> HDSPM_AutoInp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * : . : . x : . : . : <MADI> HDSPM_SMUX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * : . : .x : . : . : <MADI> HDSPM_clr_tms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * : . : x. : . : . : <MADI> HDSPM_taxi_reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * : . x: . : . : . : <MADI> HDSPM_LineOut
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * : . x: . : . : . : <AES32> ??????????????????
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * : . : x. : . : . : <AES32> HDSPM_WCK48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * : . : . : .x : . : <AES32> HDSPM_Dolby
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * : . : x . : . : . : HDSPM_Midi0InterruptEnable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * : . :x . : . : . : HDSPM_Midi1InterruptEnable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * : . : x . : . : . : HDSPM_Midi2InterruptEnable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * : . x : . : . : . : <MADI> HDSPM_Midi3InterruptEnable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * : . x : . : . : . : <AES32> HDSPM_DS_DoubleWire
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * : .x : . : . : . : <AES32> HDSPM_QS_DoubleWire
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * : x. : . : . : . : <AES32> HDSPM_QS_QuadWire
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * : . : . : . x : . : <AES32> HDSPM_Professional
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * : x . : . : . : . : HDSPM_wclk_sel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * : . : . : . : . :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * :7654.3210:7654.3210:7654.3210:7654.3210: bit number per byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * :||||.||||:||||.||||:||||.||||:||||.||||:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * :3322.2222:2222.1111:1111.1100:0000.0000: bit number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * :1098.7654:3210.9876:5432.1098:7654.3210: 0..31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * :||||.||||:||||.||||:||||.||||:||||.||||:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * :8421.8421:8421.8421:8421.8421:8421.8421:hex digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * AIO / RayDAT only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * ------------ HDSPM_WR_SETTINGS ----------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * :3322.2222:2222.1111:1111.1100:0000.0000: bit number per byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * :1098.7654:3210.9876:5432.1098:7654.3210:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * :||||.||||:||||.||||:||||.||||:||||.||||: bit number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * :7654.3210:7654.3210:7654.3210:7654.3210: 0..31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * :||||.||||:||||.||||:||||.||||:||||.||||:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * :8421.8421:8421.8421:8421.8421:8421.8421: hex digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * : . : . : . : . x: HDSPM_c0Master 1: Master, 0: Slave
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * : . : . : . : . x : HDSPM_c0_SyncRef0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * : . : . : . : . x : HDSPM_c0_SyncRef1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * : . : . : . : .x : HDSPM_c0_SyncRef2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * : . : . : . : x. : HDSPM_c0_SyncRef3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * : . : . : . : 3.210 : HDSPM_c0_SyncRefMask:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * : . : . : . : . : RayDat: 0:WC, 1:AES, 2:SPDIF, 3..6: ADAT1..4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * : . : . : . : . : 9:TCO, 10:SyncIn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * : . : . : . : . : AIO: 0:WC, 1:AES, 2: SPDIF, 3: ATAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * : . : . : . : . : 9:TCO, 10:SyncIn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * : . : . : . : . :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * : . : . : . : . :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * :3322.2222:2222.1111:1111.1100:0000.0000: bit number per byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * :1098.7654:3210.9876:5432.1098:7654.3210:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * :||||.||||:||||.||||:||||.||||:||||.||||: bit number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * :7654.3210:7654.3210:7654.3210:7654.3210: 0..31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * :||||.||||:||||.||||:||||.||||:||||.||||:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * :8421.8421:8421.8421:8421.8421:8421.8421: hex digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #include <linux/math64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #include <linux/nospec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #include <sound/control.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #include <sound/pcm_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #include <sound/info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #include <sound/asoundef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #include <sound/rawmidi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #include <sound/hwdep.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #include <sound/hdspm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) module_param_array(index, int, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) MODULE_PARM_DESC(index, "Index value for RME HDSPM interface.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) module_param_array(id, charp, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) MODULE_PARM_DESC(id, "ID string for RME HDSPM interface.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) module_param_array(enable, bool, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) MODULE_PARM_DESC(enable, "Enable/disable specific HDSPM soundcards.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) MODULE_AUTHOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) "Winfried Ritsch <ritsch_AT_iem.at>, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) "Paul Davis <paul@linuxaudiosystems.com>, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) "Marcus Andersson, Thomas Charbonnel <thomas@undata.org>, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) "Remy Bruno <remy.bruno@trinnov.com>, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) "Florian Faber <faberman@linuxproaudio.org>, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) "Adrian Knoth <adi@drcomp.erfurt.thur.de>"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) MODULE_DESCRIPTION("RME HDSPM");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* --- Write registers. ---
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) These are defined as byte-offsets from the iobase value. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define HDSPM_WR_SETTINGS 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define HDSPM_outputBufferAddress 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #define HDSPM_inputBufferAddress 36
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define HDSPM_controlRegister 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define HDSPM_interruptConfirmation 96
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #define HDSPM_control2Reg 256 /* not in specs ???????? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define HDSPM_freqReg 256 /* for setting arbitrary clock values (DDS feature) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #define HDSPM_midiDataOut0 352 /* just believe in old code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define HDSPM_midiDataOut1 356
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define HDSPM_eeprom_wr 384 /* for AES32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /* DMA enable for 64 channels, only Bit 0 is relevant */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #define HDSPM_outputEnableBase 512 /* 512-767 input DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) #define HDSPM_inputEnableBase 768 /* 768-1023 output DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* 16 page addresses for each of the 64 channels DMA buffer in and out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) (each 64k=16*4k) Buffer must be 4k aligned (which is default i386 ????) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #define HDSPM_pageAddressBufferOut 8192
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #define HDSPM_pageAddressBufferIn (HDSPM_pageAddressBufferOut+64*16*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) #define HDSPM_MADI_mixerBase 32768 /* 32768-65535 for 2x64x64 Fader */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #define HDSPM_MATRIX_MIXER_SIZE 8192 /* = 2*64*64 * 4 Byte => 32kB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /* --- Read registers. ---
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) These are defined as byte-offsets from the iobase value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #define HDSPM_statusRegister 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /*#define HDSPM_statusRegister2 96 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /* after RME Windows driver sources, status2 is 4-byte word # 48 = word at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * offset 192, for AES32 *and* MADI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * => need to check that offset 192 is working on MADI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #define HDSPM_statusRegister2 192
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #define HDSPM_timecodeRegister 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /* AIO, RayDAT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) #define HDSPM_RD_STATUS_0 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) #define HDSPM_RD_STATUS_1 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) #define HDSPM_RD_STATUS_2 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) #define HDSPM_RD_STATUS_3 192
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) #define HDSPM_RD_TCO 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) #define HDSPM_RD_PLL_FREQ 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) #define HDSPM_WR_TCO 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #define HDSPM_TCO1_TCO_lock 0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) #define HDSPM_TCO1_WCK_Input_Range_LSB 0x00000002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) #define HDSPM_TCO1_WCK_Input_Range_MSB 0x00000004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #define HDSPM_TCO1_LTC_Input_valid 0x00000008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) #define HDSPM_TCO1_WCK_Input_valid 0x00000010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) #define HDSPM_TCO1_Video_Input_Format_NTSC 0x00000020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) #define HDSPM_TCO1_Video_Input_Format_PAL 0x00000040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) #define HDSPM_TCO1_set_TC 0x00000100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) #define HDSPM_TCO1_set_drop_frame_flag 0x00000200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) #define HDSPM_TCO1_LTC_Format_LSB 0x00000400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) #define HDSPM_TCO1_LTC_Format_MSB 0x00000800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) #define HDSPM_TCO2_TC_run 0x00010000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) #define HDSPM_TCO2_WCK_IO_ratio_LSB 0x00020000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) #define HDSPM_TCO2_WCK_IO_ratio_MSB 0x00040000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) #define HDSPM_TCO2_set_num_drop_frames_LSB 0x00080000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) #define HDSPM_TCO2_set_num_drop_frames_MSB 0x00100000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) #define HDSPM_TCO2_set_jam_sync 0x00200000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) #define HDSPM_TCO2_set_flywheel 0x00400000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) #define HDSPM_TCO2_set_01_4 0x01000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) #define HDSPM_TCO2_set_pull_down 0x02000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) #define HDSPM_TCO2_set_pull_up 0x04000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) #define HDSPM_TCO2_set_freq 0x08000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) #define HDSPM_TCO2_set_term_75R 0x10000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) #define HDSPM_TCO2_set_input_LSB 0x20000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) #define HDSPM_TCO2_set_input_MSB 0x40000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) #define HDSPM_TCO2_set_freq_from_app 0x80000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) #define HDSPM_midiDataOut0 352
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) #define HDSPM_midiDataOut1 356
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) #define HDSPM_midiDataOut2 368
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) #define HDSPM_midiDataIn0 360
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) #define HDSPM_midiDataIn1 364
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) #define HDSPM_midiDataIn2 372
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) #define HDSPM_midiDataIn3 376
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /* status is data bytes in MIDI-FIFO (0-128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) #define HDSPM_midiStatusOut0 384
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) #define HDSPM_midiStatusOut1 388
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) #define HDSPM_midiStatusOut2 400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) #define HDSPM_midiStatusIn0 392
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) #define HDSPM_midiStatusIn1 396
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) #define HDSPM_midiStatusIn2 404
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) #define HDSPM_midiStatusIn3 408
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* the meters are regular i/o-mapped registers, but offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) considerably from the rest. the peak registers are reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) when read; the least-significant 4 bits are full-scale counters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) the actual peak value is in the most-significant 24 bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) #define HDSPM_MADI_INPUT_PEAK 4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) #define HDSPM_MADI_PLAYBACK_PEAK 4352
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) #define HDSPM_MADI_OUTPUT_PEAK 4608
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) #define HDSPM_MADI_INPUT_RMS_L 6144
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) #define HDSPM_MADI_PLAYBACK_RMS_L 6400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) #define HDSPM_MADI_OUTPUT_RMS_L 6656
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) #define HDSPM_MADI_INPUT_RMS_H 7168
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) #define HDSPM_MADI_PLAYBACK_RMS_H 7424
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) #define HDSPM_MADI_OUTPUT_RMS_H 7680
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* --- Control Register bits --------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) #define HDSPM_Start (1<<0) /* start engine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) #define HDSPM_Latency0 (1<<1) /* buffer size = 2^n */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) #define HDSPM_Latency1 (1<<2) /* where n is defined */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) #define HDSPM_Latency2 (1<<3) /* by Latency{2,1,0} */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) #define HDSPM_ClockModeMaster (1<<4) /* 1=Master, 0=Autosync */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) #define HDSPM_c0Master 0x1 /* Master clock bit in settings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) register [RayDAT, AIO] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) #define HDSPM_AudioInterruptEnable (1<<5) /* what do you think ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) #define HDSPM_Frequency0 (1<<6) /* 0=44.1kHz/88.2kHz 1=48kHz/96kHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) #define HDSPM_Frequency1 (1<<7) /* 0=32kHz/64kHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) #define HDSPM_DoubleSpeed (1<<8) /* 0=normal speed, 1=double speed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) #define HDSPM_QuadSpeed (1<<31) /* quad speed bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) #define HDSPM_Professional (1<<9) /* Professional */ /* AES32 ONLY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) #define HDSPM_TX_64ch (1<<10) /* Output 64channel MODE=1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 56channelMODE=0 */ /* MADI ONLY*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) #define HDSPM_Emphasis (1<<10) /* Emphasis */ /* AES32 ONLY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) #define HDSPM_AutoInp (1<<11) /* Auto Input (takeover) == Safe Mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 0=off, 1=on */ /* MADI ONLY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) #define HDSPM_Dolby (1<<11) /* Dolby = "NonAudio" ?? */ /* AES32 ONLY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) #define HDSPM_InputSelect0 (1<<14) /* Input select 0= optical, 1=coax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * -- MADI ONLY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) #define HDSPM_InputSelect1 (1<<15) /* should be 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) #define HDSPM_SyncRef2 (1<<13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) #define HDSPM_SyncRef3 (1<<25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) #define HDSPM_SMUX (1<<18) /* Frame ??? */ /* MADI ONY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) #define HDSPM_clr_tms (1<<19) /* clear track marker, do not use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) AES additional bits in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) lower 5 Audiodatabits ??? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) #define HDSPM_taxi_reset (1<<20) /* ??? */ /* MADI ONLY ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) #define HDSPM_WCK48 (1<<20) /* Frame ??? = HDSPM_SMUX */ /* AES32 ONLY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) #define HDSPM_Midi0InterruptEnable 0x0400000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) #define HDSPM_Midi1InterruptEnable 0x0800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) #define HDSPM_Midi2InterruptEnable 0x0200000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) #define HDSPM_Midi3InterruptEnable 0x4000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) #define HDSPM_LineOut (1<<24) /* Analog Out on channel 63/64 on=1, mute=0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) #define HDSPe_FLOAT_FORMAT 0x2000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) #define HDSPM_DS_DoubleWire (1<<26) /* AES32 ONLY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) #define HDSPM_QS_DoubleWire (1<<27) /* AES32 ONLY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) #define HDSPM_QS_QuadWire (1<<28) /* AES32 ONLY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) #define HDSPM_wclk_sel (1<<30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) /* additional control register bits for AIO*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) #define HDSPM_c0_Wck48 0x20 /* also RayDAT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) #define HDSPM_c0_Input0 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) #define HDSPM_c0_Input1 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) #define HDSPM_c0_Spdif_Opt 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) #define HDSPM_c0_Pro 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) #define HDSPM_c0_clr_tms 0x10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) #define HDSPM_c0_AEB1 0x20000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) #define HDSPM_c0_AEB2 0x40000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) #define HDSPM_c0_LineOut 0x80000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) #define HDSPM_c0_AD_GAIN0 0x100000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) #define HDSPM_c0_AD_GAIN1 0x200000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) #define HDSPM_c0_DA_GAIN0 0x400000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) #define HDSPM_c0_DA_GAIN1 0x800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) #define HDSPM_c0_PH_GAIN0 0x1000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) #define HDSPM_c0_PH_GAIN1 0x2000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) #define HDSPM_c0_Sym6db 0x4000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /* --- bit helper defines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) #define HDSPM_LatencyMask (HDSPM_Latency0|HDSPM_Latency1|HDSPM_Latency2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) #define HDSPM_FrequencyMask (HDSPM_Frequency0|HDSPM_Frequency1|\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) HDSPM_DoubleSpeed|HDSPM_QuadSpeed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) #define HDSPM_InputMask (HDSPM_InputSelect0|HDSPM_InputSelect1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) #define HDSPM_InputOptical 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) #define HDSPM_InputCoaxial (HDSPM_InputSelect0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) #define HDSPM_SyncRefMask (HDSPM_SyncRef0|HDSPM_SyncRef1|\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) HDSPM_SyncRef2|HDSPM_SyncRef3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) #define HDSPM_c0_SyncRef0 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) #define HDSPM_c0_SyncRef1 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) #define HDSPM_c0_SyncRef2 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) #define HDSPM_c0_SyncRef3 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) #define HDSPM_c0_SyncRefMask (HDSPM_c0_SyncRef0 | HDSPM_c0_SyncRef1 |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) HDSPM_c0_SyncRef2 | HDSPM_c0_SyncRef3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) #define HDSPM_SYNC_FROM_WORD 0 /* Preferred sync reference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) #define HDSPM_SYNC_FROM_MADI 1 /* choices - used by "pref_sync_ref" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) #define HDSPM_SYNC_FROM_TCO 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) #define HDSPM_SYNC_FROM_SYNC_IN 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) #define HDSPM_Frequency32KHz HDSPM_Frequency0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) #define HDSPM_Frequency44_1KHz HDSPM_Frequency1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) #define HDSPM_Frequency48KHz (HDSPM_Frequency1|HDSPM_Frequency0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) #define HDSPM_Frequency64KHz (HDSPM_DoubleSpeed|HDSPM_Frequency0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) #define HDSPM_Frequency88_2KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) #define HDSPM_Frequency96KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1|\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) HDSPM_Frequency0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) #define HDSPM_Frequency128KHz (HDSPM_QuadSpeed|HDSPM_Frequency0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) #define HDSPM_Frequency176_4KHz (HDSPM_QuadSpeed|HDSPM_Frequency1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) #define HDSPM_Frequency192KHz (HDSPM_QuadSpeed|HDSPM_Frequency1|\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) HDSPM_Frequency0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /* Synccheck Status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) #define HDSPM_SYNC_CHECK_NO_LOCK 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) #define HDSPM_SYNC_CHECK_LOCK 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) #define HDSPM_SYNC_CHECK_SYNC 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) /* AutoSync References - used by "autosync_ref" control switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) #define HDSPM_AUTOSYNC_FROM_WORD 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) #define HDSPM_AUTOSYNC_FROM_MADI 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) #define HDSPM_AUTOSYNC_FROM_TCO 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) #define HDSPM_AUTOSYNC_FROM_SYNC_IN 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) #define HDSPM_AUTOSYNC_FROM_NONE 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) /* Possible sources of MADI input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) #define HDSPM_OPTICAL 0 /* optical */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) #define HDSPM_COAXIAL 1 /* BNC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) #define hdspm_encode_latency(x) (((x)<<1) & HDSPM_LatencyMask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) #define hdspm_decode_latency(x) ((((x) & HDSPM_LatencyMask)>>1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) #define hdspm_encode_in(x) (((x)&0x3)<<14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) #define hdspm_decode_in(x) (((x)>>14)&0x3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) /* --- control2 register bits --- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) #define HDSPM_TMS (1<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) #define HDSPM_TCK (1<<1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) #define HDSPM_TDI (1<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) #define HDSPM_JTAG (1<<3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) #define HDSPM_PWDN (1<<4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) #define HDSPM_PROGRAM (1<<5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) #define HDSPM_CONFIG_MODE_0 (1<<6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) #define HDSPM_CONFIG_MODE_1 (1<<7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /*#define HDSPM_VERSION_BIT (1<<8) not defined any more*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) #define HDSPM_BIGENDIAN_MODE (1<<9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) #define HDSPM_RD_MULTIPLE (1<<10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /* --- Status Register bits --- */ /* MADI ONLY */ /* Bits defined here and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) that do not conflict with specific bits for AES32 seem to be valid also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) for the AES32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) #define HDSPM_audioIRQPending (1<<0) /* IRQ is high and pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) #define HDSPM_RX_64ch (1<<1) /* Input 64chan. MODE=1, 56chn MODE=0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) #define HDSPM_AB_int (1<<2) /* InputChannel Opt=0, Coax=1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * (like inp0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) #define HDSPM_madiLock (1<<3) /* MADI Locked =1, no=0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) #define HDSPM_madiSync (1<<18) /* MADI is in sync */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) #define HDSPM_tcoLockMadi 0x00000020 /* Optional TCO locked status for HDSPe MADI*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) #define HDSPM_tcoSync 0x10000000 /* Optional TCO sync status for HDSPe MADI and AES32!*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) #define HDSPM_syncInLock 0x00010000 /* Sync In lock status for HDSPe MADI! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) #define HDSPM_syncInSync 0x00020000 /* Sync In sync status for HDSPe MADI! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) #define HDSPM_BufferPositionMask 0x000FFC0 /* Bit 6..15 : h/w buffer pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) /* since 64byte accurate, last 6 bits are not used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) #define HDSPM_DoubleSpeedStatus (1<<19) /* (input) card in double speed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) #define HDSPM_madiFreq0 (1<<22) /* system freq 0=error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) #define HDSPM_madiFreq1 (1<<23) /* 1=32, 2=44.1 3=48 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) #define HDSPM_madiFreq2 (1<<24) /* 4=64, 5=88.2 6=96 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) #define HDSPM_madiFreq3 (1<<25) /* 7=128, 8=176.4 9=192 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) #define HDSPM_BufferID (1<<26) /* (Double)Buffer ID toggles with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * Interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) #define HDSPM_tco_detect 0x08000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) #define HDSPM_tcoLockAes 0x20000000 /* Optional TCO locked status for HDSPe AES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) #define HDSPM_s2_tco_detect 0x00000040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) #define HDSPM_s2_AEBO_D 0x00000080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) #define HDSPM_s2_AEBI_D 0x00000100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) #define HDSPM_midi0IRQPending 0x40000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) #define HDSPM_midi1IRQPending 0x80000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) #define HDSPM_midi2IRQPending 0x20000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) #define HDSPM_midi2IRQPendingAES 0x00000020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) #define HDSPM_midi3IRQPending 0x00200000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /* --- status bit helpers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) #define HDSPM_madiFreqMask (HDSPM_madiFreq0|HDSPM_madiFreq1|\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) HDSPM_madiFreq2|HDSPM_madiFreq3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) #define HDSPM_madiFreq32 (HDSPM_madiFreq0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) #define HDSPM_madiFreq44_1 (HDSPM_madiFreq1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) #define HDSPM_madiFreq48 (HDSPM_madiFreq0|HDSPM_madiFreq1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) #define HDSPM_madiFreq64 (HDSPM_madiFreq2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) #define HDSPM_madiFreq88_2 (HDSPM_madiFreq0|HDSPM_madiFreq2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) #define HDSPM_madiFreq96 (HDSPM_madiFreq1|HDSPM_madiFreq2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) #define HDSPM_madiFreq128 (HDSPM_madiFreq0|HDSPM_madiFreq1|HDSPM_madiFreq2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) #define HDSPM_madiFreq176_4 (HDSPM_madiFreq3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) #define HDSPM_madiFreq192 (HDSPM_madiFreq3|HDSPM_madiFreq0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /* Status2 Register bits */ /* MADI ONLY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) #define HDSPM_version0 (1<<0) /* not really defined but I guess */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) #define HDSPM_version1 (1<<1) /* in former cards it was ??? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) #define HDSPM_version2 (1<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) #define HDSPM_wcLock (1<<3) /* Wordclock is detected and locked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) #define HDSPM_wcSync (1<<4) /* Wordclock is in sync with systemclock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) #define HDSPM_wc_freq0 (1<<5) /* input freq detected via autosync */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) #define HDSPM_wc_freq1 (1<<6) /* 001=32, 010==44.1, 011=48, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) #define HDSPM_wc_freq2 (1<<7) /* 100=64, 101=88.2, 110=96, 111=128 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) #define HDSPM_wc_freq3 0x800 /* 1000=176.4, 1001=192 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) #define HDSPM_SyncRef0 0x10000 /* Sync Reference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) #define HDSPM_SyncRef1 0x20000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) #define HDSPM_SelSyncRef0 (1<<8) /* AutoSync Source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) #define HDSPM_SelSyncRef1 (1<<9) /* 000=word, 001=MADI, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) #define HDSPM_SelSyncRef2 (1<<10) /* 111=no valid signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) #define HDSPM_wc_valid (HDSPM_wcLock|HDSPM_wcSync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) #define HDSPM_wcFreqMask (HDSPM_wc_freq0|HDSPM_wc_freq1|HDSPM_wc_freq2|\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) HDSPM_wc_freq3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) #define HDSPM_wcFreq32 (HDSPM_wc_freq0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) #define HDSPM_wcFreq44_1 (HDSPM_wc_freq1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) #define HDSPM_wcFreq48 (HDSPM_wc_freq0|HDSPM_wc_freq1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) #define HDSPM_wcFreq64 (HDSPM_wc_freq2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) #define HDSPM_wcFreq88_2 (HDSPM_wc_freq0|HDSPM_wc_freq2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) #define HDSPM_wcFreq96 (HDSPM_wc_freq1|HDSPM_wc_freq2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) #define HDSPM_wcFreq128 (HDSPM_wc_freq0|HDSPM_wc_freq1|HDSPM_wc_freq2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) #define HDSPM_wcFreq176_4 (HDSPM_wc_freq3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) #define HDSPM_wcFreq192 (HDSPM_wc_freq0|HDSPM_wc_freq3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) #define HDSPM_status1_F_0 0x0400000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) #define HDSPM_status1_F_1 0x0800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) #define HDSPM_status1_F_2 0x1000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) #define HDSPM_status1_F_3 0x2000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) #define HDSPM_status1_freqMask (HDSPM_status1_F_0|HDSPM_status1_F_1|HDSPM_status1_F_2|HDSPM_status1_F_3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) #define HDSPM_SelSyncRefMask (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) HDSPM_SelSyncRef2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) #define HDSPM_SelSyncRef_WORD 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) #define HDSPM_SelSyncRef_MADI (HDSPM_SelSyncRef0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) #define HDSPM_SelSyncRef_TCO (HDSPM_SelSyncRef1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) #define HDSPM_SelSyncRef_SyncIn (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) #define HDSPM_SelSyncRef_NVALID (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) HDSPM_SelSyncRef2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) For AES32, bits for status, status2 and timecode are different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) /* status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) #define HDSPM_AES32_wcLock 0x0200000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) #define HDSPM_AES32_wcSync 0x0100000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) #define HDSPM_AES32_wcFreq_bit 22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /* (status >> HDSPM_AES32_wcFreq_bit) & 0xF gives WC frequency (cf function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) HDSPM_bit2freq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) #define HDSPM_AES32_syncref_bit 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) /* (status >> HDSPM_AES32_syncref_bit) & 0xF gives sync source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) #define HDSPM_AES32_AUTOSYNC_FROM_WORD 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) #define HDSPM_AES32_AUTOSYNC_FROM_AES1 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) #define HDSPM_AES32_AUTOSYNC_FROM_AES2 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) #define HDSPM_AES32_AUTOSYNC_FROM_AES3 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) #define HDSPM_AES32_AUTOSYNC_FROM_AES4 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) #define HDSPM_AES32_AUTOSYNC_FROM_AES5 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) #define HDSPM_AES32_AUTOSYNC_FROM_AES6 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) #define HDSPM_AES32_AUTOSYNC_FROM_AES7 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) #define HDSPM_AES32_AUTOSYNC_FROM_AES8 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) #define HDSPM_AES32_AUTOSYNC_FROM_TCO 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) #define HDSPM_AES32_AUTOSYNC_FROM_SYNC_IN 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) #define HDSPM_AES32_AUTOSYNC_FROM_NONE 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) /* status2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /* HDSPM_LockAES_bit is given by HDSPM_LockAES >> (AES# - 1) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) #define HDSPM_LockAES 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) #define HDSPM_LockAES1 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) #define HDSPM_LockAES2 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) #define HDSPM_LockAES3 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) #define HDSPM_LockAES4 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) #define HDSPM_LockAES5 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) #define HDSPM_LockAES6 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) #define HDSPM_LockAES7 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) #define HDSPM_LockAES8 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) Timecode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) After windows driver sources, bits 4*i to 4*i+3 give the input frequency on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) AES i+1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) bits 3210
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 0001 32kHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 0010 44.1kHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 0011 48kHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 0100 64kHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 0101 88.2kHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 0110 96kHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 0111 128kHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 1000 176.4kHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 1001 192kHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) NB: Timecode register doesn't seem to work on AES32 card revision 230
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) /* Mixer Values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) #define UNITY_GAIN 32768 /* = 65536/2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) #define MINUS_INFINITY_GAIN 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) /* Number of channels for different Speed Modes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) #define MADI_SS_CHANNELS 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) #define MADI_DS_CHANNELS 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) #define MADI_QS_CHANNELS 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) #define RAYDAT_SS_CHANNELS 36
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) #define RAYDAT_DS_CHANNELS 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) #define RAYDAT_QS_CHANNELS 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) #define AIO_IN_SS_CHANNELS 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) #define AIO_IN_DS_CHANNELS 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) #define AIO_IN_QS_CHANNELS 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) #define AIO_OUT_SS_CHANNELS 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) #define AIO_OUT_DS_CHANNELS 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) #define AIO_OUT_QS_CHANNELS 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) #define AES32_CHANNELS 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) /* the size of a substream (1 mono data stream) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) #define HDSPM_CHANNEL_BUFFER_SAMPLES (16*1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) #define HDSPM_CHANNEL_BUFFER_BYTES (4*HDSPM_CHANNEL_BUFFER_SAMPLES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) /* the size of the area we need to allocate for DMA transfers. the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) size is the same regardless of the number of channels, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) also the latency to use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) for one direction !!!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) #define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) #define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) #define HDSPM_RAYDAT_REV 211
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) #define HDSPM_AIO_REV 212
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) #define HDSPM_MADIFACE_REV 213
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) /* speed factor modes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) #define HDSPM_SPEED_SINGLE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) #define HDSPM_SPEED_DOUBLE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) #define HDSPM_SPEED_QUAD 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) /* names for speed modes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) static const char * const hdspm_speed_names[] = { "single", "double", "quad" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) static const char *const texts_autosync_aes_tco[] = { "Word Clock",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) "AES1", "AES2", "AES3", "AES4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) "AES5", "AES6", "AES7", "AES8",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) "TCO", "Sync In"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) static const char *const texts_autosync_aes[] = { "Word Clock",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) "AES1", "AES2", "AES3", "AES4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) "AES5", "AES6", "AES7", "AES8",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) "Sync In"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) static const char *const texts_autosync_madi_tco[] = { "Word Clock",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) "MADI", "TCO", "Sync In" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) static const char *const texts_autosync_madi[] = { "Word Clock",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) "MADI", "Sync In" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) static const char *const texts_autosync_raydat_tco[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) "Word Clock",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) "ADAT 1", "ADAT 2", "ADAT 3", "ADAT 4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) "AES", "SPDIF", "TCO", "Sync In"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) static const char *const texts_autosync_raydat[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) "Word Clock",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) "ADAT 1", "ADAT 2", "ADAT 3", "ADAT 4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) "AES", "SPDIF", "Sync In"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) static const char *const texts_autosync_aio_tco[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) "Word Clock",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) "ADAT", "AES", "SPDIF", "TCO", "Sync In"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) static const char *const texts_autosync_aio[] = { "Word Clock",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) "ADAT", "AES", "SPDIF", "Sync In" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) static const char *const texts_freq[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) "No Lock",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) "32 kHz",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) "44.1 kHz",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) "48 kHz",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) "64 kHz",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) "88.2 kHz",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) "96 kHz",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) "128 kHz",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) "176.4 kHz",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) "192 kHz"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) static const char * const texts_ports_madi[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) "MADI.1", "MADI.2", "MADI.3", "MADI.4", "MADI.5", "MADI.6",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) "MADI.7", "MADI.8", "MADI.9", "MADI.10", "MADI.11", "MADI.12",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) "MADI.13", "MADI.14", "MADI.15", "MADI.16", "MADI.17", "MADI.18",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) "MADI.19", "MADI.20", "MADI.21", "MADI.22", "MADI.23", "MADI.24",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) "MADI.25", "MADI.26", "MADI.27", "MADI.28", "MADI.29", "MADI.30",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) "MADI.31", "MADI.32", "MADI.33", "MADI.34", "MADI.35", "MADI.36",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) "MADI.37", "MADI.38", "MADI.39", "MADI.40", "MADI.41", "MADI.42",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) "MADI.43", "MADI.44", "MADI.45", "MADI.46", "MADI.47", "MADI.48",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) "MADI.49", "MADI.50", "MADI.51", "MADI.52", "MADI.53", "MADI.54",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) "MADI.55", "MADI.56", "MADI.57", "MADI.58", "MADI.59", "MADI.60",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) "MADI.61", "MADI.62", "MADI.63", "MADI.64",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) static const char * const texts_ports_raydat_ss[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) "ADAT1.1", "ADAT1.2", "ADAT1.3", "ADAT1.4", "ADAT1.5", "ADAT1.6",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) "ADAT1.7", "ADAT1.8", "ADAT2.1", "ADAT2.2", "ADAT2.3", "ADAT2.4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) "ADAT2.5", "ADAT2.6", "ADAT2.7", "ADAT2.8", "ADAT3.1", "ADAT3.2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) "ADAT3.3", "ADAT3.4", "ADAT3.5", "ADAT3.6", "ADAT3.7", "ADAT3.8",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) "ADAT4.1", "ADAT4.2", "ADAT4.3", "ADAT4.4", "ADAT4.5", "ADAT4.6",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) "ADAT4.7", "ADAT4.8",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) "AES.L", "AES.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) "SPDIF.L", "SPDIF.R"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static const char * const texts_ports_raydat_ds[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) "ADAT1.1", "ADAT1.2", "ADAT1.3", "ADAT1.4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) "ADAT2.1", "ADAT2.2", "ADAT2.3", "ADAT2.4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) "ADAT3.1", "ADAT3.2", "ADAT3.3", "ADAT3.4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) "ADAT4.1", "ADAT4.2", "ADAT4.3", "ADAT4.4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) "AES.L", "AES.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) "SPDIF.L", "SPDIF.R"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) static const char * const texts_ports_raydat_qs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) "ADAT1.1", "ADAT1.2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) "ADAT2.1", "ADAT2.2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) "ADAT3.1", "ADAT3.2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) "ADAT4.1", "ADAT4.2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) "AES.L", "AES.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) "SPDIF.L", "SPDIF.R"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) static const char * const texts_ports_aio_in_ss[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) "Analogue.L", "Analogue.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) "AES.L", "AES.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) "SPDIF.L", "SPDIF.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", "ADAT.5", "ADAT.6",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) "ADAT.7", "ADAT.8",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) "AEB.1", "AEB.2", "AEB.3", "AEB.4"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) static const char * const texts_ports_aio_out_ss[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) "Analogue.L", "Analogue.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) "AES.L", "AES.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) "SPDIF.L", "SPDIF.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", "ADAT.5", "ADAT.6",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) "ADAT.7", "ADAT.8",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) "Phone.L", "Phone.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) "AEB.1", "AEB.2", "AEB.3", "AEB.4"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) static const char * const texts_ports_aio_in_ds[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) "Analogue.L", "Analogue.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) "AES.L", "AES.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) "SPDIF.L", "SPDIF.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) "AEB.1", "AEB.2", "AEB.3", "AEB.4"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) static const char * const texts_ports_aio_out_ds[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) "Analogue.L", "Analogue.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) "AES.L", "AES.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) "SPDIF.L", "SPDIF.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) "Phone.L", "Phone.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) "AEB.1", "AEB.2", "AEB.3", "AEB.4"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) static const char * const texts_ports_aio_in_qs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) "Analogue.L", "Analogue.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) "AES.L", "AES.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) "SPDIF.L", "SPDIF.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) "AEB.1", "AEB.2", "AEB.3", "AEB.4"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) static const char * const texts_ports_aio_out_qs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) "Analogue.L", "Analogue.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) "AES.L", "AES.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) "SPDIF.L", "SPDIF.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) "Phone.L", "Phone.R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) "AEB.1", "AEB.2", "AEB.3", "AEB.4"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) static const char * const texts_ports_aes32[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) "AES.1", "AES.2", "AES.3", "AES.4", "AES.5", "AES.6", "AES.7",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) "AES.8", "AES.9.", "AES.10", "AES.11", "AES.12", "AES.13", "AES.14",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) "AES.15", "AES.16"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) /* These tables map the ALSA channels 1..N to the channels that we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) need to use in order to find the relevant channel buffer. RME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) refers to this kind of mapping as between "the ADAT channel and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) the DMA channel." We index it using the logical audio channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) and the value is the DMA channel (i.e. channel buffer number)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) where the data for that channel can be read/written from/to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) static const char channel_map_unity_ss[HDSPM_MAX_CHANNELS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 0, 1, 2, 3, 4, 5, 6, 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 8, 9, 10, 11, 12, 13, 14, 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 16, 17, 18, 19, 20, 21, 22, 23,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 24, 25, 26, 27, 28, 29, 30, 31,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 32, 33, 34, 35, 36, 37, 38, 39,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 40, 41, 42, 43, 44, 45, 46, 47,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 48, 49, 50, 51, 52, 53, 54, 55,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 56, 57, 58, 59, 60, 61, 62, 63
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) static const char channel_map_raydat_ss[HDSPM_MAX_CHANNELS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 4, 5, 6, 7, 8, 9, 10, 11, /* ADAT 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 20, 21, 22, 23, 24, 25, 26, 27, /* ADAT 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 28, 29, 30, 31, 32, 33, 34, 35, /* ADAT 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 0, 1, /* AES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 2, 3, /* SPDIF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) static const char channel_map_raydat_ds[HDSPM_MAX_CHANNELS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 4, 5, 6, 7, /* ADAT 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 8, 9, 10, 11, /* ADAT 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 12, 13, 14, 15, /* ADAT 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 16, 17, 18, 19, /* ADAT 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 0, 1, /* AES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 2, 3, /* SPDIF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) static const char channel_map_raydat_qs[HDSPM_MAX_CHANNELS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 4, 5, /* ADAT 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 6, 7, /* ADAT 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 8, 9, /* ADAT 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 10, 11, /* ADAT 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 0, 1, /* AES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 2, 3, /* SPDIF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) static const char channel_map_aio_in_ss[HDSPM_MAX_CHANNELS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) 0, 1, /* line in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 8, 9, /* aes in, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 10, 11, /* spdif in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 2, 3, 4, 5, /* AEB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) static const char channel_map_aio_out_ss[HDSPM_MAX_CHANNELS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 0, 1, /* line out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 8, 9, /* aes out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 10, 11, /* spdif out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) 6, 7, /* phone out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) 2, 3, 4, 5, /* AEB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) static const char channel_map_aio_in_ds[HDSPM_MAX_CHANNELS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) 0, 1, /* line in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) 8, 9, /* aes in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) 10, 11, /* spdif in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) 12, 14, 16, 18, /* adat in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) 2, 3, 4, 5, /* AEB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) -1, -1, -1, -1, -1, -1, -1, -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) static const char channel_map_aio_out_ds[HDSPM_MAX_CHANNELS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) 0, 1, /* line out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) 8, 9, /* aes out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) 10, 11, /* spdif out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) 12, 14, 16, 18, /* adat out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) 6, 7, /* phone out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) 2, 3, 4, 5, /* AEB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) -1, -1, -1, -1, -1, -1, -1, -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) static const char channel_map_aio_in_qs[HDSPM_MAX_CHANNELS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) 0, 1, /* line in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) 8, 9, /* aes in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) 10, 11, /* spdif in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) 12, 16, /* adat in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) 2, 3, 4, 5, /* AEB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) -1, -1, -1, -1, -1, -1, -1, -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) static const char channel_map_aio_out_qs[HDSPM_MAX_CHANNELS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) 0, 1, /* line out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) 8, 9, /* aes out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) 10, 11, /* spdif out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) 12, 16, /* adat out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) 6, 7, /* phone out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) 2, 3, 4, 5, /* AEB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) -1, -1, -1, -1, -1, -1, -1, -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) static const char channel_map_aes32[HDSPM_MAX_CHANNELS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) 0, 1, 2, 3, 4, 5, 6, 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) 8, 9, 10, 11, 12, 13, 14, 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) -1, -1, -1, -1, -1, -1, -1, -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) struct hdspm_midi {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) struct hdspm *hdspm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) struct snd_rawmidi *rmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) struct snd_rawmidi_substream *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) struct snd_rawmidi_substream *output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) char istimer; /* timer in use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) struct timer_list timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) int pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) int dataIn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) int statusIn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) int dataOut;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) int statusOut;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) int ie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) struct hdspm_tco {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) int input; /* 0: LTC, 1:Video, 2: WC*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) int framerate; /* 0=24, 1=25, 2=29.97, 3=29.97d, 4=30, 5=30d */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) int wordclock; /* 0=1:1, 1=44.1->48, 2=48->44.1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) int samplerate; /* 0=44.1, 1=48, 2= freq from app */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) int pull; /* 0=0, 1=+0.1%, 2=-0.1%, 3=+4%, 4=-4%*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) int term; /* 0 = off, 1 = on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) struct hdspm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) /* only one playback and/or capture stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) struct snd_pcm_substream *capture_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) struct snd_pcm_substream *playback_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) char *card_name; /* for procinfo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) unsigned short firmware_rev; /* dont know if relevant (yes if AES32)*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) uint8_t io_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) int monitor_outs; /* set up monitoring outs init flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) u32 control_register; /* cached value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) u32 control2_register; /* cached value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) u32 settings_register; /* cached value for AIO / RayDat (sync reference, master/slave) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) struct hdspm_midi midi[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) struct work_struct midi_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) size_t period_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) unsigned char ss_in_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) unsigned char ds_in_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) unsigned char qs_in_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) unsigned char ss_out_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) unsigned char ds_out_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) unsigned char qs_out_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) unsigned char max_channels_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) unsigned char max_channels_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) const signed char *channel_map_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) const signed char *channel_map_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) const signed char *channel_map_in_ss, *channel_map_in_ds, *channel_map_in_qs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) const signed char *channel_map_out_ss, *channel_map_out_ds, *channel_map_out_qs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) const char * const *port_names_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) const char * const *port_names_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) const char * const *port_names_in_ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) const char * const *port_names_in_ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) const char * const *port_names_in_qs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) const char * const *port_names_out_ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) const char * const *port_names_out_ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) const char * const *port_names_out_qs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) unsigned char *playback_buffer; /* suitably aligned address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) unsigned char *capture_buffer; /* suitably aligned address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) pid_t capture_pid; /* process id which uses capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) pid_t playback_pid; /* process id which uses capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) int running; /* running status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) int last_external_sample_rate; /* samplerate mystic ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) int last_internal_sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) int system_sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) int dev; /* Hardware vars... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) unsigned long port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) void __iomem *iobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) int irq_count; /* for debug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) int midiPorts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) struct snd_card *card; /* one card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) struct snd_pcm *pcm; /* has one pcm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) struct snd_hwdep *hwdep; /* and a hwdep for additional ioctl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) struct pci_dev *pci; /* and an pci info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) /* Mixer vars */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) /* fast alsa mixer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) struct snd_kcontrol *playback_mixer_ctls[HDSPM_MAX_CHANNELS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) /* but input to much, so not used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) struct snd_kcontrol *input_mixer_ctls[HDSPM_MAX_CHANNELS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) /* full mixer accessible over mixer ioctl or hwdep-device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) struct hdspm_mixer *mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) struct hdspm_tco *tco; /* NULL if no TCO detected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) const char *const *texts_autosync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) int texts_autosync_items;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) cycles_t last_interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) unsigned int serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) struct hdspm_peak_rms peak_rms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) static const struct pci_device_id snd_hdspm_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) .vendor = PCI_VENDOR_ID_XILINX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) .device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) .subvendor = PCI_ANY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) .subdevice = PCI_ANY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) .class = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) .class_mask = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) .driver_data = 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) {0,}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) MODULE_DEVICE_TABLE(pci, snd_hdspm_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) /* prototypes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) static int snd_hdspm_create_alsa_devices(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) struct hdspm *hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) static int snd_hdspm_create_pcm(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) struct hdspm *hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) static inline void snd_hdspm_initialize_midi_flush(struct hdspm *hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) static inline int hdspm_get_pll_freq(struct hdspm *hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) static int hdspm_update_simple_mixer_controls(struct hdspm *hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) static int hdspm_autosync_ref(struct hdspm *hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) static int hdspm_set_toggle_setting(struct hdspm *hdspm, u32 regmask, int out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) static int snd_hdspm_set_defaults(struct hdspm *hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) static int hdspm_system_clock_mode(struct hdspm *hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) static void hdspm_set_channel_dma_addr(struct hdspm *hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) unsigned int reg, int channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) static int hdspm_aes_sync_check(struct hdspm *hdspm, int idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) static int hdspm_wc_sync_check(struct hdspm *hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) static int hdspm_tco_sync_check(struct hdspm *hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) static int hdspm_sync_in_sync_check(struct hdspm *hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) static int hdspm_get_aes_sample_rate(struct hdspm *hdspm, int index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) static int hdspm_get_tco_sample_rate(struct hdspm *hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) static int hdspm_get_wc_sample_rate(struct hdspm *hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) static inline int HDSPM_bit2freq(int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) static const int bit2freq_tab[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 0, 32000, 44100, 48000, 64000, 88200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 96000, 128000, 176400, 192000 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (n < 1 || n > 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) return bit2freq_tab[n];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) static bool hdspm_is_raydat_or_aio(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) return ((AIO == hdspm->io_type) || (RayDAT == hdspm->io_type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) /* Write/read to/from HDSPM with Adresses in Bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) not words but only 32Bit writes are allowed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) static inline void hdspm_write(struct hdspm * hdspm, unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) unsigned int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) writel(val, hdspm->iobase + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) static inline unsigned int hdspm_read(struct hdspm * hdspm, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) return readl(hdspm->iobase + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) /* for each output channel (chan) I have an Input (in) and Playback (pb) Fader
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) mixer is write only on hardware so we have to cache him for read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) each fader is a u32, but uses only the first 16 bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) static inline int hdspm_read_in_gain(struct hdspm * hdspm, unsigned int chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) unsigned int in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) if (chan >= HDSPM_MIXER_CHANNELS || in >= HDSPM_MIXER_CHANNELS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) return hdspm->mixer->ch[chan].in[in];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) static inline int hdspm_read_pb_gain(struct hdspm * hdspm, unsigned int chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) unsigned int pb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) if (chan >= HDSPM_MIXER_CHANNELS || pb >= HDSPM_MIXER_CHANNELS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) return hdspm->mixer->ch[chan].pb[pb];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) static int hdspm_write_in_gain(struct hdspm *hdspm, unsigned int chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) unsigned int in, unsigned short data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) if (chan >= HDSPM_MIXER_CHANNELS || in >= HDSPM_MIXER_CHANNELS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) hdspm_write(hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) HDSPM_MADI_mixerBase +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) ((in + 128 * chan) * sizeof(u32)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) (hdspm->mixer->ch[chan].in[in] = data & 0xFFFF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) static int hdspm_write_pb_gain(struct hdspm *hdspm, unsigned int chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) unsigned int pb, unsigned short data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) if (chan >= HDSPM_MIXER_CHANNELS || pb >= HDSPM_MIXER_CHANNELS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) hdspm_write(hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) HDSPM_MADI_mixerBase +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) ((64 + pb + 128 * chan) * sizeof(u32)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) (hdspm->mixer->ch[chan].pb[pb] = data & 0xFFFF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) /* enable DMA for specific channels, now available for DSP-MADI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) static inline void snd_hdspm_enable_in(struct hdspm * hdspm, int i, int v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) hdspm_write(hdspm, HDSPM_inputEnableBase + (4 * i), v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) static inline void snd_hdspm_enable_out(struct hdspm * hdspm, int i, int v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) hdspm_write(hdspm, HDSPM_outputEnableBase + (4 * i), v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) /* check if same process is writing and reading */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) static int snd_hdspm_use_is_exclusive(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) int ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) spin_lock_irqsave(&hdspm->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) if ((hdspm->playback_pid != hdspm->capture_pid) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) (hdspm->playback_pid >= 0) && (hdspm->capture_pid >= 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) spin_unlock_irqrestore(&hdspm->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) /* round arbitrary sample rates to commonly known rates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) static int hdspm_round_frequency(int rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) if (rate < 38050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) return 32000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) if (rate < 46008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) return 44100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) return 48000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) /* QS and DS rates normally can not be detected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) * automatically by the card. Only exception is MADI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) * in 96k frame mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) * So if we read SS values (32 .. 48k), check for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) * user-provided DS/QS bits in the control register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) * and multiply the base frequency accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) static int hdspm_rate_multiplier(struct hdspm *hdspm, int rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) if (rate <= 48000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) if (hdspm->control_register & HDSPM_QuadSpeed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) return rate * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) else if (hdspm->control_register &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) HDSPM_DoubleSpeed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) return rate * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) return rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) /* check for external sample rate, returns the sample rate in Hz*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) static int hdspm_external_sample_rate(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) unsigned int status, status2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) int syncref, rate = 0, rate_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) case AES32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) status = hdspm_read(hdspm, HDSPM_statusRegister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) syncref = hdspm_autosync_ref(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) switch (syncref) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) case HDSPM_AES32_AUTOSYNC_FROM_WORD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) /* Check WC sync and get sample rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) if (hdspm_wc_sync_check(hdspm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) return HDSPM_bit2freq(hdspm_get_wc_sample_rate(hdspm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) case HDSPM_AES32_AUTOSYNC_FROM_AES1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) case HDSPM_AES32_AUTOSYNC_FROM_AES2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) case HDSPM_AES32_AUTOSYNC_FROM_AES3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) case HDSPM_AES32_AUTOSYNC_FROM_AES4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) case HDSPM_AES32_AUTOSYNC_FROM_AES5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) case HDSPM_AES32_AUTOSYNC_FROM_AES6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) case HDSPM_AES32_AUTOSYNC_FROM_AES7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) case HDSPM_AES32_AUTOSYNC_FROM_AES8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) /* Check AES sync and get sample rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) if (hdspm_aes_sync_check(hdspm, syncref - HDSPM_AES32_AUTOSYNC_FROM_AES1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) return HDSPM_bit2freq(hdspm_get_aes_sample_rate(hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) syncref - HDSPM_AES32_AUTOSYNC_FROM_AES1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) case HDSPM_AES32_AUTOSYNC_FROM_TCO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) /* Check TCO sync and get sample rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (hdspm_tco_sync_check(hdspm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) return HDSPM_bit2freq(hdspm_get_tco_sample_rate(hdspm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) } /* end switch(syncref) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) case MADIface:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) status = hdspm_read(hdspm, HDSPM_statusRegister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) if (!(status & HDSPM_madiLock)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) rate = 0; /* no lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) switch (status & (HDSPM_status1_freqMask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) case HDSPM_status1_F_0*1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) rate = 32000; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) case HDSPM_status1_F_0*2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) rate = 44100; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) case HDSPM_status1_F_0*3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) rate = 48000; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) case HDSPM_status1_F_0*4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) rate = 64000; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) case HDSPM_status1_F_0*5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) rate = 88200; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) case HDSPM_status1_F_0*6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) rate = 96000; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) case HDSPM_status1_F_0*7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) rate = 128000; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) case HDSPM_status1_F_0*8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) rate = 176400; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) case HDSPM_status1_F_0*9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) rate = 192000; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) rate = 0; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) case MADI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) status = hdspm_read(hdspm, HDSPM_statusRegister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) /* if wordclock has synced freq and wordclock is valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) if ((status2 & HDSPM_wcLock) != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) (status2 & HDSPM_SelSyncRef0) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) rate_bits = status2 & HDSPM_wcFreqMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) switch (rate_bits) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) case HDSPM_wcFreq32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) rate = 32000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) case HDSPM_wcFreq44_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) rate = 44100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) case HDSPM_wcFreq48:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) rate = 48000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) case HDSPM_wcFreq64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) rate = 64000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) case HDSPM_wcFreq88_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) rate = 88200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) case HDSPM_wcFreq96:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) rate = 96000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) case HDSPM_wcFreq128:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) rate = 128000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) case HDSPM_wcFreq176_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) rate = 176400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) case HDSPM_wcFreq192:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) rate = 192000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) /* if rate detected and Syncref is Word than have it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) * word has priority to MADI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) if (rate != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) (status2 & HDSPM_SelSyncRefMask) == HDSPM_SelSyncRef_WORD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) return hdspm_rate_multiplier(hdspm, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) /* maybe a madi input (which is taken if sel sync is madi) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) if (status & HDSPM_madiLock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) rate_bits = status & HDSPM_madiFreqMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) switch (rate_bits) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) case HDSPM_madiFreq32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) rate = 32000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) case HDSPM_madiFreq44_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) rate = 44100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) case HDSPM_madiFreq48:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) rate = 48000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) case HDSPM_madiFreq64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) rate = 64000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) case HDSPM_madiFreq88_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) rate = 88200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) case HDSPM_madiFreq96:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) rate = 96000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) case HDSPM_madiFreq128:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) rate = 128000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) case HDSPM_madiFreq176_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) rate = 176400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) case HDSPM_madiFreq192:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) rate = 192000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) } /* endif HDSPM_madiLock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) /* check sample rate from TCO or SYNC_IN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) bool is_valid_input = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) bool has_sync = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) syncref = hdspm_autosync_ref(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) if (HDSPM_AUTOSYNC_FROM_TCO == syncref) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) is_valid_input = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) has_sync = (HDSPM_SYNC_CHECK_SYNC ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) hdspm_tco_sync_check(hdspm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) } else if (HDSPM_AUTOSYNC_FROM_SYNC_IN == syncref) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) is_valid_input = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) has_sync = (HDSPM_SYNC_CHECK_SYNC ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) hdspm_sync_in_sync_check(hdspm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) if (is_valid_input && has_sync) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) rate = hdspm_round_frequency(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) hdspm_get_pll_freq(hdspm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) rate = hdspm_rate_multiplier(hdspm, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) return rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) /* return latency in samples per period */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) static int hdspm_get_latency(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) n = hdspm_decode_latency(hdspm->control_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) /* Special case for new RME cards with 32 samples period size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) * The three latency bits in the control register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) * (HDSP_LatencyMask) encode latency values of 64 samples as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) * 0, 128 samples as 1 ... 4096 samples as 6. For old cards, 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) * denotes 8192 samples, but on new cards like RayDAT or AIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) * it corresponds to 32 samples.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) if ((7 == n) && (RayDAT == hdspm->io_type || AIO == hdspm->io_type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) n = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) return 1 << (n + 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) /* Latency function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) static inline void hdspm_compute_period_size(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) hdspm->period_bytes = 4 * hdspm_get_latency(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) static snd_pcm_uframes_t hdspm_hw_pointer(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) int position;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) position = hdspm_read(hdspm, HDSPM_statusRegister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) position &= HDSPM_BufferPositionMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) position /= 4; /* Bytes per sample */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) position = (position & HDSPM_BufferID) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) (hdspm->period_bytes / 4) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) return position;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) static inline void hdspm_start_audio(struct hdspm * s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) s->control_register |= (HDSPM_AudioInterruptEnable | HDSPM_Start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) hdspm_write(s, HDSPM_controlRegister, s->control_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) static inline void hdspm_stop_audio(struct hdspm * s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) s->control_register &= ~(HDSPM_Start | HDSPM_AudioInterruptEnable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) hdspm_write(s, HDSPM_controlRegister, s->control_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) /* should I silence all or only opened ones ? doit all for first even is 4MB*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) static void hdspm_silence_playback(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) int n = hdspm->period_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) void *buf = hdspm->playback_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) for (i = 0; i < HDSPM_MAX_CHANNELS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) memset(buf, 0, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) buf += HDSPM_CHANNEL_BUFFER_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) static int hdspm_set_interrupt_interval(struct hdspm *s, unsigned int frames)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) spin_lock_irq(&s->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) if (32 == frames) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) /* Special case for new RME cards like RayDAT/AIO which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) * support period sizes of 32 samples. Since latency is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) * encoded in the three bits of HDSP_LatencyMask, we can only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) * have values from 0 .. 7. While 0 still means 64 samples and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) * 6 represents 4096 samples on all cards, 7 represents 8192
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) * on older cards and 32 samples on new cards.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) * In other words, period size in samples is calculated by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) * 2^(n+6) with n ranging from 0 .. 7.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) n = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) frames >>= 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) while (frames) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) frames >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) s->control_register &= ~HDSPM_LatencyMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) s->control_register |= hdspm_encode_latency(n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) hdspm_write(s, HDSPM_controlRegister, s->control_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) hdspm_compute_period_size(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) spin_unlock_irq(&s->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) static u64 hdspm_calc_dds_value(struct hdspm *hdspm, u64 period)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) u64 freq_const;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) if (period == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) case MADI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) case AES32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) freq_const = 110069313433624ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) freq_const = 104857600000000ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) case MADIface:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) freq_const = 131072000000000ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) snd_BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) return div_u64(freq_const, period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) static void hdspm_set_dds_value(struct hdspm *hdspm, int rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) u64 n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) if (snd_BUG_ON(rate <= 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) if (rate >= 112000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) rate /= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) else if (rate >= 56000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) rate /= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) case MADIface:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) n = 131072000000000ULL; /* 125 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) case MADI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) case AES32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) n = 110069313433624ULL; /* 105 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) n = 104857600000000ULL; /* 100 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) snd_BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) n = div_u64(n, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) /* n should be less than 2^32 for being written to FREQ register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) snd_BUG_ON(n >> 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) hdspm_write(hdspm, HDSPM_freqReg, (u32)n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) /* dummy set rate lets see what happens */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) int current_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) int rate_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) int not_set = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) int current_speed, target_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) /* ASSUMPTION: hdspm->lock is either set, or there is no need for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) it (e.g. during module initialization).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) if (!(hdspm->control_register & HDSPM_ClockModeMaster)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) /* SLAVE --- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) if (called_internally) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) /* request from ctl or card initialization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) just make a warning an remember setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) for future master mode switching */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) dev_warn(hdspm->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) "Warning: device is not running as a clock master.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) not_set = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) /* hw_param request while in AutoSync mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) int external_freq =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) hdspm_external_sample_rate(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) if (hdspm_autosync_ref(hdspm) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) HDSPM_AUTOSYNC_FROM_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) dev_warn(hdspm->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) "Detected no External Sync\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) not_set = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) } else if (rate != external_freq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) dev_warn(hdspm->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) "Warning: No AutoSync source for requested rate\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) not_set = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) current_rate = hdspm->system_sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) /* Changing between Singe, Double and Quad speed is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) allowed if any substreams are open. This is because such a change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) causes a shift in the location of the DMA buffers and a reduction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) in the number of available buffers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) Note that a similar but essentially insoluble problem exists for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) externally-driven rate changes. All we can do is to flag rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) changes in the read/write routines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) if (current_rate <= 48000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) current_speed = HDSPM_SPEED_SINGLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) else if (current_rate <= 96000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) current_speed = HDSPM_SPEED_DOUBLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) current_speed = HDSPM_SPEED_QUAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) if (rate <= 48000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) target_speed = HDSPM_SPEED_SINGLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) else if (rate <= 96000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) target_speed = HDSPM_SPEED_DOUBLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) target_speed = HDSPM_SPEED_QUAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) switch (rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) case 32000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) rate_bits = HDSPM_Frequency32KHz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) case 44100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) rate_bits = HDSPM_Frequency44_1KHz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) case 48000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) rate_bits = HDSPM_Frequency48KHz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) case 64000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) rate_bits = HDSPM_Frequency64KHz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) case 88200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) rate_bits = HDSPM_Frequency88_2KHz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) case 96000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) rate_bits = HDSPM_Frequency96KHz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) case 128000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) rate_bits = HDSPM_Frequency128KHz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) case 176400:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) rate_bits = HDSPM_Frequency176_4KHz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) case 192000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) rate_bits = HDSPM_Frequency192KHz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) if (current_speed != target_speed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) && (hdspm->capture_pid >= 0 || hdspm->playback_pid >= 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) dev_err(hdspm->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) "cannot change from %s speed to %s speed mode (capture PID = %d, playback PID = %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) hdspm_speed_names[current_speed],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) hdspm_speed_names[target_speed],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) hdspm->capture_pid, hdspm->playback_pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) hdspm->control_register &= ~HDSPM_FrequencyMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) hdspm->control_register |= rate_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) /* For AES32, need to set DDS value in FREQ register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) For MADI, also apparently */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) hdspm_set_dds_value(hdspm, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) if (AES32 == hdspm->io_type && rate != current_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) hdspm_write(hdspm, HDSPM_eeprom_wr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) hdspm->system_sample_rate = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) if (rate <= 48000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) hdspm->channel_map_in = hdspm->channel_map_in_ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) hdspm->channel_map_out = hdspm->channel_map_out_ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) hdspm->max_channels_in = hdspm->ss_in_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) hdspm->max_channels_out = hdspm->ss_out_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) hdspm->port_names_in = hdspm->port_names_in_ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) hdspm->port_names_out = hdspm->port_names_out_ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) } else if (rate <= 96000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) hdspm->channel_map_in = hdspm->channel_map_in_ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) hdspm->channel_map_out = hdspm->channel_map_out_ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) hdspm->max_channels_in = hdspm->ds_in_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) hdspm->max_channels_out = hdspm->ds_out_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) hdspm->port_names_in = hdspm->port_names_in_ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) hdspm->port_names_out = hdspm->port_names_out_ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) hdspm->channel_map_in = hdspm->channel_map_in_qs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) hdspm->channel_map_out = hdspm->channel_map_out_qs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) hdspm->max_channels_in = hdspm->qs_in_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) hdspm->max_channels_out = hdspm->qs_out_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) hdspm->port_names_in = hdspm->port_names_in_qs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) hdspm->port_names_out = hdspm->port_names_out_qs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) if (not_set != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) /* mainly for init to 0 on load */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) static void all_in_all_mixer(struct hdspm * hdspm, int sgain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) unsigned int gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) if (sgain > UNITY_GAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) gain = UNITY_GAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) else if (sgain < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) gain = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) gain = sgain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) for (i = 0; i < HDSPM_MIXER_CHANNELS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) for (j = 0; j < HDSPM_MIXER_CHANNELS; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) hdspm_write_in_gain(hdspm, i, j, gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) hdspm_write_pb_gain(hdspm, i, j, gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) /*----------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) MIDI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) ----------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) static inline unsigned char snd_hdspm_midi_read_byte (struct hdspm *hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) /* the hardware already does the relevant bit-mask with 0xff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) return hdspm_read(hdspm, hdspm->midi[id].dataIn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) static inline void snd_hdspm_midi_write_byte (struct hdspm *hdspm, int id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) /* the hardware already does the relevant bit-mask with 0xff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) return hdspm_write(hdspm, hdspm->midi[id].dataOut, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) static inline int snd_hdspm_midi_input_available (struct hdspm *hdspm, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) return hdspm_read(hdspm, hdspm->midi[id].statusIn) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) static inline int snd_hdspm_midi_output_possible (struct hdspm *hdspm, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) int fifo_bytes_used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) fifo_bytes_used = hdspm_read(hdspm, hdspm->midi[id].statusOut) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) if (fifo_bytes_used < 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) return 128 - fifo_bytes_used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) static void snd_hdspm_flush_midi_input(struct hdspm *hdspm, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) while (snd_hdspm_midi_input_available (hdspm, id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) snd_hdspm_midi_read_byte (hdspm, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) static int snd_hdspm_midi_output_write (struct hdspm_midi *hmidi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) int n_pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) int to_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) unsigned char buf[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) /* Output is not interrupt driven */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) spin_lock_irqsave (&hmidi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) if (hmidi->output &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) !snd_rawmidi_transmit_empty (hmidi->output)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) n_pending = snd_hdspm_midi_output_possible (hmidi->hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) hmidi->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) if (n_pending > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) if (n_pending > (int)sizeof (buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) n_pending = sizeof (buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) to_write = snd_rawmidi_transmit (hmidi->output, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) n_pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) if (to_write > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) for (i = 0; i < to_write; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) snd_hdspm_midi_write_byte (hmidi->hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) hmidi->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) buf[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) spin_unlock_irqrestore (&hmidi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) static int snd_hdspm_midi_input_read (struct hdspm_midi *hmidi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) unsigned char buf[128]; /* this buffer is designed to match the MIDI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) * input FIFO size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) int n_pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) spin_lock_irqsave (&hmidi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) n_pending = snd_hdspm_midi_input_available (hmidi->hdspm, hmidi->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) if (n_pending > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) if (hmidi->input) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) if (n_pending > (int)sizeof (buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) n_pending = sizeof (buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) for (i = 0; i < n_pending; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) buf[i] = snd_hdspm_midi_read_byte (hmidi->hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) hmidi->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) if (n_pending)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) snd_rawmidi_receive (hmidi->input, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) n_pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) /* flush the MIDI input FIFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) while (n_pending--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) snd_hdspm_midi_read_byte (hmidi->hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) hmidi->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) hmidi->pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) spin_unlock_irqrestore(&hmidi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) spin_lock_irqsave(&hmidi->hdspm->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) hmidi->hdspm->control_register |= hmidi->ie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) hdspm_write(hmidi->hdspm, HDSPM_controlRegister,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) hmidi->hdspm->control_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) spin_unlock_irqrestore(&hmidi->hdspm->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) return snd_hdspm_midi_output_write (hmidi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) snd_hdspm_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) struct hdspm *hdspm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) struct hdspm_midi *hmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) hmidi = substream->rmidi->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) hdspm = hmidi->hdspm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) spin_lock_irqsave (&hdspm->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) if (up) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) if (!(hdspm->control_register & hmidi->ie)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) snd_hdspm_flush_midi_input (hdspm, hmidi->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) hdspm->control_register |= hmidi->ie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) hdspm->control_register &= ~hmidi->ie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) spin_unlock_irqrestore (&hdspm->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) static void snd_hdspm_midi_output_timer(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) struct hdspm_midi *hmidi = from_timer(hmidi, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) snd_hdspm_midi_output_write(hmidi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) spin_lock_irqsave (&hmidi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) /* this does not bump hmidi->istimer, because the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) kernel automatically removed the timer when it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) expired, and we are now adding it back, thus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) leaving istimer wherever it was set before.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) if (hmidi->istimer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) mod_timer(&hmidi->timer, 1 + jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) spin_unlock_irqrestore (&hmidi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) snd_hdspm_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) struct hdspm_midi *hmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) hmidi = substream->rmidi->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) spin_lock_irqsave (&hmidi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) if (up) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) if (!hmidi->istimer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) timer_setup(&hmidi->timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) snd_hdspm_midi_output_timer, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) mod_timer(&hmidi->timer, 1 + jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) hmidi->istimer++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) if (hmidi->istimer && --hmidi->istimer <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) del_timer (&hmidi->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) spin_unlock_irqrestore (&hmidi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) if (up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) snd_hdspm_midi_output_write(hmidi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) static int snd_hdspm_midi_input_open(struct snd_rawmidi_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) struct hdspm_midi *hmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) hmidi = substream->rmidi->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) spin_lock_irq (&hmidi->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) snd_hdspm_flush_midi_input (hmidi->hdspm, hmidi->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) hmidi->input = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) spin_unlock_irq (&hmidi->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) static int snd_hdspm_midi_output_open(struct snd_rawmidi_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) struct hdspm_midi *hmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) hmidi = substream->rmidi->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) spin_lock_irq (&hmidi->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) hmidi->output = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) spin_unlock_irq (&hmidi->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) static int snd_hdspm_midi_input_close(struct snd_rawmidi_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) struct hdspm_midi *hmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) snd_hdspm_midi_input_trigger (substream, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) hmidi = substream->rmidi->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) spin_lock_irq (&hmidi->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) hmidi->input = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) spin_unlock_irq (&hmidi->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) static int snd_hdspm_midi_output_close(struct snd_rawmidi_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) struct hdspm_midi *hmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) snd_hdspm_midi_output_trigger (substream, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) hmidi = substream->rmidi->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) spin_lock_irq (&hmidi->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) hmidi->output = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) spin_unlock_irq (&hmidi->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) static const struct snd_rawmidi_ops snd_hdspm_midi_output =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) .open = snd_hdspm_midi_output_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) .close = snd_hdspm_midi_output_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) .trigger = snd_hdspm_midi_output_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) static const struct snd_rawmidi_ops snd_hdspm_midi_input =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) .open = snd_hdspm_midi_input_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) .close = snd_hdspm_midi_input_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) .trigger = snd_hdspm_midi_input_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) static int snd_hdspm_create_midi(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) struct hdspm *hdspm, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) char buf[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) hdspm->midi[id].id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) hdspm->midi[id].hdspm = hdspm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) spin_lock_init (&hdspm->midi[id].lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) if (0 == id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) if (MADIface == hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) /* MIDI-over-MADI on HDSPe MADIface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) hdspm->midi[0].dataIn = HDSPM_midiDataIn2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) hdspm->midi[0].statusIn = HDSPM_midiStatusIn2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) hdspm->midi[0].dataOut = HDSPM_midiDataOut2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) hdspm->midi[0].statusOut = HDSPM_midiStatusOut2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) hdspm->midi[0].ie = HDSPM_Midi2InterruptEnable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) hdspm->midi[0].irq = HDSPM_midi2IRQPending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) hdspm->midi[0].dataIn = HDSPM_midiDataIn0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) hdspm->midi[0].statusIn = HDSPM_midiStatusIn0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) hdspm->midi[0].dataOut = HDSPM_midiDataOut0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) hdspm->midi[0].statusOut = HDSPM_midiStatusOut0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) hdspm->midi[0].ie = HDSPM_Midi0InterruptEnable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) hdspm->midi[0].irq = HDSPM_midi0IRQPending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) } else if (1 == id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) hdspm->midi[1].dataIn = HDSPM_midiDataIn1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) hdspm->midi[1].statusIn = HDSPM_midiStatusIn1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) hdspm->midi[1].dataOut = HDSPM_midiDataOut1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) hdspm->midi[1].statusOut = HDSPM_midiStatusOut1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) hdspm->midi[1].ie = HDSPM_Midi1InterruptEnable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) hdspm->midi[1].irq = HDSPM_midi1IRQPending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) } else if ((2 == id) && (MADI == hdspm->io_type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) /* MIDI-over-MADI on HDSPe MADI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) hdspm->midi[2].dataIn = HDSPM_midiDataIn2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) hdspm->midi[2].statusIn = HDSPM_midiStatusIn2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) hdspm->midi[2].dataOut = HDSPM_midiDataOut2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) hdspm->midi[2].statusOut = HDSPM_midiStatusOut2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) hdspm->midi[2].ie = HDSPM_Midi2InterruptEnable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) hdspm->midi[2].irq = HDSPM_midi2IRQPending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) } else if (2 == id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) /* TCO MTC, read only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) hdspm->midi[2].dataIn = HDSPM_midiDataIn2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) hdspm->midi[2].statusIn = HDSPM_midiStatusIn2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) hdspm->midi[2].dataOut = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) hdspm->midi[2].statusOut = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) hdspm->midi[2].ie = HDSPM_Midi2InterruptEnable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) hdspm->midi[2].irq = HDSPM_midi2IRQPendingAES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) } else if (3 == id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) /* TCO MTC on HDSPe MADI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) hdspm->midi[3].dataIn = HDSPM_midiDataIn3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) hdspm->midi[3].statusIn = HDSPM_midiStatusIn3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) hdspm->midi[3].dataOut = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) hdspm->midi[3].statusOut = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) hdspm->midi[3].ie = HDSPM_Midi3InterruptEnable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) hdspm->midi[3].irq = HDSPM_midi3IRQPending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) if ((id < 2) || ((2 == id) && ((MADI == hdspm->io_type) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) (MADIface == hdspm->io_type)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) if ((id == 0) && (MADIface == hdspm->io_type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) snprintf(buf, sizeof(buf), "%s MIDIoverMADI",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) card->shortname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) } else if ((id == 2) && (MADI == hdspm->io_type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) snprintf(buf, sizeof(buf), "%s MIDIoverMADI",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) card->shortname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) snprintf(buf, sizeof(buf), "%s MIDI %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) card->shortname, id+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) err = snd_rawmidi_new(card, buf, id, 1, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) &hdspm->midi[id].rmidi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) snprintf(hdspm->midi[id].rmidi->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) sizeof(hdspm->midi[id].rmidi->name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) "%s MIDI %d", card->id, id+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) hdspm->midi[id].rmidi->private_data = &hdspm->midi[id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) snd_rawmidi_set_ops(hdspm->midi[id].rmidi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) SNDRV_RAWMIDI_STREAM_OUTPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) &snd_hdspm_midi_output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) snd_rawmidi_set_ops(hdspm->midi[id].rmidi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) SNDRV_RAWMIDI_STREAM_INPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) &snd_hdspm_midi_input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) hdspm->midi[id].rmidi->info_flags |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) SNDRV_RAWMIDI_INFO_OUTPUT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) SNDRV_RAWMIDI_INFO_INPUT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) SNDRV_RAWMIDI_INFO_DUPLEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) /* TCO MTC, read only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) snprintf(buf, sizeof(buf), "%s MTC %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) card->shortname, id+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) err = snd_rawmidi_new(card, buf, id, 1, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) &hdspm->midi[id].rmidi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) snprintf(hdspm->midi[id].rmidi->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) sizeof(hdspm->midi[id].rmidi->name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) "%s MTC %d", card->id, id+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) hdspm->midi[id].rmidi->private_data = &hdspm->midi[id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) snd_rawmidi_set_ops(hdspm->midi[id].rmidi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) SNDRV_RAWMIDI_STREAM_INPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) &snd_hdspm_midi_input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) hdspm->midi[id].rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) static void hdspm_midi_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) struct hdspm *hdspm = container_of(work, struct hdspm, midi_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) while (i < hdspm->midiPorts) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) if (hdspm->midi[i].pending)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) snd_hdspm_midi_input_read(&hdspm->midi[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) /*-----------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) Status Interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) ----------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) /* get the system sample rate which is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) static inline int hdspm_get_pll_freq(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) unsigned int period, rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) period = hdspm_read(hdspm, HDSPM_RD_PLL_FREQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) rate = hdspm_calc_dds_value(hdspm, period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) return rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) * Calculate the real sample rate from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) * current DDS value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) static int hdspm_get_system_sample_rate(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) unsigned int rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) rate = hdspm_get_pll_freq(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) if (rate > 207000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) /* Unreasonable high sample rate as seen on PCI MADI cards. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) if (0 == hdspm_system_clock_mode(hdspm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) /* master mode, return internal sample rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) rate = hdspm->system_sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) /* slave mode, return external sample rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) rate = hdspm_external_sample_rate(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) if (!rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) rate = hdspm->system_sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) return rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) #define HDSPM_SYSTEM_SAMPLE_RATE(xname, xindex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) .index = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) .info = snd_hdspm_info_system_sample_rate, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) .put = snd_hdspm_put_system_sample_rate, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) .get = snd_hdspm_get_system_sample_rate \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) static int snd_hdspm_info_system_sample_rate(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) uinfo->value.integer.min = 27000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) uinfo->value.integer.max = 207000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) uinfo->value.integer.step = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) static int snd_hdspm_get_system_sample_rate(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) struct snd_ctl_elem_value *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) ucontrol->value.integer.value[0] = hdspm_get_system_sample_rate(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) static int snd_hdspm_put_system_sample_rate(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) struct snd_ctl_elem_value *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) int rate = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) if (rate < 27000 || rate > 207000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) hdspm_set_dds_value(hdspm, ucontrol->value.integer.value[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) * Returns the WordClock sample rate class for the given card.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) static int hdspm_get_wc_sample_rate(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) status = hdspm_read(hdspm, HDSPM_RD_STATUS_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) return (status >> 16) & 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) case AES32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) status = hdspm_read(hdspm, HDSPM_statusRegister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) return (status >> HDSPM_AES32_wcFreq_bit) & 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) * Returns the TCO sample rate class for the given card.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) static int hdspm_get_tco_sample_rate(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) if (hdspm->tco) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) status = hdspm_read(hdspm, HDSPM_RD_STATUS_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) return (status >> 20) & 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) case AES32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) status = hdspm_read(hdspm, HDSPM_statusRegister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) return (status >> 1) & 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) * Returns the SYNC_IN sample rate class for the given card.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) static int hdspm_get_sync_in_sample_rate(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) if (hdspm->tco) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) status = hdspm_read(hdspm, HDSPM_RD_STATUS_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) return (status >> 12) & 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) * Returns the AES sample rate class for the given card.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) static int hdspm_get_aes_sample_rate(struct hdspm *hdspm, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) int timecode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) case AES32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) timecode = hdspm_read(hdspm, HDSPM_timecodeRegister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) return (timecode >> (4*index)) & 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) * Returns the sample rate class for input source <idx> for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) * 'new style' cards like the AIO and RayDAT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) static int hdspm_get_s1_sample_rate(struct hdspm *hdspm, unsigned int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) int status = hdspm_read(hdspm, HDSPM_RD_STATUS_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) return (status >> (idx*4)) & 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) #define ENUMERATED_CTL_INFO(info, texts) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) snd_ctl_enum_info(info, 1, ARRAY_SIZE(texts), texts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) /* Helper function to query the external sample rate and return the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) * corresponding enum to be returned to userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) static int hdspm_external_rate_to_enum(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) int rate = hdspm_external_sample_rate(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) int i, selected_rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) for (i = 1; i < 10; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) if (HDSPM_bit2freq(i) == rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) selected_rate = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) return selected_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) #define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) .private_value = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) .access = SNDRV_CTL_ELEM_ACCESS_READ, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) .info = snd_hdspm_info_autosync_sample_rate, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) .get = snd_hdspm_get_autosync_sample_rate \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) static int snd_hdspm_info_autosync_sample_rate(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) ENUMERATED_CTL_INFO(uinfo, texts_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) static int snd_hdspm_get_autosync_sample_rate(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) struct snd_ctl_elem_value *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) switch (kcontrol->private_value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) ucontrol->value.enumerated.item[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) hdspm_get_wc_sample_rate(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) ucontrol->value.enumerated.item[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) hdspm_get_tco_sample_rate(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) ucontrol->value.enumerated.item[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) hdspm_get_sync_in_sample_rate(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) ucontrol->value.enumerated.item[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) hdspm_get_s1_sample_rate(hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) kcontrol->private_value-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) switch (kcontrol->private_value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) case 0: /* WC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) ucontrol->value.enumerated.item[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) hdspm_get_wc_sample_rate(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) case 4: /* TCO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) ucontrol->value.enumerated.item[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) hdspm_get_tco_sample_rate(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) case 5: /* SYNC_IN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) ucontrol->value.enumerated.item[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) hdspm_get_sync_in_sample_rate(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) ucontrol->value.enumerated.item[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) hdspm_get_s1_sample_rate(hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) kcontrol->private_value-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) case AES32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) switch (kcontrol->private_value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) case 0: /* WC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) ucontrol->value.enumerated.item[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) hdspm_get_wc_sample_rate(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) case 9: /* TCO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) ucontrol->value.enumerated.item[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) hdspm_get_tco_sample_rate(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) case 10: /* SYNC_IN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) ucontrol->value.enumerated.item[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) hdspm_get_sync_in_sample_rate(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) case 11: /* External Rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) ucontrol->value.enumerated.item[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) hdspm_external_rate_to_enum(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) default: /* AES1 to AES8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) ucontrol->value.enumerated.item[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) hdspm_get_aes_sample_rate(hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) kcontrol->private_value -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) HDSPM_AES32_AUTOSYNC_FROM_AES1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) case MADI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) case MADIface:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) ucontrol->value.enumerated.item[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) hdspm_external_rate_to_enum(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) #define HDSPM_SYSTEM_CLOCK_MODE(xname, xindex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) .index = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) .info = snd_hdspm_info_system_clock_mode, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) .get = snd_hdspm_get_system_clock_mode, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) .put = snd_hdspm_put_system_clock_mode, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) * Returns the system clock mode for the given card.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) * @returns 0 - master, 1 - slave
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) static int hdspm_system_clock_mode(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) if (hdspm->settings_register & HDSPM_c0Master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) if (hdspm->control_register & HDSPM_ClockModeMaster)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) * Sets the system clock mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) * @param mode 0 - master, 1 - slave
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) static void hdspm_set_system_clock_mode(struct hdspm *hdspm, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) hdspm_set_toggle_setting(hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) (hdspm_is_raydat_or_aio(hdspm)) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) HDSPM_c0Master : HDSPM_ClockModeMaster,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) (0 == mode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) static int snd_hdspm_info_system_clock_mode(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) static const char *const texts[] = { "Master", "AutoSync" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) ENUMERATED_CTL_INFO(uinfo, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) static int snd_hdspm_get_system_clock_mode(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) ucontrol->value.enumerated.item[0] = hdspm_system_clock_mode(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) static int snd_hdspm_put_system_clock_mode(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) if (!snd_hdspm_use_is_exclusive(hdspm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) val = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) else if (val > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) val = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) hdspm_set_system_clock_mode(hdspm, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) #define HDSPM_INTERNAL_CLOCK(xname, xindex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) .index = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) .info = snd_hdspm_info_clock_source, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) .get = snd_hdspm_get_clock_source, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) .put = snd_hdspm_put_clock_source \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) static int hdspm_clock_source(struct hdspm * hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) switch (hdspm->system_sample_rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) case 32000: return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) case 44100: return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) case 48000: return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) case 64000: return 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) case 88200: return 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) case 96000: return 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) case 128000: return 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) case 176400: return 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) case 192000: return 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) static int hdspm_set_clock_source(struct hdspm * hdspm, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) int rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) rate = 32000; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) rate = 44100; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) rate = 48000; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) rate = 64000; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) rate = 88200; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) rate = 96000; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) rate = 128000; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) rate = 176400; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) rate = 192000; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) rate = 48000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) hdspm_set_rate(hdspm, rate, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) static int snd_hdspm_info_clock_source(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) return snd_ctl_enum_info(uinfo, 1, 9, texts_freq + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) static int snd_hdspm_get_clock_source(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) ucontrol->value.enumerated.item[0] = hdspm_clock_source(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) static int snd_hdspm_put_clock_source(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) if (!snd_hdspm_use_is_exclusive(hdspm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) val = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) if (val > 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) val = 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) spin_lock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) if (val != hdspm_clock_source(hdspm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) change = (hdspm_set_clock_source(hdspm, val) == 0) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) #define HDSPM_PREF_SYNC_REF(xname, xindex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) .index = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) .info = snd_hdspm_info_pref_sync_ref, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) .get = snd_hdspm_get_pref_sync_ref, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) .put = snd_hdspm_put_pref_sync_ref \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) * Returns the current preferred sync reference setting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) * The semantics of the return value are depending on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) * card, please see the comments for clarification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) static int hdspm_pref_sync_ref(struct hdspm * hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) case AES32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) switch (hdspm->control_register & HDSPM_SyncRefMask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) case 0: return 0; /* WC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) case HDSPM_SyncRef0: return 1; /* AES 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) case HDSPM_SyncRef1: return 2; /* AES 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) case HDSPM_SyncRef1+HDSPM_SyncRef0: return 3; /* AES 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) case HDSPM_SyncRef2: return 4; /* AES 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) case HDSPM_SyncRef2+HDSPM_SyncRef0: return 5; /* AES 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) case HDSPM_SyncRef2+HDSPM_SyncRef1: return 6; /* AES 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) case HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) return 7; /* AES 7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) case HDSPM_SyncRef3: return 8; /* AES 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) case HDSPM_SyncRef3+HDSPM_SyncRef0: return 9; /* TCO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) case MADI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) case MADIface:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) if (hdspm->tco) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) switch (hdspm->control_register & HDSPM_SyncRefMask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) case 0: return 0; /* WC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) case HDSPM_SyncRef0: return 1; /* MADI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) case HDSPM_SyncRef1: return 2; /* TCO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) case HDSPM_SyncRef1+HDSPM_SyncRef0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) return 3; /* SYNC_IN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) switch (hdspm->control_register & HDSPM_SyncRefMask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) case 0: return 0; /* WC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) case HDSPM_SyncRef0: return 1; /* MADI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) case HDSPM_SyncRef1+HDSPM_SyncRef0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) return 2; /* SYNC_IN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) if (hdspm->tco) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) switch ((hdspm->settings_register &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) HDSPM_c0_SyncRefMask) / HDSPM_c0_SyncRef0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) case 0: return 0; /* WC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) case 3: return 1; /* ADAT 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) case 4: return 2; /* ADAT 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) case 5: return 3; /* ADAT 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) case 6: return 4; /* ADAT 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) case 1: return 5; /* AES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) case 2: return 6; /* SPDIF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) case 9: return 7; /* TCO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) case 10: return 8; /* SYNC_IN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) switch ((hdspm->settings_register &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) HDSPM_c0_SyncRefMask) / HDSPM_c0_SyncRef0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) case 0: return 0; /* WC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) case 3: return 1; /* ADAT 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) case 4: return 2; /* ADAT 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) case 5: return 3; /* ADAT 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) case 6: return 4; /* ADAT 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) case 1: return 5; /* AES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) case 2: return 6; /* SPDIF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) case 10: return 7; /* SYNC_IN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) if (hdspm->tco) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) switch ((hdspm->settings_register &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) HDSPM_c0_SyncRefMask) / HDSPM_c0_SyncRef0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) case 0: return 0; /* WC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) case 3: return 1; /* ADAT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) case 1: return 2; /* AES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) case 2: return 3; /* SPDIF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) case 9: return 4; /* TCO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) case 10: return 5; /* SYNC_IN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) switch ((hdspm->settings_register &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) HDSPM_c0_SyncRefMask) / HDSPM_c0_SyncRef0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) case 0: return 0; /* WC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) case 3: return 1; /* ADAT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) case 1: return 2; /* AES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) case 2: return 3; /* SPDIF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) case 10: return 4; /* SYNC_IN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) * Set the preferred sync reference to <pref>. The semantics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) * of <pref> are depending on the card type, see the comments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) * for clarification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) static int hdspm_set_pref_sync_ref(struct hdspm * hdspm, int pref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) int p = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) case AES32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) hdspm->control_register &= ~HDSPM_SyncRefMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) switch (pref) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) case 0: /* WC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) case 1: /* AES 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) hdspm->control_register |= HDSPM_SyncRef0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) case 2: /* AES 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) hdspm->control_register |= HDSPM_SyncRef1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) case 3: /* AES 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) hdspm->control_register |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) HDSPM_SyncRef1+HDSPM_SyncRef0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) case 4: /* AES 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) hdspm->control_register |= HDSPM_SyncRef2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) case 5: /* AES 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) hdspm->control_register |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) HDSPM_SyncRef2+HDSPM_SyncRef0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) case 6: /* AES 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) hdspm->control_register |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) HDSPM_SyncRef2+HDSPM_SyncRef1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) case 7: /* AES 7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) hdspm->control_register |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) case 8: /* AES 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) hdspm->control_register |= HDSPM_SyncRef3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) case 9: /* TCO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) hdspm->control_register |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) HDSPM_SyncRef3+HDSPM_SyncRef0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) case MADI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) case MADIface:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) hdspm->control_register &= ~HDSPM_SyncRefMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) if (hdspm->tco) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) switch (pref) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) case 0: /* WC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) case 1: /* MADI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) hdspm->control_register |= HDSPM_SyncRef0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) case 2: /* TCO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) hdspm->control_register |= HDSPM_SyncRef1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) case 3: /* SYNC_IN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) hdspm->control_register |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) HDSPM_SyncRef0+HDSPM_SyncRef1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) switch (pref) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) case 0: /* WC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) case 1: /* MADI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) hdspm->control_register |= HDSPM_SyncRef0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) case 2: /* SYNC_IN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) hdspm->control_register |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) HDSPM_SyncRef0+HDSPM_SyncRef1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) if (hdspm->tco) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) switch (pref) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) case 0: p = 0; break; /* WC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) case 1: p = 3; break; /* ADAT 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) case 2: p = 4; break; /* ADAT 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) case 3: p = 5; break; /* ADAT 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) case 4: p = 6; break; /* ADAT 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) case 5: p = 1; break; /* AES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) case 6: p = 2; break; /* SPDIF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) case 7: p = 9; break; /* TCO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) case 8: p = 10; break; /* SYNC_IN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) default: return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) switch (pref) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) case 0: p = 0; break; /* WC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) case 1: p = 3; break; /* ADAT 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) case 2: p = 4; break; /* ADAT 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) case 3: p = 5; break; /* ADAT 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) case 4: p = 6; break; /* ADAT 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) case 5: p = 1; break; /* AES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) case 6: p = 2; break; /* SPDIF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) case 7: p = 10; break; /* SYNC_IN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) default: return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) if (hdspm->tco) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) switch (pref) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) case 0: p = 0; break; /* WC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) case 1: p = 3; break; /* ADAT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) case 2: p = 1; break; /* AES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) case 3: p = 2; break; /* SPDIF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) case 4: p = 9; break; /* TCO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) case 5: p = 10; break; /* SYNC_IN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) default: return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) switch (pref) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) case 0: p = 0; break; /* WC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) case 1: p = 3; break; /* ADAT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) case 2: p = 1; break; /* AES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) case 3: p = 2; break; /* SPDIF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) case 4: p = 10; break; /* SYNC_IN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) default: return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) hdspm->settings_register &= ~HDSPM_c0_SyncRefMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) hdspm->settings_register |= HDSPM_c0_SyncRef0 * p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) case MADI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) case MADIface:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) case AES32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) hdspm_write(hdspm, HDSPM_controlRegister,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) hdspm->control_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) static int snd_hdspm_info_pref_sync_ref(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) snd_ctl_enum_info(uinfo, 1, hdspm->texts_autosync_items, hdspm->texts_autosync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) static int snd_hdspm_get_pref_sync_ref(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) int psf = hdspm_pref_sync_ref(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) if (psf >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) ucontrol->value.enumerated.item[0] = psf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) int val, change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) if (!snd_hdspm_use_is_exclusive(hdspm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) val = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) else if (val >= hdspm->texts_autosync_items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) val = hdspm->texts_autosync_items-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) spin_lock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) if (val != hdspm_pref_sync_ref(hdspm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) change = (0 == hdspm_set_pref_sync_ref(hdspm, val)) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) #define HDSPM_AUTOSYNC_REF(xname, xindex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) .index = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) .access = SNDRV_CTL_ELEM_ACCESS_READ, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) .info = snd_hdspm_info_autosync_ref, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) .get = snd_hdspm_get_autosync_ref, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) static int hdspm_autosync_ref(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) /* This looks at the autosync selected sync reference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) if (AES32 == hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) unsigned int syncref = (status >> HDSPM_AES32_syncref_bit) & 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) /* syncref >= HDSPM_AES32_AUTOSYNC_FROM_WORD is always true */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) if (syncref <= HDSPM_AES32_AUTOSYNC_FROM_SYNC_IN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) return syncref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) return HDSPM_AES32_AUTOSYNC_FROM_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) } else if (MADI == hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) switch (status2 & HDSPM_SelSyncRefMask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) case HDSPM_SelSyncRef_WORD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) return HDSPM_AUTOSYNC_FROM_WORD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) case HDSPM_SelSyncRef_MADI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) return HDSPM_AUTOSYNC_FROM_MADI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) case HDSPM_SelSyncRef_TCO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) return HDSPM_AUTOSYNC_FROM_TCO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) case HDSPM_SelSyncRef_SyncIn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) return HDSPM_AUTOSYNC_FROM_SYNC_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) case HDSPM_SelSyncRef_NVALID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) return HDSPM_AUTOSYNC_FROM_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) return HDSPM_AUTOSYNC_FROM_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) static int snd_hdspm_info_autosync_ref(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) if (AES32 == hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) static const char *const texts[] = { "WordClock", "AES1", "AES2", "AES3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) "AES4", "AES5", "AES6", "AES7", "AES8", "TCO", "Sync In", "None"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) ENUMERATED_CTL_INFO(uinfo, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) } else if (MADI == hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) static const char *const texts[] = {"Word Clock", "MADI", "TCO",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) "Sync In", "None" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) ENUMERATED_CTL_INFO(uinfo, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) static int snd_hdspm_get_autosync_ref(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) ucontrol->value.enumerated.item[0] = hdspm_autosync_ref(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) #define HDSPM_TCO_VIDEO_INPUT_FORMAT(xname, xindex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) .access = SNDRV_CTL_ELEM_ACCESS_READ |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) .info = snd_hdspm_info_tco_video_input_format, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) .get = snd_hdspm_get_tco_video_input_format, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) static int snd_hdspm_info_tco_video_input_format(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) static const char *const texts[] = {"No video", "NTSC", "PAL"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) ENUMERATED_CTL_INFO(uinfo, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) static int snd_hdspm_get_tco_video_input_format(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) status = hdspm_read(hdspm, HDSPM_RD_TCO + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) switch (status & (HDSPM_TCO1_Video_Input_Format_NTSC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) HDSPM_TCO1_Video_Input_Format_PAL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) case HDSPM_TCO1_Video_Input_Format_NTSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) /* ntsc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) case HDSPM_TCO1_Video_Input_Format_PAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) /* pal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) ret = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) /* no video */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) ucontrol->value.enumerated.item[0] = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) #define HDSPM_TCO_LTC_FRAMES(xname, xindex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) .access = SNDRV_CTL_ELEM_ACCESS_READ |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) .info = snd_hdspm_info_tco_ltc_frames, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) .get = snd_hdspm_get_tco_ltc_frames, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) static int snd_hdspm_info_tco_ltc_frames(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) static const char *const texts[] = {"No lock", "24 fps", "25 fps", "29.97 fps",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) "30 fps"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) ENUMERATED_CTL_INFO(uinfo, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) static int hdspm_tco_ltc_frames(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) status = hdspm_read(hdspm, HDSPM_RD_TCO + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) if (status & HDSPM_TCO1_LTC_Input_valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) switch (status & (HDSPM_TCO1_LTC_Format_LSB |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) HDSPM_TCO1_LTC_Format_MSB)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) /* 24 fps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) ret = fps_24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) case HDSPM_TCO1_LTC_Format_LSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) /* 25 fps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) ret = fps_25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) case HDSPM_TCO1_LTC_Format_MSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) /* 29.97 fps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) ret = fps_2997;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) /* 30 fps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) ret = fps_30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) static int snd_hdspm_get_tco_ltc_frames(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) ucontrol->value.enumerated.item[0] = hdspm_tco_ltc_frames(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) #define HDSPM_TOGGLE_SETTING(xname, xindex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) .private_value = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) .info = snd_hdspm_info_toggle_setting, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) .get = snd_hdspm_get_toggle_setting, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) .put = snd_hdspm_put_toggle_setting \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) static int hdspm_toggle_setting(struct hdspm *hdspm, u32 regmask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) if (hdspm_is_raydat_or_aio(hdspm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) reg = hdspm->settings_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) reg = hdspm->control_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) return (reg & regmask) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) static int hdspm_set_toggle_setting(struct hdspm *hdspm, u32 regmask, int out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) u32 *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) u32 target_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) if (hdspm_is_raydat_or_aio(hdspm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) reg = &(hdspm->settings_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) target_reg = HDSPM_WR_SETTINGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) reg = &(hdspm->control_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) target_reg = HDSPM_controlRegister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) if (out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) *reg |= regmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) *reg &= ~regmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) hdspm_write(hdspm, target_reg, *reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) #define snd_hdspm_info_toggle_setting snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) static int snd_hdspm_get_toggle_setting(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) u32 regmask = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) spin_lock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) ucontrol->value.integer.value[0] = hdspm_toggle_setting(hdspm, regmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) static int snd_hdspm_put_toggle_setting(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) u32 regmask = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) if (!snd_hdspm_use_is_exclusive(hdspm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) val = ucontrol->value.integer.value[0] & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) spin_lock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) change = (int) val != hdspm_toggle_setting(hdspm, regmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) hdspm_set_toggle_setting(hdspm, regmask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) #define HDSPM_INPUT_SELECT(xname, xindex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) .index = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) .info = snd_hdspm_info_input_select, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) .get = snd_hdspm_get_input_select, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) .put = snd_hdspm_put_input_select \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) static int hdspm_input_select(struct hdspm * hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) return (hdspm->control_register & HDSPM_InputSelect0) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) static int hdspm_set_input_select(struct hdspm * hdspm, int out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) if (out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) hdspm->control_register |= HDSPM_InputSelect0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) hdspm->control_register &= ~HDSPM_InputSelect0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) static int snd_hdspm_info_input_select(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) static const char *const texts[] = { "optical", "coaxial" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) ENUMERATED_CTL_INFO(uinfo, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) static int snd_hdspm_get_input_select(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) spin_lock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) ucontrol->value.enumerated.item[0] = hdspm_input_select(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) static int snd_hdspm_put_input_select(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) if (!snd_hdspm_use_is_exclusive(hdspm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) val = ucontrol->value.integer.value[0] & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) spin_lock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) change = (int) val != hdspm_input_select(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) hdspm_set_input_select(hdspm, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) #define HDSPM_DS_WIRE(xname, xindex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) .index = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) .info = snd_hdspm_info_ds_wire, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) .get = snd_hdspm_get_ds_wire, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) .put = snd_hdspm_put_ds_wire \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) static int hdspm_ds_wire(struct hdspm * hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) return (hdspm->control_register & HDSPM_DS_DoubleWire) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) static int hdspm_set_ds_wire(struct hdspm * hdspm, int ds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) if (ds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) hdspm->control_register |= HDSPM_DS_DoubleWire;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) hdspm->control_register &= ~HDSPM_DS_DoubleWire;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) static int snd_hdspm_info_ds_wire(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) static const char *const texts[] = { "Single", "Double" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) ENUMERATED_CTL_INFO(uinfo, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) static int snd_hdspm_get_ds_wire(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) spin_lock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) ucontrol->value.enumerated.item[0] = hdspm_ds_wire(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) static int snd_hdspm_put_ds_wire(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) if (!snd_hdspm_use_is_exclusive(hdspm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) val = ucontrol->value.integer.value[0] & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) spin_lock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) change = (int) val != hdspm_ds_wire(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) hdspm_set_ds_wire(hdspm, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) #define HDSPM_QS_WIRE(xname, xindex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) .index = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) .info = snd_hdspm_info_qs_wire, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) .get = snd_hdspm_get_qs_wire, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) .put = snd_hdspm_put_qs_wire \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) static int hdspm_qs_wire(struct hdspm * hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) if (hdspm->control_register & HDSPM_QS_DoubleWire)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) if (hdspm->control_register & HDSPM_QS_QuadWire)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) static int hdspm_set_qs_wire(struct hdspm * hdspm, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) hdspm->control_register &= ~(HDSPM_QS_DoubleWire | HDSPM_QS_QuadWire);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) hdspm->control_register |= HDSPM_QS_DoubleWire;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) hdspm->control_register |= HDSPM_QS_QuadWire;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) static int snd_hdspm_info_qs_wire(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) static const char *const texts[] = { "Single", "Double", "Quad" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) ENUMERATED_CTL_INFO(uinfo, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) static int snd_hdspm_get_qs_wire(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) spin_lock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) ucontrol->value.enumerated.item[0] = hdspm_qs_wire(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) static int snd_hdspm_put_qs_wire(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) if (!snd_hdspm_use_is_exclusive(hdspm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) val = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) if (val > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) val = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) spin_lock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) change = val != hdspm_qs_wire(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) hdspm_set_qs_wire(hdspm, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) #define HDSPM_CONTROL_TRISTATE(xname, xindex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) .private_value = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) .info = snd_hdspm_info_tristate, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) .get = snd_hdspm_get_tristate, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) .put = snd_hdspm_put_tristate \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) static int hdspm_tristate(struct hdspm *hdspm, u32 regmask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) u32 reg = hdspm->settings_register & (regmask * 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) return reg / regmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) static int hdspm_set_tristate(struct hdspm *hdspm, int mode, u32 regmask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) hdspm->settings_register &= ~(regmask * 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) hdspm->settings_register |= (regmask * mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) static int snd_hdspm_info_tristate(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) u32 regmask = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) static const char *const texts_spdif[] = { "Optical", "Coaxial", "Internal" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) static const char *const texts_levels[] = { "Hi Gain", "+4 dBu", "-10 dBV" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) switch (regmask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) case HDSPM_c0_Input0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) ENUMERATED_CTL_INFO(uinfo, texts_spdif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) ENUMERATED_CTL_INFO(uinfo, texts_levels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) static int snd_hdspm_get_tristate(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) u32 regmask = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) spin_lock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) ucontrol->value.enumerated.item[0] = hdspm_tristate(hdspm, regmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) static int snd_hdspm_put_tristate(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) u32 regmask = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) if (!snd_hdspm_use_is_exclusive(hdspm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) val = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) if (val > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) val = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) spin_lock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) change = val != hdspm_tristate(hdspm, regmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) hdspm_set_tristate(hdspm, val, regmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) #define HDSPM_MADI_SPEEDMODE(xname, xindex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) .index = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) .info = snd_hdspm_info_madi_speedmode, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) .get = snd_hdspm_get_madi_speedmode, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) .put = snd_hdspm_put_madi_speedmode \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) static int hdspm_madi_speedmode(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) if (hdspm->control_register & HDSPM_QuadSpeed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) if (hdspm->control_register & HDSPM_DoubleSpeed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) static int hdspm_set_madi_speedmode(struct hdspm *hdspm, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) hdspm->control_register &= ~(HDSPM_DoubleSpeed | HDSPM_QuadSpeed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) hdspm->control_register |= HDSPM_DoubleSpeed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) hdspm->control_register |= HDSPM_QuadSpeed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) static int snd_hdspm_info_madi_speedmode(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) static const char *const texts[] = { "Single", "Double", "Quad" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) ENUMERATED_CTL_INFO(uinfo, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) static int snd_hdspm_get_madi_speedmode(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) spin_lock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) ucontrol->value.enumerated.item[0] = hdspm_madi_speedmode(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) static int snd_hdspm_put_madi_speedmode(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) if (!snd_hdspm_use_is_exclusive(hdspm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) val = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) if (val > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) val = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) spin_lock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) change = val != hdspm_madi_speedmode(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) hdspm_set_madi_speedmode(hdspm, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) #define HDSPM_MIXER(xname, xindex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) .index = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) .device = 0, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) .info = snd_hdspm_info_mixer, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) .get = snd_hdspm_get_mixer, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) .put = snd_hdspm_put_mixer \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) static int snd_hdspm_info_mixer(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) uinfo->count = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) uinfo->value.integer.max = 65535;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) uinfo->value.integer.step = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) static int snd_hdspm_get_mixer(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) int source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) int destination;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) source = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) if (source < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) source = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) else if (source >= 2 * HDSPM_MAX_CHANNELS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) source = 2 * HDSPM_MAX_CHANNELS - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) destination = ucontrol->value.integer.value[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) if (destination < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) destination = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) else if (destination >= HDSPM_MAX_CHANNELS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) destination = HDSPM_MAX_CHANNELS - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) spin_lock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) if (source >= HDSPM_MAX_CHANNELS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) ucontrol->value.integer.value[2] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) hdspm_read_pb_gain(hdspm, destination,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) source - HDSPM_MAX_CHANNELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) ucontrol->value.integer.value[2] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) hdspm_read_in_gain(hdspm, destination, source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) static int snd_hdspm_put_mixer(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) int source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) int destination;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) int gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) if (!snd_hdspm_use_is_exclusive(hdspm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) source = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) destination = ucontrol->value.integer.value[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) if (source < 0 || source >= 2 * HDSPM_MAX_CHANNELS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) if (destination < 0 || destination >= HDSPM_MAX_CHANNELS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) gain = ucontrol->value.integer.value[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) spin_lock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) if (source >= HDSPM_MAX_CHANNELS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) change = gain != hdspm_read_pb_gain(hdspm, destination,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) source -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) HDSPM_MAX_CHANNELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) change = gain != hdspm_read_in_gain(hdspm, destination,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) if (change) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) if (source >= HDSPM_MAX_CHANNELS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) hdspm_write_pb_gain(hdspm, destination,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) source - HDSPM_MAX_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) hdspm_write_in_gain(hdspm, destination, source,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) /* The simple mixer control(s) provide gain control for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) basic 1:1 mappings of playback streams to output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) streams.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) #define HDSPM_PLAYBACK_MIXER \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) .info = snd_hdspm_info_playback_mixer, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) .get = snd_hdspm_get_playback_mixer, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) .put = snd_hdspm_put_playback_mixer \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) static int snd_hdspm_info_playback_mixer(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) uinfo->value.integer.max = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) uinfo->value.integer.step = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) static int snd_hdspm_get_playback_mixer(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) int channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) channel = ucontrol->id.index - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) spin_lock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) ucontrol->value.integer.value[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) (hdspm_read_pb_gain(hdspm, channel, channel)*64)/UNITY_GAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) static int snd_hdspm_put_playback_mixer(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) int channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) int gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) if (!snd_hdspm_use_is_exclusive(hdspm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) channel = ucontrol->id.index - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) gain = ucontrol->value.integer.value[0]*UNITY_GAIN/64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) spin_lock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) change =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) gain != hdspm_read_pb_gain(hdspm, channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) if (change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) hdspm_write_pb_gain(hdspm, channel, channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) #define HDSPM_SYNC_CHECK(xname, xindex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) .private_value = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) .info = snd_hdspm_info_sync_check, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) .get = snd_hdspm_get_sync_check \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) #define HDSPM_TCO_LOCK_CHECK(xname, xindex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) .private_value = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) .info = snd_hdspm_tco_info_lock_check, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) .get = snd_hdspm_get_sync_check \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) static const char *const texts[] = { "No Lock", "Lock", "Sync", "N/A" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) ENUMERATED_CTL_INFO(uinfo, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) static int snd_hdspm_tco_info_lock_check(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) static const char *const texts[] = { "No Lock", "Lock" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) ENUMERATED_CTL_INFO(uinfo, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) static int hdspm_wc_sync_check(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) int status, status2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) case AES32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) status = hdspm_read(hdspm, HDSPM_statusRegister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) if (status & HDSPM_AES32_wcLock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) if (status & HDSPM_AES32_wcSync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) case MADI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) if (status2 & HDSPM_wcLock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) if (status2 & HDSPM_wcSync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) status = hdspm_read(hdspm, HDSPM_statusRegister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) if (status & 0x2000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) else if (status & 0x1000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) case MADIface:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) return 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) static int hdspm_madi_sync_check(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) int status = hdspm_read(hdspm, HDSPM_statusRegister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) if (status & HDSPM_madiLock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) if (status & HDSPM_madiSync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) static int hdspm_s1_sync_check(struct hdspm *hdspm, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) int status, lock, sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) status = hdspm_read(hdspm, HDSPM_RD_STATUS_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) lock = (status & (0x1<<idx)) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) sync = (status & (0x100<<idx)) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) if (lock && sync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) else if (lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) static int hdspm_sync_in_sync_check(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) int status, lock = 0, sync = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) status = hdspm_read(hdspm, HDSPM_RD_STATUS_3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) lock = (status & 0x400) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) sync = (status & 0x800) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) case MADI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) status = hdspm_read(hdspm, HDSPM_statusRegister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) lock = (status & HDSPM_syncInLock) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) sync = (status & HDSPM_syncInSync) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) case AES32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) status = hdspm_read(hdspm, HDSPM_statusRegister2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) lock = (status & 0x100000) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) sync = (status & 0x200000) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) case MADIface:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) if (lock && sync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) else if (lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) static int hdspm_aes_sync_check(struct hdspm *hdspm, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) int status2, lock, sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) lock = (status2 & (0x0080 >> idx)) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) sync = (status2 & (0x8000 >> idx)) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) if (sync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) else if (lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) static int hdspm_tco_input_check(struct hdspm *hdspm, u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) status = hdspm_read(hdspm, HDSPM_RD_TCO + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) return (status & mask) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) static int hdspm_tco_sync_check(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) if (hdspm->tco) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) case MADI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) status = hdspm_read(hdspm, HDSPM_statusRegister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) if (status & HDSPM_tcoLockMadi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) if (status & HDSPM_tcoSync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) case AES32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) status = hdspm_read(hdspm, HDSPM_statusRegister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) if (status & HDSPM_tcoLockAes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) if (status & HDSPM_tcoSync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) status = hdspm_read(hdspm, HDSPM_RD_STATUS_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) if (status & 0x8000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) return 2; /* Sync */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) if (status & 0x4000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) return 1; /* Lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) return 0; /* No signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) return 3; /* N/A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) int val = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) switch (kcontrol->private_value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) case 0: /* WC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) val = hdspm_wc_sync_check(hdspm); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) case 7: /* TCO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) val = hdspm_tco_sync_check(hdspm); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) case 8: /* SYNC IN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) val = hdspm_sync_in_sync_check(hdspm); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) val = hdspm_s1_sync_check(hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) kcontrol->private_value-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) switch (kcontrol->private_value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) case 0: /* WC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) val = hdspm_wc_sync_check(hdspm); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) case 4: /* TCO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) val = hdspm_tco_sync_check(hdspm); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) case 5: /* SYNC IN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) val = hdspm_sync_in_sync_check(hdspm); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) val = hdspm_s1_sync_check(hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) kcontrol->private_value-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) case MADI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) switch (kcontrol->private_value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) case 0: /* WC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) val = hdspm_wc_sync_check(hdspm); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) case 1: /* MADI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) val = hdspm_madi_sync_check(hdspm); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) case 2: /* TCO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) val = hdspm_tco_sync_check(hdspm); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) case 3: /* SYNC_IN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) val = hdspm_sync_in_sync_check(hdspm); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) case MADIface:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) val = hdspm_madi_sync_check(hdspm); /* MADI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) case AES32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) switch (kcontrol->private_value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) case 0: /* WC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) val = hdspm_wc_sync_check(hdspm); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) case 9: /* TCO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) val = hdspm_tco_sync_check(hdspm); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) case 10 /* SYNC IN */:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) val = hdspm_sync_in_sync_check(hdspm); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) default: /* AES1 to AES8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) val = hdspm_aes_sync_check(hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) kcontrol->private_value-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) if (hdspm->tco) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) switch (kcontrol->private_value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) case 11:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) /* Check TCO for lock state of its current input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) val = hdspm_tco_input_check(hdspm, HDSPM_TCO1_TCO_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) case 12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) /* Check TCO for valid time code on LTC input. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) val = hdspm_tco_input_check(hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) HDSPM_TCO1_LTC_Input_valid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) if (-1 == val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) val = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) ucontrol->value.enumerated.item[0] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) * TCO controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) static void hdspm_tco_write(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) unsigned int tc[4] = { 0, 0, 0, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) switch (hdspm->tco->input) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) tc[2] |= HDSPM_TCO2_set_input_MSB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) tc[2] |= HDSPM_TCO2_set_input_LSB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) switch (hdspm->tco->framerate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) tc[1] |= HDSPM_TCO1_LTC_Format_LSB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) tc[1] |= HDSPM_TCO1_LTC_Format_MSB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) tc[1] |= HDSPM_TCO1_LTC_Format_MSB +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) HDSPM_TCO1_set_drop_frame_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) tc[1] |= HDSPM_TCO1_LTC_Format_LSB +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) HDSPM_TCO1_LTC_Format_MSB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) tc[1] |= HDSPM_TCO1_LTC_Format_LSB +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) HDSPM_TCO1_LTC_Format_MSB +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) HDSPM_TCO1_set_drop_frame_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) switch (hdspm->tco->wordclock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) tc[2] |= HDSPM_TCO2_WCK_IO_ratio_LSB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) tc[2] |= HDSPM_TCO2_WCK_IO_ratio_MSB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) switch (hdspm->tco->samplerate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) tc[2] |= HDSPM_TCO2_set_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) tc[2] |= HDSPM_TCO2_set_freq_from_app;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) switch (hdspm->tco->pull) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) tc[2] |= HDSPM_TCO2_set_pull_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) tc[2] |= HDSPM_TCO2_set_pull_down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) tc[2] |= HDSPM_TCO2_set_pull_up + HDSPM_TCO2_set_01_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) tc[2] |= HDSPM_TCO2_set_pull_down + HDSPM_TCO2_set_01_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) if (1 == hdspm->tco->term) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) tc[2] |= HDSPM_TCO2_set_term_75R;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) hdspm_write(hdspm, HDSPM_WR_TCO, tc[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) hdspm_write(hdspm, HDSPM_WR_TCO+4, tc[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) hdspm_write(hdspm, HDSPM_WR_TCO+8, tc[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) hdspm_write(hdspm, HDSPM_WR_TCO+12, tc[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) #define HDSPM_TCO_SAMPLE_RATE(xname, xindex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) .index = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) .info = snd_hdspm_info_tco_sample_rate, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) .get = snd_hdspm_get_tco_sample_rate, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) .put = snd_hdspm_put_tco_sample_rate \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) static int snd_hdspm_info_tco_sample_rate(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) /* TODO freq from app could be supported here, see tco->samplerate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) static const char *const texts[] = { "44.1 kHz", "48 kHz" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) ENUMERATED_CTL_INFO(uinfo, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) static int snd_hdspm_get_tco_sample_rate(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) ucontrol->value.enumerated.item[0] = hdspm->tco->samplerate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) static int snd_hdspm_put_tco_sample_rate(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) if (hdspm->tco->samplerate != ucontrol->value.enumerated.item[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) hdspm->tco->samplerate = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) hdspm_tco_write(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) #define HDSPM_TCO_PULL(xname, xindex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) .index = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) .info = snd_hdspm_info_tco_pull, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) .get = snd_hdspm_get_tco_pull, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) .put = snd_hdspm_put_tco_pull \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) static int snd_hdspm_info_tco_pull(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) static const char *const texts[] = { "0", "+ 0.1 %", "- 0.1 %",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) "+ 4 %", "- 4 %" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) ENUMERATED_CTL_INFO(uinfo, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) static int snd_hdspm_get_tco_pull(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) ucontrol->value.enumerated.item[0] = hdspm->tco->pull;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) static int snd_hdspm_put_tco_pull(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) if (hdspm->tco->pull != ucontrol->value.enumerated.item[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) hdspm->tco->pull = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) hdspm_tco_write(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) #define HDSPM_TCO_WCK_CONVERSION(xname, xindex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) .index = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) .info = snd_hdspm_info_tco_wck_conversion, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) .get = snd_hdspm_get_tco_wck_conversion, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) .put = snd_hdspm_put_tco_wck_conversion \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) static int snd_hdspm_info_tco_wck_conversion(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) static const char *const texts[] = { "1:1", "44.1 -> 48", "48 -> 44.1" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) ENUMERATED_CTL_INFO(uinfo, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) static int snd_hdspm_get_tco_wck_conversion(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) ucontrol->value.enumerated.item[0] = hdspm->tco->wordclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) static int snd_hdspm_put_tco_wck_conversion(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) if (hdspm->tco->wordclock != ucontrol->value.enumerated.item[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) hdspm->tco->wordclock = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) hdspm_tco_write(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) #define HDSPM_TCO_FRAME_RATE(xname, xindex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) .index = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) .info = snd_hdspm_info_tco_frame_rate, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) .get = snd_hdspm_get_tco_frame_rate, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) .put = snd_hdspm_put_tco_frame_rate \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) static int snd_hdspm_info_tco_frame_rate(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) static const char *const texts[] = { "24 fps", "25 fps", "29.97fps",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) "29.97 dfps", "30 fps", "30 dfps" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) ENUMERATED_CTL_INFO(uinfo, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) static int snd_hdspm_get_tco_frame_rate(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) ucontrol->value.enumerated.item[0] = hdspm->tco->framerate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) static int snd_hdspm_put_tco_frame_rate(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) if (hdspm->tco->framerate != ucontrol->value.enumerated.item[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) hdspm->tco->framerate = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) hdspm_tco_write(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) #define HDSPM_TCO_SYNC_SOURCE(xname, xindex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) .index = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) .info = snd_hdspm_info_tco_sync_source, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) .get = snd_hdspm_get_tco_sync_source, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) .put = snd_hdspm_put_tco_sync_source \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) static int snd_hdspm_info_tco_sync_source(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) static const char *const texts[] = { "LTC", "Video", "WCK" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) ENUMERATED_CTL_INFO(uinfo, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) static int snd_hdspm_get_tco_sync_source(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) ucontrol->value.enumerated.item[0] = hdspm->tco->input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) static int snd_hdspm_put_tco_sync_source(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) if (hdspm->tco->input != ucontrol->value.enumerated.item[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) hdspm->tco->input = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) hdspm_tco_write(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) #define HDSPM_TCO_WORD_TERM(xname, xindex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) .index = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) .info = snd_hdspm_info_tco_word_term, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) .get = snd_hdspm_get_tco_word_term, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) .put = snd_hdspm_put_tco_word_term \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) static int snd_hdspm_info_tco_word_term(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) uinfo->value.integer.max = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) static int snd_hdspm_get_tco_word_term(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) ucontrol->value.integer.value[0] = hdspm->tco->term;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) static int snd_hdspm_put_tco_word_term(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) if (hdspm->tco->term != ucontrol->value.integer.value[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) hdspm->tco->term = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) hdspm_tco_write(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) static const struct snd_kcontrol_new snd_hdspm_controls_madi[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) HDSPM_MIXER("Mixer", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) HDSPM_INTERNAL_CLOCK("Internal Clock", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) HDSPM_AUTOSYNC_REF("AutoSync Reference", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) HDSPM_SYNC_CHECK("WC SyncCheck", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) HDSPM_SYNC_CHECK("MADI SyncCheck", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) HDSPM_SYNC_CHECK("TCO SyncCheck", 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) HDSPM_TOGGLE_SETTING("Line Out", HDSPM_LineOut),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) HDSPM_TOGGLE_SETTING("TX 64 channels mode", HDSPM_TX_64ch),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) HDSPM_TOGGLE_SETTING("Disable 96K frames", HDSPM_SMUX),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) HDSPM_TOGGLE_SETTING("Clear Track Marker", HDSPM_clr_tms),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) HDSPM_TOGGLE_SETTING("Safe Mode", HDSPM_AutoInp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) HDSPM_INPUT_SELECT("Input Select", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503) HDSPM_MADI_SPEEDMODE("MADI Speed Mode", 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) static const struct snd_kcontrol_new snd_hdspm_controls_madiface[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) HDSPM_MIXER("Mixer", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) HDSPM_INTERNAL_CLOCK("Internal Clock", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) HDSPM_SYNC_CHECK("MADI SyncCheck", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) HDSPM_TOGGLE_SETTING("TX 64 channels mode", HDSPM_TX_64ch),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) HDSPM_TOGGLE_SETTING("Clear Track Marker", HDSPM_clr_tms),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) HDSPM_TOGGLE_SETTING("Safe Mode", HDSPM_AutoInp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) HDSPM_MADI_SPEEDMODE("MADI Speed Mode", 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) static const struct snd_kcontrol_new snd_hdspm_controls_aio[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) HDSPM_MIXER("Mixer", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) HDSPM_INTERNAL_CLOCK("Internal Clock", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) HDSPM_SYNC_CHECK("WC SyncCheck", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) HDSPM_SYNC_CHECK("AES SyncCheck", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) HDSPM_SYNC_CHECK("SPDIF SyncCheck", 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) HDSPM_SYNC_CHECK("ADAT SyncCheck", 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) HDSPM_SYNC_CHECK("TCO SyncCheck", 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) HDSPM_AUTOSYNC_SAMPLE_RATE("WC Frequency", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) HDSPM_AUTOSYNC_SAMPLE_RATE("AES Frequency", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) HDSPM_AUTOSYNC_SAMPLE_RATE("SPDIF Frequency", 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT Frequency", 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) HDSPM_CONTROL_TRISTATE("S/PDIF Input", HDSPM_c0_Input0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540) HDSPM_TOGGLE_SETTING("S/PDIF Out Optical", HDSPM_c0_Spdif_Opt),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) HDSPM_TOGGLE_SETTING("S/PDIF Out Professional", HDSPM_c0_Pro),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) HDSPM_TOGGLE_SETTING("ADAT internal (AEB/TEB)", HDSPM_c0_AEB1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) HDSPM_TOGGLE_SETTING("XLR Breakout Cable", HDSPM_c0_Sym6db),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) HDSPM_TOGGLE_SETTING("Single Speed WordClock Out", HDSPM_c0_Wck48),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) HDSPM_CONTROL_TRISTATE("Input Level", HDSPM_c0_AD_GAIN0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) HDSPM_CONTROL_TRISTATE("Output Level", HDSPM_c0_DA_GAIN0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) HDSPM_CONTROL_TRISTATE("Phones Level", HDSPM_c0_PH_GAIN0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) HDSPM_INPUT_SELECT("Input Select", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) HDSPM_SPDIF_OPTICAL("SPDIF Out Optical", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) HDSPM_PROFESSIONAL("SPDIF Out Professional", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) HDSPM_SPDIF_IN("SPDIF In", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) HDSPM_BREAKOUT_CABLE("Breakout Cable", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) HDSPM_INPUT_LEVEL("Input Level", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) HDSPM_OUTPUT_LEVEL("Output Level", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) HDSPM_PHONES("Phones", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) static const struct snd_kcontrol_new snd_hdspm_controls_raydat[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) HDSPM_MIXER("Mixer", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) HDSPM_INTERNAL_CLOCK("Internal Clock", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) HDSPM_SYSTEM_CLOCK_MODE("Clock Mode", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) HDSPM_PREF_SYNC_REF("Pref Sync Ref", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) HDSPM_SYNC_CHECK("WC SyncCheck", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) HDSPM_SYNC_CHECK("AES SyncCheck", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) HDSPM_SYNC_CHECK("SPDIF SyncCheck", 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) HDSPM_SYNC_CHECK("ADAT1 SyncCheck", 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) HDSPM_SYNC_CHECK("ADAT2 SyncCheck", 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) HDSPM_SYNC_CHECK("ADAT3 SyncCheck", 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) HDSPM_SYNC_CHECK("ADAT4 SyncCheck", 6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) HDSPM_SYNC_CHECK("TCO SyncCheck", 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) HDSPM_AUTOSYNC_SAMPLE_RATE("WC Frequency", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) HDSPM_AUTOSYNC_SAMPLE_RATE("AES Frequency", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) HDSPM_AUTOSYNC_SAMPLE_RATE("SPDIF Frequency", 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT1 Frequency", 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT2 Frequency", 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT3 Frequency", 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT4 Frequency", 6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584) HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) HDSPM_TOGGLE_SETTING("S/PDIF Out Professional", HDSPM_c0_Pro),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) HDSPM_TOGGLE_SETTING("Single Speed WordClock Out", HDSPM_c0_Wck48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) static const struct snd_kcontrol_new snd_hdspm_controls_aes32[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) HDSPM_MIXER("Mixer", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) HDSPM_INTERNAL_CLOCK("Internal Clock", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) HDSPM_AUTOSYNC_REF("AutoSync Reference", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 11),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) HDSPM_SYNC_CHECK("WC Sync Check", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598) HDSPM_SYNC_CHECK("AES1 Sync Check", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) HDSPM_SYNC_CHECK("AES2 Sync Check", 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) HDSPM_SYNC_CHECK("AES3 Sync Check", 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) HDSPM_SYNC_CHECK("AES4 Sync Check", 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) HDSPM_SYNC_CHECK("AES5 Sync Check", 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) HDSPM_SYNC_CHECK("AES6 Sync Check", 6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) HDSPM_SYNC_CHECK("AES7 Sync Check", 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) HDSPM_SYNC_CHECK("AES8 Sync Check", 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) HDSPM_SYNC_CHECK("TCO Sync Check", 9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) HDSPM_SYNC_CHECK("SYNC IN Sync Check", 10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) HDSPM_AUTOSYNC_SAMPLE_RATE("WC Frequency", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) HDSPM_AUTOSYNC_SAMPLE_RATE("AES1 Frequency", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) HDSPM_AUTOSYNC_SAMPLE_RATE("AES2 Frequency", 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) HDSPM_AUTOSYNC_SAMPLE_RATE("AES3 Frequency", 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) HDSPM_AUTOSYNC_SAMPLE_RATE("AES4 Frequency", 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) HDSPM_AUTOSYNC_SAMPLE_RATE("AES5 Frequency", 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) HDSPM_AUTOSYNC_SAMPLE_RATE("AES6 Frequency", 6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) HDSPM_AUTOSYNC_SAMPLE_RATE("AES7 Frequency", 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616) HDSPM_AUTOSYNC_SAMPLE_RATE("AES8 Frequency", 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619) HDSPM_TOGGLE_SETTING("Line Out", HDSPM_LineOut),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) HDSPM_TOGGLE_SETTING("Emphasis", HDSPM_Emphasis),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621) HDSPM_TOGGLE_SETTING("Non Audio", HDSPM_Dolby),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) HDSPM_TOGGLE_SETTING("Professional", HDSPM_Professional),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) HDSPM_TOGGLE_SETTING("Clear Track Marker", HDSPM_clr_tms),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) HDSPM_DS_WIRE("Double Speed Wire Mode", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) HDSPM_QS_WIRE("Quad Speed Wire Mode", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) /* Control elements for the optional TCO module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) static const struct snd_kcontrol_new snd_hdspm_controls_tco[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) HDSPM_TCO_SAMPLE_RATE("TCO Sample Rate", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) HDSPM_TCO_PULL("TCO Pull", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) HDSPM_TCO_WCK_CONVERSION("TCO WCK Conversion", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) HDSPM_TCO_FRAME_RATE("TCO Frame Rate", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) HDSPM_TCO_SYNC_SOURCE("TCO Sync Source", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) HDSPM_TCO_WORD_TERM("TCO Word Term", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) HDSPM_TCO_LOCK_CHECK("TCO Input Check", 11),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) HDSPM_TCO_LOCK_CHECK("TCO LTC Valid", 12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) HDSPM_TCO_LTC_FRAMES("TCO Detected Frame Rate", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) HDSPM_TCO_VIDEO_INPUT_FORMAT("Video Input Format", 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) static struct snd_kcontrol_new snd_hdspm_playback_mixer = HDSPM_PLAYBACK_MIXER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) static int hdspm_update_simple_mixer_controls(struct hdspm * hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) for (i = hdspm->ds_out_channels; i < hdspm->ss_out_channels; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) if (hdspm->system_sample_rate > 48000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654) hdspm->playback_mixer_ctls[i]->vd[0].access =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655) SNDRV_CTL_ELEM_ACCESS_INACTIVE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) SNDRV_CTL_ELEM_ACCESS_READ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) SNDRV_CTL_ELEM_ACCESS_VOLATILE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659) hdspm->playback_mixer_ctls[i]->vd[0].access =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) SNDRV_CTL_ELEM_ACCESS_VOLATILE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663) snd_ctl_notify(hdspm->card, SNDRV_CTL_EVENT_MASK_VALUE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) SNDRV_CTL_EVENT_MASK_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665) &hdspm->playback_mixer_ctls[i]->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) static int snd_hdspm_create_controls(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673) struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) unsigned int idx, limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) struct snd_kcontrol *kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678) const struct snd_kcontrol_new *list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) case MADI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) list = snd_hdspm_controls_madi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) limit = ARRAY_SIZE(snd_hdspm_controls_madi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) case MADIface:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) list = snd_hdspm_controls_madiface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687) limit = ARRAY_SIZE(snd_hdspm_controls_madiface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690) list = snd_hdspm_controls_aio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691) limit = ARRAY_SIZE(snd_hdspm_controls_aio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694) list = snd_hdspm_controls_raydat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) limit = ARRAY_SIZE(snd_hdspm_controls_raydat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) case AES32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698) list = snd_hdspm_controls_aes32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699) limit = ARRAY_SIZE(snd_hdspm_controls_aes32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703) if (list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) for (idx = 0; idx < limit; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) err = snd_ctl_add(card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) snd_ctl_new1(&list[idx], hdspm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713) /* create simple 1:1 playback mixer controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714) snd_hdspm_playback_mixer.name = "Chn";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) if (hdspm->system_sample_rate >= 128000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) limit = hdspm->qs_out_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717) } else if (hdspm->system_sample_rate >= 64000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718) limit = hdspm->ds_out_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) limit = hdspm->ss_out_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722) for (idx = 0; idx < limit; ++idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) snd_hdspm_playback_mixer.index = idx + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) kctl = snd_ctl_new1(&snd_hdspm_playback_mixer, hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725) err = snd_ctl_add(card, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) hdspm->playback_mixer_ctls[idx] = kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) if (hdspm->tco) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) /* add tco control elements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) list = snd_hdspm_controls_tco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) limit = ARRAY_SIZE(snd_hdspm_controls_tco);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) for (idx = 0; idx < limit; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) err = snd_ctl_add(card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738) snd_ctl_new1(&list[idx], hdspm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) /*------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) /proc interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) ------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) snd_hdspm_proc_read_tco(struct snd_info_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) struct snd_info_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755) struct hdspm *hdspm = entry->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) unsigned int status, control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757) int a, ltc, frames, seconds, minutes, hours;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) unsigned int period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) u64 freq_const = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760) u32 rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762) snd_iprintf(buffer, "--- TCO ---\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764) status = hdspm_read(hdspm, HDSPM_statusRegister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765) control = hdspm->control_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768) if (status & HDSPM_tco_detect) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) snd_iprintf(buffer, "TCO module detected.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770) a = hdspm_read(hdspm, HDSPM_RD_TCO+4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) if (a & HDSPM_TCO1_LTC_Input_valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772) snd_iprintf(buffer, " LTC valid, ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773) switch (a & (HDSPM_TCO1_LTC_Format_LSB |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774) HDSPM_TCO1_LTC_Format_MSB)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) snd_iprintf(buffer, "24 fps, ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) case HDSPM_TCO1_LTC_Format_LSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) snd_iprintf(buffer, "25 fps, ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) case HDSPM_TCO1_LTC_Format_MSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) snd_iprintf(buffer, "29.97 fps, ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785) snd_iprintf(buffer, "30 fps, ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788) if (a & HDSPM_TCO1_set_drop_frame_flag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789) snd_iprintf(buffer, "drop frame\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791) snd_iprintf(buffer, "full frame\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794) snd_iprintf(buffer, " no LTC\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796) if (a & HDSPM_TCO1_Video_Input_Format_NTSC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797) snd_iprintf(buffer, " Video: NTSC\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) } else if (a & HDSPM_TCO1_Video_Input_Format_PAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) snd_iprintf(buffer, " Video: PAL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) snd_iprintf(buffer, " No video\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803) if (a & HDSPM_TCO1_TCO_lock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) snd_iprintf(buffer, " Sync: lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806) snd_iprintf(buffer, " Sync: no lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) case MADI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) case AES32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812) freq_const = 110069313433624ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816) freq_const = 104857600000000ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818) case MADIface:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819) break; /* no TCO possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) period = hdspm_read(hdspm, HDSPM_RD_PLL_FREQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823) snd_iprintf(buffer, " period: %u\n", period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) /* rate = freq_const/period; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827) rate = div_u64(freq_const, period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) if (control & HDSPM_QuadSpeed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) rate *= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) } else if (control & HDSPM_DoubleSpeed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) rate *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835) snd_iprintf(buffer, " Frequency: %u Hz\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836) (unsigned int) rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) ltc = hdspm_read(hdspm, HDSPM_RD_TCO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) frames = ltc & 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840) ltc >>= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) frames += (ltc & 0x3) * 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) ltc >>= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843) seconds = ltc & 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) ltc >>= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845) seconds += (ltc & 0x7) * 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) ltc >>= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) minutes = ltc & 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) ltc >>= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849) minutes += (ltc & 0x7) * 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) ltc >>= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) hours = ltc & 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) ltc >>= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) hours += (ltc & 0x3) * 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854) snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) " LTC In: %02d:%02d:%02d:%02d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856) hours, minutes, seconds, frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859) snd_iprintf(buffer, "No TCO module detected.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864) snd_hdspm_proc_read_madi(struct snd_info_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) struct snd_info_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) struct hdspm *hdspm = entry->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868) unsigned int status, status2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) char *pref_sync_ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871) char *autosync_ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872) char *system_clock_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) int x, x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) status = hdspm_read(hdspm, HDSPM_statusRegister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876) status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) snd_iprintf(buffer, "%s (Card #%d) Rev.%x Status2first3bits: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) hdspm->card_name, hdspm->card->number + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) hdspm->firmware_rev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881) (status2 & HDSPM_version0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) (status2 & HDSPM_version1) | (status2 &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883) HDSPM_version2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) snd_iprintf(buffer, "HW Serial: 0x%06x%06x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886) (hdspm_read(hdspm, HDSPM_midiStatusIn1)>>8) & 0xFFFFFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) hdspm->serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889) snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890) hdspm->irq, hdspm->port, (unsigned long)hdspm->iobase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892) snd_iprintf(buffer, "--- System ---\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895) "IRQ Pending: Audio=%d, MIDI0=%d, MIDI1=%d, IRQcount=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896) status & HDSPM_audioIRQPending,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) (status & HDSPM_midi0IRQPending) ? 1 : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898) (status & HDSPM_midi1IRQPending) ? 1 : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899) hdspm->irq_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900) snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901) "HW pointer: id = %d, rawptr = %d (%d->%d) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902) "estimated= %ld (bytes)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903) ((status & HDSPM_BufferID) ? 1 : 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) (status & HDSPM_BufferPositionMask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905) (status & HDSPM_BufferPositionMask) %
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) (2 * (int)hdspm->period_bytes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907) ((status & HDSPM_BufferPositionMask) - 64) %
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) (2 * (int)hdspm->period_bytes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909) (long) hdspm_hw_pointer(hdspm) * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911) snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) "MIDI FIFO: Out1=0x%x, Out2=0x%x, In1=0x%x, In2=0x%x \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915) hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916) hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) "MIDIoverMADI FIFO: In=0x%x, Out=0x%x \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) hdspm_read(hdspm, HDSPM_midiStatusIn2) & 0xFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) hdspm_read(hdspm, HDSPM_midiStatusOut2) & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921) snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922) "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923) "status2=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924) hdspm->control_register, hdspm->control2_register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925) status, status2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928) snd_iprintf(buffer, "--- Settings ---\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930) x = hdspm_get_latency(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932) snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933) "Size (Latency): %d samples (2 periods of %lu bytes)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934) x, (unsigned long) hdspm->period_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936) snd_iprintf(buffer, "Line out: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937) (hdspm->control_register & HDSPM_LineOut) ? "on " : "off");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939) snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940) "ClearTrackMarker = %s, Transmit in %s Channel Mode, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941) "Auto Input %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942) (hdspm->control_register & HDSPM_clr_tms) ? "on" : "off",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943) (hdspm->control_register & HDSPM_TX_64ch) ? "64" : "56",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944) (hdspm->control_register & HDSPM_AutoInp) ? "on" : "off");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947) if (!(hdspm->control_register & HDSPM_ClockModeMaster))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948) system_clock_mode = "AutoSync";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) system_clock_mode = "Master";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951) snd_iprintf(buffer, "AutoSync Reference: %s\n", system_clock_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953) switch (hdspm_pref_sync_ref(hdspm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954) case HDSPM_SYNC_FROM_WORD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) pref_sync_ref = "Word Clock";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) case HDSPM_SYNC_FROM_MADI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958) pref_sync_ref = "MADI Sync";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4959) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960) case HDSPM_SYNC_FROM_TCO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961) pref_sync_ref = "TCO";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963) case HDSPM_SYNC_FROM_SYNC_IN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964) pref_sync_ref = "Sync In";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) pref_sync_ref = "XXXX Clock";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) snd_iprintf(buffer, "Preferred Sync Reference: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971) pref_sync_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973) snd_iprintf(buffer, "System Clock Frequency: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974) hdspm->system_sample_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977) snd_iprintf(buffer, "--- Status:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979) x = status & HDSPM_madiSync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980) x2 = status2 & HDSPM_wcSync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) snd_iprintf(buffer, "Inputs MADI=%s, WordClock=%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983) (status & HDSPM_madiLock) ? (x ? "Sync" : "Lock") :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984) "NoLock",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985) (status2 & HDSPM_wcLock) ? (x2 ? "Sync" : "Lock") :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4986) "NoLock");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4988) switch (hdspm_autosync_ref(hdspm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4989) case HDSPM_AUTOSYNC_FROM_SYNC_IN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4990) autosync_ref = "Sync In";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4991) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4992) case HDSPM_AUTOSYNC_FROM_TCO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4993) autosync_ref = "TCO";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4994) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4995) case HDSPM_AUTOSYNC_FROM_WORD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4996) autosync_ref = "Word Clock";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4997) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4998) case HDSPM_AUTOSYNC_FROM_MADI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4999) autosync_ref = "MADI Sync";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5000) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5001) case HDSPM_AUTOSYNC_FROM_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5002) autosync_ref = "Input not valid";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5003) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5004) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5005) autosync_ref = "---";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5006) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5008) snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5009) "AutoSync: Reference= %s, Freq=%d (MADI = %d, Word = %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5010) autosync_ref, hdspm_external_sample_rate(hdspm),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5011) (status & HDSPM_madiFreqMask) >> 22,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5012) (status2 & HDSPM_wcFreqMask) >> 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5014) snd_iprintf(buffer, "Input: %s, Mode=%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5015) (status & HDSPM_AB_int) ? "Coax" : "Optical",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5016) (status & HDSPM_RX_64ch) ? "64 channels" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5017) "56 channels");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5019) /* call readout function for TCO specific status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5020) snd_hdspm_proc_read_tco(entry, buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5022) snd_iprintf(buffer, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5025) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5026) snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5027) struct snd_info_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5028) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5029) struct hdspm *hdspm = entry->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5030) unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5031) unsigned int status2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5032) unsigned int timecode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5033) unsigned int wcLock, wcSync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5034) int pref_syncref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5035) char *autosync_ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5036) int x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5038) status = hdspm_read(hdspm, HDSPM_statusRegister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5039) status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5040) timecode = hdspm_read(hdspm, HDSPM_timecodeRegister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5042) snd_iprintf(buffer, "%s (Card #%d) Rev.%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5043) hdspm->card_name, hdspm->card->number + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5044) hdspm->firmware_rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5046) snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5047) hdspm->irq, hdspm->port, (unsigned long)hdspm->iobase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5049) snd_iprintf(buffer, "--- System ---\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5051) snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5052) "IRQ Pending: Audio=%d, MIDI0=%d, MIDI1=%d, IRQcount=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5053) status & HDSPM_audioIRQPending,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5054) (status & HDSPM_midi0IRQPending) ? 1 : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5055) (status & HDSPM_midi1IRQPending) ? 1 : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5056) hdspm->irq_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5057) snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5058) "HW pointer: id = %d, rawptr = %d (%d->%d) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5059) "estimated= %ld (bytes)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5060) ((status & HDSPM_BufferID) ? 1 : 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5061) (status & HDSPM_BufferPositionMask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5062) (status & HDSPM_BufferPositionMask) %
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5063) (2 * (int)hdspm->period_bytes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5064) ((status & HDSPM_BufferPositionMask) - 64) %
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5065) (2 * (int)hdspm->period_bytes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5066) (long) hdspm_hw_pointer(hdspm) * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5068) snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5069) "MIDI FIFO: Out1=0x%x, Out2=0x%x, In1=0x%x, In2=0x%x \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5070) hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5071) hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5072) hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5073) hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5074) snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5075) "MIDIoverMADI FIFO: In=0x%x, Out=0x%x \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5076) hdspm_read(hdspm, HDSPM_midiStatusIn2) & 0xFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5077) hdspm_read(hdspm, HDSPM_midiStatusOut2) & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5078) snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5079) "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5080) "status2=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5081) hdspm->control_register, hdspm->control2_register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5082) status, status2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5084) snd_iprintf(buffer, "--- Settings ---\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5086) x = hdspm_get_latency(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5088) snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5089) "Size (Latency): %d samples (2 periods of %lu bytes)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5090) x, (unsigned long) hdspm->period_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5092) snd_iprintf(buffer, "Line out: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5093) (hdspm->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5094) control_register & HDSPM_LineOut) ? "on " : "off");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5096) snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5097) "ClearTrackMarker %s, Emphasis %s, Dolby %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5098) (hdspm->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5099) control_register & HDSPM_clr_tms) ? "on" : "off",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5100) (hdspm->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5101) control_register & HDSPM_Emphasis) ? "on" : "off",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5102) (hdspm->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5103) control_register & HDSPM_Dolby) ? "on" : "off");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5106) pref_syncref = hdspm_pref_sync_ref(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5107) if (pref_syncref == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5108) snd_iprintf(buffer, "Preferred Sync Reference: Word Clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5109) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5110) snd_iprintf(buffer, "Preferred Sync Reference: AES%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5111) pref_syncref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5113) snd_iprintf(buffer, "System Clock Frequency: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5114) hdspm->system_sample_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5116) snd_iprintf(buffer, "Double speed: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5117) hdspm->control_register & HDSPM_DS_DoubleWire?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5118) "Double wire" : "Single wire");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5119) snd_iprintf(buffer, "Quad speed: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5120) hdspm->control_register & HDSPM_QS_DoubleWire?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5121) "Double wire" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5122) hdspm->control_register & HDSPM_QS_QuadWire?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5123) "Quad wire" : "Single wire");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5125) snd_iprintf(buffer, "--- Status:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5127) wcLock = status & HDSPM_AES32_wcLock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5128) wcSync = wcLock && (status & HDSPM_AES32_wcSync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5130) snd_iprintf(buffer, "Word: %s Frequency: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5131) (wcLock) ? (wcSync ? "Sync " : "Lock ") : "No Lock",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5132) HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5134) for (x = 0; x < 8; x++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5135) snd_iprintf(buffer, "AES%d: %s Frequency: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5136) x+1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5137) (status2 & (HDSPM_LockAES >> x)) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5138) "Sync " : "No Lock",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5139) HDSPM_bit2freq((timecode >> (4*x)) & 0xF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5142) switch (hdspm_autosync_ref(hdspm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5143) case HDSPM_AES32_AUTOSYNC_FROM_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5144) autosync_ref = "None"; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5145) case HDSPM_AES32_AUTOSYNC_FROM_WORD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5146) autosync_ref = "Word Clock"; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5147) case HDSPM_AES32_AUTOSYNC_FROM_AES1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5148) autosync_ref = "AES1"; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5149) case HDSPM_AES32_AUTOSYNC_FROM_AES2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5150) autosync_ref = "AES2"; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5151) case HDSPM_AES32_AUTOSYNC_FROM_AES3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5152) autosync_ref = "AES3"; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5153) case HDSPM_AES32_AUTOSYNC_FROM_AES4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5154) autosync_ref = "AES4"; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5155) case HDSPM_AES32_AUTOSYNC_FROM_AES5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5156) autosync_ref = "AES5"; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5157) case HDSPM_AES32_AUTOSYNC_FROM_AES6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5158) autosync_ref = "AES6"; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5159) case HDSPM_AES32_AUTOSYNC_FROM_AES7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5160) autosync_ref = "AES7"; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5161) case HDSPM_AES32_AUTOSYNC_FROM_AES8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5162) autosync_ref = "AES8"; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5163) case HDSPM_AES32_AUTOSYNC_FROM_TCO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5164) autosync_ref = "TCO"; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5165) case HDSPM_AES32_AUTOSYNC_FROM_SYNC_IN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5166) autosync_ref = "Sync In"; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5167) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5168) autosync_ref = "---"; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5170) snd_iprintf(buffer, "AutoSync ref = %s\n", autosync_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5172) /* call readout function for TCO specific status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5173) snd_hdspm_proc_read_tco(entry, buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5175) snd_iprintf(buffer, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5178) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5179) snd_hdspm_proc_read_raydat(struct snd_info_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5180) struct snd_info_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5182) struct hdspm *hdspm = entry->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5183) unsigned int status1, status2, status3, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5184) unsigned int lock, sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5186) status1 = hdspm_read(hdspm, HDSPM_RD_STATUS_1); /* s1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5187) status2 = hdspm_read(hdspm, HDSPM_RD_STATUS_2); /* freq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5188) status3 = hdspm_read(hdspm, HDSPM_RD_STATUS_3); /* s2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5190) snd_iprintf(buffer, "STATUS1: 0x%08x\n", status1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5191) snd_iprintf(buffer, "STATUS2: 0x%08x\n", status2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5192) snd_iprintf(buffer, "STATUS3: 0x%08x\n", status3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5195) snd_iprintf(buffer, "\n*** CLOCK MODE\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5197) snd_iprintf(buffer, "Clock mode : %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5198) (hdspm_system_clock_mode(hdspm) == 0) ? "master" : "slave");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5199) snd_iprintf(buffer, "System frequency: %d Hz\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5200) hdspm_get_system_sample_rate(hdspm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5202) snd_iprintf(buffer, "\n*** INPUT STATUS\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5204) lock = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5205) sync = 0x100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5207) for (i = 0; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5208) snd_iprintf(buffer, "s1_input %d: Lock %d, Sync %d, Freq %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5209) i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5210) (status1 & lock) ? 1 : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5211) (status1 & sync) ? 1 : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5212) texts_freq[(status2 >> (i * 4)) & 0xF]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5214) lock = lock<<1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5215) sync = sync<<1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5218) snd_iprintf(buffer, "WC input: Lock %d, Sync %d, Freq %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5219) (status1 & 0x1000000) ? 1 : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5220) (status1 & 0x2000000) ? 1 : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5221) texts_freq[(status1 >> 16) & 0xF]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5223) snd_iprintf(buffer, "TCO input: Lock %d, Sync %d, Freq %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5224) (status1 & 0x4000000) ? 1 : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5225) (status1 & 0x8000000) ? 1 : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5226) texts_freq[(status1 >> 20) & 0xF]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5228) snd_iprintf(buffer, "SYNC IN: Lock %d, Sync %d, Freq %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5229) (status3 & 0x400) ? 1 : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5230) (status3 & 0x800) ? 1 : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5231) texts_freq[(status2 >> 12) & 0xF]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5235) #ifdef CONFIG_SND_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5236) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5237) snd_hdspm_proc_read_debug(struct snd_info_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5238) struct snd_info_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5240) struct hdspm *hdspm = entry->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5242) int j,i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5244) for (i = 0; i < 256 /* 1024*64 */; i += j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5245) snd_iprintf(buffer, "0x%08X: ", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5246) for (j = 0; j < 16; j += 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5247) snd_iprintf(buffer, "%08X ", hdspm_read(hdspm, i + j));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5248) snd_iprintf(buffer, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5251) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5254) static void snd_hdspm_proc_ports_in(struct snd_info_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5255) struct snd_info_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5257) struct hdspm *hdspm = entry->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5258) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5260) snd_iprintf(buffer, "# generated by hdspm\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5262) for (i = 0; i < hdspm->max_channels_in; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5263) snd_iprintf(buffer, "%d=%s\n", i+1, hdspm->port_names_in[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5267) static void snd_hdspm_proc_ports_out(struct snd_info_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5268) struct snd_info_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5270) struct hdspm *hdspm = entry->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5271) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5273) snd_iprintf(buffer, "# generated by hdspm\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5275) for (i = 0; i < hdspm->max_channels_out; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5276) snd_iprintf(buffer, "%d=%s\n", i+1, hdspm->port_names_out[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5281) static void snd_hdspm_proc_init(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5283) void (*read)(struct snd_info_entry *, struct snd_info_buffer *) = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5285) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5286) case AES32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5287) read = snd_hdspm_proc_read_aes32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5288) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5289) case MADI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5290) read = snd_hdspm_proc_read_madi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5291) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5292) case MADIface:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5293) /* read = snd_hdspm_proc_read_madiface; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5294) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5295) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5296) read = snd_hdspm_proc_read_raydat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5297) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5298) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5299) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5302) snd_card_ro_proc_new(hdspm->card, "hdspm", hdspm, read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5303) snd_card_ro_proc_new(hdspm->card, "ports.in", hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5304) snd_hdspm_proc_ports_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5305) snd_card_ro_proc_new(hdspm->card, "ports.out", hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5306) snd_hdspm_proc_ports_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5308) #ifdef CONFIG_SND_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5309) /* debug file to read all hdspm registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5310) snd_card_ro_proc_new(hdspm->card, "debug", hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5311) snd_hdspm_proc_read_debug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5312) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5315) /*------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5316) hdspm intitialize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5317) ------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5319) static int snd_hdspm_set_defaults(struct hdspm * hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5321) /* ASSUMPTION: hdspm->lock is either held, or there is no need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5322) hold it (e.g. during module initialization).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5323) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5325) /* set defaults: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5327) hdspm->settings_register = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5329) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5330) case MADI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5331) case MADIface:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5332) hdspm->control_register =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5333) 0x2 + 0x8 + 0x10 + 0x80 + 0x400 + 0x4000 + 0x1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5334) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5336) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5337) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5338) hdspm->settings_register = 0x1 + 0x1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5339) /* Magic values are: LAT_0, LAT_2, Master, freq1, tx64ch, inp_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5340) * line_out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5341) hdspm->control_register =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5342) 0x2 + 0x8 + 0x10 + 0x80 + 0x400 + 0x4000 + 0x1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5343) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5345) case AES32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5346) hdspm->control_register =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5347) HDSPM_ClockModeMaster | /* Master Clock Mode on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5348) hdspm_encode_latency(7) | /* latency max=8192samples */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5349) HDSPM_SyncRef0 | /* AES1 is syncclock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5350) HDSPM_LineOut | /* Analog output in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5351) HDSPM_Professional; /* Professional mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5352) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5355) hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5357) if (AES32 == hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5358) /* No control2 register for AES32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5359) #ifdef SNDRV_BIG_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5360) hdspm->control2_register = HDSPM_BIGENDIAN_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5361) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5362) hdspm->control2_register = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5363) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5365) hdspm_write(hdspm, HDSPM_control2Reg, hdspm->control2_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5367) hdspm_compute_period_size(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5369) /* silence everything */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5371) all_in_all_mixer(hdspm, 0 * UNITY_GAIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5373) if (hdspm_is_raydat_or_aio(hdspm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5374) hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5376) /* set a default rate so that the channel map is set up. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5377) hdspm_set_rate(hdspm, 48000, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5379) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5383) /*------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5384) interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5385) ------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5387) static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5389) struct hdspm *hdspm = (struct hdspm *) dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5390) unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5391) int i, audio, midi, schedule = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5392) /* cycles_t now; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5394) status = hdspm_read(hdspm, HDSPM_statusRegister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5396) audio = status & HDSPM_audioIRQPending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5397) midi = status & (HDSPM_midi0IRQPending | HDSPM_midi1IRQPending |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5398) HDSPM_midi2IRQPending | HDSPM_midi3IRQPending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5400) /* now = get_cycles(); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5401) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5402) * LAT_2..LAT_0 period counter (win) counter (mac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5403) * 6 4096 ~256053425 ~514672358
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5404) * 5 2048 ~128024983 ~257373821
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5405) * 4 1024 ~64023706 ~128718089
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5406) * 3 512 ~32005945 ~64385999
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5407) * 2 256 ~16003039 ~32260176
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5408) * 1 128 ~7998738 ~16194507
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5409) * 0 64 ~3998231 ~8191558
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5410) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5411) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5412) dev_info(hdspm->card->dev, "snd_hdspm_interrupt %llu @ %llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5413) now-hdspm->last_interrupt, status & 0xFFC0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5414) hdspm->last_interrupt = now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5415) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5417) if (!audio && !midi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5418) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5420) hdspm_write(hdspm, HDSPM_interruptConfirmation, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5421) hdspm->irq_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5424) if (audio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5425) if (hdspm->capture_substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5426) snd_pcm_period_elapsed(hdspm->capture_substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5428) if (hdspm->playback_substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5429) snd_pcm_period_elapsed(hdspm->playback_substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5432) if (midi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5433) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5434) while (i < hdspm->midiPorts) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5435) if ((hdspm_read(hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5436) hdspm->midi[i].statusIn) & 0xff) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5437) (status & hdspm->midi[i].irq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5438) /* we disable interrupts for this input until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5439) * processing is done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5440) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5441) hdspm->control_register &= ~hdspm->midi[i].ie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5442) hdspm_write(hdspm, HDSPM_controlRegister,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5443) hdspm->control_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5444) hdspm->midi[i].pending = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5445) schedule = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5448) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5451) if (schedule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5452) queue_work(system_highpri_wq, &hdspm->midi_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5455) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5458) /*------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5459) pcm interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5460) ------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5463) static snd_pcm_uframes_t snd_hdspm_hw_pointer(struct snd_pcm_substream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5464) *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5465) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5466) struct hdspm *hdspm = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5467) return hdspm_hw_pointer(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5471) static int snd_hdspm_reset(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5473) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5474) struct hdspm *hdspm = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5475) struct snd_pcm_substream *other;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5477) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5478) other = hdspm->capture_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5479) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5480) other = hdspm->playback_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5482) if (hdspm->running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5483) runtime->status->hw_ptr = hdspm_hw_pointer(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5484) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5485) runtime->status->hw_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5486) if (other) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5487) struct snd_pcm_substream *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5488) struct snd_pcm_runtime *oruntime = other->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5489) snd_pcm_group_for_each_entry(s, substream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5490) if (s == other) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5491) oruntime->status->hw_ptr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5492) runtime->status->hw_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5493) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5497) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5500) static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5501) struct snd_pcm_hw_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5503) struct hdspm *hdspm = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5504) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5505) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5506) pid_t this_pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5507) pid_t other_pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5509) spin_lock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5511) if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5512) this_pid = hdspm->playback_pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5513) other_pid = hdspm->capture_pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5514) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5515) this_pid = hdspm->capture_pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5516) other_pid = hdspm->playback_pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5519) if (other_pid > 0 && this_pid != other_pid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5521) /* The other stream is open, and not by the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5522) task as this one. Make sure that the parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5523) that matter are the same.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5524) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5526) if (params_rate(params) != hdspm->system_sample_rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5527) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5528) _snd_pcm_hw_param_setempty(params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5529) SNDRV_PCM_HW_PARAM_RATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5530) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5533) if (params_period_size(params) != hdspm->period_bytes / 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5534) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5535) _snd_pcm_hw_param_setempty(params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5536) SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5537) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5541) /* We're fine. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5542) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5544) /* how to make sure that the rate matches an externally-set one ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5546) spin_lock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5547) err = hdspm_set_rate(hdspm, params_rate(params), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5548) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5549) dev_info(hdspm->card->dev, "err on hdspm_set_rate: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5550) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5551) _snd_pcm_hw_param_setempty(params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5552) SNDRV_PCM_HW_PARAM_RATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5553) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5555) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5557) err = hdspm_set_interrupt_interval(hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5558) params_period_size(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5559) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5560) dev_info(hdspm->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5561) "err on hdspm_set_interrupt_interval: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5562) _snd_pcm_hw_param_setempty(params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5563) SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5564) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5567) /* Memory allocation, takashi's method, dont know if we should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5568) * spinlock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5569) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5570) /* malloc all buffer even if not enabled to get sure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5571) /* Update for MADI rev 204: we need to allocate for all channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5572) * otherwise it doesn't work at 96kHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5574) err =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5575) snd_pcm_lib_malloc_pages(substream, HDSPM_DMA_AREA_BYTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5576) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5577) dev_info(hdspm->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5578) "err on snd_pcm_lib_malloc_pages: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5579) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5582) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5584) for (i = 0; i < params_channels(params); ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5585) int c = hdspm->channel_map_out[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5587) if (c < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5588) continue; /* just make sure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5589) hdspm_set_channel_dma_addr(hdspm, substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5590) HDSPM_pageAddressBufferOut,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5591) c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5592) snd_hdspm_enable_out(hdspm, c, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5595) hdspm->playback_buffer =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5596) (unsigned char *) substream->runtime->dma_area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5597) dev_dbg(hdspm->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5598) "Allocated sample buffer for playback at %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5599) hdspm->playback_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5600) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5601) for (i = 0; i < params_channels(params); ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5602) int c = hdspm->channel_map_in[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5604) if (c < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5605) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5606) hdspm_set_channel_dma_addr(hdspm, substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5607) HDSPM_pageAddressBufferIn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5608) c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5609) snd_hdspm_enable_in(hdspm, c, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5612) hdspm->capture_buffer =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5613) (unsigned char *) substream->runtime->dma_area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5614) dev_dbg(hdspm->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5615) "Allocated sample buffer for capture at %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5616) hdspm->capture_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5619) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5620) dev_dbg(hdspm->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5621) "Allocated sample buffer for %s at 0x%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5622) substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5623) "playback" : "capture",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5624) snd_pcm_sgbuf_get_addr(substream, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5625) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5626) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5627) dev_dbg(hdspm->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5628) "set_hwparams: %s %d Hz, %d channels, bs = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5629) substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5630) "playback" : "capture",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5631) params_rate(params), params_channels(params),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5632) params_buffer_size(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5633) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5636) /* For AES cards, the float format bit is the same as the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5637) * preferred sync reference. Since we don't want to break
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5638) * sync settings, we have to skip the remaining part of this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5639) * function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5640) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5641) if (hdspm->io_type == AES32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5642) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5646) /* Switch to native float format if requested */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5647) if (SNDRV_PCM_FORMAT_FLOAT_LE == params_format(params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5648) if (!(hdspm->control_register & HDSPe_FLOAT_FORMAT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5649) dev_info(hdspm->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5650) "Switching to native 32bit LE float format.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5652) hdspm->control_register |= HDSPe_FLOAT_FORMAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5653) } else if (SNDRV_PCM_FORMAT_S32_LE == params_format(params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5654) if (hdspm->control_register & HDSPe_FLOAT_FORMAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5655) dev_info(hdspm->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5656) "Switching to native 32bit LE integer format.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5658) hdspm->control_register &= ~HDSPe_FLOAT_FORMAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5660) hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5662) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5665) static int snd_hdspm_hw_free(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5667) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5668) struct hdspm *hdspm = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5670) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5671) /* Just disable all channels. The saving when disabling a */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5672) /* smaller set is not worth the trouble. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5673) for (i = 0; i < HDSPM_MAX_CHANNELS; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5674) snd_hdspm_enable_out(hdspm, i, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5676) hdspm->playback_buffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5677) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5678) for (i = 0; i < HDSPM_MAX_CHANNELS; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5679) snd_hdspm_enable_in(hdspm, i, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5681) hdspm->capture_buffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5684) snd_pcm_lib_free_pages(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5686) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5690) static int snd_hdspm_channel_info(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5691) struct snd_pcm_channel_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5693) struct hdspm *hdspm = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5694) unsigned int channel = info->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5696) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5697) if (snd_BUG_ON(channel >= hdspm->max_channels_out)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5698) dev_info(hdspm->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5699) "snd_hdspm_channel_info: output channel out of range (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5700) channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5701) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5704) channel = array_index_nospec(channel, hdspm->max_channels_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5705) if (hdspm->channel_map_out[channel] < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5706) dev_info(hdspm->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5707) "snd_hdspm_channel_info: output channel %d mapped out\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5708) channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5709) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5712) info->offset = hdspm->channel_map_out[channel] *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5713) HDSPM_CHANNEL_BUFFER_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5714) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5715) if (snd_BUG_ON(channel >= hdspm->max_channels_in)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5716) dev_info(hdspm->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5717) "snd_hdspm_channel_info: input channel out of range (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5718) channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5719) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5722) channel = array_index_nospec(channel, hdspm->max_channels_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5723) if (hdspm->channel_map_in[channel] < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5724) dev_info(hdspm->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5725) "snd_hdspm_channel_info: input channel %d mapped out\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5726) channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5727) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5730) info->offset = hdspm->channel_map_in[channel] *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5731) HDSPM_CHANNEL_BUFFER_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5734) info->first = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5735) info->step = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5736) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5740) static int snd_hdspm_ioctl(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5741) unsigned int cmd, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5742) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5743) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5744) case SNDRV_PCM_IOCTL1_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5745) return snd_hdspm_reset(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5747) case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5749) struct snd_pcm_channel_info *info = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5750) return snd_hdspm_channel_info(substream, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5752) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5753) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5756) return snd_pcm_lib_ioctl(substream, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5759) static int snd_hdspm_trigger(struct snd_pcm_substream *substream, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5760) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5761) struct hdspm *hdspm = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5762) struct snd_pcm_substream *other;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5763) int running;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5765) spin_lock(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5766) running = hdspm->running;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5767) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5768) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5769) running |= 1 << substream->stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5770) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5771) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5772) running &= ~(1 << substream->stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5773) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5774) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5775) snd_BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5776) spin_unlock(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5777) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5779) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5780) other = hdspm->capture_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5781) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5782) other = hdspm->playback_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5784) if (other) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5785) struct snd_pcm_substream *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5786) snd_pcm_group_for_each_entry(s, substream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5787) if (s == other) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5788) snd_pcm_trigger_done(s, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5789) if (cmd == SNDRV_PCM_TRIGGER_START)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5790) running |= 1 << s->stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5791) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5792) running &= ~(1 << s->stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5793) goto _ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5796) if (cmd == SNDRV_PCM_TRIGGER_START) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5797) if (!(running & (1 << SNDRV_PCM_STREAM_PLAYBACK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5798) && substream->stream ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5799) SNDRV_PCM_STREAM_CAPTURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5800) hdspm_silence_playback(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5801) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5802) if (running &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5803) substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5804) hdspm_silence_playback(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5806) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5807) if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5808) hdspm_silence_playback(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5810) _ok:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5811) snd_pcm_trigger_done(substream, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5812) if (!hdspm->running && running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5813) hdspm_start_audio(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5814) else if (hdspm->running && !running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5815) hdspm_stop_audio(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5816) hdspm->running = running;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5817) spin_unlock(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5819) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5822) static int snd_hdspm_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5824) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5827) static const struct snd_pcm_hardware snd_hdspm_playback_subinfo = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5828) .info = (SNDRV_PCM_INFO_MMAP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5829) SNDRV_PCM_INFO_MMAP_VALID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5830) SNDRV_PCM_INFO_NONINTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5831) SNDRV_PCM_INFO_SYNC_START | SNDRV_PCM_INFO_DOUBLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5832) .formats = SNDRV_PCM_FMTBIT_S32_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5833) .rates = (SNDRV_PCM_RATE_32000 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5834) SNDRV_PCM_RATE_44100 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5835) SNDRV_PCM_RATE_48000 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5836) SNDRV_PCM_RATE_64000 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5837) SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5838) SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000 ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5839) .rate_min = 32000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5840) .rate_max = 192000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5841) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5842) .channels_max = HDSPM_MAX_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5843) .buffer_bytes_max =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5844) HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5845) .period_bytes_min = (32 * 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5846) .period_bytes_max = (8192 * 4) * HDSPM_MAX_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5847) .periods_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5848) .periods_max = 512,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5849) .fifo_size = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5850) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5852) static const struct snd_pcm_hardware snd_hdspm_capture_subinfo = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5853) .info = (SNDRV_PCM_INFO_MMAP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5854) SNDRV_PCM_INFO_MMAP_VALID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5855) SNDRV_PCM_INFO_NONINTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5856) SNDRV_PCM_INFO_SYNC_START),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5857) .formats = SNDRV_PCM_FMTBIT_S32_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5858) .rates = (SNDRV_PCM_RATE_32000 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5859) SNDRV_PCM_RATE_44100 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5860) SNDRV_PCM_RATE_48000 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5861) SNDRV_PCM_RATE_64000 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5862) SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5863) SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5864) .rate_min = 32000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5865) .rate_max = 192000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5866) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5867) .channels_max = HDSPM_MAX_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5868) .buffer_bytes_max =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5869) HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5870) .period_bytes_min = (32 * 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5871) .period_bytes_max = (8192 * 4) * HDSPM_MAX_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5872) .periods_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5873) .periods_max = 512,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5874) .fifo_size = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5875) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5877) static int snd_hdspm_hw_rule_in_channels_rate(struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5878) struct snd_pcm_hw_rule *rule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5880) struct hdspm *hdspm = rule->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5881) struct snd_interval *c =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5882) hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5883) struct snd_interval *r =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5884) hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5886) if (r->min > 96000 && r->max <= 192000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5887) struct snd_interval t = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5888) .min = hdspm->qs_in_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5889) .max = hdspm->qs_in_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5890) .integer = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5891) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5892) return snd_interval_refine(c, &t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5893) } else if (r->min > 48000 && r->max <= 96000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5894) struct snd_interval t = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5895) .min = hdspm->ds_in_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5896) .max = hdspm->ds_in_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5897) .integer = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5898) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5899) return snd_interval_refine(c, &t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5900) } else if (r->max < 64000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5901) struct snd_interval t = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5902) .min = hdspm->ss_in_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5903) .max = hdspm->ss_in_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5904) .integer = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5905) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5906) return snd_interval_refine(c, &t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5909) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5912) static int snd_hdspm_hw_rule_out_channels_rate(struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5913) struct snd_pcm_hw_rule * rule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5914) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5915) struct hdspm *hdspm = rule->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5916) struct snd_interval *c =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5917) hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5918) struct snd_interval *r =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5919) hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5921) if (r->min > 96000 && r->max <= 192000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5922) struct snd_interval t = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5923) .min = hdspm->qs_out_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5924) .max = hdspm->qs_out_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5925) .integer = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5926) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5927) return snd_interval_refine(c, &t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5928) } else if (r->min > 48000 && r->max <= 96000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5929) struct snd_interval t = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5930) .min = hdspm->ds_out_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5931) .max = hdspm->ds_out_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5932) .integer = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5933) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5934) return snd_interval_refine(c, &t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5935) } else if (r->max < 64000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5936) struct snd_interval t = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5937) .min = hdspm->ss_out_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5938) .max = hdspm->ss_out_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5939) .integer = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5940) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5941) return snd_interval_refine(c, &t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5942) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5944) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5947) static int snd_hdspm_hw_rule_rate_in_channels(struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5948) struct snd_pcm_hw_rule * rule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5949) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5950) struct hdspm *hdspm = rule->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5951) struct snd_interval *c =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5952) hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5953) struct snd_interval *r =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5954) hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5956) if (c->min >= hdspm->ss_in_channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5957) struct snd_interval t = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5958) .min = 32000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5959) .max = 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5960) .integer = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5961) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5962) return snd_interval_refine(r, &t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5963) } else if (c->max <= hdspm->qs_in_channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5964) struct snd_interval t = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5965) .min = 128000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5966) .max = 192000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5967) .integer = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5968) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5969) return snd_interval_refine(r, &t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5970) } else if (c->max <= hdspm->ds_in_channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5971) struct snd_interval t = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5972) .min = 64000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5973) .max = 96000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5974) .integer = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5975) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5976) return snd_interval_refine(r, &t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5979) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5981) static int snd_hdspm_hw_rule_rate_out_channels(struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5982) struct snd_pcm_hw_rule *rule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5983) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5984) struct hdspm *hdspm = rule->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5985) struct snd_interval *c =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5986) hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5987) struct snd_interval *r =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5988) hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5990) if (c->min >= hdspm->ss_out_channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5991) struct snd_interval t = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5992) .min = 32000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5993) .max = 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5994) .integer = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5995) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5996) return snd_interval_refine(r, &t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5997) } else if (c->max <= hdspm->qs_out_channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5998) struct snd_interval t = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5999) .min = 128000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6000) .max = 192000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6001) .integer = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6002) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6003) return snd_interval_refine(r, &t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6004) } else if (c->max <= hdspm->ds_out_channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6005) struct snd_interval t = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6006) .min = 64000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6007) .max = 96000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6008) .integer = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6009) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6010) return snd_interval_refine(r, &t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6013) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6016) static int snd_hdspm_hw_rule_in_channels(struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6017) struct snd_pcm_hw_rule *rule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6018) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6019) unsigned int list[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6020) struct hdspm *hdspm = rule->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6021) struct snd_interval *c = hw_param_interval(params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6022) SNDRV_PCM_HW_PARAM_CHANNELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6024) list[0] = hdspm->qs_in_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6025) list[1] = hdspm->ds_in_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6026) list[2] = hdspm->ss_in_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6027) return snd_interval_list(c, 3, list, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6030) static int snd_hdspm_hw_rule_out_channels(struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6031) struct snd_pcm_hw_rule *rule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6033) unsigned int list[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6034) struct hdspm *hdspm = rule->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6035) struct snd_interval *c = hw_param_interval(params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6036) SNDRV_PCM_HW_PARAM_CHANNELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6038) list[0] = hdspm->qs_out_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6039) list[1] = hdspm->ds_out_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6040) list[2] = hdspm->ss_out_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6041) return snd_interval_list(c, 3, list, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6045) static const unsigned int hdspm_aes32_sample_rates[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6046) 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6047) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6049) static const struct snd_pcm_hw_constraint_list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6050) hdspm_hw_constraints_aes32_sample_rates = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6051) .count = ARRAY_SIZE(hdspm_aes32_sample_rates),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6052) .list = hdspm_aes32_sample_rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6053) .mask = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6054) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6056) static int snd_hdspm_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6057) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6058) struct hdspm *hdspm = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6059) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6060) bool playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6062) spin_lock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6063) snd_pcm_set_sync(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6064) runtime->hw = (playback) ? snd_hdspm_playback_subinfo :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6065) snd_hdspm_capture_subinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6067) if (playback) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6068) if (!hdspm->capture_substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6069) hdspm_stop_audio(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6071) hdspm->playback_pid = current->pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6072) hdspm->playback_substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6073) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6074) if (!hdspm->playback_substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6075) hdspm_stop_audio(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6077) hdspm->capture_pid = current->pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6078) hdspm->capture_substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6081) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6083) snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6084) snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6086) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6087) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6088) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6089) snd_pcm_hw_constraint_minmax(runtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6090) SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6091) 32, 4096);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6092) /* RayDAT & AIO have a fixed buffer of 16384 samples per channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6093) snd_pcm_hw_constraint_single(runtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6094) SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6095) 16384);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6096) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6098) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6099) snd_pcm_hw_constraint_minmax(runtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6100) SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6101) 64, 8192);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6102) snd_pcm_hw_constraint_single(runtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6103) SNDRV_PCM_HW_PARAM_PERIODS, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6104) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6107) if (AES32 == hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6108) runtime->hw.rates |= SNDRV_PCM_RATE_KNOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6109) snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6110) &hdspm_hw_constraints_aes32_sample_rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6111) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6112) snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6113) (playback ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6114) snd_hdspm_hw_rule_rate_out_channels :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6115) snd_hdspm_hw_rule_rate_in_channels), hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6116) SNDRV_PCM_HW_PARAM_CHANNELS, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6119) snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6120) (playback ? snd_hdspm_hw_rule_out_channels :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6121) snd_hdspm_hw_rule_in_channels), hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6122) SNDRV_PCM_HW_PARAM_CHANNELS, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6124) snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6125) (playback ? snd_hdspm_hw_rule_out_channels_rate :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6126) snd_hdspm_hw_rule_in_channels_rate), hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6127) SNDRV_PCM_HW_PARAM_RATE, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6129) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6132) static int snd_hdspm_release(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6134) struct hdspm *hdspm = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6135) bool playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6137) spin_lock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6139) if (playback) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6140) hdspm->playback_pid = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6141) hdspm->playback_substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6142) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6143) hdspm->capture_pid = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6144) hdspm->capture_substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6147) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6149) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6152) static int snd_hdspm_hwdep_dummy_op(struct snd_hwdep *hw, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6154) /* we have nothing to initialize but the call is required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6155) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6158) static inline int copy_u32_le(void __user *dest, void __iomem *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6160) u32 val = readl(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6161) return copy_to_user(dest, &val, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6164) static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6165) unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6167) void __user *argp = (void __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6168) struct hdspm *hdspm = hw->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6169) struct hdspm_mixer_ioctl mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6170) struct hdspm_config info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6171) struct hdspm_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6172) struct hdspm_version hdspm_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6173) struct hdspm_peak_rms *levels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6174) struct hdspm_ltc ltc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6175) unsigned int statusregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6176) long unsigned int s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6177) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6179) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6181) case SNDRV_HDSPM_IOCTL_GET_PEAK_RMS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6182) levels = &hdspm->peak_rms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6183) for (i = 0; i < HDSPM_MAX_CHANNELS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6184) levels->input_peaks[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6185) readl(hdspm->iobase +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6186) HDSPM_MADI_INPUT_PEAK + i*4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6187) levels->playback_peaks[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6188) readl(hdspm->iobase +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6189) HDSPM_MADI_PLAYBACK_PEAK + i*4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6190) levels->output_peaks[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6191) readl(hdspm->iobase +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6192) HDSPM_MADI_OUTPUT_PEAK + i*4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6194) levels->input_rms[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6195) ((uint64_t) readl(hdspm->iobase +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6196) HDSPM_MADI_INPUT_RMS_H + i*4) << 32) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6197) (uint64_t) readl(hdspm->iobase +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6198) HDSPM_MADI_INPUT_RMS_L + i*4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6199) levels->playback_rms[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6200) ((uint64_t)readl(hdspm->iobase +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6201) HDSPM_MADI_PLAYBACK_RMS_H+i*4) << 32) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6202) (uint64_t)readl(hdspm->iobase +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6203) HDSPM_MADI_PLAYBACK_RMS_L + i*4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6204) levels->output_rms[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6205) ((uint64_t)readl(hdspm->iobase +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6206) HDSPM_MADI_OUTPUT_RMS_H + i*4) << 32) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6207) (uint64_t)readl(hdspm->iobase +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6208) HDSPM_MADI_OUTPUT_RMS_L + i*4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6211) if (hdspm->system_sample_rate > 96000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6212) levels->speed = qs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6213) } else if (hdspm->system_sample_rate > 48000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6214) levels->speed = ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6215) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6216) levels->speed = ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6218) levels->status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6220) s = copy_to_user(argp, levels, sizeof(*levels));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6221) if (0 != s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6222) /* dev_err(hdspm->card->dev, "copy_to_user(.., .., %lu): %lu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6223) [Levels]\n", sizeof(struct hdspm_peak_rms), s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6224) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6225) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6227) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6229) case SNDRV_HDSPM_IOCTL_GET_LTC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6230) ltc.ltc = hdspm_read(hdspm, HDSPM_RD_TCO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6231) i = hdspm_read(hdspm, HDSPM_RD_TCO + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6232) if (i & HDSPM_TCO1_LTC_Input_valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6233) switch (i & (HDSPM_TCO1_LTC_Format_LSB |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6234) HDSPM_TCO1_LTC_Format_MSB)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6235) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6236) ltc.format = fps_24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6237) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6238) case HDSPM_TCO1_LTC_Format_LSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6239) ltc.format = fps_25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6240) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6241) case HDSPM_TCO1_LTC_Format_MSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6242) ltc.format = fps_2997;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6243) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6244) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6245) ltc.format = fps_30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6246) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6248) if (i & HDSPM_TCO1_set_drop_frame_flag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6249) ltc.frame = drop_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6250) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6251) ltc.frame = full_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6253) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6254) ltc.format = format_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6255) ltc.frame = frame_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6257) if (i & HDSPM_TCO1_Video_Input_Format_NTSC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6258) ltc.input_format = ntsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6259) } else if (i & HDSPM_TCO1_Video_Input_Format_PAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6260) ltc.input_format = pal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6261) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6262) ltc.input_format = no_video;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6265) s = copy_to_user(argp, <c, sizeof(ltc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6266) if (0 != s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6267) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6268) dev_err(hdspm->card->dev, "copy_to_user(.., .., %lu): %lu [LTC]\n", sizeof(struct hdspm_ltc), s); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6269) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6272) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6274) case SNDRV_HDSPM_IOCTL_GET_CONFIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6276) memset(&info, 0, sizeof(info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6277) spin_lock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6278) info.pref_sync_ref = hdspm_pref_sync_ref(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6279) info.wordclock_sync_check = hdspm_wc_sync_check(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6281) info.system_sample_rate = hdspm->system_sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6282) info.autosync_sample_rate =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6283) hdspm_external_sample_rate(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6284) info.system_clock_mode = hdspm_system_clock_mode(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6285) info.clock_source = hdspm_clock_source(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6286) info.autosync_ref = hdspm_autosync_ref(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6287) info.line_out = hdspm_toggle_setting(hdspm, HDSPM_LineOut);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6288) info.passthru = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6289) spin_unlock_irq(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6290) if (copy_to_user(argp, &info, sizeof(info)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6291) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6292) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6294) case SNDRV_HDSPM_IOCTL_GET_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6295) memset(&status, 0, sizeof(status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6297) status.card_type = hdspm->io_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6299) status.autosync_source = hdspm_autosync_ref(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6301) status.card_clock = 110069313433624ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6302) status.master_period = hdspm_read(hdspm, HDSPM_RD_PLL_FREQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6304) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6305) case MADI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6306) case MADIface:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6307) status.card_specific.madi.sync_wc =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6308) hdspm_wc_sync_check(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6309) status.card_specific.madi.sync_madi =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6310) hdspm_madi_sync_check(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6311) status.card_specific.madi.sync_tco =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6312) hdspm_tco_sync_check(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6313) status.card_specific.madi.sync_in =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6314) hdspm_sync_in_sync_check(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6316) statusregister =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6317) hdspm_read(hdspm, HDSPM_statusRegister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6318) status.card_specific.madi.madi_input =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6319) (statusregister & HDSPM_AB_int) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6320) status.card_specific.madi.channel_format =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6321) (statusregister & HDSPM_RX_64ch) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6322) /* TODO: Mac driver sets it when f_s>48kHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6323) status.card_specific.madi.frame_format = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6325) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6326) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6329) if (copy_to_user(argp, &status, sizeof(status)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6330) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6333) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6335) case SNDRV_HDSPM_IOCTL_GET_VERSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6336) memset(&hdspm_version, 0, sizeof(hdspm_version));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6338) hdspm_version.card_type = hdspm->io_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6339) strlcpy(hdspm_version.cardname, hdspm->card_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6340) sizeof(hdspm_version.cardname));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6341) hdspm_version.serial = hdspm->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6342) hdspm_version.firmware_rev = hdspm->firmware_rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6343) hdspm_version.addons = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6344) if (hdspm->tco)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6345) hdspm_version.addons |= HDSPM_ADDON_TCO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6347) if (copy_to_user(argp, &hdspm_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6348) sizeof(hdspm_version)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6349) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6350) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6352) case SNDRV_HDSPM_IOCTL_GET_MIXER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6353) if (copy_from_user(&mixer, argp, sizeof(mixer)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6354) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6355) if (copy_to_user((void __user *)mixer.mixer, hdspm->mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6356) sizeof(*mixer.mixer)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6357) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6358) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6360) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6361) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6363) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6366) static const struct snd_pcm_ops snd_hdspm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6367) .open = snd_hdspm_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6368) .close = snd_hdspm_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6369) .ioctl = snd_hdspm_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6370) .hw_params = snd_hdspm_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6371) .hw_free = snd_hdspm_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6372) .prepare = snd_hdspm_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6373) .trigger = snd_hdspm_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6374) .pointer = snd_hdspm_hw_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6375) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6377) static int snd_hdspm_create_hwdep(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6378) struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6380) struct snd_hwdep *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6381) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6383) err = snd_hwdep_new(card, "HDSPM hwdep", 0, &hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6384) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6385) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6387) hdspm->hwdep = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6388) hw->private_data = hdspm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6389) strcpy(hw->name, "HDSPM hwdep interface");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6391) hw->ops.open = snd_hdspm_hwdep_dummy_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6392) hw->ops.ioctl = snd_hdspm_hwdep_ioctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6393) hw->ops.ioctl_compat = snd_hdspm_hwdep_ioctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6394) hw->ops.release = snd_hdspm_hwdep_dummy_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6396) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6400) /*------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6401) memory interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6402) ------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6403) static int snd_hdspm_preallocate_memory(struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6405) struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6406) size_t wanted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6408) pcm = hdspm->pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6410) wanted = HDSPM_DMA_AREA_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6412) snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6413) &hdspm->pci->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6414) wanted, wanted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6415) dev_dbg(hdspm->card->dev, " Preallocated %zd Bytes\n", wanted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6416) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6419) /* Inform the card what DMA addresses to use for the indicated channel. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6420) /* Each channel got 16 4K pages allocated for DMA transfers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6421) static void hdspm_set_channel_dma_addr(struct hdspm *hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6422) struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6423) unsigned int reg, int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6425) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6427) for (i = channel * 16; i < channel * 16 + 16; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6428) hdspm_write(hdspm, reg + 4 * i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6429) snd_pcm_sgbuf_get_addr(substream, 4096 * i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6433) /* ------------- ALSA Devices ---------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6434) static int snd_hdspm_create_pcm(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6435) struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6437) struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6438) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6440) err = snd_pcm_new(card, hdspm->card_name, 0, 1, 1, &pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6441) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6442) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6444) hdspm->pcm = pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6445) pcm->private_data = hdspm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6446) strcpy(pcm->name, hdspm->card_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6448) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6449) &snd_hdspm_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6450) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6451) &snd_hdspm_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6453) pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6455) err = snd_hdspm_preallocate_memory(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6456) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6457) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6459) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6462) static inline void snd_hdspm_initialize_midi_flush(struct hdspm * hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6464) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6466) for (i = 0; i < hdspm->midiPorts; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6467) snd_hdspm_flush_midi_input(hdspm, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6470) static int snd_hdspm_create_alsa_devices(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6471) struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6473) int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6475) dev_dbg(card->dev, "Create card...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6476) err = snd_hdspm_create_pcm(card, hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6477) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6478) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6480) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6481) while (i < hdspm->midiPorts) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6482) err = snd_hdspm_create_midi(card, hdspm, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6483) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6484) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6486) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6489) err = snd_hdspm_create_controls(card, hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6490) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6491) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6493) err = snd_hdspm_create_hwdep(card, hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6494) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6495) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6497) dev_dbg(card->dev, "proc init...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6498) snd_hdspm_proc_init(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6500) hdspm->system_sample_rate = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6501) hdspm->last_external_sample_rate = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6502) hdspm->last_internal_sample_rate = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6503) hdspm->playback_pid = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6504) hdspm->capture_pid = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6505) hdspm->capture_substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6506) hdspm->playback_substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6508) dev_dbg(card->dev, "Set defaults...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6509) err = snd_hdspm_set_defaults(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6510) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6511) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6513) dev_dbg(card->dev, "Update mixer controls...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6514) hdspm_update_simple_mixer_controls(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6516) dev_dbg(card->dev, "Initializing complete?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6518) err = snd_card_register(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6519) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6520) dev_err(card->dev, "error registering card\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6521) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6524) dev_dbg(card->dev, "... yes now\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6526) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6529) static int snd_hdspm_create(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6530) struct hdspm *hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6533) struct pci_dev *pci = hdspm->pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6534) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6535) unsigned long io_extent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6537) hdspm->irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6538) hdspm->card = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6540) spin_lock_init(&hdspm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6541) INIT_WORK(&hdspm->midi_work, hdspm_midi_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6543) pci_read_config_word(hdspm->pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6544) PCI_CLASS_REVISION, &hdspm->firmware_rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6546) strcpy(card->mixername, "Xilinx FPGA");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6547) strcpy(card->driver, "HDSPM");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6549) switch (hdspm->firmware_rev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6550) case HDSPM_RAYDAT_REV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6551) hdspm->io_type = RayDAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6552) hdspm->card_name = "RME RayDAT";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6553) hdspm->midiPorts = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6554) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6555) case HDSPM_AIO_REV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6556) hdspm->io_type = AIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6557) hdspm->card_name = "RME AIO";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6558) hdspm->midiPorts = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6559) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6560) case HDSPM_MADIFACE_REV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6561) hdspm->io_type = MADIface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6562) hdspm->card_name = "RME MADIface";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6563) hdspm->midiPorts = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6564) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6565) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6566) if ((hdspm->firmware_rev == 0xf0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6567) ((hdspm->firmware_rev >= 0xe6) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6568) (hdspm->firmware_rev <= 0xea))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6569) hdspm->io_type = AES32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6570) hdspm->card_name = "RME AES32";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6571) hdspm->midiPorts = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6572) } else if ((hdspm->firmware_rev == 0xd2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6573) ((hdspm->firmware_rev >= 0xc8) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6574) (hdspm->firmware_rev <= 0xcf))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6575) hdspm->io_type = MADI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6576) hdspm->card_name = "RME MADI";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6577) hdspm->midiPorts = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6578) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6579) dev_err(card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6580) "unknown firmware revision %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6581) hdspm->firmware_rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6582) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6586) err = pci_enable_device(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6587) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6588) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6590) pci_set_master(hdspm->pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6592) err = pci_request_regions(pci, "hdspm");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6593) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6594) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6596) hdspm->port = pci_resource_start(pci, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6597) io_extent = pci_resource_len(pci, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6599) dev_dbg(card->dev, "grabbed memory region 0x%lx-0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6600) hdspm->port, hdspm->port + io_extent - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6602) hdspm->iobase = ioremap(hdspm->port, io_extent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6603) if (!hdspm->iobase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6604) dev_err(card->dev, "unable to remap region 0x%lx-0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6605) hdspm->port, hdspm->port + io_extent - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6606) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6608) dev_dbg(card->dev, "remapped region (0x%lx) 0x%lx-0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6609) (unsigned long)hdspm->iobase, hdspm->port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6610) hdspm->port + io_extent - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6612) if (request_irq(pci->irq, snd_hdspm_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6613) IRQF_SHARED, KBUILD_MODNAME, hdspm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6614) dev_err(card->dev, "unable to use IRQ %d\n", pci->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6615) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6618) dev_dbg(card->dev, "use IRQ %d\n", pci->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6620) hdspm->irq = pci->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6621) card->sync_irq = hdspm->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6623) dev_dbg(card->dev, "kmalloc Mixer memory of %zd Bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6624) sizeof(*hdspm->mixer));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6625) hdspm->mixer = kzalloc(sizeof(*hdspm->mixer), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6626) if (!hdspm->mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6627) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6629) hdspm->port_names_in = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6630) hdspm->port_names_out = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6632) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6633) case AES32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6634) hdspm->ss_in_channels = hdspm->ss_out_channels = AES32_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6635) hdspm->ds_in_channels = hdspm->ds_out_channels = AES32_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6636) hdspm->qs_in_channels = hdspm->qs_out_channels = AES32_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6638) hdspm->channel_map_in_ss = hdspm->channel_map_out_ss =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6639) channel_map_aes32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6640) hdspm->channel_map_in_ds = hdspm->channel_map_out_ds =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6641) channel_map_aes32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6642) hdspm->channel_map_in_qs = hdspm->channel_map_out_qs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6643) channel_map_aes32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6644) hdspm->port_names_in_ss = hdspm->port_names_out_ss =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6645) texts_ports_aes32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6646) hdspm->port_names_in_ds = hdspm->port_names_out_ds =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6647) texts_ports_aes32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6648) hdspm->port_names_in_qs = hdspm->port_names_out_qs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6649) texts_ports_aes32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6651) hdspm->max_channels_out = hdspm->max_channels_in =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6652) AES32_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6653) hdspm->port_names_in = hdspm->port_names_out =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6654) texts_ports_aes32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6655) hdspm->channel_map_in = hdspm->channel_map_out =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6656) channel_map_aes32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6658) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6660) case MADI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6661) case MADIface:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6662) hdspm->ss_in_channels = hdspm->ss_out_channels =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6663) MADI_SS_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6664) hdspm->ds_in_channels = hdspm->ds_out_channels =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6665) MADI_DS_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6666) hdspm->qs_in_channels = hdspm->qs_out_channels =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6667) MADI_QS_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6669) hdspm->channel_map_in_ss = hdspm->channel_map_out_ss =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6670) channel_map_unity_ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6671) hdspm->channel_map_in_ds = hdspm->channel_map_out_ds =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6672) channel_map_unity_ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6673) hdspm->channel_map_in_qs = hdspm->channel_map_out_qs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6674) channel_map_unity_ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6676) hdspm->port_names_in_ss = hdspm->port_names_out_ss =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6677) texts_ports_madi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6678) hdspm->port_names_in_ds = hdspm->port_names_out_ds =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6679) texts_ports_madi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6680) hdspm->port_names_in_qs = hdspm->port_names_out_qs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6681) texts_ports_madi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6682) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6684) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6685) hdspm->ss_in_channels = AIO_IN_SS_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6686) hdspm->ds_in_channels = AIO_IN_DS_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6687) hdspm->qs_in_channels = AIO_IN_QS_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6688) hdspm->ss_out_channels = AIO_OUT_SS_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6689) hdspm->ds_out_channels = AIO_OUT_DS_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6690) hdspm->qs_out_channels = AIO_OUT_QS_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6692) if (0 == (hdspm_read(hdspm, HDSPM_statusRegister2) & HDSPM_s2_AEBI_D)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6693) dev_info(card->dev, "AEB input board found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6694) hdspm->ss_in_channels += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6695) hdspm->ds_in_channels += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6696) hdspm->qs_in_channels += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6699) if (0 == (hdspm_read(hdspm, HDSPM_statusRegister2) & HDSPM_s2_AEBO_D)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6700) dev_info(card->dev, "AEB output board found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6701) hdspm->ss_out_channels += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6702) hdspm->ds_out_channels += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6703) hdspm->qs_out_channels += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6706) hdspm->channel_map_out_ss = channel_map_aio_out_ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6707) hdspm->channel_map_out_ds = channel_map_aio_out_ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6708) hdspm->channel_map_out_qs = channel_map_aio_out_qs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6710) hdspm->channel_map_in_ss = channel_map_aio_in_ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6711) hdspm->channel_map_in_ds = channel_map_aio_in_ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6712) hdspm->channel_map_in_qs = channel_map_aio_in_qs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6714) hdspm->port_names_in_ss = texts_ports_aio_in_ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6715) hdspm->port_names_out_ss = texts_ports_aio_out_ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6716) hdspm->port_names_in_ds = texts_ports_aio_in_ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6717) hdspm->port_names_out_ds = texts_ports_aio_out_ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6718) hdspm->port_names_in_qs = texts_ports_aio_in_qs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6719) hdspm->port_names_out_qs = texts_ports_aio_out_qs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6721) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6723) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6724) hdspm->ss_in_channels = hdspm->ss_out_channels =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6725) RAYDAT_SS_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6726) hdspm->ds_in_channels = hdspm->ds_out_channels =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6727) RAYDAT_DS_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6728) hdspm->qs_in_channels = hdspm->qs_out_channels =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6729) RAYDAT_QS_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6731) hdspm->max_channels_in = RAYDAT_SS_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6732) hdspm->max_channels_out = RAYDAT_SS_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6734) hdspm->channel_map_in_ss = hdspm->channel_map_out_ss =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6735) channel_map_raydat_ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6736) hdspm->channel_map_in_ds = hdspm->channel_map_out_ds =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6737) channel_map_raydat_ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6738) hdspm->channel_map_in_qs = hdspm->channel_map_out_qs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6739) channel_map_raydat_qs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6740) hdspm->channel_map_in = hdspm->channel_map_out =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6741) channel_map_raydat_ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6743) hdspm->port_names_in_ss = hdspm->port_names_out_ss =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6744) texts_ports_raydat_ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6745) hdspm->port_names_in_ds = hdspm->port_names_out_ds =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6746) texts_ports_raydat_ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6747) hdspm->port_names_in_qs = hdspm->port_names_out_qs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6748) texts_ports_raydat_qs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6751) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6755) /* TCO detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6756) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6757) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6758) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6759) if (hdspm_read(hdspm, HDSPM_statusRegister2) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6760) HDSPM_s2_tco_detect) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6761) hdspm->midiPorts++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6762) hdspm->tco = kzalloc(sizeof(*hdspm->tco), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6763) if (hdspm->tco)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6764) hdspm_tco_write(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6766) dev_info(card->dev, "AIO/RayDAT TCO module found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6767) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6768) hdspm->tco = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6770) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6772) case MADI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6773) case AES32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6774) if (hdspm_read(hdspm, HDSPM_statusRegister) & HDSPM_tco_detect) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6775) hdspm->midiPorts++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6776) hdspm->tco = kzalloc(sizeof(*hdspm->tco), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6777) if (hdspm->tco)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6778) hdspm_tco_write(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6780) dev_info(card->dev, "MADI/AES TCO module found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6781) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6782) hdspm->tco = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6784) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6786) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6787) hdspm->tco = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6790) /* texts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6791) switch (hdspm->io_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6792) case AES32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6793) if (hdspm->tco) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6794) hdspm->texts_autosync = texts_autosync_aes_tco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6795) hdspm->texts_autosync_items =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6796) ARRAY_SIZE(texts_autosync_aes_tco);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6797) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6798) hdspm->texts_autosync = texts_autosync_aes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6799) hdspm->texts_autosync_items =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6800) ARRAY_SIZE(texts_autosync_aes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6802) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6804) case MADI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6805) if (hdspm->tco) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6806) hdspm->texts_autosync = texts_autosync_madi_tco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6807) hdspm->texts_autosync_items = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6808) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6809) hdspm->texts_autosync = texts_autosync_madi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6810) hdspm->texts_autosync_items = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6812) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6814) case MADIface:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6816) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6818) case RayDAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6819) if (hdspm->tco) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6820) hdspm->texts_autosync = texts_autosync_raydat_tco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6821) hdspm->texts_autosync_items = 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6822) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6823) hdspm->texts_autosync = texts_autosync_raydat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6824) hdspm->texts_autosync_items = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6826) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6828) case AIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6829) if (hdspm->tco) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6830) hdspm->texts_autosync = texts_autosync_aio_tco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6831) hdspm->texts_autosync_items = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6832) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6833) hdspm->texts_autosync = texts_autosync_aio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6834) hdspm->texts_autosync_items = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6836) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6840) if (hdspm->io_type != MADIface) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6841) hdspm->serial = (hdspm_read(hdspm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6842) HDSPM_midiStatusIn0)>>8) & 0xFFFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6843) /* id contains either a user-provided value or the default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6844) * NULL. If it's the default, we're safe to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6845) * fill card->id with the serial number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6846) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6847) * If the serial number is 0xFFFFFF, then we're dealing with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6848) * an old PCI revision that comes without a sane number. In
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6849) * this case, we don't set card->id to avoid collisions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6850) * when running with multiple cards.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6851) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6852) if (!id[hdspm->dev] && hdspm->serial != 0xFFFFFF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6853) snprintf(card->id, sizeof(card->id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6854) "HDSPMx%06x", hdspm->serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6855) snd_card_set_id(card, card->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6859) dev_dbg(card->dev, "create alsa devices.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6860) err = snd_hdspm_create_alsa_devices(card, hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6861) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6862) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6864) snd_hdspm_initialize_midi_flush(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6866) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6870) static int snd_hdspm_free(struct hdspm * hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6871) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6873) if (hdspm->port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6874) cancel_work_sync(&hdspm->midi_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6876) /* stop th audio, and cancel all interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6877) hdspm->control_register &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6878) ~(HDSPM_Start | HDSPM_AudioInterruptEnable |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6879) HDSPM_Midi0InterruptEnable | HDSPM_Midi1InterruptEnable |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6880) HDSPM_Midi2InterruptEnable | HDSPM_Midi3InterruptEnable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6881) hdspm_write(hdspm, HDSPM_controlRegister,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6882) hdspm->control_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6885) if (hdspm->irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6886) free_irq(hdspm->irq, (void *) hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6888) kfree(hdspm->mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6889) iounmap(hdspm->iobase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6891) if (hdspm->port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6892) pci_release_regions(hdspm->pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6894) if (pci_is_enabled(hdspm->pci))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6895) pci_disable_device(hdspm->pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6896) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6900) static void snd_hdspm_card_free(struct snd_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6902) struct hdspm *hdspm = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6904) if (hdspm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6905) snd_hdspm_free(hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6909) static int snd_hdspm_probe(struct pci_dev *pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6910) const struct pci_device_id *pci_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6911) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6912) static int dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6913) struct hdspm *hdspm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6914) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6915) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6917) if (dev >= SNDRV_CARDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6918) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6919) if (!enable[dev]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6920) dev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6921) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6924) err = snd_card_new(&pci->dev, index[dev], id[dev],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6925) THIS_MODULE, sizeof(*hdspm), &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6926) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6927) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6929) hdspm = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6930) card->private_free = snd_hdspm_card_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6931) hdspm->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6932) hdspm->pci = pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6934) err = snd_hdspm_create(card, hdspm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6935) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6936) goto free_card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6938) if (hdspm->io_type != MADIface) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6939) snprintf(card->shortname, sizeof(card->shortname), "%s_%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6940) hdspm->card_name, hdspm->serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6941) snprintf(card->longname, sizeof(card->longname),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6942) "%s S/N 0x%x at 0x%lx, irq %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6943) hdspm->card_name, hdspm->serial,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6944) hdspm->port, hdspm->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6945) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6946) snprintf(card->shortname, sizeof(card->shortname), "%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6947) hdspm->card_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6948) snprintf(card->longname, sizeof(card->longname),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6949) "%s at 0x%lx, irq %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6950) hdspm->card_name, hdspm->port, hdspm->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6953) err = snd_card_register(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6954) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6955) goto free_card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6957) pci_set_drvdata(pci, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6959) dev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6960) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6962) free_card:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6963) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6964) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6967) static void snd_hdspm_remove(struct pci_dev *pci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6968) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6969) snd_card_free(pci_get_drvdata(pci));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6972) static struct pci_driver hdspm_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6973) .name = KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6974) .id_table = snd_hdspm_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6975) .probe = snd_hdspm_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6976) .remove = snd_hdspm_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6977) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6979) module_pci_driver(hdspm_driver);