Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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, &ltc, 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);