1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * ALSA driver for RME Digi9652 audio interfaces
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (c) 1999 IEM - Winfried Ritsch
6*4882a593Smuzhiyun * Copyright (c) 1999-2001 Paul Davis
7*4882a593Smuzhiyun */
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun #include <linux/delay.h>
10*4882a593Smuzhiyun #include <linux/init.h>
11*4882a593Smuzhiyun #include <linux/interrupt.h>
12*4882a593Smuzhiyun #include <linux/pci.h>
13*4882a593Smuzhiyun #include <linux/module.h>
14*4882a593Smuzhiyun #include <linux/io.h>
15*4882a593Smuzhiyun #include <linux/nospec.h>
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun #include <sound/core.h>
18*4882a593Smuzhiyun #include <sound/control.h>
19*4882a593Smuzhiyun #include <sound/pcm.h>
20*4882a593Smuzhiyun #include <sound/info.h>
21*4882a593Smuzhiyun #include <sound/asoundef.h>
22*4882a593Smuzhiyun #include <sound/initval.h>
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun #include <asm/current.h>
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
27*4882a593Smuzhiyun static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
28*4882a593Smuzhiyun static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
29*4882a593Smuzhiyun static bool precise_ptr[SNDRV_CARDS]; /* Enable precise pointer */
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun module_param_array(index, int, NULL, 0444);
32*4882a593Smuzhiyun MODULE_PARM_DESC(index, "Index value for RME Digi9652 (Hammerfall) soundcard.");
33*4882a593Smuzhiyun module_param_array(id, charp, NULL, 0444);
34*4882a593Smuzhiyun MODULE_PARM_DESC(id, "ID string for RME Digi9652 (Hammerfall) soundcard.");
35*4882a593Smuzhiyun module_param_array(enable, bool, NULL, 0444);
36*4882a593Smuzhiyun MODULE_PARM_DESC(enable, "Enable/disable specific RME96{52,36} soundcards.");
37*4882a593Smuzhiyun module_param_array(precise_ptr, bool, NULL, 0444);
38*4882a593Smuzhiyun MODULE_PARM_DESC(precise_ptr, "Enable precise pointer (doesn't work reliably).");
39*4882a593Smuzhiyun MODULE_AUTHOR("Paul Davis <pbd@op.net>, Winfried Ritsch");
40*4882a593Smuzhiyun MODULE_DESCRIPTION("RME Digi9652/Digi9636");
41*4882a593Smuzhiyun MODULE_LICENSE("GPL");
42*4882a593Smuzhiyun MODULE_SUPPORTED_DEVICE("{{RME,Hammerfall},"
43*4882a593Smuzhiyun "{RME,Hammerfall-Light}}");
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun /* The Hammerfall has two sets of 24 ADAT + 2 S/PDIF channels, one for
46*4882a593Smuzhiyun capture, one for playback. Both the ADAT and S/PDIF channels appear
47*4882a593Smuzhiyun to the host CPU in the same block of memory. There is no functional
48*4882a593Smuzhiyun difference between them in terms of access.
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun The Hammerfall Light is identical to the Hammerfall, except that it
51*4882a593Smuzhiyun has 2 sets 18 channels (16 ADAT + 2 S/PDIF) for capture and playback.
52*4882a593Smuzhiyun */
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun #define RME9652_NCHANNELS 26
55*4882a593Smuzhiyun #define RME9636_NCHANNELS 18
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun /* Preferred sync source choices - used by "sync_pref" control switch */
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun #define RME9652_SYNC_FROM_SPDIF 0
60*4882a593Smuzhiyun #define RME9652_SYNC_FROM_ADAT1 1
61*4882a593Smuzhiyun #define RME9652_SYNC_FROM_ADAT2 2
62*4882a593Smuzhiyun #define RME9652_SYNC_FROM_ADAT3 3
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun /* Possible sources of S/PDIF input */
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun #define RME9652_SPDIFIN_OPTICAL 0 /* optical (ADAT1) */
67*4882a593Smuzhiyun #define RME9652_SPDIFIN_COAXIAL 1 /* coaxial (RCA) */
68*4882a593Smuzhiyun #define RME9652_SPDIFIN_INTERN 2 /* internal (CDROM) */
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun /* ------------- Status-Register bits --------------------- */
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun #define RME9652_IRQ (1<<0) /* IRQ is High if not reset by irq_clear */
73*4882a593Smuzhiyun #define RME9652_lock_2 (1<<1) /* ADAT 3-PLL: 1=locked, 0=unlocked */
74*4882a593Smuzhiyun #define RME9652_lock_1 (1<<2) /* ADAT 2-PLL: 1=locked, 0=unlocked */
75*4882a593Smuzhiyun #define RME9652_lock_0 (1<<3) /* ADAT 1-PLL: 1=locked, 0=unlocked */
76*4882a593Smuzhiyun #define RME9652_fs48 (1<<4) /* sample rate is 0=44.1/88.2,1=48/96 Khz */
77*4882a593Smuzhiyun #define RME9652_wsel_rd (1<<5) /* if Word-Clock is used and valid then 1 */
78*4882a593Smuzhiyun /* bits 6-15 encode h/w buffer pointer position */
79*4882a593Smuzhiyun #define RME9652_sync_2 (1<<16) /* if ADAT-IN 3 in sync to system clock */
80*4882a593Smuzhiyun #define RME9652_sync_1 (1<<17) /* if ADAT-IN 2 in sync to system clock */
81*4882a593Smuzhiyun #define RME9652_sync_0 (1<<18) /* if ADAT-IN 1 in sync to system clock */
82*4882a593Smuzhiyun #define RME9652_DS_rd (1<<19) /* 1=Double Speed Mode, 0=Normal Speed */
83*4882a593Smuzhiyun #define RME9652_tc_busy (1<<20) /* 1=time-code copy in progress (960ms) */
84*4882a593Smuzhiyun #define RME9652_tc_out (1<<21) /* time-code out bit */
85*4882a593Smuzhiyun #define RME9652_F_0 (1<<22) /* 000=64kHz, 100=88.2kHz, 011=96kHz */
86*4882a593Smuzhiyun #define RME9652_F_1 (1<<23) /* 111=32kHz, 110=44.1kHz, 101=48kHz, */
87*4882a593Smuzhiyun #define RME9652_F_2 (1<<24) /* external Crystal Chip if ERF=1 */
88*4882a593Smuzhiyun #define RME9652_ERF (1<<25) /* Error-Flag of SDPIF Receiver (1=No Lock) */
89*4882a593Smuzhiyun #define RME9652_buffer_id (1<<26) /* toggles by each interrupt on rec/play */
90*4882a593Smuzhiyun #define RME9652_tc_valid (1<<27) /* 1 = a signal is detected on time-code input */
91*4882a593Smuzhiyun #define RME9652_SPDIF_READ (1<<28) /* byte available from Rev 1.5+ S/PDIF interface */
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun #define RME9652_sync (RME9652_sync_0|RME9652_sync_1|RME9652_sync_2)
94*4882a593Smuzhiyun #define RME9652_lock (RME9652_lock_0|RME9652_lock_1|RME9652_lock_2)
95*4882a593Smuzhiyun #define RME9652_F (RME9652_F_0|RME9652_F_1|RME9652_F_2)
96*4882a593Smuzhiyun #define rme9652_decode_spdif_rate(x) ((x)>>22)
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun /* Bit 6..15 : h/w buffer pointer */
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun #define RME9652_buf_pos 0x000FFC0
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun /* Bits 31,30,29 are bits 5,4,3 of h/w pointer position on later
103*4882a593Smuzhiyun Rev G EEPROMS and Rev 1.5 cards or later.
104*4882a593Smuzhiyun */
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun #define RME9652_REV15_buf_pos(x) ((((x)&0xE0000000)>>26)|((x)&RME9652_buf_pos))
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun /* amount of io space we remap for register access. i'm not sure we
109*4882a593Smuzhiyun even need this much, but 1K is nice round number :)
110*4882a593Smuzhiyun */
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun #define RME9652_IO_EXTENT 1024
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun #define RME9652_init_buffer 0
115*4882a593Smuzhiyun #define RME9652_play_buffer 32 /* holds ptr to 26x64kBit host RAM */
116*4882a593Smuzhiyun #define RME9652_rec_buffer 36 /* holds ptr to 26x64kBit host RAM */
117*4882a593Smuzhiyun #define RME9652_control_register 64
118*4882a593Smuzhiyun #define RME9652_irq_clear 96
119*4882a593Smuzhiyun #define RME9652_time_code 100 /* useful if used with alesis adat */
120*4882a593Smuzhiyun #define RME9652_thru_base 128 /* 132...228 Thru for 26 channels */
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun /* Read-only registers */
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun /* Writing to any of the register locations writes to the status
125*4882a593Smuzhiyun register. We'll use the first location as our point of access.
126*4882a593Smuzhiyun */
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun #define RME9652_status_register 0
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun /* --------- Control-Register Bits ---------------- */
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun #define RME9652_start_bit (1<<0) /* start record/play */
134*4882a593Smuzhiyun /* bits 1-3 encode buffersize/latency */
135*4882a593Smuzhiyun #define RME9652_Master (1<<4) /* Clock Mode Master=1,Slave/Auto=0 */
136*4882a593Smuzhiyun #define RME9652_IE (1<<5) /* Interrupt Enable */
137*4882a593Smuzhiyun #define RME9652_freq (1<<6) /* samplerate 0=44.1/88.2, 1=48/96 kHz */
138*4882a593Smuzhiyun #define RME9652_freq1 (1<<7) /* if 0, 32kHz, else always 1 */
139*4882a593Smuzhiyun #define RME9652_DS (1<<8) /* Doule Speed 0=44.1/48, 1=88.2/96 Khz */
140*4882a593Smuzhiyun #define RME9652_PRO (1<<9) /* S/PDIF out: 0=consumer, 1=professional */
141*4882a593Smuzhiyun #define RME9652_EMP (1<<10) /* Emphasis 0=None, 1=ON */
142*4882a593Smuzhiyun #define RME9652_Dolby (1<<11) /* Non-audio bit 1=set, 0=unset */
143*4882a593Smuzhiyun #define RME9652_opt_out (1<<12) /* Use 1st optical OUT as SPDIF: 1=yes,0=no */
144*4882a593Smuzhiyun #define RME9652_wsel (1<<13) /* use Wordclock as sync (overwrites master) */
145*4882a593Smuzhiyun #define RME9652_inp_0 (1<<14) /* SPDIF-IN: 00=optical (ADAT1), */
146*4882a593Smuzhiyun #define RME9652_inp_1 (1<<15) /* 01=koaxial (Cinch), 10=Internal CDROM */
147*4882a593Smuzhiyun #define RME9652_SyncPref_ADAT2 (1<<16)
148*4882a593Smuzhiyun #define RME9652_SyncPref_ADAT3 (1<<17)
149*4882a593Smuzhiyun #define RME9652_SPDIF_RESET (1<<18) /* Rev 1.5+: h/w S/PDIF receiver */
150*4882a593Smuzhiyun #define RME9652_SPDIF_SELECT (1<<19)
151*4882a593Smuzhiyun #define RME9652_SPDIF_CLOCK (1<<20)
152*4882a593Smuzhiyun #define RME9652_SPDIF_WRITE (1<<21)
153*4882a593Smuzhiyun #define RME9652_ADAT1_INTERNAL (1<<22) /* Rev 1.5+: if set, internal CD connector carries ADAT */
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun /* buffersize = 512Bytes * 2^n, where n is made from Bit2 ... Bit0 */
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun #define RME9652_latency 0x0e
158*4882a593Smuzhiyun #define rme9652_encode_latency(x) (((x)&0x7)<<1)
159*4882a593Smuzhiyun #define rme9652_decode_latency(x) (((x)>>1)&0x7)
160*4882a593Smuzhiyun #define rme9652_running_double_speed(s) ((s)->control_register & RME9652_DS)
161*4882a593Smuzhiyun #define RME9652_inp (RME9652_inp_0|RME9652_inp_1)
162*4882a593Smuzhiyun #define rme9652_encode_spdif_in(x) (((x)&0x3)<<14)
163*4882a593Smuzhiyun #define rme9652_decode_spdif_in(x) (((x)>>14)&0x3)
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun #define RME9652_SyncPref_Mask (RME9652_SyncPref_ADAT2|RME9652_SyncPref_ADAT3)
166*4882a593Smuzhiyun #define RME9652_SyncPref_ADAT1 0
167*4882a593Smuzhiyun #define RME9652_SyncPref_SPDIF (RME9652_SyncPref_ADAT2|RME9652_SyncPref_ADAT3)
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun /* the size of a substream (1 mono data stream) */
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun #define RME9652_CHANNEL_BUFFER_SAMPLES (16*1024)
172*4882a593Smuzhiyun #define RME9652_CHANNEL_BUFFER_BYTES (4*RME9652_CHANNEL_BUFFER_SAMPLES)
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun /* the size of the area we need to allocate for DMA transfers. the
175*4882a593Smuzhiyun size is the same regardless of the number of channels - the
176*4882a593Smuzhiyun 9636 still uses the same memory area.
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun Note that we allocate 1 more channel than is apparently needed
179*4882a593Smuzhiyun because the h/w seems to write 1 byte beyond the end of the last
180*4882a593Smuzhiyun page. Sigh.
181*4882a593Smuzhiyun */
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun #define RME9652_DMA_AREA_BYTES ((RME9652_NCHANNELS+1) * RME9652_CHANNEL_BUFFER_BYTES)
184*4882a593Smuzhiyun #define RME9652_DMA_AREA_KILOBYTES (RME9652_DMA_AREA_BYTES/1024)
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun struct snd_rme9652 {
187*4882a593Smuzhiyun int dev;
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun spinlock_t lock;
190*4882a593Smuzhiyun int irq;
191*4882a593Smuzhiyun unsigned long port;
192*4882a593Smuzhiyun void __iomem *iobase;
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun int precise_ptr;
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun u32 control_register; /* cached value */
197*4882a593Smuzhiyun u32 thru_bits; /* thru 1=on, 0=off channel 1=Bit1... channel 26= Bit26 */
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun u32 creg_spdif;
200*4882a593Smuzhiyun u32 creg_spdif_stream;
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun char *card_name; /* hammerfall or hammerfall light names */
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun size_t hw_offsetmask; /* &-with status register to get real hw_offset */
205*4882a593Smuzhiyun size_t prev_hw_offset; /* previous hw offset */
206*4882a593Smuzhiyun size_t max_jitter; /* maximum jitter in frames for
207*4882a593Smuzhiyun hw pointer */
208*4882a593Smuzhiyun size_t period_bytes; /* guess what this is */
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun unsigned char ds_channels;
211*4882a593Smuzhiyun unsigned char ss_channels; /* different for hammerfall/hammerfall-light */
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun struct snd_dma_buffer playback_dma_buf;
214*4882a593Smuzhiyun struct snd_dma_buffer capture_dma_buf;
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun unsigned char *capture_buffer; /* suitably aligned address */
217*4882a593Smuzhiyun unsigned char *playback_buffer; /* suitably aligned address */
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun pid_t capture_pid;
220*4882a593Smuzhiyun pid_t playback_pid;
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun struct snd_pcm_substream *capture_substream;
223*4882a593Smuzhiyun struct snd_pcm_substream *playback_substream;
224*4882a593Smuzhiyun int running;
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun int passthru; /* non-zero if doing pass-thru */
227*4882a593Smuzhiyun int hw_rev; /* h/w rev * 10 (i.e. 1.5 has hw_rev = 15) */
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun int last_spdif_sample_rate; /* so that we can catch externally ... */
230*4882a593Smuzhiyun int last_adat_sample_rate; /* ... induced rate changes */
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun const signed char *channel_map;
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun struct snd_card *card;
235*4882a593Smuzhiyun struct snd_pcm *pcm;
236*4882a593Smuzhiyun struct pci_dev *pci;
237*4882a593Smuzhiyun struct snd_kcontrol *spdif_ctl;
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun };
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun /* These tables map the ALSA channels 1..N to the channels that we
242*4882a593Smuzhiyun need to use in order to find the relevant channel buffer. RME
243*4882a593Smuzhiyun refer to this kind of mapping as between "the ADAT channel and
244*4882a593Smuzhiyun the DMA channel." We index it using the logical audio channel,
245*4882a593Smuzhiyun and the value is the DMA channel (i.e. channel buffer number)
246*4882a593Smuzhiyun where the data for that channel can be read/written from/to.
247*4882a593Smuzhiyun */
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun static const signed char channel_map_9652_ss[26] = {
250*4882a593Smuzhiyun 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
251*4882a593Smuzhiyun 18, 19, 20, 21, 22, 23, 24, 25
252*4882a593Smuzhiyun };
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun static const signed char channel_map_9636_ss[26] = {
255*4882a593Smuzhiyun 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
256*4882a593Smuzhiyun /* channels 16 and 17 are S/PDIF */
257*4882a593Smuzhiyun 24, 25,
258*4882a593Smuzhiyun /* channels 18-25 don't exist */
259*4882a593Smuzhiyun -1, -1, -1, -1, -1, -1, -1, -1
260*4882a593Smuzhiyun };
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun static const signed char channel_map_9652_ds[26] = {
263*4882a593Smuzhiyun /* ADAT channels are remapped */
264*4882a593Smuzhiyun 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23,
265*4882a593Smuzhiyun /* channels 12 and 13 are S/PDIF */
266*4882a593Smuzhiyun 24, 25,
267*4882a593Smuzhiyun /* others don't exist */
268*4882a593Smuzhiyun -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
269*4882a593Smuzhiyun };
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun static const signed char channel_map_9636_ds[26] = {
272*4882a593Smuzhiyun /* ADAT channels are remapped */
273*4882a593Smuzhiyun 1, 3, 5, 7, 9, 11, 13, 15,
274*4882a593Smuzhiyun /* channels 8 and 9 are S/PDIF */
275*4882a593Smuzhiyun 24, 25,
276*4882a593Smuzhiyun /* others don't exist */
277*4882a593Smuzhiyun -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
278*4882a593Smuzhiyun };
279*4882a593Smuzhiyun
snd_hammerfall_get_buffer(struct pci_dev * pci,struct snd_dma_buffer * dmab,size_t size)280*4882a593Smuzhiyun static int snd_hammerfall_get_buffer(struct pci_dev *pci, struct snd_dma_buffer *dmab, size_t size)
281*4882a593Smuzhiyun {
282*4882a593Smuzhiyun return snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev, size, dmab);
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun
snd_hammerfall_free_buffer(struct snd_dma_buffer * dmab,struct pci_dev * pci)285*4882a593Smuzhiyun static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_dev *pci)
286*4882a593Smuzhiyun {
287*4882a593Smuzhiyun if (dmab->area)
288*4882a593Smuzhiyun snd_dma_free_pages(dmab);
289*4882a593Smuzhiyun }
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun static const struct pci_device_id snd_rme9652_ids[] = {
293*4882a593Smuzhiyun {
294*4882a593Smuzhiyun .vendor = 0x10ee,
295*4882a593Smuzhiyun .device = 0x3fc4,
296*4882a593Smuzhiyun .subvendor = PCI_ANY_ID,
297*4882a593Smuzhiyun .subdevice = PCI_ANY_ID,
298*4882a593Smuzhiyun }, /* RME Digi9652 */
299*4882a593Smuzhiyun { 0, },
300*4882a593Smuzhiyun };
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun MODULE_DEVICE_TABLE(pci, snd_rme9652_ids);
303*4882a593Smuzhiyun
rme9652_write(struct snd_rme9652 * rme9652,int reg,int val)304*4882a593Smuzhiyun static inline void rme9652_write(struct snd_rme9652 *rme9652, int reg, int val)
305*4882a593Smuzhiyun {
306*4882a593Smuzhiyun writel(val, rme9652->iobase + reg);
307*4882a593Smuzhiyun }
308*4882a593Smuzhiyun
rme9652_read(struct snd_rme9652 * rme9652,int reg)309*4882a593Smuzhiyun static inline unsigned int rme9652_read(struct snd_rme9652 *rme9652, int reg)
310*4882a593Smuzhiyun {
311*4882a593Smuzhiyun return readl(rme9652->iobase + reg);
312*4882a593Smuzhiyun }
313*4882a593Smuzhiyun
snd_rme9652_use_is_exclusive(struct snd_rme9652 * rme9652)314*4882a593Smuzhiyun static inline int snd_rme9652_use_is_exclusive(struct snd_rme9652 *rme9652)
315*4882a593Smuzhiyun {
316*4882a593Smuzhiyun unsigned long flags;
317*4882a593Smuzhiyun int ret = 1;
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun spin_lock_irqsave(&rme9652->lock, flags);
320*4882a593Smuzhiyun if ((rme9652->playback_pid != rme9652->capture_pid) &&
321*4882a593Smuzhiyun (rme9652->playback_pid >= 0) && (rme9652->capture_pid >= 0)) {
322*4882a593Smuzhiyun ret = 0;
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun spin_unlock_irqrestore(&rme9652->lock, flags);
325*4882a593Smuzhiyun return ret;
326*4882a593Smuzhiyun }
327*4882a593Smuzhiyun
rme9652_adat_sample_rate(struct snd_rme9652 * rme9652)328*4882a593Smuzhiyun static inline int rme9652_adat_sample_rate(struct snd_rme9652 *rme9652)
329*4882a593Smuzhiyun {
330*4882a593Smuzhiyun if (rme9652_running_double_speed(rme9652)) {
331*4882a593Smuzhiyun return (rme9652_read(rme9652, RME9652_status_register) &
332*4882a593Smuzhiyun RME9652_fs48) ? 96000 : 88200;
333*4882a593Smuzhiyun } else {
334*4882a593Smuzhiyun return (rme9652_read(rme9652, RME9652_status_register) &
335*4882a593Smuzhiyun RME9652_fs48) ? 48000 : 44100;
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun }
338*4882a593Smuzhiyun
rme9652_compute_period_size(struct snd_rme9652 * rme9652)339*4882a593Smuzhiyun static inline void rme9652_compute_period_size(struct snd_rme9652 *rme9652)
340*4882a593Smuzhiyun {
341*4882a593Smuzhiyun unsigned int i;
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun i = rme9652->control_register & RME9652_latency;
344*4882a593Smuzhiyun rme9652->period_bytes = 1 << ((rme9652_decode_latency(i) + 8));
345*4882a593Smuzhiyun rme9652->hw_offsetmask =
346*4882a593Smuzhiyun (rme9652->period_bytes * 2 - 1) & RME9652_buf_pos;
347*4882a593Smuzhiyun rme9652->max_jitter = 80;
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun
rme9652_hw_pointer(struct snd_rme9652 * rme9652)350*4882a593Smuzhiyun static snd_pcm_uframes_t rme9652_hw_pointer(struct snd_rme9652 *rme9652)
351*4882a593Smuzhiyun {
352*4882a593Smuzhiyun int status;
353*4882a593Smuzhiyun unsigned int offset, frag;
354*4882a593Smuzhiyun snd_pcm_uframes_t period_size = rme9652->period_bytes / 4;
355*4882a593Smuzhiyun snd_pcm_sframes_t delta;
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun status = rme9652_read(rme9652, RME9652_status_register);
358*4882a593Smuzhiyun if (!rme9652->precise_ptr)
359*4882a593Smuzhiyun return (status & RME9652_buffer_id) ? period_size : 0;
360*4882a593Smuzhiyun offset = status & RME9652_buf_pos;
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun /* The hardware may give a backward movement for up to 80 frames
363*4882a593Smuzhiyun Martin Kirst <martin.kirst@freenet.de> knows the details.
364*4882a593Smuzhiyun */
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun delta = rme9652->prev_hw_offset - offset;
367*4882a593Smuzhiyun delta &= 0xffff;
368*4882a593Smuzhiyun if (delta <= (snd_pcm_sframes_t)rme9652->max_jitter * 4)
369*4882a593Smuzhiyun offset = rme9652->prev_hw_offset;
370*4882a593Smuzhiyun else
371*4882a593Smuzhiyun rme9652->prev_hw_offset = offset;
372*4882a593Smuzhiyun offset &= rme9652->hw_offsetmask;
373*4882a593Smuzhiyun offset /= 4;
374*4882a593Smuzhiyun frag = status & RME9652_buffer_id;
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun if (offset < period_size) {
377*4882a593Smuzhiyun if (offset > rme9652->max_jitter) {
378*4882a593Smuzhiyun if (frag)
379*4882a593Smuzhiyun dev_err(rme9652->card->dev,
380*4882a593Smuzhiyun "Unexpected hw_pointer position (bufid == 0): status: %x offset: %d\n",
381*4882a593Smuzhiyun status, offset);
382*4882a593Smuzhiyun } else if (!frag)
383*4882a593Smuzhiyun return 0;
384*4882a593Smuzhiyun offset -= rme9652->max_jitter;
385*4882a593Smuzhiyun if ((int)offset < 0)
386*4882a593Smuzhiyun offset += period_size * 2;
387*4882a593Smuzhiyun } else {
388*4882a593Smuzhiyun if (offset > period_size + rme9652->max_jitter) {
389*4882a593Smuzhiyun if (!frag)
390*4882a593Smuzhiyun dev_err(rme9652->card->dev,
391*4882a593Smuzhiyun "Unexpected hw_pointer position (bufid == 1): status: %x offset: %d\n",
392*4882a593Smuzhiyun status, offset);
393*4882a593Smuzhiyun } else if (frag)
394*4882a593Smuzhiyun return period_size;
395*4882a593Smuzhiyun offset -= rme9652->max_jitter;
396*4882a593Smuzhiyun }
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun return offset;
399*4882a593Smuzhiyun }
400*4882a593Smuzhiyun
rme9652_reset_hw_pointer(struct snd_rme9652 * rme9652)401*4882a593Smuzhiyun static inline void rme9652_reset_hw_pointer(struct snd_rme9652 *rme9652)
402*4882a593Smuzhiyun {
403*4882a593Smuzhiyun int i;
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun /* reset the FIFO pointer to zero. We do this by writing to 8
406*4882a593Smuzhiyun registers, each of which is a 32bit wide register, and set
407*4882a593Smuzhiyun them all to zero. Note that s->iobase is a pointer to
408*4882a593Smuzhiyun int32, not pointer to char.
409*4882a593Smuzhiyun */
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun for (i = 0; i < 8; i++) {
412*4882a593Smuzhiyun rme9652_write(rme9652, i * 4, 0);
413*4882a593Smuzhiyun udelay(10);
414*4882a593Smuzhiyun }
415*4882a593Smuzhiyun rme9652->prev_hw_offset = 0;
416*4882a593Smuzhiyun }
417*4882a593Smuzhiyun
rme9652_start(struct snd_rme9652 * s)418*4882a593Smuzhiyun static inline void rme9652_start(struct snd_rme9652 *s)
419*4882a593Smuzhiyun {
420*4882a593Smuzhiyun s->control_register |= (RME9652_IE | RME9652_start_bit);
421*4882a593Smuzhiyun rme9652_write(s, RME9652_control_register, s->control_register);
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun
rme9652_stop(struct snd_rme9652 * s)424*4882a593Smuzhiyun static inline void rme9652_stop(struct snd_rme9652 *s)
425*4882a593Smuzhiyun {
426*4882a593Smuzhiyun s->control_register &= ~(RME9652_start_bit | RME9652_IE);
427*4882a593Smuzhiyun rme9652_write(s, RME9652_control_register, s->control_register);
428*4882a593Smuzhiyun }
429*4882a593Smuzhiyun
rme9652_set_interrupt_interval(struct snd_rme9652 * s,unsigned int frames)430*4882a593Smuzhiyun static int rme9652_set_interrupt_interval(struct snd_rme9652 *s,
431*4882a593Smuzhiyun unsigned int frames)
432*4882a593Smuzhiyun {
433*4882a593Smuzhiyun int restart = 0;
434*4882a593Smuzhiyun int n;
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun spin_lock_irq(&s->lock);
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun if ((restart = s->running)) {
439*4882a593Smuzhiyun rme9652_stop(s);
440*4882a593Smuzhiyun }
441*4882a593Smuzhiyun
442*4882a593Smuzhiyun frames >>= 7;
443*4882a593Smuzhiyun n = 0;
444*4882a593Smuzhiyun while (frames) {
445*4882a593Smuzhiyun n++;
446*4882a593Smuzhiyun frames >>= 1;
447*4882a593Smuzhiyun }
448*4882a593Smuzhiyun
449*4882a593Smuzhiyun s->control_register &= ~RME9652_latency;
450*4882a593Smuzhiyun s->control_register |= rme9652_encode_latency(n);
451*4882a593Smuzhiyun
452*4882a593Smuzhiyun rme9652_write(s, RME9652_control_register, s->control_register);
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun rme9652_compute_period_size(s);
455*4882a593Smuzhiyun
456*4882a593Smuzhiyun if (restart)
457*4882a593Smuzhiyun rme9652_start(s);
458*4882a593Smuzhiyun
459*4882a593Smuzhiyun spin_unlock_irq(&s->lock);
460*4882a593Smuzhiyun
461*4882a593Smuzhiyun return 0;
462*4882a593Smuzhiyun }
463*4882a593Smuzhiyun
rme9652_set_rate(struct snd_rme9652 * rme9652,int rate)464*4882a593Smuzhiyun static int rme9652_set_rate(struct snd_rme9652 *rme9652, int rate)
465*4882a593Smuzhiyun {
466*4882a593Smuzhiyun int restart;
467*4882a593Smuzhiyun int reject_if_open = 0;
468*4882a593Smuzhiyun int xrate;
469*4882a593Smuzhiyun
470*4882a593Smuzhiyun if (!snd_rme9652_use_is_exclusive (rme9652)) {
471*4882a593Smuzhiyun return -EBUSY;
472*4882a593Smuzhiyun }
473*4882a593Smuzhiyun
474*4882a593Smuzhiyun /* Changing from a "single speed" to a "double speed" rate is
475*4882a593Smuzhiyun not allowed if any substreams are open. This is because
476*4882a593Smuzhiyun such a change causes a shift in the location of
477*4882a593Smuzhiyun the DMA buffers and a reduction in the number of available
478*4882a593Smuzhiyun buffers.
479*4882a593Smuzhiyun
480*4882a593Smuzhiyun Note that a similar but essentially insoluble problem
481*4882a593Smuzhiyun exists for externally-driven rate changes. All we can do
482*4882a593Smuzhiyun is to flag rate changes in the read/write routines.
483*4882a593Smuzhiyun */
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun spin_lock_irq(&rme9652->lock);
486*4882a593Smuzhiyun xrate = rme9652_adat_sample_rate(rme9652);
487*4882a593Smuzhiyun
488*4882a593Smuzhiyun switch (rate) {
489*4882a593Smuzhiyun case 44100:
490*4882a593Smuzhiyun if (xrate > 48000) {
491*4882a593Smuzhiyun reject_if_open = 1;
492*4882a593Smuzhiyun }
493*4882a593Smuzhiyun rate = 0;
494*4882a593Smuzhiyun break;
495*4882a593Smuzhiyun case 48000:
496*4882a593Smuzhiyun if (xrate > 48000) {
497*4882a593Smuzhiyun reject_if_open = 1;
498*4882a593Smuzhiyun }
499*4882a593Smuzhiyun rate = RME9652_freq;
500*4882a593Smuzhiyun break;
501*4882a593Smuzhiyun case 88200:
502*4882a593Smuzhiyun if (xrate < 48000) {
503*4882a593Smuzhiyun reject_if_open = 1;
504*4882a593Smuzhiyun }
505*4882a593Smuzhiyun rate = RME9652_DS;
506*4882a593Smuzhiyun break;
507*4882a593Smuzhiyun case 96000:
508*4882a593Smuzhiyun if (xrate < 48000) {
509*4882a593Smuzhiyun reject_if_open = 1;
510*4882a593Smuzhiyun }
511*4882a593Smuzhiyun rate = RME9652_DS | RME9652_freq;
512*4882a593Smuzhiyun break;
513*4882a593Smuzhiyun default:
514*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
515*4882a593Smuzhiyun return -EINVAL;
516*4882a593Smuzhiyun }
517*4882a593Smuzhiyun
518*4882a593Smuzhiyun if (reject_if_open && (rme9652->capture_pid >= 0 || rme9652->playback_pid >= 0)) {
519*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
520*4882a593Smuzhiyun return -EBUSY;
521*4882a593Smuzhiyun }
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun if ((restart = rme9652->running)) {
524*4882a593Smuzhiyun rme9652_stop(rme9652);
525*4882a593Smuzhiyun }
526*4882a593Smuzhiyun rme9652->control_register &= ~(RME9652_freq | RME9652_DS);
527*4882a593Smuzhiyun rme9652->control_register |= rate;
528*4882a593Smuzhiyun rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
529*4882a593Smuzhiyun
530*4882a593Smuzhiyun if (restart) {
531*4882a593Smuzhiyun rme9652_start(rme9652);
532*4882a593Smuzhiyun }
533*4882a593Smuzhiyun
534*4882a593Smuzhiyun if (rate & RME9652_DS) {
535*4882a593Smuzhiyun if (rme9652->ss_channels == RME9652_NCHANNELS) {
536*4882a593Smuzhiyun rme9652->channel_map = channel_map_9652_ds;
537*4882a593Smuzhiyun } else {
538*4882a593Smuzhiyun rme9652->channel_map = channel_map_9636_ds;
539*4882a593Smuzhiyun }
540*4882a593Smuzhiyun } else {
541*4882a593Smuzhiyun if (rme9652->ss_channels == RME9652_NCHANNELS) {
542*4882a593Smuzhiyun rme9652->channel_map = channel_map_9652_ss;
543*4882a593Smuzhiyun } else {
544*4882a593Smuzhiyun rme9652->channel_map = channel_map_9636_ss;
545*4882a593Smuzhiyun }
546*4882a593Smuzhiyun }
547*4882a593Smuzhiyun
548*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
549*4882a593Smuzhiyun return 0;
550*4882a593Smuzhiyun }
551*4882a593Smuzhiyun
rme9652_set_thru(struct snd_rme9652 * rme9652,int channel,int enable)552*4882a593Smuzhiyun static void rme9652_set_thru(struct snd_rme9652 *rme9652, int channel, int enable)
553*4882a593Smuzhiyun {
554*4882a593Smuzhiyun int i;
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun rme9652->passthru = 0;
557*4882a593Smuzhiyun
558*4882a593Smuzhiyun if (channel < 0) {
559*4882a593Smuzhiyun
560*4882a593Smuzhiyun /* set thru for all channels */
561*4882a593Smuzhiyun
562*4882a593Smuzhiyun if (enable) {
563*4882a593Smuzhiyun for (i = 0; i < RME9652_NCHANNELS; i++) {
564*4882a593Smuzhiyun rme9652->thru_bits |= (1 << i);
565*4882a593Smuzhiyun rme9652_write(rme9652, RME9652_thru_base + i * 4, 1);
566*4882a593Smuzhiyun }
567*4882a593Smuzhiyun } else {
568*4882a593Smuzhiyun for (i = 0; i < RME9652_NCHANNELS; i++) {
569*4882a593Smuzhiyun rme9652->thru_bits &= ~(1 << i);
570*4882a593Smuzhiyun rme9652_write(rme9652, RME9652_thru_base + i * 4, 0);
571*4882a593Smuzhiyun }
572*4882a593Smuzhiyun }
573*4882a593Smuzhiyun
574*4882a593Smuzhiyun } else {
575*4882a593Smuzhiyun int mapped_channel;
576*4882a593Smuzhiyun
577*4882a593Smuzhiyun mapped_channel = rme9652->channel_map[channel];
578*4882a593Smuzhiyun
579*4882a593Smuzhiyun if (enable) {
580*4882a593Smuzhiyun rme9652->thru_bits |= (1 << mapped_channel);
581*4882a593Smuzhiyun } else {
582*4882a593Smuzhiyun rme9652->thru_bits &= ~(1 << mapped_channel);
583*4882a593Smuzhiyun }
584*4882a593Smuzhiyun
585*4882a593Smuzhiyun rme9652_write(rme9652,
586*4882a593Smuzhiyun RME9652_thru_base + mapped_channel * 4,
587*4882a593Smuzhiyun enable ? 1 : 0);
588*4882a593Smuzhiyun }
589*4882a593Smuzhiyun }
590*4882a593Smuzhiyun
rme9652_set_passthru(struct snd_rme9652 * rme9652,int onoff)591*4882a593Smuzhiyun static int rme9652_set_passthru(struct snd_rme9652 *rme9652, int onoff)
592*4882a593Smuzhiyun {
593*4882a593Smuzhiyun if (onoff) {
594*4882a593Smuzhiyun rme9652_set_thru(rme9652, -1, 1);
595*4882a593Smuzhiyun
596*4882a593Smuzhiyun /* we don't want interrupts, so do a
597*4882a593Smuzhiyun custom version of rme9652_start().
598*4882a593Smuzhiyun */
599*4882a593Smuzhiyun
600*4882a593Smuzhiyun rme9652->control_register =
601*4882a593Smuzhiyun RME9652_inp_0 |
602*4882a593Smuzhiyun rme9652_encode_latency(7) |
603*4882a593Smuzhiyun RME9652_start_bit;
604*4882a593Smuzhiyun
605*4882a593Smuzhiyun rme9652_reset_hw_pointer(rme9652);
606*4882a593Smuzhiyun
607*4882a593Smuzhiyun rme9652_write(rme9652, RME9652_control_register,
608*4882a593Smuzhiyun rme9652->control_register);
609*4882a593Smuzhiyun rme9652->passthru = 1;
610*4882a593Smuzhiyun } else {
611*4882a593Smuzhiyun rme9652_set_thru(rme9652, -1, 0);
612*4882a593Smuzhiyun rme9652_stop(rme9652);
613*4882a593Smuzhiyun rme9652->passthru = 0;
614*4882a593Smuzhiyun }
615*4882a593Smuzhiyun
616*4882a593Smuzhiyun return 0;
617*4882a593Smuzhiyun }
618*4882a593Smuzhiyun
rme9652_spdif_set_bit(struct snd_rme9652 * rme9652,int mask,int onoff)619*4882a593Smuzhiyun static void rme9652_spdif_set_bit (struct snd_rme9652 *rme9652, int mask, int onoff)
620*4882a593Smuzhiyun {
621*4882a593Smuzhiyun if (onoff)
622*4882a593Smuzhiyun rme9652->control_register |= mask;
623*4882a593Smuzhiyun else
624*4882a593Smuzhiyun rme9652->control_register &= ~mask;
625*4882a593Smuzhiyun
626*4882a593Smuzhiyun rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
627*4882a593Smuzhiyun }
628*4882a593Smuzhiyun
rme9652_spdif_write_byte(struct snd_rme9652 * rme9652,const int val)629*4882a593Smuzhiyun static void rme9652_spdif_write_byte (struct snd_rme9652 *rme9652, const int val)
630*4882a593Smuzhiyun {
631*4882a593Smuzhiyun long mask;
632*4882a593Smuzhiyun long i;
633*4882a593Smuzhiyun
634*4882a593Smuzhiyun for (i = 0, mask = 0x80; i < 8; i++, mask >>= 1) {
635*4882a593Smuzhiyun if (val & mask)
636*4882a593Smuzhiyun rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_WRITE, 1);
637*4882a593Smuzhiyun else
638*4882a593Smuzhiyun rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_WRITE, 0);
639*4882a593Smuzhiyun
640*4882a593Smuzhiyun rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_CLOCK, 1);
641*4882a593Smuzhiyun rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_CLOCK, 0);
642*4882a593Smuzhiyun }
643*4882a593Smuzhiyun }
644*4882a593Smuzhiyun
rme9652_spdif_read_byte(struct snd_rme9652 * rme9652)645*4882a593Smuzhiyun static int rme9652_spdif_read_byte (struct snd_rme9652 *rme9652)
646*4882a593Smuzhiyun {
647*4882a593Smuzhiyun long mask;
648*4882a593Smuzhiyun long val;
649*4882a593Smuzhiyun long i;
650*4882a593Smuzhiyun
651*4882a593Smuzhiyun val = 0;
652*4882a593Smuzhiyun
653*4882a593Smuzhiyun for (i = 0, mask = 0x80; i < 8; i++, mask >>= 1) {
654*4882a593Smuzhiyun rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_CLOCK, 1);
655*4882a593Smuzhiyun if (rme9652_read (rme9652, RME9652_status_register) & RME9652_SPDIF_READ)
656*4882a593Smuzhiyun val |= mask;
657*4882a593Smuzhiyun rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_CLOCK, 0);
658*4882a593Smuzhiyun }
659*4882a593Smuzhiyun
660*4882a593Smuzhiyun return val;
661*4882a593Smuzhiyun }
662*4882a593Smuzhiyun
rme9652_write_spdif_codec(struct snd_rme9652 * rme9652,const int address,const int data)663*4882a593Smuzhiyun static void rme9652_write_spdif_codec (struct snd_rme9652 *rme9652, const int address, const int data)
664*4882a593Smuzhiyun {
665*4882a593Smuzhiyun rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 1);
666*4882a593Smuzhiyun rme9652_spdif_write_byte (rme9652, 0x20);
667*4882a593Smuzhiyun rme9652_spdif_write_byte (rme9652, address);
668*4882a593Smuzhiyun rme9652_spdif_write_byte (rme9652, data);
669*4882a593Smuzhiyun rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 0);
670*4882a593Smuzhiyun }
671*4882a593Smuzhiyun
672*4882a593Smuzhiyun
rme9652_spdif_read_codec(struct snd_rme9652 * rme9652,const int address)673*4882a593Smuzhiyun static int rme9652_spdif_read_codec (struct snd_rme9652 *rme9652, const int address)
674*4882a593Smuzhiyun {
675*4882a593Smuzhiyun int ret;
676*4882a593Smuzhiyun
677*4882a593Smuzhiyun rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 1);
678*4882a593Smuzhiyun rme9652_spdif_write_byte (rme9652, 0x20);
679*4882a593Smuzhiyun rme9652_spdif_write_byte (rme9652, address);
680*4882a593Smuzhiyun rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 0);
681*4882a593Smuzhiyun rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 1);
682*4882a593Smuzhiyun
683*4882a593Smuzhiyun rme9652_spdif_write_byte (rme9652, 0x21);
684*4882a593Smuzhiyun ret = rme9652_spdif_read_byte (rme9652);
685*4882a593Smuzhiyun rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 0);
686*4882a593Smuzhiyun
687*4882a593Smuzhiyun return ret;
688*4882a593Smuzhiyun }
689*4882a593Smuzhiyun
rme9652_initialize_spdif_receiver(struct snd_rme9652 * rme9652)690*4882a593Smuzhiyun static void rme9652_initialize_spdif_receiver (struct snd_rme9652 *rme9652)
691*4882a593Smuzhiyun {
692*4882a593Smuzhiyun /* XXX what unsets this ? */
693*4882a593Smuzhiyun
694*4882a593Smuzhiyun rme9652->control_register |= RME9652_SPDIF_RESET;
695*4882a593Smuzhiyun
696*4882a593Smuzhiyun rme9652_write_spdif_codec (rme9652, 4, 0x40);
697*4882a593Smuzhiyun rme9652_write_spdif_codec (rme9652, 17, 0x13);
698*4882a593Smuzhiyun rme9652_write_spdif_codec (rme9652, 6, 0x02);
699*4882a593Smuzhiyun }
700*4882a593Smuzhiyun
rme9652_spdif_sample_rate(struct snd_rme9652 * s)701*4882a593Smuzhiyun static inline int rme9652_spdif_sample_rate(struct snd_rme9652 *s)
702*4882a593Smuzhiyun {
703*4882a593Smuzhiyun unsigned int rate_bits;
704*4882a593Smuzhiyun
705*4882a593Smuzhiyun if (rme9652_read(s, RME9652_status_register) & RME9652_ERF) {
706*4882a593Smuzhiyun return -1; /* error condition */
707*4882a593Smuzhiyun }
708*4882a593Smuzhiyun
709*4882a593Smuzhiyun if (s->hw_rev == 15) {
710*4882a593Smuzhiyun
711*4882a593Smuzhiyun int x, y, ret;
712*4882a593Smuzhiyun
713*4882a593Smuzhiyun x = rme9652_spdif_read_codec (s, 30);
714*4882a593Smuzhiyun
715*4882a593Smuzhiyun if (x != 0)
716*4882a593Smuzhiyun y = 48000 * 64 / x;
717*4882a593Smuzhiyun else
718*4882a593Smuzhiyun y = 0;
719*4882a593Smuzhiyun
720*4882a593Smuzhiyun if (y > 30400 && y < 33600) ret = 32000;
721*4882a593Smuzhiyun else if (y > 41900 && y < 46000) ret = 44100;
722*4882a593Smuzhiyun else if (y > 46000 && y < 50400) ret = 48000;
723*4882a593Smuzhiyun else if (y > 60800 && y < 67200) ret = 64000;
724*4882a593Smuzhiyun else if (y > 83700 && y < 92000) ret = 88200;
725*4882a593Smuzhiyun else if (y > 92000 && y < 100000) ret = 96000;
726*4882a593Smuzhiyun else ret = 0;
727*4882a593Smuzhiyun return ret;
728*4882a593Smuzhiyun }
729*4882a593Smuzhiyun
730*4882a593Smuzhiyun rate_bits = rme9652_read(s, RME9652_status_register) & RME9652_F;
731*4882a593Smuzhiyun
732*4882a593Smuzhiyun switch (rme9652_decode_spdif_rate(rate_bits)) {
733*4882a593Smuzhiyun case 0x7:
734*4882a593Smuzhiyun return 32000;
735*4882a593Smuzhiyun break;
736*4882a593Smuzhiyun
737*4882a593Smuzhiyun case 0x6:
738*4882a593Smuzhiyun return 44100;
739*4882a593Smuzhiyun break;
740*4882a593Smuzhiyun
741*4882a593Smuzhiyun case 0x5:
742*4882a593Smuzhiyun return 48000;
743*4882a593Smuzhiyun break;
744*4882a593Smuzhiyun
745*4882a593Smuzhiyun case 0x4:
746*4882a593Smuzhiyun return 88200;
747*4882a593Smuzhiyun break;
748*4882a593Smuzhiyun
749*4882a593Smuzhiyun case 0x3:
750*4882a593Smuzhiyun return 96000;
751*4882a593Smuzhiyun break;
752*4882a593Smuzhiyun
753*4882a593Smuzhiyun case 0x0:
754*4882a593Smuzhiyun return 64000;
755*4882a593Smuzhiyun break;
756*4882a593Smuzhiyun
757*4882a593Smuzhiyun default:
758*4882a593Smuzhiyun dev_err(s->card->dev,
759*4882a593Smuzhiyun "%s: unknown S/PDIF input rate (bits = 0x%x)\n",
760*4882a593Smuzhiyun s->card_name, rate_bits);
761*4882a593Smuzhiyun return 0;
762*4882a593Smuzhiyun break;
763*4882a593Smuzhiyun }
764*4882a593Smuzhiyun }
765*4882a593Smuzhiyun
766*4882a593Smuzhiyun /*-----------------------------------------------------------------------------
767*4882a593Smuzhiyun Control Interface
768*4882a593Smuzhiyun ----------------------------------------------------------------------------*/
769*4882a593Smuzhiyun
snd_rme9652_convert_from_aes(struct snd_aes_iec958 * aes)770*4882a593Smuzhiyun static u32 snd_rme9652_convert_from_aes(struct snd_aes_iec958 *aes)
771*4882a593Smuzhiyun {
772*4882a593Smuzhiyun u32 val = 0;
773*4882a593Smuzhiyun val |= (aes->status[0] & IEC958_AES0_PROFESSIONAL) ? RME9652_PRO : 0;
774*4882a593Smuzhiyun val |= (aes->status[0] & IEC958_AES0_NONAUDIO) ? RME9652_Dolby : 0;
775*4882a593Smuzhiyun if (val & RME9652_PRO)
776*4882a593Smuzhiyun val |= (aes->status[0] & IEC958_AES0_PRO_EMPHASIS_5015) ? RME9652_EMP : 0;
777*4882a593Smuzhiyun else
778*4882a593Smuzhiyun val |= (aes->status[0] & IEC958_AES0_CON_EMPHASIS_5015) ? RME9652_EMP : 0;
779*4882a593Smuzhiyun return val;
780*4882a593Smuzhiyun }
781*4882a593Smuzhiyun
snd_rme9652_convert_to_aes(struct snd_aes_iec958 * aes,u32 val)782*4882a593Smuzhiyun static void snd_rme9652_convert_to_aes(struct snd_aes_iec958 *aes, u32 val)
783*4882a593Smuzhiyun {
784*4882a593Smuzhiyun aes->status[0] = ((val & RME9652_PRO) ? IEC958_AES0_PROFESSIONAL : 0) |
785*4882a593Smuzhiyun ((val & RME9652_Dolby) ? IEC958_AES0_NONAUDIO : 0);
786*4882a593Smuzhiyun if (val & RME9652_PRO)
787*4882a593Smuzhiyun aes->status[0] |= (val & RME9652_EMP) ? IEC958_AES0_PRO_EMPHASIS_5015 : 0;
788*4882a593Smuzhiyun else
789*4882a593Smuzhiyun aes->status[0] |= (val & RME9652_EMP) ? IEC958_AES0_CON_EMPHASIS_5015 : 0;
790*4882a593Smuzhiyun }
791*4882a593Smuzhiyun
snd_rme9652_control_spdif_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)792*4882a593Smuzhiyun static int snd_rme9652_control_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
793*4882a593Smuzhiyun {
794*4882a593Smuzhiyun uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
795*4882a593Smuzhiyun uinfo->count = 1;
796*4882a593Smuzhiyun return 0;
797*4882a593Smuzhiyun }
798*4882a593Smuzhiyun
snd_rme9652_control_spdif_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)799*4882a593Smuzhiyun static int snd_rme9652_control_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
800*4882a593Smuzhiyun {
801*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
802*4882a593Smuzhiyun
803*4882a593Smuzhiyun snd_rme9652_convert_to_aes(&ucontrol->value.iec958, rme9652->creg_spdif);
804*4882a593Smuzhiyun return 0;
805*4882a593Smuzhiyun }
806*4882a593Smuzhiyun
snd_rme9652_control_spdif_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)807*4882a593Smuzhiyun static int snd_rme9652_control_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
808*4882a593Smuzhiyun {
809*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
810*4882a593Smuzhiyun int change;
811*4882a593Smuzhiyun u32 val;
812*4882a593Smuzhiyun
813*4882a593Smuzhiyun val = snd_rme9652_convert_from_aes(&ucontrol->value.iec958);
814*4882a593Smuzhiyun spin_lock_irq(&rme9652->lock);
815*4882a593Smuzhiyun change = val != rme9652->creg_spdif;
816*4882a593Smuzhiyun rme9652->creg_spdif = val;
817*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
818*4882a593Smuzhiyun return change;
819*4882a593Smuzhiyun }
820*4882a593Smuzhiyun
snd_rme9652_control_spdif_stream_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)821*4882a593Smuzhiyun static int snd_rme9652_control_spdif_stream_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
822*4882a593Smuzhiyun {
823*4882a593Smuzhiyun uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
824*4882a593Smuzhiyun uinfo->count = 1;
825*4882a593Smuzhiyun return 0;
826*4882a593Smuzhiyun }
827*4882a593Smuzhiyun
snd_rme9652_control_spdif_stream_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)828*4882a593Smuzhiyun static int snd_rme9652_control_spdif_stream_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
829*4882a593Smuzhiyun {
830*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
831*4882a593Smuzhiyun
832*4882a593Smuzhiyun snd_rme9652_convert_to_aes(&ucontrol->value.iec958, rme9652->creg_spdif_stream);
833*4882a593Smuzhiyun return 0;
834*4882a593Smuzhiyun }
835*4882a593Smuzhiyun
snd_rme9652_control_spdif_stream_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)836*4882a593Smuzhiyun static int snd_rme9652_control_spdif_stream_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
837*4882a593Smuzhiyun {
838*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
839*4882a593Smuzhiyun int change;
840*4882a593Smuzhiyun u32 val;
841*4882a593Smuzhiyun
842*4882a593Smuzhiyun val = snd_rme9652_convert_from_aes(&ucontrol->value.iec958);
843*4882a593Smuzhiyun spin_lock_irq(&rme9652->lock);
844*4882a593Smuzhiyun change = val != rme9652->creg_spdif_stream;
845*4882a593Smuzhiyun rme9652->creg_spdif_stream = val;
846*4882a593Smuzhiyun rme9652->control_register &= ~(RME9652_PRO | RME9652_Dolby | RME9652_EMP);
847*4882a593Smuzhiyun rme9652_write(rme9652, RME9652_control_register, rme9652->control_register |= val);
848*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
849*4882a593Smuzhiyun return change;
850*4882a593Smuzhiyun }
851*4882a593Smuzhiyun
snd_rme9652_control_spdif_mask_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)852*4882a593Smuzhiyun static int snd_rme9652_control_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
853*4882a593Smuzhiyun {
854*4882a593Smuzhiyun uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
855*4882a593Smuzhiyun uinfo->count = 1;
856*4882a593Smuzhiyun return 0;
857*4882a593Smuzhiyun }
858*4882a593Smuzhiyun
snd_rme9652_control_spdif_mask_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)859*4882a593Smuzhiyun static int snd_rme9652_control_spdif_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
860*4882a593Smuzhiyun {
861*4882a593Smuzhiyun ucontrol->value.iec958.status[0] = kcontrol->private_value;
862*4882a593Smuzhiyun return 0;
863*4882a593Smuzhiyun }
864*4882a593Smuzhiyun
865*4882a593Smuzhiyun #define RME9652_ADAT1_IN(xname, xindex) \
866*4882a593Smuzhiyun { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
867*4882a593Smuzhiyun .info = snd_rme9652_info_adat1_in, \
868*4882a593Smuzhiyun .get = snd_rme9652_get_adat1_in, \
869*4882a593Smuzhiyun .put = snd_rme9652_put_adat1_in }
870*4882a593Smuzhiyun
rme9652_adat1_in(struct snd_rme9652 * rme9652)871*4882a593Smuzhiyun static unsigned int rme9652_adat1_in(struct snd_rme9652 *rme9652)
872*4882a593Smuzhiyun {
873*4882a593Smuzhiyun if (rme9652->control_register & RME9652_ADAT1_INTERNAL)
874*4882a593Smuzhiyun return 1;
875*4882a593Smuzhiyun return 0;
876*4882a593Smuzhiyun }
877*4882a593Smuzhiyun
rme9652_set_adat1_input(struct snd_rme9652 * rme9652,int internal)878*4882a593Smuzhiyun static int rme9652_set_adat1_input(struct snd_rme9652 *rme9652, int internal)
879*4882a593Smuzhiyun {
880*4882a593Smuzhiyun int restart = 0;
881*4882a593Smuzhiyun
882*4882a593Smuzhiyun if (internal) {
883*4882a593Smuzhiyun rme9652->control_register |= RME9652_ADAT1_INTERNAL;
884*4882a593Smuzhiyun } else {
885*4882a593Smuzhiyun rme9652->control_register &= ~RME9652_ADAT1_INTERNAL;
886*4882a593Smuzhiyun }
887*4882a593Smuzhiyun
888*4882a593Smuzhiyun /* XXX do we actually need to stop the card when we do this ? */
889*4882a593Smuzhiyun
890*4882a593Smuzhiyun if ((restart = rme9652->running)) {
891*4882a593Smuzhiyun rme9652_stop(rme9652);
892*4882a593Smuzhiyun }
893*4882a593Smuzhiyun
894*4882a593Smuzhiyun rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
895*4882a593Smuzhiyun
896*4882a593Smuzhiyun if (restart) {
897*4882a593Smuzhiyun rme9652_start(rme9652);
898*4882a593Smuzhiyun }
899*4882a593Smuzhiyun
900*4882a593Smuzhiyun return 0;
901*4882a593Smuzhiyun }
902*4882a593Smuzhiyun
snd_rme9652_info_adat1_in(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)903*4882a593Smuzhiyun static int snd_rme9652_info_adat1_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
904*4882a593Smuzhiyun {
905*4882a593Smuzhiyun static const char * const texts[2] = {"ADAT1", "Internal"};
906*4882a593Smuzhiyun
907*4882a593Smuzhiyun return snd_ctl_enum_info(uinfo, 1, 2, texts);
908*4882a593Smuzhiyun }
909*4882a593Smuzhiyun
snd_rme9652_get_adat1_in(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)910*4882a593Smuzhiyun static int snd_rme9652_get_adat1_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
911*4882a593Smuzhiyun {
912*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
913*4882a593Smuzhiyun
914*4882a593Smuzhiyun spin_lock_irq(&rme9652->lock);
915*4882a593Smuzhiyun ucontrol->value.enumerated.item[0] = rme9652_adat1_in(rme9652);
916*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
917*4882a593Smuzhiyun return 0;
918*4882a593Smuzhiyun }
919*4882a593Smuzhiyun
snd_rme9652_put_adat1_in(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)920*4882a593Smuzhiyun static int snd_rme9652_put_adat1_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
921*4882a593Smuzhiyun {
922*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
923*4882a593Smuzhiyun int change;
924*4882a593Smuzhiyun unsigned int val;
925*4882a593Smuzhiyun
926*4882a593Smuzhiyun if (!snd_rme9652_use_is_exclusive(rme9652))
927*4882a593Smuzhiyun return -EBUSY;
928*4882a593Smuzhiyun val = ucontrol->value.enumerated.item[0] % 2;
929*4882a593Smuzhiyun spin_lock_irq(&rme9652->lock);
930*4882a593Smuzhiyun change = val != rme9652_adat1_in(rme9652);
931*4882a593Smuzhiyun if (change)
932*4882a593Smuzhiyun rme9652_set_adat1_input(rme9652, val);
933*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
934*4882a593Smuzhiyun return change;
935*4882a593Smuzhiyun }
936*4882a593Smuzhiyun
937*4882a593Smuzhiyun #define RME9652_SPDIF_IN(xname, xindex) \
938*4882a593Smuzhiyun { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
939*4882a593Smuzhiyun .info = snd_rme9652_info_spdif_in, \
940*4882a593Smuzhiyun .get = snd_rme9652_get_spdif_in, .put = snd_rme9652_put_spdif_in }
941*4882a593Smuzhiyun
rme9652_spdif_in(struct snd_rme9652 * rme9652)942*4882a593Smuzhiyun static unsigned int rme9652_spdif_in(struct snd_rme9652 *rme9652)
943*4882a593Smuzhiyun {
944*4882a593Smuzhiyun return rme9652_decode_spdif_in(rme9652->control_register &
945*4882a593Smuzhiyun RME9652_inp);
946*4882a593Smuzhiyun }
947*4882a593Smuzhiyun
rme9652_set_spdif_input(struct snd_rme9652 * rme9652,int in)948*4882a593Smuzhiyun static int rme9652_set_spdif_input(struct snd_rme9652 *rme9652, int in)
949*4882a593Smuzhiyun {
950*4882a593Smuzhiyun int restart = 0;
951*4882a593Smuzhiyun
952*4882a593Smuzhiyun rme9652->control_register &= ~RME9652_inp;
953*4882a593Smuzhiyun rme9652->control_register |= rme9652_encode_spdif_in(in);
954*4882a593Smuzhiyun
955*4882a593Smuzhiyun if ((restart = rme9652->running)) {
956*4882a593Smuzhiyun rme9652_stop(rme9652);
957*4882a593Smuzhiyun }
958*4882a593Smuzhiyun
959*4882a593Smuzhiyun rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
960*4882a593Smuzhiyun
961*4882a593Smuzhiyun if (restart) {
962*4882a593Smuzhiyun rme9652_start(rme9652);
963*4882a593Smuzhiyun }
964*4882a593Smuzhiyun
965*4882a593Smuzhiyun return 0;
966*4882a593Smuzhiyun }
967*4882a593Smuzhiyun
snd_rme9652_info_spdif_in(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)968*4882a593Smuzhiyun static int snd_rme9652_info_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
969*4882a593Smuzhiyun {
970*4882a593Smuzhiyun static const char * const texts[3] = {"ADAT1", "Coaxial", "Internal"};
971*4882a593Smuzhiyun
972*4882a593Smuzhiyun return snd_ctl_enum_info(uinfo, 1, 3, texts);
973*4882a593Smuzhiyun }
974*4882a593Smuzhiyun
snd_rme9652_get_spdif_in(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)975*4882a593Smuzhiyun static int snd_rme9652_get_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
976*4882a593Smuzhiyun {
977*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
978*4882a593Smuzhiyun
979*4882a593Smuzhiyun spin_lock_irq(&rme9652->lock);
980*4882a593Smuzhiyun ucontrol->value.enumerated.item[0] = rme9652_spdif_in(rme9652);
981*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
982*4882a593Smuzhiyun return 0;
983*4882a593Smuzhiyun }
984*4882a593Smuzhiyun
snd_rme9652_put_spdif_in(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)985*4882a593Smuzhiyun static int snd_rme9652_put_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
986*4882a593Smuzhiyun {
987*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
988*4882a593Smuzhiyun int change;
989*4882a593Smuzhiyun unsigned int val;
990*4882a593Smuzhiyun
991*4882a593Smuzhiyun if (!snd_rme9652_use_is_exclusive(rme9652))
992*4882a593Smuzhiyun return -EBUSY;
993*4882a593Smuzhiyun val = ucontrol->value.enumerated.item[0] % 3;
994*4882a593Smuzhiyun spin_lock_irq(&rme9652->lock);
995*4882a593Smuzhiyun change = val != rme9652_spdif_in(rme9652);
996*4882a593Smuzhiyun if (change)
997*4882a593Smuzhiyun rme9652_set_spdif_input(rme9652, val);
998*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
999*4882a593Smuzhiyun return change;
1000*4882a593Smuzhiyun }
1001*4882a593Smuzhiyun
1002*4882a593Smuzhiyun #define RME9652_SPDIF_OUT(xname, xindex) \
1003*4882a593Smuzhiyun { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
1004*4882a593Smuzhiyun .info = snd_rme9652_info_spdif_out, \
1005*4882a593Smuzhiyun .get = snd_rme9652_get_spdif_out, .put = snd_rme9652_put_spdif_out }
1006*4882a593Smuzhiyun
rme9652_spdif_out(struct snd_rme9652 * rme9652)1007*4882a593Smuzhiyun static int rme9652_spdif_out(struct snd_rme9652 *rme9652)
1008*4882a593Smuzhiyun {
1009*4882a593Smuzhiyun return (rme9652->control_register & RME9652_opt_out) ? 1 : 0;
1010*4882a593Smuzhiyun }
1011*4882a593Smuzhiyun
rme9652_set_spdif_output(struct snd_rme9652 * rme9652,int out)1012*4882a593Smuzhiyun static int rme9652_set_spdif_output(struct snd_rme9652 *rme9652, int out)
1013*4882a593Smuzhiyun {
1014*4882a593Smuzhiyun int restart = 0;
1015*4882a593Smuzhiyun
1016*4882a593Smuzhiyun if (out) {
1017*4882a593Smuzhiyun rme9652->control_register |= RME9652_opt_out;
1018*4882a593Smuzhiyun } else {
1019*4882a593Smuzhiyun rme9652->control_register &= ~RME9652_opt_out;
1020*4882a593Smuzhiyun }
1021*4882a593Smuzhiyun
1022*4882a593Smuzhiyun if ((restart = rme9652->running)) {
1023*4882a593Smuzhiyun rme9652_stop(rme9652);
1024*4882a593Smuzhiyun }
1025*4882a593Smuzhiyun
1026*4882a593Smuzhiyun rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
1027*4882a593Smuzhiyun
1028*4882a593Smuzhiyun if (restart) {
1029*4882a593Smuzhiyun rme9652_start(rme9652);
1030*4882a593Smuzhiyun }
1031*4882a593Smuzhiyun
1032*4882a593Smuzhiyun return 0;
1033*4882a593Smuzhiyun }
1034*4882a593Smuzhiyun
1035*4882a593Smuzhiyun #define snd_rme9652_info_spdif_out snd_ctl_boolean_mono_info
1036*4882a593Smuzhiyun
snd_rme9652_get_spdif_out(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1037*4882a593Smuzhiyun static int snd_rme9652_get_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1038*4882a593Smuzhiyun {
1039*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
1040*4882a593Smuzhiyun
1041*4882a593Smuzhiyun spin_lock_irq(&rme9652->lock);
1042*4882a593Smuzhiyun ucontrol->value.integer.value[0] = rme9652_spdif_out(rme9652);
1043*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
1044*4882a593Smuzhiyun return 0;
1045*4882a593Smuzhiyun }
1046*4882a593Smuzhiyun
snd_rme9652_put_spdif_out(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1047*4882a593Smuzhiyun static int snd_rme9652_put_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1048*4882a593Smuzhiyun {
1049*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
1050*4882a593Smuzhiyun int change;
1051*4882a593Smuzhiyun unsigned int val;
1052*4882a593Smuzhiyun
1053*4882a593Smuzhiyun if (!snd_rme9652_use_is_exclusive(rme9652))
1054*4882a593Smuzhiyun return -EBUSY;
1055*4882a593Smuzhiyun val = ucontrol->value.integer.value[0] & 1;
1056*4882a593Smuzhiyun spin_lock_irq(&rme9652->lock);
1057*4882a593Smuzhiyun change = (int)val != rme9652_spdif_out(rme9652);
1058*4882a593Smuzhiyun rme9652_set_spdif_output(rme9652, val);
1059*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
1060*4882a593Smuzhiyun return change;
1061*4882a593Smuzhiyun }
1062*4882a593Smuzhiyun
1063*4882a593Smuzhiyun #define RME9652_SYNC_MODE(xname, xindex) \
1064*4882a593Smuzhiyun { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
1065*4882a593Smuzhiyun .info = snd_rme9652_info_sync_mode, \
1066*4882a593Smuzhiyun .get = snd_rme9652_get_sync_mode, .put = snd_rme9652_put_sync_mode }
1067*4882a593Smuzhiyun
rme9652_sync_mode(struct snd_rme9652 * rme9652)1068*4882a593Smuzhiyun static int rme9652_sync_mode(struct snd_rme9652 *rme9652)
1069*4882a593Smuzhiyun {
1070*4882a593Smuzhiyun if (rme9652->control_register & RME9652_wsel) {
1071*4882a593Smuzhiyun return 2;
1072*4882a593Smuzhiyun } else if (rme9652->control_register & RME9652_Master) {
1073*4882a593Smuzhiyun return 1;
1074*4882a593Smuzhiyun } else {
1075*4882a593Smuzhiyun return 0;
1076*4882a593Smuzhiyun }
1077*4882a593Smuzhiyun }
1078*4882a593Smuzhiyun
rme9652_set_sync_mode(struct snd_rme9652 * rme9652,int mode)1079*4882a593Smuzhiyun static int rme9652_set_sync_mode(struct snd_rme9652 *rme9652, int mode)
1080*4882a593Smuzhiyun {
1081*4882a593Smuzhiyun int restart = 0;
1082*4882a593Smuzhiyun
1083*4882a593Smuzhiyun switch (mode) {
1084*4882a593Smuzhiyun case 0:
1085*4882a593Smuzhiyun rme9652->control_register &=
1086*4882a593Smuzhiyun ~(RME9652_Master | RME9652_wsel);
1087*4882a593Smuzhiyun break;
1088*4882a593Smuzhiyun case 1:
1089*4882a593Smuzhiyun rme9652->control_register =
1090*4882a593Smuzhiyun (rme9652->control_register & ~RME9652_wsel) | RME9652_Master;
1091*4882a593Smuzhiyun break;
1092*4882a593Smuzhiyun case 2:
1093*4882a593Smuzhiyun rme9652->control_register |=
1094*4882a593Smuzhiyun (RME9652_Master | RME9652_wsel);
1095*4882a593Smuzhiyun break;
1096*4882a593Smuzhiyun }
1097*4882a593Smuzhiyun
1098*4882a593Smuzhiyun if ((restart = rme9652->running)) {
1099*4882a593Smuzhiyun rme9652_stop(rme9652);
1100*4882a593Smuzhiyun }
1101*4882a593Smuzhiyun
1102*4882a593Smuzhiyun rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
1103*4882a593Smuzhiyun
1104*4882a593Smuzhiyun if (restart) {
1105*4882a593Smuzhiyun rme9652_start(rme9652);
1106*4882a593Smuzhiyun }
1107*4882a593Smuzhiyun
1108*4882a593Smuzhiyun return 0;
1109*4882a593Smuzhiyun }
1110*4882a593Smuzhiyun
snd_rme9652_info_sync_mode(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)1111*4882a593Smuzhiyun static int snd_rme9652_info_sync_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1112*4882a593Smuzhiyun {
1113*4882a593Smuzhiyun static const char * const texts[3] = {
1114*4882a593Smuzhiyun "AutoSync", "Master", "Word Clock"
1115*4882a593Smuzhiyun };
1116*4882a593Smuzhiyun
1117*4882a593Smuzhiyun return snd_ctl_enum_info(uinfo, 1, 3, texts);
1118*4882a593Smuzhiyun }
1119*4882a593Smuzhiyun
snd_rme9652_get_sync_mode(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1120*4882a593Smuzhiyun static int snd_rme9652_get_sync_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1121*4882a593Smuzhiyun {
1122*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
1123*4882a593Smuzhiyun
1124*4882a593Smuzhiyun spin_lock_irq(&rme9652->lock);
1125*4882a593Smuzhiyun ucontrol->value.enumerated.item[0] = rme9652_sync_mode(rme9652);
1126*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
1127*4882a593Smuzhiyun return 0;
1128*4882a593Smuzhiyun }
1129*4882a593Smuzhiyun
snd_rme9652_put_sync_mode(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1130*4882a593Smuzhiyun static int snd_rme9652_put_sync_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1131*4882a593Smuzhiyun {
1132*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
1133*4882a593Smuzhiyun int change;
1134*4882a593Smuzhiyun unsigned int val;
1135*4882a593Smuzhiyun
1136*4882a593Smuzhiyun val = ucontrol->value.enumerated.item[0] % 3;
1137*4882a593Smuzhiyun spin_lock_irq(&rme9652->lock);
1138*4882a593Smuzhiyun change = (int)val != rme9652_sync_mode(rme9652);
1139*4882a593Smuzhiyun rme9652_set_sync_mode(rme9652, val);
1140*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
1141*4882a593Smuzhiyun return change;
1142*4882a593Smuzhiyun }
1143*4882a593Smuzhiyun
1144*4882a593Smuzhiyun #define RME9652_SYNC_PREF(xname, xindex) \
1145*4882a593Smuzhiyun { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
1146*4882a593Smuzhiyun .info = snd_rme9652_info_sync_pref, \
1147*4882a593Smuzhiyun .get = snd_rme9652_get_sync_pref, .put = snd_rme9652_put_sync_pref }
1148*4882a593Smuzhiyun
rme9652_sync_pref(struct snd_rme9652 * rme9652)1149*4882a593Smuzhiyun static int rme9652_sync_pref(struct snd_rme9652 *rme9652)
1150*4882a593Smuzhiyun {
1151*4882a593Smuzhiyun switch (rme9652->control_register & RME9652_SyncPref_Mask) {
1152*4882a593Smuzhiyun case RME9652_SyncPref_ADAT1:
1153*4882a593Smuzhiyun return RME9652_SYNC_FROM_ADAT1;
1154*4882a593Smuzhiyun case RME9652_SyncPref_ADAT2:
1155*4882a593Smuzhiyun return RME9652_SYNC_FROM_ADAT2;
1156*4882a593Smuzhiyun case RME9652_SyncPref_ADAT3:
1157*4882a593Smuzhiyun return RME9652_SYNC_FROM_ADAT3;
1158*4882a593Smuzhiyun case RME9652_SyncPref_SPDIF:
1159*4882a593Smuzhiyun return RME9652_SYNC_FROM_SPDIF;
1160*4882a593Smuzhiyun }
1161*4882a593Smuzhiyun /* Not reachable */
1162*4882a593Smuzhiyun return 0;
1163*4882a593Smuzhiyun }
1164*4882a593Smuzhiyun
rme9652_set_sync_pref(struct snd_rme9652 * rme9652,int pref)1165*4882a593Smuzhiyun static int rme9652_set_sync_pref(struct snd_rme9652 *rme9652, int pref)
1166*4882a593Smuzhiyun {
1167*4882a593Smuzhiyun int restart;
1168*4882a593Smuzhiyun
1169*4882a593Smuzhiyun rme9652->control_register &= ~RME9652_SyncPref_Mask;
1170*4882a593Smuzhiyun switch (pref) {
1171*4882a593Smuzhiyun case RME9652_SYNC_FROM_ADAT1:
1172*4882a593Smuzhiyun rme9652->control_register |= RME9652_SyncPref_ADAT1;
1173*4882a593Smuzhiyun break;
1174*4882a593Smuzhiyun case RME9652_SYNC_FROM_ADAT2:
1175*4882a593Smuzhiyun rme9652->control_register |= RME9652_SyncPref_ADAT2;
1176*4882a593Smuzhiyun break;
1177*4882a593Smuzhiyun case RME9652_SYNC_FROM_ADAT3:
1178*4882a593Smuzhiyun rme9652->control_register |= RME9652_SyncPref_ADAT3;
1179*4882a593Smuzhiyun break;
1180*4882a593Smuzhiyun case RME9652_SYNC_FROM_SPDIF:
1181*4882a593Smuzhiyun rme9652->control_register |= RME9652_SyncPref_SPDIF;
1182*4882a593Smuzhiyun break;
1183*4882a593Smuzhiyun }
1184*4882a593Smuzhiyun
1185*4882a593Smuzhiyun if ((restart = rme9652->running)) {
1186*4882a593Smuzhiyun rme9652_stop(rme9652);
1187*4882a593Smuzhiyun }
1188*4882a593Smuzhiyun
1189*4882a593Smuzhiyun rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
1190*4882a593Smuzhiyun
1191*4882a593Smuzhiyun if (restart) {
1192*4882a593Smuzhiyun rme9652_start(rme9652);
1193*4882a593Smuzhiyun }
1194*4882a593Smuzhiyun
1195*4882a593Smuzhiyun return 0;
1196*4882a593Smuzhiyun }
1197*4882a593Smuzhiyun
snd_rme9652_info_sync_pref(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)1198*4882a593Smuzhiyun static int snd_rme9652_info_sync_pref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1199*4882a593Smuzhiyun {
1200*4882a593Smuzhiyun static const char * const texts[4] = {
1201*4882a593Smuzhiyun "IEC958 In", "ADAT1 In", "ADAT2 In", "ADAT3 In"
1202*4882a593Smuzhiyun };
1203*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
1204*4882a593Smuzhiyun
1205*4882a593Smuzhiyun return snd_ctl_enum_info(uinfo, 1,
1206*4882a593Smuzhiyun rme9652->ss_channels == RME9652_NCHANNELS ? 4 : 3,
1207*4882a593Smuzhiyun texts);
1208*4882a593Smuzhiyun }
1209*4882a593Smuzhiyun
snd_rme9652_get_sync_pref(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1210*4882a593Smuzhiyun static int snd_rme9652_get_sync_pref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1211*4882a593Smuzhiyun {
1212*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
1213*4882a593Smuzhiyun
1214*4882a593Smuzhiyun spin_lock_irq(&rme9652->lock);
1215*4882a593Smuzhiyun ucontrol->value.enumerated.item[0] = rme9652_sync_pref(rme9652);
1216*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
1217*4882a593Smuzhiyun return 0;
1218*4882a593Smuzhiyun }
1219*4882a593Smuzhiyun
snd_rme9652_put_sync_pref(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1220*4882a593Smuzhiyun static int snd_rme9652_put_sync_pref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1221*4882a593Smuzhiyun {
1222*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
1223*4882a593Smuzhiyun int change, max;
1224*4882a593Smuzhiyun unsigned int val;
1225*4882a593Smuzhiyun
1226*4882a593Smuzhiyun if (!snd_rme9652_use_is_exclusive(rme9652))
1227*4882a593Smuzhiyun return -EBUSY;
1228*4882a593Smuzhiyun max = rme9652->ss_channels == RME9652_NCHANNELS ? 4 : 3;
1229*4882a593Smuzhiyun val = ucontrol->value.enumerated.item[0] % max;
1230*4882a593Smuzhiyun spin_lock_irq(&rme9652->lock);
1231*4882a593Smuzhiyun change = (int)val != rme9652_sync_pref(rme9652);
1232*4882a593Smuzhiyun rme9652_set_sync_pref(rme9652, val);
1233*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
1234*4882a593Smuzhiyun return change;
1235*4882a593Smuzhiyun }
1236*4882a593Smuzhiyun
snd_rme9652_info_thru(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)1237*4882a593Smuzhiyun static int snd_rme9652_info_thru(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1238*4882a593Smuzhiyun {
1239*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
1240*4882a593Smuzhiyun uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1241*4882a593Smuzhiyun uinfo->count = rme9652->ss_channels;
1242*4882a593Smuzhiyun uinfo->value.integer.min = 0;
1243*4882a593Smuzhiyun uinfo->value.integer.max = 1;
1244*4882a593Smuzhiyun return 0;
1245*4882a593Smuzhiyun }
1246*4882a593Smuzhiyun
snd_rme9652_get_thru(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1247*4882a593Smuzhiyun static int snd_rme9652_get_thru(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1248*4882a593Smuzhiyun {
1249*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
1250*4882a593Smuzhiyun unsigned int k;
1251*4882a593Smuzhiyun u32 thru_bits = rme9652->thru_bits;
1252*4882a593Smuzhiyun
1253*4882a593Smuzhiyun for (k = 0; k < rme9652->ss_channels; ++k) {
1254*4882a593Smuzhiyun ucontrol->value.integer.value[k] = !!(thru_bits & (1 << k));
1255*4882a593Smuzhiyun }
1256*4882a593Smuzhiyun return 0;
1257*4882a593Smuzhiyun }
1258*4882a593Smuzhiyun
snd_rme9652_put_thru(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1259*4882a593Smuzhiyun static int snd_rme9652_put_thru(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1260*4882a593Smuzhiyun {
1261*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
1262*4882a593Smuzhiyun int change;
1263*4882a593Smuzhiyun unsigned int chn;
1264*4882a593Smuzhiyun u32 thru_bits = 0;
1265*4882a593Smuzhiyun
1266*4882a593Smuzhiyun if (!snd_rme9652_use_is_exclusive(rme9652))
1267*4882a593Smuzhiyun return -EBUSY;
1268*4882a593Smuzhiyun
1269*4882a593Smuzhiyun for (chn = 0; chn < rme9652->ss_channels; ++chn) {
1270*4882a593Smuzhiyun if (ucontrol->value.integer.value[chn])
1271*4882a593Smuzhiyun thru_bits |= 1 << chn;
1272*4882a593Smuzhiyun }
1273*4882a593Smuzhiyun
1274*4882a593Smuzhiyun spin_lock_irq(&rme9652->lock);
1275*4882a593Smuzhiyun change = thru_bits ^ rme9652->thru_bits;
1276*4882a593Smuzhiyun if (change) {
1277*4882a593Smuzhiyun for (chn = 0; chn < rme9652->ss_channels; ++chn) {
1278*4882a593Smuzhiyun if (!(change & (1 << chn)))
1279*4882a593Smuzhiyun continue;
1280*4882a593Smuzhiyun rme9652_set_thru(rme9652,chn,thru_bits&(1<<chn));
1281*4882a593Smuzhiyun }
1282*4882a593Smuzhiyun }
1283*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
1284*4882a593Smuzhiyun return !!change;
1285*4882a593Smuzhiyun }
1286*4882a593Smuzhiyun
1287*4882a593Smuzhiyun #define RME9652_PASSTHRU(xname, xindex) \
1288*4882a593Smuzhiyun { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
1289*4882a593Smuzhiyun .info = snd_rme9652_info_passthru, \
1290*4882a593Smuzhiyun .put = snd_rme9652_put_passthru, \
1291*4882a593Smuzhiyun .get = snd_rme9652_get_passthru }
1292*4882a593Smuzhiyun
1293*4882a593Smuzhiyun #define snd_rme9652_info_passthru snd_ctl_boolean_mono_info
1294*4882a593Smuzhiyun
snd_rme9652_get_passthru(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1295*4882a593Smuzhiyun static int snd_rme9652_get_passthru(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1296*4882a593Smuzhiyun {
1297*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
1298*4882a593Smuzhiyun
1299*4882a593Smuzhiyun spin_lock_irq(&rme9652->lock);
1300*4882a593Smuzhiyun ucontrol->value.integer.value[0] = rme9652->passthru;
1301*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
1302*4882a593Smuzhiyun return 0;
1303*4882a593Smuzhiyun }
1304*4882a593Smuzhiyun
snd_rme9652_put_passthru(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1305*4882a593Smuzhiyun static int snd_rme9652_put_passthru(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1306*4882a593Smuzhiyun {
1307*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
1308*4882a593Smuzhiyun int change;
1309*4882a593Smuzhiyun unsigned int val;
1310*4882a593Smuzhiyun int err = 0;
1311*4882a593Smuzhiyun
1312*4882a593Smuzhiyun if (!snd_rme9652_use_is_exclusive(rme9652))
1313*4882a593Smuzhiyun return -EBUSY;
1314*4882a593Smuzhiyun
1315*4882a593Smuzhiyun val = ucontrol->value.integer.value[0] & 1;
1316*4882a593Smuzhiyun spin_lock_irq(&rme9652->lock);
1317*4882a593Smuzhiyun change = (ucontrol->value.integer.value[0] != rme9652->passthru);
1318*4882a593Smuzhiyun if (change)
1319*4882a593Smuzhiyun err = rme9652_set_passthru(rme9652, val);
1320*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
1321*4882a593Smuzhiyun return err ? err : change;
1322*4882a593Smuzhiyun }
1323*4882a593Smuzhiyun
1324*4882a593Smuzhiyun /* Read-only switches */
1325*4882a593Smuzhiyun
1326*4882a593Smuzhiyun #define RME9652_SPDIF_RATE(xname, xindex) \
1327*4882a593Smuzhiyun { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
1328*4882a593Smuzhiyun .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
1329*4882a593Smuzhiyun .info = snd_rme9652_info_spdif_rate, \
1330*4882a593Smuzhiyun .get = snd_rme9652_get_spdif_rate }
1331*4882a593Smuzhiyun
snd_rme9652_info_spdif_rate(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)1332*4882a593Smuzhiyun static int snd_rme9652_info_spdif_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1333*4882a593Smuzhiyun {
1334*4882a593Smuzhiyun uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1335*4882a593Smuzhiyun uinfo->count = 1;
1336*4882a593Smuzhiyun uinfo->value.integer.min = 0;
1337*4882a593Smuzhiyun uinfo->value.integer.max = 96000;
1338*4882a593Smuzhiyun return 0;
1339*4882a593Smuzhiyun }
1340*4882a593Smuzhiyun
snd_rme9652_get_spdif_rate(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1341*4882a593Smuzhiyun static int snd_rme9652_get_spdif_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1342*4882a593Smuzhiyun {
1343*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
1344*4882a593Smuzhiyun
1345*4882a593Smuzhiyun spin_lock_irq(&rme9652->lock);
1346*4882a593Smuzhiyun ucontrol->value.integer.value[0] = rme9652_spdif_sample_rate(rme9652);
1347*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
1348*4882a593Smuzhiyun return 0;
1349*4882a593Smuzhiyun }
1350*4882a593Smuzhiyun
1351*4882a593Smuzhiyun #define RME9652_ADAT_SYNC(xname, xindex, xidx) \
1352*4882a593Smuzhiyun { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
1353*4882a593Smuzhiyun .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
1354*4882a593Smuzhiyun .info = snd_rme9652_info_adat_sync, \
1355*4882a593Smuzhiyun .get = snd_rme9652_get_adat_sync, .private_value = xidx }
1356*4882a593Smuzhiyun
snd_rme9652_info_adat_sync(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)1357*4882a593Smuzhiyun static int snd_rme9652_info_adat_sync(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1358*4882a593Smuzhiyun {
1359*4882a593Smuzhiyun static const char * const texts[4] = {
1360*4882a593Smuzhiyun "No Lock", "Lock", "No Lock Sync", "Lock Sync"
1361*4882a593Smuzhiyun };
1362*4882a593Smuzhiyun
1363*4882a593Smuzhiyun return snd_ctl_enum_info(uinfo, 1, 4, texts);
1364*4882a593Smuzhiyun }
1365*4882a593Smuzhiyun
snd_rme9652_get_adat_sync(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1366*4882a593Smuzhiyun static int snd_rme9652_get_adat_sync(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1367*4882a593Smuzhiyun {
1368*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
1369*4882a593Smuzhiyun unsigned int mask1, mask2, val;
1370*4882a593Smuzhiyun
1371*4882a593Smuzhiyun switch (kcontrol->private_value) {
1372*4882a593Smuzhiyun case 0: mask1 = RME9652_lock_0; mask2 = RME9652_sync_0; break;
1373*4882a593Smuzhiyun case 1: mask1 = RME9652_lock_1; mask2 = RME9652_sync_1; break;
1374*4882a593Smuzhiyun case 2: mask1 = RME9652_lock_2; mask2 = RME9652_sync_2; break;
1375*4882a593Smuzhiyun default: return -EINVAL;
1376*4882a593Smuzhiyun }
1377*4882a593Smuzhiyun val = rme9652_read(rme9652, RME9652_status_register);
1378*4882a593Smuzhiyun ucontrol->value.enumerated.item[0] = (val & mask1) ? 1 : 0;
1379*4882a593Smuzhiyun ucontrol->value.enumerated.item[0] |= (val & mask2) ? 2 : 0;
1380*4882a593Smuzhiyun return 0;
1381*4882a593Smuzhiyun }
1382*4882a593Smuzhiyun
1383*4882a593Smuzhiyun #define RME9652_TC_VALID(xname, xindex) \
1384*4882a593Smuzhiyun { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
1385*4882a593Smuzhiyun .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
1386*4882a593Smuzhiyun .info = snd_rme9652_info_tc_valid, \
1387*4882a593Smuzhiyun .get = snd_rme9652_get_tc_valid }
1388*4882a593Smuzhiyun
1389*4882a593Smuzhiyun #define snd_rme9652_info_tc_valid snd_ctl_boolean_mono_info
1390*4882a593Smuzhiyun
snd_rme9652_get_tc_valid(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1391*4882a593Smuzhiyun static int snd_rme9652_get_tc_valid(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1392*4882a593Smuzhiyun {
1393*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
1394*4882a593Smuzhiyun
1395*4882a593Smuzhiyun ucontrol->value.integer.value[0] =
1396*4882a593Smuzhiyun (rme9652_read(rme9652, RME9652_status_register) & RME9652_tc_valid) ? 1 : 0;
1397*4882a593Smuzhiyun return 0;
1398*4882a593Smuzhiyun }
1399*4882a593Smuzhiyun
1400*4882a593Smuzhiyun #ifdef ALSA_HAS_STANDARD_WAY_OF_RETURNING_TIMECODE
1401*4882a593Smuzhiyun
1402*4882a593Smuzhiyun /* FIXME: this routine needs a port to the new control API --jk */
1403*4882a593Smuzhiyun
snd_rme9652_get_tc_value(void * private_data,snd_kswitch_t * kswitch,snd_switch_t * uswitch)1404*4882a593Smuzhiyun static int snd_rme9652_get_tc_value(void *private_data,
1405*4882a593Smuzhiyun snd_kswitch_t *kswitch,
1406*4882a593Smuzhiyun snd_switch_t *uswitch)
1407*4882a593Smuzhiyun {
1408*4882a593Smuzhiyun struct snd_rme9652 *s = (struct snd_rme9652 *) private_data;
1409*4882a593Smuzhiyun u32 value;
1410*4882a593Smuzhiyun int i;
1411*4882a593Smuzhiyun
1412*4882a593Smuzhiyun uswitch->type = SNDRV_SW_TYPE_DWORD;
1413*4882a593Smuzhiyun
1414*4882a593Smuzhiyun if ((rme9652_read(s, RME9652_status_register) &
1415*4882a593Smuzhiyun RME9652_tc_valid) == 0) {
1416*4882a593Smuzhiyun uswitch->value.data32[0] = 0;
1417*4882a593Smuzhiyun return 0;
1418*4882a593Smuzhiyun }
1419*4882a593Smuzhiyun
1420*4882a593Smuzhiyun /* timecode request */
1421*4882a593Smuzhiyun
1422*4882a593Smuzhiyun rme9652_write(s, RME9652_time_code, 0);
1423*4882a593Smuzhiyun
1424*4882a593Smuzhiyun /* XXX bug alert: loop-based timing !!!! */
1425*4882a593Smuzhiyun
1426*4882a593Smuzhiyun for (i = 0; i < 50; i++) {
1427*4882a593Smuzhiyun if (!(rme9652_read(s, i * 4) & RME9652_tc_busy))
1428*4882a593Smuzhiyun break;
1429*4882a593Smuzhiyun }
1430*4882a593Smuzhiyun
1431*4882a593Smuzhiyun if (!(rme9652_read(s, i * 4) & RME9652_tc_busy)) {
1432*4882a593Smuzhiyun return -EIO;
1433*4882a593Smuzhiyun }
1434*4882a593Smuzhiyun
1435*4882a593Smuzhiyun value = 0;
1436*4882a593Smuzhiyun
1437*4882a593Smuzhiyun for (i = 0; i < 32; i++) {
1438*4882a593Smuzhiyun value >>= 1;
1439*4882a593Smuzhiyun
1440*4882a593Smuzhiyun if (rme9652_read(s, i * 4) & RME9652_tc_out)
1441*4882a593Smuzhiyun value |= 0x80000000;
1442*4882a593Smuzhiyun }
1443*4882a593Smuzhiyun
1444*4882a593Smuzhiyun if (value > 2 * 60 * 48000) {
1445*4882a593Smuzhiyun value -= 2 * 60 * 48000;
1446*4882a593Smuzhiyun } else {
1447*4882a593Smuzhiyun value = 0;
1448*4882a593Smuzhiyun }
1449*4882a593Smuzhiyun
1450*4882a593Smuzhiyun uswitch->value.data32[0] = value;
1451*4882a593Smuzhiyun
1452*4882a593Smuzhiyun return 0;
1453*4882a593Smuzhiyun }
1454*4882a593Smuzhiyun
1455*4882a593Smuzhiyun #endif /* ALSA_HAS_STANDARD_WAY_OF_RETURNING_TIMECODE */
1456*4882a593Smuzhiyun
1457*4882a593Smuzhiyun static const struct snd_kcontrol_new snd_rme9652_controls[] = {
1458*4882a593Smuzhiyun {
1459*4882a593Smuzhiyun .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1460*4882a593Smuzhiyun .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
1461*4882a593Smuzhiyun .info = snd_rme9652_control_spdif_info,
1462*4882a593Smuzhiyun .get = snd_rme9652_control_spdif_get,
1463*4882a593Smuzhiyun .put = snd_rme9652_control_spdif_put,
1464*4882a593Smuzhiyun },
1465*4882a593Smuzhiyun {
1466*4882a593Smuzhiyun .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1467*4882a593Smuzhiyun .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1468*4882a593Smuzhiyun .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
1469*4882a593Smuzhiyun .info = snd_rme9652_control_spdif_stream_info,
1470*4882a593Smuzhiyun .get = snd_rme9652_control_spdif_stream_get,
1471*4882a593Smuzhiyun .put = snd_rme9652_control_spdif_stream_put,
1472*4882a593Smuzhiyun },
1473*4882a593Smuzhiyun {
1474*4882a593Smuzhiyun .access = SNDRV_CTL_ELEM_ACCESS_READ,
1475*4882a593Smuzhiyun .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1476*4882a593Smuzhiyun .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
1477*4882a593Smuzhiyun .info = snd_rme9652_control_spdif_mask_info,
1478*4882a593Smuzhiyun .get = snd_rme9652_control_spdif_mask_get,
1479*4882a593Smuzhiyun .private_value = IEC958_AES0_NONAUDIO |
1480*4882a593Smuzhiyun IEC958_AES0_PROFESSIONAL |
1481*4882a593Smuzhiyun IEC958_AES0_CON_EMPHASIS,
1482*4882a593Smuzhiyun },
1483*4882a593Smuzhiyun {
1484*4882a593Smuzhiyun .access = SNDRV_CTL_ELEM_ACCESS_READ,
1485*4882a593Smuzhiyun .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1486*4882a593Smuzhiyun .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
1487*4882a593Smuzhiyun .info = snd_rme9652_control_spdif_mask_info,
1488*4882a593Smuzhiyun .get = snd_rme9652_control_spdif_mask_get,
1489*4882a593Smuzhiyun .private_value = IEC958_AES0_NONAUDIO |
1490*4882a593Smuzhiyun IEC958_AES0_PROFESSIONAL |
1491*4882a593Smuzhiyun IEC958_AES0_PRO_EMPHASIS,
1492*4882a593Smuzhiyun },
1493*4882a593Smuzhiyun RME9652_SPDIF_IN("IEC958 Input Connector", 0),
1494*4882a593Smuzhiyun RME9652_SPDIF_OUT("IEC958 Output also on ADAT1", 0),
1495*4882a593Smuzhiyun RME9652_SYNC_MODE("Sync Mode", 0),
1496*4882a593Smuzhiyun RME9652_SYNC_PREF("Preferred Sync Source", 0),
1497*4882a593Smuzhiyun {
1498*4882a593Smuzhiyun .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1499*4882a593Smuzhiyun .name = "Channels Thru",
1500*4882a593Smuzhiyun .index = 0,
1501*4882a593Smuzhiyun .info = snd_rme9652_info_thru,
1502*4882a593Smuzhiyun .get = snd_rme9652_get_thru,
1503*4882a593Smuzhiyun .put = snd_rme9652_put_thru,
1504*4882a593Smuzhiyun },
1505*4882a593Smuzhiyun RME9652_SPDIF_RATE("IEC958 Sample Rate", 0),
1506*4882a593Smuzhiyun RME9652_ADAT_SYNC("ADAT1 Sync Check", 0, 0),
1507*4882a593Smuzhiyun RME9652_ADAT_SYNC("ADAT2 Sync Check", 0, 1),
1508*4882a593Smuzhiyun RME9652_TC_VALID("Timecode Valid", 0),
1509*4882a593Smuzhiyun RME9652_PASSTHRU("Passthru", 0)
1510*4882a593Smuzhiyun };
1511*4882a593Smuzhiyun
1512*4882a593Smuzhiyun static const struct snd_kcontrol_new snd_rme9652_adat3_check =
1513*4882a593Smuzhiyun RME9652_ADAT_SYNC("ADAT3 Sync Check", 0, 2);
1514*4882a593Smuzhiyun
1515*4882a593Smuzhiyun static const struct snd_kcontrol_new snd_rme9652_adat1_input =
1516*4882a593Smuzhiyun RME9652_ADAT1_IN("ADAT1 Input Source", 0);
1517*4882a593Smuzhiyun
snd_rme9652_create_controls(struct snd_card * card,struct snd_rme9652 * rme9652)1518*4882a593Smuzhiyun static int snd_rme9652_create_controls(struct snd_card *card, struct snd_rme9652 *rme9652)
1519*4882a593Smuzhiyun {
1520*4882a593Smuzhiyun unsigned int idx;
1521*4882a593Smuzhiyun int err;
1522*4882a593Smuzhiyun struct snd_kcontrol *kctl;
1523*4882a593Smuzhiyun
1524*4882a593Smuzhiyun for (idx = 0; idx < ARRAY_SIZE(snd_rme9652_controls); idx++) {
1525*4882a593Smuzhiyun if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme9652_controls[idx], rme9652))) < 0)
1526*4882a593Smuzhiyun return err;
1527*4882a593Smuzhiyun if (idx == 1) /* IEC958 (S/PDIF) Stream */
1528*4882a593Smuzhiyun rme9652->spdif_ctl = kctl;
1529*4882a593Smuzhiyun }
1530*4882a593Smuzhiyun
1531*4882a593Smuzhiyun if (rme9652->ss_channels == RME9652_NCHANNELS)
1532*4882a593Smuzhiyun if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme9652_adat3_check, rme9652))) < 0)
1533*4882a593Smuzhiyun return err;
1534*4882a593Smuzhiyun
1535*4882a593Smuzhiyun if (rme9652->hw_rev >= 15)
1536*4882a593Smuzhiyun if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme9652_adat1_input, rme9652))) < 0)
1537*4882a593Smuzhiyun return err;
1538*4882a593Smuzhiyun
1539*4882a593Smuzhiyun return 0;
1540*4882a593Smuzhiyun }
1541*4882a593Smuzhiyun
1542*4882a593Smuzhiyun /*------------------------------------------------------------
1543*4882a593Smuzhiyun /proc interface
1544*4882a593Smuzhiyun ------------------------------------------------------------*/
1545*4882a593Smuzhiyun
1546*4882a593Smuzhiyun static void
snd_rme9652_proc_read(struct snd_info_entry * entry,struct snd_info_buffer * buffer)1547*4882a593Smuzhiyun snd_rme9652_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
1548*4882a593Smuzhiyun {
1549*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = (struct snd_rme9652 *) entry->private_data;
1550*4882a593Smuzhiyun u32 thru_bits = rme9652->thru_bits;
1551*4882a593Smuzhiyun int show_auto_sync_source = 0;
1552*4882a593Smuzhiyun int i;
1553*4882a593Smuzhiyun unsigned int status;
1554*4882a593Smuzhiyun int x;
1555*4882a593Smuzhiyun
1556*4882a593Smuzhiyun status = rme9652_read(rme9652, RME9652_status_register);
1557*4882a593Smuzhiyun
1558*4882a593Smuzhiyun snd_iprintf(buffer, "%s (Card #%d)\n", rme9652->card_name, rme9652->card->number + 1);
1559*4882a593Smuzhiyun snd_iprintf(buffer, "Buffers: capture %p playback %p\n",
1560*4882a593Smuzhiyun rme9652->capture_buffer, rme9652->playback_buffer);
1561*4882a593Smuzhiyun snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
1562*4882a593Smuzhiyun rme9652->irq, rme9652->port, (unsigned long)rme9652->iobase);
1563*4882a593Smuzhiyun snd_iprintf(buffer, "Control register: %x\n", rme9652->control_register);
1564*4882a593Smuzhiyun
1565*4882a593Smuzhiyun snd_iprintf(buffer, "\n");
1566*4882a593Smuzhiyun
1567*4882a593Smuzhiyun x = 1 << (6 + rme9652_decode_latency(rme9652->control_register &
1568*4882a593Smuzhiyun RME9652_latency));
1569*4882a593Smuzhiyun
1570*4882a593Smuzhiyun snd_iprintf(buffer, "Latency: %d samples (2 periods of %lu bytes)\n",
1571*4882a593Smuzhiyun x, (unsigned long) rme9652->period_bytes);
1572*4882a593Smuzhiyun snd_iprintf(buffer, "Hardware pointer (frames): %ld\n",
1573*4882a593Smuzhiyun rme9652_hw_pointer(rme9652));
1574*4882a593Smuzhiyun snd_iprintf(buffer, "Passthru: %s\n",
1575*4882a593Smuzhiyun rme9652->passthru ? "yes" : "no");
1576*4882a593Smuzhiyun
1577*4882a593Smuzhiyun if ((rme9652->control_register & (RME9652_Master | RME9652_wsel)) == 0) {
1578*4882a593Smuzhiyun snd_iprintf(buffer, "Clock mode: autosync\n");
1579*4882a593Smuzhiyun show_auto_sync_source = 1;
1580*4882a593Smuzhiyun } else if (rme9652->control_register & RME9652_wsel) {
1581*4882a593Smuzhiyun if (status & RME9652_wsel_rd) {
1582*4882a593Smuzhiyun snd_iprintf(buffer, "Clock mode: word clock\n");
1583*4882a593Smuzhiyun } else {
1584*4882a593Smuzhiyun snd_iprintf(buffer, "Clock mode: word clock (no signal)\n");
1585*4882a593Smuzhiyun }
1586*4882a593Smuzhiyun } else {
1587*4882a593Smuzhiyun snd_iprintf(buffer, "Clock mode: master\n");
1588*4882a593Smuzhiyun }
1589*4882a593Smuzhiyun
1590*4882a593Smuzhiyun if (show_auto_sync_source) {
1591*4882a593Smuzhiyun switch (rme9652->control_register & RME9652_SyncPref_Mask) {
1592*4882a593Smuzhiyun case RME9652_SyncPref_ADAT1:
1593*4882a593Smuzhiyun snd_iprintf(buffer, "Pref. sync source: ADAT1\n");
1594*4882a593Smuzhiyun break;
1595*4882a593Smuzhiyun case RME9652_SyncPref_ADAT2:
1596*4882a593Smuzhiyun snd_iprintf(buffer, "Pref. sync source: ADAT2\n");
1597*4882a593Smuzhiyun break;
1598*4882a593Smuzhiyun case RME9652_SyncPref_ADAT3:
1599*4882a593Smuzhiyun snd_iprintf(buffer, "Pref. sync source: ADAT3\n");
1600*4882a593Smuzhiyun break;
1601*4882a593Smuzhiyun case RME9652_SyncPref_SPDIF:
1602*4882a593Smuzhiyun snd_iprintf(buffer, "Pref. sync source: IEC958\n");
1603*4882a593Smuzhiyun break;
1604*4882a593Smuzhiyun default:
1605*4882a593Smuzhiyun snd_iprintf(buffer, "Pref. sync source: ???\n");
1606*4882a593Smuzhiyun }
1607*4882a593Smuzhiyun }
1608*4882a593Smuzhiyun
1609*4882a593Smuzhiyun if (rme9652->hw_rev >= 15)
1610*4882a593Smuzhiyun snd_iprintf(buffer, "\nADAT1 Input source: %s\n",
1611*4882a593Smuzhiyun (rme9652->control_register & RME9652_ADAT1_INTERNAL) ?
1612*4882a593Smuzhiyun "Internal" : "ADAT1 optical");
1613*4882a593Smuzhiyun
1614*4882a593Smuzhiyun snd_iprintf(buffer, "\n");
1615*4882a593Smuzhiyun
1616*4882a593Smuzhiyun switch (rme9652_decode_spdif_in(rme9652->control_register &
1617*4882a593Smuzhiyun RME9652_inp)) {
1618*4882a593Smuzhiyun case RME9652_SPDIFIN_OPTICAL:
1619*4882a593Smuzhiyun snd_iprintf(buffer, "IEC958 input: ADAT1\n");
1620*4882a593Smuzhiyun break;
1621*4882a593Smuzhiyun case RME9652_SPDIFIN_COAXIAL:
1622*4882a593Smuzhiyun snd_iprintf(buffer, "IEC958 input: Coaxial\n");
1623*4882a593Smuzhiyun break;
1624*4882a593Smuzhiyun case RME9652_SPDIFIN_INTERN:
1625*4882a593Smuzhiyun snd_iprintf(buffer, "IEC958 input: Internal\n");
1626*4882a593Smuzhiyun break;
1627*4882a593Smuzhiyun default:
1628*4882a593Smuzhiyun snd_iprintf(buffer, "IEC958 input: ???\n");
1629*4882a593Smuzhiyun break;
1630*4882a593Smuzhiyun }
1631*4882a593Smuzhiyun
1632*4882a593Smuzhiyun if (rme9652->control_register & RME9652_opt_out) {
1633*4882a593Smuzhiyun snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n");
1634*4882a593Smuzhiyun } else {
1635*4882a593Smuzhiyun snd_iprintf(buffer, "IEC958 output: Coaxial only\n");
1636*4882a593Smuzhiyun }
1637*4882a593Smuzhiyun
1638*4882a593Smuzhiyun if (rme9652->control_register & RME9652_PRO) {
1639*4882a593Smuzhiyun snd_iprintf(buffer, "IEC958 quality: Professional\n");
1640*4882a593Smuzhiyun } else {
1641*4882a593Smuzhiyun snd_iprintf(buffer, "IEC958 quality: Consumer\n");
1642*4882a593Smuzhiyun }
1643*4882a593Smuzhiyun
1644*4882a593Smuzhiyun if (rme9652->control_register & RME9652_EMP) {
1645*4882a593Smuzhiyun snd_iprintf(buffer, "IEC958 emphasis: on\n");
1646*4882a593Smuzhiyun } else {
1647*4882a593Smuzhiyun snd_iprintf(buffer, "IEC958 emphasis: off\n");
1648*4882a593Smuzhiyun }
1649*4882a593Smuzhiyun
1650*4882a593Smuzhiyun if (rme9652->control_register & RME9652_Dolby) {
1651*4882a593Smuzhiyun snd_iprintf(buffer, "IEC958 Dolby: on\n");
1652*4882a593Smuzhiyun } else {
1653*4882a593Smuzhiyun snd_iprintf(buffer, "IEC958 Dolby: off\n");
1654*4882a593Smuzhiyun }
1655*4882a593Smuzhiyun
1656*4882a593Smuzhiyun i = rme9652_spdif_sample_rate(rme9652);
1657*4882a593Smuzhiyun
1658*4882a593Smuzhiyun if (i < 0) {
1659*4882a593Smuzhiyun snd_iprintf(buffer,
1660*4882a593Smuzhiyun "IEC958 sample rate: error flag set\n");
1661*4882a593Smuzhiyun } else if (i == 0) {
1662*4882a593Smuzhiyun snd_iprintf(buffer, "IEC958 sample rate: undetermined\n");
1663*4882a593Smuzhiyun } else {
1664*4882a593Smuzhiyun snd_iprintf(buffer, "IEC958 sample rate: %d\n", i);
1665*4882a593Smuzhiyun }
1666*4882a593Smuzhiyun
1667*4882a593Smuzhiyun snd_iprintf(buffer, "\n");
1668*4882a593Smuzhiyun
1669*4882a593Smuzhiyun snd_iprintf(buffer, "ADAT Sample rate: %dHz\n",
1670*4882a593Smuzhiyun rme9652_adat_sample_rate(rme9652));
1671*4882a593Smuzhiyun
1672*4882a593Smuzhiyun /* Sync Check */
1673*4882a593Smuzhiyun
1674*4882a593Smuzhiyun x = status & RME9652_sync_0;
1675*4882a593Smuzhiyun if (status & RME9652_lock_0) {
1676*4882a593Smuzhiyun snd_iprintf(buffer, "ADAT1: %s\n", x ? "Sync" : "Lock");
1677*4882a593Smuzhiyun } else {
1678*4882a593Smuzhiyun snd_iprintf(buffer, "ADAT1: No Lock\n");
1679*4882a593Smuzhiyun }
1680*4882a593Smuzhiyun
1681*4882a593Smuzhiyun x = status & RME9652_sync_1;
1682*4882a593Smuzhiyun if (status & RME9652_lock_1) {
1683*4882a593Smuzhiyun snd_iprintf(buffer, "ADAT2: %s\n", x ? "Sync" : "Lock");
1684*4882a593Smuzhiyun } else {
1685*4882a593Smuzhiyun snd_iprintf(buffer, "ADAT2: No Lock\n");
1686*4882a593Smuzhiyun }
1687*4882a593Smuzhiyun
1688*4882a593Smuzhiyun x = status & RME9652_sync_2;
1689*4882a593Smuzhiyun if (status & RME9652_lock_2) {
1690*4882a593Smuzhiyun snd_iprintf(buffer, "ADAT3: %s\n", x ? "Sync" : "Lock");
1691*4882a593Smuzhiyun } else {
1692*4882a593Smuzhiyun snd_iprintf(buffer, "ADAT3: No Lock\n");
1693*4882a593Smuzhiyun }
1694*4882a593Smuzhiyun
1695*4882a593Smuzhiyun snd_iprintf(buffer, "\n");
1696*4882a593Smuzhiyun
1697*4882a593Smuzhiyun snd_iprintf(buffer, "Timecode signal: %s\n",
1698*4882a593Smuzhiyun (status & RME9652_tc_valid) ? "yes" : "no");
1699*4882a593Smuzhiyun
1700*4882a593Smuzhiyun /* thru modes */
1701*4882a593Smuzhiyun
1702*4882a593Smuzhiyun snd_iprintf(buffer, "Punch Status:\n\n");
1703*4882a593Smuzhiyun
1704*4882a593Smuzhiyun for (i = 0; i < rme9652->ss_channels; i++) {
1705*4882a593Smuzhiyun if (thru_bits & (1 << i)) {
1706*4882a593Smuzhiyun snd_iprintf(buffer, "%2d: on ", i + 1);
1707*4882a593Smuzhiyun } else {
1708*4882a593Smuzhiyun snd_iprintf(buffer, "%2d: off ", i + 1);
1709*4882a593Smuzhiyun }
1710*4882a593Smuzhiyun
1711*4882a593Smuzhiyun if (((i + 1) % 8) == 0) {
1712*4882a593Smuzhiyun snd_iprintf(buffer, "\n");
1713*4882a593Smuzhiyun }
1714*4882a593Smuzhiyun }
1715*4882a593Smuzhiyun
1716*4882a593Smuzhiyun snd_iprintf(buffer, "\n");
1717*4882a593Smuzhiyun }
1718*4882a593Smuzhiyun
snd_rme9652_proc_init(struct snd_rme9652 * rme9652)1719*4882a593Smuzhiyun static void snd_rme9652_proc_init(struct snd_rme9652 *rme9652)
1720*4882a593Smuzhiyun {
1721*4882a593Smuzhiyun snd_card_ro_proc_new(rme9652->card, "rme9652", rme9652,
1722*4882a593Smuzhiyun snd_rme9652_proc_read);
1723*4882a593Smuzhiyun }
1724*4882a593Smuzhiyun
snd_rme9652_free_buffers(struct snd_rme9652 * rme9652)1725*4882a593Smuzhiyun static void snd_rme9652_free_buffers(struct snd_rme9652 *rme9652)
1726*4882a593Smuzhiyun {
1727*4882a593Smuzhiyun snd_hammerfall_free_buffer(&rme9652->capture_dma_buf, rme9652->pci);
1728*4882a593Smuzhiyun snd_hammerfall_free_buffer(&rme9652->playback_dma_buf, rme9652->pci);
1729*4882a593Smuzhiyun }
1730*4882a593Smuzhiyun
snd_rme9652_free(struct snd_rme9652 * rme9652)1731*4882a593Smuzhiyun static int snd_rme9652_free(struct snd_rme9652 *rme9652)
1732*4882a593Smuzhiyun {
1733*4882a593Smuzhiyun if (rme9652->irq >= 0)
1734*4882a593Smuzhiyun rme9652_stop(rme9652);
1735*4882a593Smuzhiyun snd_rme9652_free_buffers(rme9652);
1736*4882a593Smuzhiyun
1737*4882a593Smuzhiyun if (rme9652->irq >= 0)
1738*4882a593Smuzhiyun free_irq(rme9652->irq, (void *)rme9652);
1739*4882a593Smuzhiyun iounmap(rme9652->iobase);
1740*4882a593Smuzhiyun if (rme9652->port)
1741*4882a593Smuzhiyun pci_release_regions(rme9652->pci);
1742*4882a593Smuzhiyun
1743*4882a593Smuzhiyun if (pci_is_enabled(rme9652->pci))
1744*4882a593Smuzhiyun pci_disable_device(rme9652->pci);
1745*4882a593Smuzhiyun return 0;
1746*4882a593Smuzhiyun }
1747*4882a593Smuzhiyun
snd_rme9652_initialize_memory(struct snd_rme9652 * rme9652)1748*4882a593Smuzhiyun static int snd_rme9652_initialize_memory(struct snd_rme9652 *rme9652)
1749*4882a593Smuzhiyun {
1750*4882a593Smuzhiyun unsigned long pb_bus, cb_bus;
1751*4882a593Smuzhiyun
1752*4882a593Smuzhiyun if (snd_hammerfall_get_buffer(rme9652->pci, &rme9652->capture_dma_buf, RME9652_DMA_AREA_BYTES) < 0 ||
1753*4882a593Smuzhiyun snd_hammerfall_get_buffer(rme9652->pci, &rme9652->playback_dma_buf, RME9652_DMA_AREA_BYTES) < 0) {
1754*4882a593Smuzhiyun if (rme9652->capture_dma_buf.area)
1755*4882a593Smuzhiyun snd_dma_free_pages(&rme9652->capture_dma_buf);
1756*4882a593Smuzhiyun dev_err(rme9652->card->dev,
1757*4882a593Smuzhiyun "%s: no buffers available\n", rme9652->card_name);
1758*4882a593Smuzhiyun return -ENOMEM;
1759*4882a593Smuzhiyun }
1760*4882a593Smuzhiyun
1761*4882a593Smuzhiyun /* Align to bus-space 64K boundary */
1762*4882a593Smuzhiyun
1763*4882a593Smuzhiyun cb_bus = ALIGN(rme9652->capture_dma_buf.addr, 0x10000ul);
1764*4882a593Smuzhiyun pb_bus = ALIGN(rme9652->playback_dma_buf.addr, 0x10000ul);
1765*4882a593Smuzhiyun
1766*4882a593Smuzhiyun /* Tell the card where it is */
1767*4882a593Smuzhiyun
1768*4882a593Smuzhiyun rme9652_write(rme9652, RME9652_rec_buffer, cb_bus);
1769*4882a593Smuzhiyun rme9652_write(rme9652, RME9652_play_buffer, pb_bus);
1770*4882a593Smuzhiyun
1771*4882a593Smuzhiyun rme9652->capture_buffer = rme9652->capture_dma_buf.area + (cb_bus - rme9652->capture_dma_buf.addr);
1772*4882a593Smuzhiyun rme9652->playback_buffer = rme9652->playback_dma_buf.area + (pb_bus - rme9652->playback_dma_buf.addr);
1773*4882a593Smuzhiyun
1774*4882a593Smuzhiyun return 0;
1775*4882a593Smuzhiyun }
1776*4882a593Smuzhiyun
snd_rme9652_set_defaults(struct snd_rme9652 * rme9652)1777*4882a593Smuzhiyun static void snd_rme9652_set_defaults(struct snd_rme9652 *rme9652)
1778*4882a593Smuzhiyun {
1779*4882a593Smuzhiyun unsigned int k;
1780*4882a593Smuzhiyun
1781*4882a593Smuzhiyun /* ASSUMPTION: rme9652->lock is either held, or
1782*4882a593Smuzhiyun there is no need to hold it (e.g. during module
1783*4882a593Smuzhiyun initialization).
1784*4882a593Smuzhiyun */
1785*4882a593Smuzhiyun
1786*4882a593Smuzhiyun /* set defaults:
1787*4882a593Smuzhiyun
1788*4882a593Smuzhiyun SPDIF Input via Coax
1789*4882a593Smuzhiyun autosync clock mode
1790*4882a593Smuzhiyun maximum latency (7 = 8192 samples, 64Kbyte buffer,
1791*4882a593Smuzhiyun which implies 2 4096 sample, 32Kbyte periods).
1792*4882a593Smuzhiyun
1793*4882a593Smuzhiyun if rev 1.5, initialize the S/PDIF receiver.
1794*4882a593Smuzhiyun
1795*4882a593Smuzhiyun */
1796*4882a593Smuzhiyun
1797*4882a593Smuzhiyun rme9652->control_register =
1798*4882a593Smuzhiyun RME9652_inp_0 | rme9652_encode_latency(7);
1799*4882a593Smuzhiyun
1800*4882a593Smuzhiyun rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
1801*4882a593Smuzhiyun
1802*4882a593Smuzhiyun rme9652_reset_hw_pointer(rme9652);
1803*4882a593Smuzhiyun rme9652_compute_period_size(rme9652);
1804*4882a593Smuzhiyun
1805*4882a593Smuzhiyun /* default: thru off for all channels */
1806*4882a593Smuzhiyun
1807*4882a593Smuzhiyun for (k = 0; k < RME9652_NCHANNELS; ++k)
1808*4882a593Smuzhiyun rme9652_write(rme9652, RME9652_thru_base + k * 4, 0);
1809*4882a593Smuzhiyun
1810*4882a593Smuzhiyun rme9652->thru_bits = 0;
1811*4882a593Smuzhiyun rme9652->passthru = 0;
1812*4882a593Smuzhiyun
1813*4882a593Smuzhiyun /* set a default rate so that the channel map is set up */
1814*4882a593Smuzhiyun
1815*4882a593Smuzhiyun rme9652_set_rate(rme9652, 48000);
1816*4882a593Smuzhiyun }
1817*4882a593Smuzhiyun
snd_rme9652_interrupt(int irq,void * dev_id)1818*4882a593Smuzhiyun static irqreturn_t snd_rme9652_interrupt(int irq, void *dev_id)
1819*4882a593Smuzhiyun {
1820*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = (struct snd_rme9652 *) dev_id;
1821*4882a593Smuzhiyun
1822*4882a593Smuzhiyun if (!(rme9652_read(rme9652, RME9652_status_register) & RME9652_IRQ)) {
1823*4882a593Smuzhiyun return IRQ_NONE;
1824*4882a593Smuzhiyun }
1825*4882a593Smuzhiyun
1826*4882a593Smuzhiyun rme9652_write(rme9652, RME9652_irq_clear, 0);
1827*4882a593Smuzhiyun
1828*4882a593Smuzhiyun if (rme9652->capture_substream) {
1829*4882a593Smuzhiyun snd_pcm_period_elapsed(rme9652->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
1830*4882a593Smuzhiyun }
1831*4882a593Smuzhiyun
1832*4882a593Smuzhiyun if (rme9652->playback_substream) {
1833*4882a593Smuzhiyun snd_pcm_period_elapsed(rme9652->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream);
1834*4882a593Smuzhiyun }
1835*4882a593Smuzhiyun return IRQ_HANDLED;
1836*4882a593Smuzhiyun }
1837*4882a593Smuzhiyun
snd_rme9652_hw_pointer(struct snd_pcm_substream * substream)1838*4882a593Smuzhiyun static snd_pcm_uframes_t snd_rme9652_hw_pointer(struct snd_pcm_substream *substream)
1839*4882a593Smuzhiyun {
1840*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
1841*4882a593Smuzhiyun return rme9652_hw_pointer(rme9652);
1842*4882a593Smuzhiyun }
1843*4882a593Smuzhiyun
rme9652_channel_buffer_location(struct snd_rme9652 * rme9652,int stream,int channel)1844*4882a593Smuzhiyun static signed char *rme9652_channel_buffer_location(struct snd_rme9652 *rme9652,
1845*4882a593Smuzhiyun int stream,
1846*4882a593Smuzhiyun int channel)
1847*4882a593Smuzhiyun
1848*4882a593Smuzhiyun {
1849*4882a593Smuzhiyun int mapped_channel;
1850*4882a593Smuzhiyun
1851*4882a593Smuzhiyun if (snd_BUG_ON(channel < 0 || channel >= RME9652_NCHANNELS))
1852*4882a593Smuzhiyun return NULL;
1853*4882a593Smuzhiyun
1854*4882a593Smuzhiyun if ((mapped_channel = rme9652->channel_map[channel]) < 0) {
1855*4882a593Smuzhiyun return NULL;
1856*4882a593Smuzhiyun }
1857*4882a593Smuzhiyun
1858*4882a593Smuzhiyun if (stream == SNDRV_PCM_STREAM_CAPTURE) {
1859*4882a593Smuzhiyun return rme9652->capture_buffer +
1860*4882a593Smuzhiyun (mapped_channel * RME9652_CHANNEL_BUFFER_BYTES);
1861*4882a593Smuzhiyun } else {
1862*4882a593Smuzhiyun return rme9652->playback_buffer +
1863*4882a593Smuzhiyun (mapped_channel * RME9652_CHANNEL_BUFFER_BYTES);
1864*4882a593Smuzhiyun }
1865*4882a593Smuzhiyun }
1866*4882a593Smuzhiyun
snd_rme9652_playback_copy(struct snd_pcm_substream * substream,int channel,unsigned long pos,void __user * src,unsigned long count)1867*4882a593Smuzhiyun static int snd_rme9652_playback_copy(struct snd_pcm_substream *substream,
1868*4882a593Smuzhiyun int channel, unsigned long pos,
1869*4882a593Smuzhiyun void __user *src, unsigned long count)
1870*4882a593Smuzhiyun {
1871*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
1872*4882a593Smuzhiyun signed char *channel_buf;
1873*4882a593Smuzhiyun
1874*4882a593Smuzhiyun if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES))
1875*4882a593Smuzhiyun return -EINVAL;
1876*4882a593Smuzhiyun
1877*4882a593Smuzhiyun channel_buf = rme9652_channel_buffer_location (rme9652,
1878*4882a593Smuzhiyun substream->pstr->stream,
1879*4882a593Smuzhiyun channel);
1880*4882a593Smuzhiyun if (snd_BUG_ON(!channel_buf))
1881*4882a593Smuzhiyun return -EIO;
1882*4882a593Smuzhiyun if (copy_from_user(channel_buf + pos, src, count))
1883*4882a593Smuzhiyun return -EFAULT;
1884*4882a593Smuzhiyun return 0;
1885*4882a593Smuzhiyun }
1886*4882a593Smuzhiyun
snd_rme9652_playback_copy_kernel(struct snd_pcm_substream * substream,int channel,unsigned long pos,void * src,unsigned long count)1887*4882a593Smuzhiyun static int snd_rme9652_playback_copy_kernel(struct snd_pcm_substream *substream,
1888*4882a593Smuzhiyun int channel, unsigned long pos,
1889*4882a593Smuzhiyun void *src, unsigned long count)
1890*4882a593Smuzhiyun {
1891*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
1892*4882a593Smuzhiyun signed char *channel_buf;
1893*4882a593Smuzhiyun
1894*4882a593Smuzhiyun channel_buf = rme9652_channel_buffer_location(rme9652,
1895*4882a593Smuzhiyun substream->pstr->stream,
1896*4882a593Smuzhiyun channel);
1897*4882a593Smuzhiyun if (snd_BUG_ON(!channel_buf))
1898*4882a593Smuzhiyun return -EIO;
1899*4882a593Smuzhiyun memcpy(channel_buf + pos, src, count);
1900*4882a593Smuzhiyun return 0;
1901*4882a593Smuzhiyun }
1902*4882a593Smuzhiyun
snd_rme9652_capture_copy(struct snd_pcm_substream * substream,int channel,unsigned long pos,void __user * dst,unsigned long count)1903*4882a593Smuzhiyun static int snd_rme9652_capture_copy(struct snd_pcm_substream *substream,
1904*4882a593Smuzhiyun int channel, unsigned long pos,
1905*4882a593Smuzhiyun void __user *dst, unsigned long count)
1906*4882a593Smuzhiyun {
1907*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
1908*4882a593Smuzhiyun signed char *channel_buf;
1909*4882a593Smuzhiyun
1910*4882a593Smuzhiyun if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES))
1911*4882a593Smuzhiyun return -EINVAL;
1912*4882a593Smuzhiyun
1913*4882a593Smuzhiyun channel_buf = rme9652_channel_buffer_location (rme9652,
1914*4882a593Smuzhiyun substream->pstr->stream,
1915*4882a593Smuzhiyun channel);
1916*4882a593Smuzhiyun if (snd_BUG_ON(!channel_buf))
1917*4882a593Smuzhiyun return -EIO;
1918*4882a593Smuzhiyun if (copy_to_user(dst, channel_buf + pos, count))
1919*4882a593Smuzhiyun return -EFAULT;
1920*4882a593Smuzhiyun return 0;
1921*4882a593Smuzhiyun }
1922*4882a593Smuzhiyun
snd_rme9652_capture_copy_kernel(struct snd_pcm_substream * substream,int channel,unsigned long pos,void * dst,unsigned long count)1923*4882a593Smuzhiyun static int snd_rme9652_capture_copy_kernel(struct snd_pcm_substream *substream,
1924*4882a593Smuzhiyun int channel, unsigned long pos,
1925*4882a593Smuzhiyun void *dst, unsigned long count)
1926*4882a593Smuzhiyun {
1927*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
1928*4882a593Smuzhiyun signed char *channel_buf;
1929*4882a593Smuzhiyun
1930*4882a593Smuzhiyun channel_buf = rme9652_channel_buffer_location(rme9652,
1931*4882a593Smuzhiyun substream->pstr->stream,
1932*4882a593Smuzhiyun channel);
1933*4882a593Smuzhiyun if (snd_BUG_ON(!channel_buf))
1934*4882a593Smuzhiyun return -EIO;
1935*4882a593Smuzhiyun memcpy(dst, channel_buf + pos, count);
1936*4882a593Smuzhiyun return 0;
1937*4882a593Smuzhiyun }
1938*4882a593Smuzhiyun
snd_rme9652_hw_silence(struct snd_pcm_substream * substream,int channel,unsigned long pos,unsigned long count)1939*4882a593Smuzhiyun static int snd_rme9652_hw_silence(struct snd_pcm_substream *substream,
1940*4882a593Smuzhiyun int channel, unsigned long pos,
1941*4882a593Smuzhiyun unsigned long count)
1942*4882a593Smuzhiyun {
1943*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
1944*4882a593Smuzhiyun signed char *channel_buf;
1945*4882a593Smuzhiyun
1946*4882a593Smuzhiyun channel_buf = rme9652_channel_buffer_location (rme9652,
1947*4882a593Smuzhiyun substream->pstr->stream,
1948*4882a593Smuzhiyun channel);
1949*4882a593Smuzhiyun if (snd_BUG_ON(!channel_buf))
1950*4882a593Smuzhiyun return -EIO;
1951*4882a593Smuzhiyun memset(channel_buf + pos, 0, count);
1952*4882a593Smuzhiyun return 0;
1953*4882a593Smuzhiyun }
1954*4882a593Smuzhiyun
snd_rme9652_reset(struct snd_pcm_substream * substream)1955*4882a593Smuzhiyun static int snd_rme9652_reset(struct snd_pcm_substream *substream)
1956*4882a593Smuzhiyun {
1957*4882a593Smuzhiyun struct snd_pcm_runtime *runtime = substream->runtime;
1958*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
1959*4882a593Smuzhiyun struct snd_pcm_substream *other;
1960*4882a593Smuzhiyun if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1961*4882a593Smuzhiyun other = rme9652->capture_substream;
1962*4882a593Smuzhiyun else
1963*4882a593Smuzhiyun other = rme9652->playback_substream;
1964*4882a593Smuzhiyun if (rme9652->running)
1965*4882a593Smuzhiyun runtime->status->hw_ptr = rme9652_hw_pointer(rme9652);
1966*4882a593Smuzhiyun else
1967*4882a593Smuzhiyun runtime->status->hw_ptr = 0;
1968*4882a593Smuzhiyun if (other) {
1969*4882a593Smuzhiyun struct snd_pcm_substream *s;
1970*4882a593Smuzhiyun struct snd_pcm_runtime *oruntime = other->runtime;
1971*4882a593Smuzhiyun snd_pcm_group_for_each_entry(s, substream) {
1972*4882a593Smuzhiyun if (s == other) {
1973*4882a593Smuzhiyun oruntime->status->hw_ptr = runtime->status->hw_ptr;
1974*4882a593Smuzhiyun break;
1975*4882a593Smuzhiyun }
1976*4882a593Smuzhiyun }
1977*4882a593Smuzhiyun }
1978*4882a593Smuzhiyun return 0;
1979*4882a593Smuzhiyun }
1980*4882a593Smuzhiyun
snd_rme9652_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params)1981*4882a593Smuzhiyun static int snd_rme9652_hw_params(struct snd_pcm_substream *substream,
1982*4882a593Smuzhiyun struct snd_pcm_hw_params *params)
1983*4882a593Smuzhiyun {
1984*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
1985*4882a593Smuzhiyun int err;
1986*4882a593Smuzhiyun pid_t this_pid;
1987*4882a593Smuzhiyun pid_t other_pid;
1988*4882a593Smuzhiyun
1989*4882a593Smuzhiyun spin_lock_irq(&rme9652->lock);
1990*4882a593Smuzhiyun
1991*4882a593Smuzhiyun if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1992*4882a593Smuzhiyun rme9652->control_register &= ~(RME9652_PRO | RME9652_Dolby | RME9652_EMP);
1993*4882a593Smuzhiyun rme9652_write(rme9652, RME9652_control_register, rme9652->control_register |= rme9652->creg_spdif_stream);
1994*4882a593Smuzhiyun this_pid = rme9652->playback_pid;
1995*4882a593Smuzhiyun other_pid = rme9652->capture_pid;
1996*4882a593Smuzhiyun } else {
1997*4882a593Smuzhiyun this_pid = rme9652->capture_pid;
1998*4882a593Smuzhiyun other_pid = rme9652->playback_pid;
1999*4882a593Smuzhiyun }
2000*4882a593Smuzhiyun
2001*4882a593Smuzhiyun if ((other_pid > 0) && (this_pid != other_pid)) {
2002*4882a593Smuzhiyun
2003*4882a593Smuzhiyun /* The other stream is open, and not by the same
2004*4882a593Smuzhiyun task as this one. Make sure that the parameters
2005*4882a593Smuzhiyun that matter are the same.
2006*4882a593Smuzhiyun */
2007*4882a593Smuzhiyun
2008*4882a593Smuzhiyun if ((int)params_rate(params) !=
2009*4882a593Smuzhiyun rme9652_adat_sample_rate(rme9652)) {
2010*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
2011*4882a593Smuzhiyun _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
2012*4882a593Smuzhiyun return -EBUSY;
2013*4882a593Smuzhiyun }
2014*4882a593Smuzhiyun
2015*4882a593Smuzhiyun if (params_period_size(params) != rme9652->period_bytes / 4) {
2016*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
2017*4882a593Smuzhiyun _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
2018*4882a593Smuzhiyun return -EBUSY;
2019*4882a593Smuzhiyun }
2020*4882a593Smuzhiyun
2021*4882a593Smuzhiyun /* We're fine. */
2022*4882a593Smuzhiyun
2023*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
2024*4882a593Smuzhiyun return 0;
2025*4882a593Smuzhiyun
2026*4882a593Smuzhiyun } else {
2027*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
2028*4882a593Smuzhiyun }
2029*4882a593Smuzhiyun
2030*4882a593Smuzhiyun /* how to make sure that the rate matches an externally-set one ?
2031*4882a593Smuzhiyun */
2032*4882a593Smuzhiyun
2033*4882a593Smuzhiyun if ((err = rme9652_set_rate(rme9652, params_rate(params))) < 0) {
2034*4882a593Smuzhiyun _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
2035*4882a593Smuzhiyun return err;
2036*4882a593Smuzhiyun }
2037*4882a593Smuzhiyun
2038*4882a593Smuzhiyun if ((err = rme9652_set_interrupt_interval(rme9652, params_period_size(params))) < 0) {
2039*4882a593Smuzhiyun _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
2040*4882a593Smuzhiyun return err;
2041*4882a593Smuzhiyun }
2042*4882a593Smuzhiyun
2043*4882a593Smuzhiyun return 0;
2044*4882a593Smuzhiyun }
2045*4882a593Smuzhiyun
snd_rme9652_channel_info(struct snd_pcm_substream * substream,struct snd_pcm_channel_info * info)2046*4882a593Smuzhiyun static int snd_rme9652_channel_info(struct snd_pcm_substream *substream,
2047*4882a593Smuzhiyun struct snd_pcm_channel_info *info)
2048*4882a593Smuzhiyun {
2049*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
2050*4882a593Smuzhiyun int chn;
2051*4882a593Smuzhiyun
2052*4882a593Smuzhiyun if (snd_BUG_ON(info->channel >= RME9652_NCHANNELS))
2053*4882a593Smuzhiyun return -EINVAL;
2054*4882a593Smuzhiyun
2055*4882a593Smuzhiyun chn = rme9652->channel_map[array_index_nospec(info->channel,
2056*4882a593Smuzhiyun RME9652_NCHANNELS)];
2057*4882a593Smuzhiyun if (chn < 0)
2058*4882a593Smuzhiyun return -EINVAL;
2059*4882a593Smuzhiyun
2060*4882a593Smuzhiyun info->offset = chn * RME9652_CHANNEL_BUFFER_BYTES;
2061*4882a593Smuzhiyun info->first = 0;
2062*4882a593Smuzhiyun info->step = 32;
2063*4882a593Smuzhiyun return 0;
2064*4882a593Smuzhiyun }
2065*4882a593Smuzhiyun
snd_rme9652_ioctl(struct snd_pcm_substream * substream,unsigned int cmd,void * arg)2066*4882a593Smuzhiyun static int snd_rme9652_ioctl(struct snd_pcm_substream *substream,
2067*4882a593Smuzhiyun unsigned int cmd, void *arg)
2068*4882a593Smuzhiyun {
2069*4882a593Smuzhiyun switch (cmd) {
2070*4882a593Smuzhiyun case SNDRV_PCM_IOCTL1_RESET:
2071*4882a593Smuzhiyun {
2072*4882a593Smuzhiyun return snd_rme9652_reset(substream);
2073*4882a593Smuzhiyun }
2074*4882a593Smuzhiyun case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
2075*4882a593Smuzhiyun {
2076*4882a593Smuzhiyun struct snd_pcm_channel_info *info = arg;
2077*4882a593Smuzhiyun return snd_rme9652_channel_info(substream, info);
2078*4882a593Smuzhiyun }
2079*4882a593Smuzhiyun default:
2080*4882a593Smuzhiyun break;
2081*4882a593Smuzhiyun }
2082*4882a593Smuzhiyun
2083*4882a593Smuzhiyun return snd_pcm_lib_ioctl(substream, cmd, arg);
2084*4882a593Smuzhiyun }
2085*4882a593Smuzhiyun
rme9652_silence_playback(struct snd_rme9652 * rme9652)2086*4882a593Smuzhiyun static void rme9652_silence_playback(struct snd_rme9652 *rme9652)
2087*4882a593Smuzhiyun {
2088*4882a593Smuzhiyun memset(rme9652->playback_buffer, 0, RME9652_DMA_AREA_BYTES);
2089*4882a593Smuzhiyun }
2090*4882a593Smuzhiyun
snd_rme9652_trigger(struct snd_pcm_substream * substream,int cmd)2091*4882a593Smuzhiyun static int snd_rme9652_trigger(struct snd_pcm_substream *substream,
2092*4882a593Smuzhiyun int cmd)
2093*4882a593Smuzhiyun {
2094*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
2095*4882a593Smuzhiyun struct snd_pcm_substream *other;
2096*4882a593Smuzhiyun int running;
2097*4882a593Smuzhiyun spin_lock(&rme9652->lock);
2098*4882a593Smuzhiyun running = rme9652->running;
2099*4882a593Smuzhiyun switch (cmd) {
2100*4882a593Smuzhiyun case SNDRV_PCM_TRIGGER_START:
2101*4882a593Smuzhiyun running |= 1 << substream->stream;
2102*4882a593Smuzhiyun break;
2103*4882a593Smuzhiyun case SNDRV_PCM_TRIGGER_STOP:
2104*4882a593Smuzhiyun running &= ~(1 << substream->stream);
2105*4882a593Smuzhiyun break;
2106*4882a593Smuzhiyun default:
2107*4882a593Smuzhiyun snd_BUG();
2108*4882a593Smuzhiyun spin_unlock(&rme9652->lock);
2109*4882a593Smuzhiyun return -EINVAL;
2110*4882a593Smuzhiyun }
2111*4882a593Smuzhiyun if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
2112*4882a593Smuzhiyun other = rme9652->capture_substream;
2113*4882a593Smuzhiyun else
2114*4882a593Smuzhiyun other = rme9652->playback_substream;
2115*4882a593Smuzhiyun
2116*4882a593Smuzhiyun if (other) {
2117*4882a593Smuzhiyun struct snd_pcm_substream *s;
2118*4882a593Smuzhiyun snd_pcm_group_for_each_entry(s, substream) {
2119*4882a593Smuzhiyun if (s == other) {
2120*4882a593Smuzhiyun snd_pcm_trigger_done(s, substream);
2121*4882a593Smuzhiyun if (cmd == SNDRV_PCM_TRIGGER_START)
2122*4882a593Smuzhiyun running |= 1 << s->stream;
2123*4882a593Smuzhiyun else
2124*4882a593Smuzhiyun running &= ~(1 << s->stream);
2125*4882a593Smuzhiyun goto _ok;
2126*4882a593Smuzhiyun }
2127*4882a593Smuzhiyun }
2128*4882a593Smuzhiyun if (cmd == SNDRV_PCM_TRIGGER_START) {
2129*4882a593Smuzhiyun if (!(running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) &&
2130*4882a593Smuzhiyun substream->stream == SNDRV_PCM_STREAM_CAPTURE)
2131*4882a593Smuzhiyun rme9652_silence_playback(rme9652);
2132*4882a593Smuzhiyun } else {
2133*4882a593Smuzhiyun if (running &&
2134*4882a593Smuzhiyun substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
2135*4882a593Smuzhiyun rme9652_silence_playback(rme9652);
2136*4882a593Smuzhiyun }
2137*4882a593Smuzhiyun } else {
2138*4882a593Smuzhiyun if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
2139*4882a593Smuzhiyun rme9652_silence_playback(rme9652);
2140*4882a593Smuzhiyun }
2141*4882a593Smuzhiyun _ok:
2142*4882a593Smuzhiyun snd_pcm_trigger_done(substream, substream);
2143*4882a593Smuzhiyun if (!rme9652->running && running)
2144*4882a593Smuzhiyun rme9652_start(rme9652);
2145*4882a593Smuzhiyun else if (rme9652->running && !running)
2146*4882a593Smuzhiyun rme9652_stop(rme9652);
2147*4882a593Smuzhiyun rme9652->running = running;
2148*4882a593Smuzhiyun spin_unlock(&rme9652->lock);
2149*4882a593Smuzhiyun
2150*4882a593Smuzhiyun return 0;
2151*4882a593Smuzhiyun }
2152*4882a593Smuzhiyun
snd_rme9652_prepare(struct snd_pcm_substream * substream)2153*4882a593Smuzhiyun static int snd_rme9652_prepare(struct snd_pcm_substream *substream)
2154*4882a593Smuzhiyun {
2155*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
2156*4882a593Smuzhiyun unsigned long flags;
2157*4882a593Smuzhiyun
2158*4882a593Smuzhiyun spin_lock_irqsave(&rme9652->lock, flags);
2159*4882a593Smuzhiyun if (!rme9652->running)
2160*4882a593Smuzhiyun rme9652_reset_hw_pointer(rme9652);
2161*4882a593Smuzhiyun spin_unlock_irqrestore(&rme9652->lock, flags);
2162*4882a593Smuzhiyun return 0;
2163*4882a593Smuzhiyun }
2164*4882a593Smuzhiyun
2165*4882a593Smuzhiyun static const struct snd_pcm_hardware snd_rme9652_playback_subinfo =
2166*4882a593Smuzhiyun {
2167*4882a593Smuzhiyun .info = (SNDRV_PCM_INFO_MMAP |
2168*4882a593Smuzhiyun SNDRV_PCM_INFO_MMAP_VALID |
2169*4882a593Smuzhiyun SNDRV_PCM_INFO_NONINTERLEAVED |
2170*4882a593Smuzhiyun SNDRV_PCM_INFO_SYNC_START |
2171*4882a593Smuzhiyun SNDRV_PCM_INFO_DOUBLE),
2172*4882a593Smuzhiyun .formats = SNDRV_PCM_FMTBIT_S32_LE,
2173*4882a593Smuzhiyun .rates = (SNDRV_PCM_RATE_44100 |
2174*4882a593Smuzhiyun SNDRV_PCM_RATE_48000 |
2175*4882a593Smuzhiyun SNDRV_PCM_RATE_88200 |
2176*4882a593Smuzhiyun SNDRV_PCM_RATE_96000),
2177*4882a593Smuzhiyun .rate_min = 44100,
2178*4882a593Smuzhiyun .rate_max = 96000,
2179*4882a593Smuzhiyun .channels_min = 10,
2180*4882a593Smuzhiyun .channels_max = 26,
2181*4882a593Smuzhiyun .buffer_bytes_max = RME9652_CHANNEL_BUFFER_BYTES * 26,
2182*4882a593Smuzhiyun .period_bytes_min = (64 * 4) * 10,
2183*4882a593Smuzhiyun .period_bytes_max = (8192 * 4) * 26,
2184*4882a593Smuzhiyun .periods_min = 2,
2185*4882a593Smuzhiyun .periods_max = 2,
2186*4882a593Smuzhiyun .fifo_size = 0,
2187*4882a593Smuzhiyun };
2188*4882a593Smuzhiyun
2189*4882a593Smuzhiyun static const struct snd_pcm_hardware snd_rme9652_capture_subinfo =
2190*4882a593Smuzhiyun {
2191*4882a593Smuzhiyun .info = (SNDRV_PCM_INFO_MMAP |
2192*4882a593Smuzhiyun SNDRV_PCM_INFO_MMAP_VALID |
2193*4882a593Smuzhiyun SNDRV_PCM_INFO_NONINTERLEAVED |
2194*4882a593Smuzhiyun SNDRV_PCM_INFO_SYNC_START),
2195*4882a593Smuzhiyun .formats = SNDRV_PCM_FMTBIT_S32_LE,
2196*4882a593Smuzhiyun .rates = (SNDRV_PCM_RATE_44100 |
2197*4882a593Smuzhiyun SNDRV_PCM_RATE_48000 |
2198*4882a593Smuzhiyun SNDRV_PCM_RATE_88200 |
2199*4882a593Smuzhiyun SNDRV_PCM_RATE_96000),
2200*4882a593Smuzhiyun .rate_min = 44100,
2201*4882a593Smuzhiyun .rate_max = 96000,
2202*4882a593Smuzhiyun .channels_min = 10,
2203*4882a593Smuzhiyun .channels_max = 26,
2204*4882a593Smuzhiyun .buffer_bytes_max = RME9652_CHANNEL_BUFFER_BYTES *26,
2205*4882a593Smuzhiyun .period_bytes_min = (64 * 4) * 10,
2206*4882a593Smuzhiyun .period_bytes_max = (8192 * 4) * 26,
2207*4882a593Smuzhiyun .periods_min = 2,
2208*4882a593Smuzhiyun .periods_max = 2,
2209*4882a593Smuzhiyun .fifo_size = 0,
2210*4882a593Smuzhiyun };
2211*4882a593Smuzhiyun
2212*4882a593Smuzhiyun static const unsigned int period_sizes[] = { 64, 128, 256, 512, 1024, 2048, 4096, 8192 };
2213*4882a593Smuzhiyun
2214*4882a593Smuzhiyun static const struct snd_pcm_hw_constraint_list hw_constraints_period_sizes = {
2215*4882a593Smuzhiyun .count = ARRAY_SIZE(period_sizes),
2216*4882a593Smuzhiyun .list = period_sizes,
2217*4882a593Smuzhiyun .mask = 0
2218*4882a593Smuzhiyun };
2219*4882a593Smuzhiyun
snd_rme9652_hw_rule_channels(struct snd_pcm_hw_params * params,struct snd_pcm_hw_rule * rule)2220*4882a593Smuzhiyun static int snd_rme9652_hw_rule_channels(struct snd_pcm_hw_params *params,
2221*4882a593Smuzhiyun struct snd_pcm_hw_rule *rule)
2222*4882a593Smuzhiyun {
2223*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = rule->private;
2224*4882a593Smuzhiyun struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
2225*4882a593Smuzhiyun unsigned int list[2] = { rme9652->ds_channels, rme9652->ss_channels };
2226*4882a593Smuzhiyun return snd_interval_list(c, 2, list, 0);
2227*4882a593Smuzhiyun }
2228*4882a593Smuzhiyun
snd_rme9652_hw_rule_channels_rate(struct snd_pcm_hw_params * params,struct snd_pcm_hw_rule * rule)2229*4882a593Smuzhiyun static int snd_rme9652_hw_rule_channels_rate(struct snd_pcm_hw_params *params,
2230*4882a593Smuzhiyun struct snd_pcm_hw_rule *rule)
2231*4882a593Smuzhiyun {
2232*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = rule->private;
2233*4882a593Smuzhiyun struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
2234*4882a593Smuzhiyun struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
2235*4882a593Smuzhiyun if (r->min > 48000) {
2236*4882a593Smuzhiyun struct snd_interval t = {
2237*4882a593Smuzhiyun .min = rme9652->ds_channels,
2238*4882a593Smuzhiyun .max = rme9652->ds_channels,
2239*4882a593Smuzhiyun .integer = 1,
2240*4882a593Smuzhiyun };
2241*4882a593Smuzhiyun return snd_interval_refine(c, &t);
2242*4882a593Smuzhiyun } else if (r->max < 88200) {
2243*4882a593Smuzhiyun struct snd_interval t = {
2244*4882a593Smuzhiyun .min = rme9652->ss_channels,
2245*4882a593Smuzhiyun .max = rme9652->ss_channels,
2246*4882a593Smuzhiyun .integer = 1,
2247*4882a593Smuzhiyun };
2248*4882a593Smuzhiyun return snd_interval_refine(c, &t);
2249*4882a593Smuzhiyun }
2250*4882a593Smuzhiyun return 0;
2251*4882a593Smuzhiyun }
2252*4882a593Smuzhiyun
snd_rme9652_hw_rule_rate_channels(struct snd_pcm_hw_params * params,struct snd_pcm_hw_rule * rule)2253*4882a593Smuzhiyun static int snd_rme9652_hw_rule_rate_channels(struct snd_pcm_hw_params *params,
2254*4882a593Smuzhiyun struct snd_pcm_hw_rule *rule)
2255*4882a593Smuzhiyun {
2256*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = rule->private;
2257*4882a593Smuzhiyun struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
2258*4882a593Smuzhiyun struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
2259*4882a593Smuzhiyun if (c->min >= rme9652->ss_channels) {
2260*4882a593Smuzhiyun struct snd_interval t = {
2261*4882a593Smuzhiyun .min = 44100,
2262*4882a593Smuzhiyun .max = 48000,
2263*4882a593Smuzhiyun .integer = 1,
2264*4882a593Smuzhiyun };
2265*4882a593Smuzhiyun return snd_interval_refine(r, &t);
2266*4882a593Smuzhiyun } else if (c->max <= rme9652->ds_channels) {
2267*4882a593Smuzhiyun struct snd_interval t = {
2268*4882a593Smuzhiyun .min = 88200,
2269*4882a593Smuzhiyun .max = 96000,
2270*4882a593Smuzhiyun .integer = 1,
2271*4882a593Smuzhiyun };
2272*4882a593Smuzhiyun return snd_interval_refine(r, &t);
2273*4882a593Smuzhiyun }
2274*4882a593Smuzhiyun return 0;
2275*4882a593Smuzhiyun }
2276*4882a593Smuzhiyun
snd_rme9652_playback_open(struct snd_pcm_substream * substream)2277*4882a593Smuzhiyun static int snd_rme9652_playback_open(struct snd_pcm_substream *substream)
2278*4882a593Smuzhiyun {
2279*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
2280*4882a593Smuzhiyun struct snd_pcm_runtime *runtime = substream->runtime;
2281*4882a593Smuzhiyun
2282*4882a593Smuzhiyun spin_lock_irq(&rme9652->lock);
2283*4882a593Smuzhiyun
2284*4882a593Smuzhiyun snd_pcm_set_sync(substream);
2285*4882a593Smuzhiyun
2286*4882a593Smuzhiyun runtime->hw = snd_rme9652_playback_subinfo;
2287*4882a593Smuzhiyun runtime->dma_area = rme9652->playback_buffer;
2288*4882a593Smuzhiyun runtime->dma_bytes = RME9652_DMA_AREA_BYTES;
2289*4882a593Smuzhiyun
2290*4882a593Smuzhiyun if (rme9652->capture_substream == NULL) {
2291*4882a593Smuzhiyun rme9652_stop(rme9652);
2292*4882a593Smuzhiyun rme9652_set_thru(rme9652, -1, 0);
2293*4882a593Smuzhiyun }
2294*4882a593Smuzhiyun
2295*4882a593Smuzhiyun rme9652->playback_pid = current->pid;
2296*4882a593Smuzhiyun rme9652->playback_substream = substream;
2297*4882a593Smuzhiyun
2298*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
2299*4882a593Smuzhiyun
2300*4882a593Smuzhiyun snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
2301*4882a593Smuzhiyun snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_period_sizes);
2302*4882a593Smuzhiyun snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
2303*4882a593Smuzhiyun snd_rme9652_hw_rule_channels, rme9652,
2304*4882a593Smuzhiyun SNDRV_PCM_HW_PARAM_CHANNELS, -1);
2305*4882a593Smuzhiyun snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
2306*4882a593Smuzhiyun snd_rme9652_hw_rule_channels_rate, rme9652,
2307*4882a593Smuzhiyun SNDRV_PCM_HW_PARAM_RATE, -1);
2308*4882a593Smuzhiyun snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
2309*4882a593Smuzhiyun snd_rme9652_hw_rule_rate_channels, rme9652,
2310*4882a593Smuzhiyun SNDRV_PCM_HW_PARAM_CHANNELS, -1);
2311*4882a593Smuzhiyun
2312*4882a593Smuzhiyun rme9652->creg_spdif_stream = rme9652->creg_spdif;
2313*4882a593Smuzhiyun rme9652->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
2314*4882a593Smuzhiyun snd_ctl_notify(rme9652->card, SNDRV_CTL_EVENT_MASK_VALUE |
2315*4882a593Smuzhiyun SNDRV_CTL_EVENT_MASK_INFO, &rme9652->spdif_ctl->id);
2316*4882a593Smuzhiyun return 0;
2317*4882a593Smuzhiyun }
2318*4882a593Smuzhiyun
snd_rme9652_playback_release(struct snd_pcm_substream * substream)2319*4882a593Smuzhiyun static int snd_rme9652_playback_release(struct snd_pcm_substream *substream)
2320*4882a593Smuzhiyun {
2321*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
2322*4882a593Smuzhiyun
2323*4882a593Smuzhiyun spin_lock_irq(&rme9652->lock);
2324*4882a593Smuzhiyun
2325*4882a593Smuzhiyun rme9652->playback_pid = -1;
2326*4882a593Smuzhiyun rme9652->playback_substream = NULL;
2327*4882a593Smuzhiyun
2328*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
2329*4882a593Smuzhiyun
2330*4882a593Smuzhiyun rme9652->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
2331*4882a593Smuzhiyun snd_ctl_notify(rme9652->card, SNDRV_CTL_EVENT_MASK_VALUE |
2332*4882a593Smuzhiyun SNDRV_CTL_EVENT_MASK_INFO, &rme9652->spdif_ctl->id);
2333*4882a593Smuzhiyun return 0;
2334*4882a593Smuzhiyun }
2335*4882a593Smuzhiyun
2336*4882a593Smuzhiyun
snd_rme9652_capture_open(struct snd_pcm_substream * substream)2337*4882a593Smuzhiyun static int snd_rme9652_capture_open(struct snd_pcm_substream *substream)
2338*4882a593Smuzhiyun {
2339*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
2340*4882a593Smuzhiyun struct snd_pcm_runtime *runtime = substream->runtime;
2341*4882a593Smuzhiyun
2342*4882a593Smuzhiyun spin_lock_irq(&rme9652->lock);
2343*4882a593Smuzhiyun
2344*4882a593Smuzhiyun snd_pcm_set_sync(substream);
2345*4882a593Smuzhiyun
2346*4882a593Smuzhiyun runtime->hw = snd_rme9652_capture_subinfo;
2347*4882a593Smuzhiyun runtime->dma_area = rme9652->capture_buffer;
2348*4882a593Smuzhiyun runtime->dma_bytes = RME9652_DMA_AREA_BYTES;
2349*4882a593Smuzhiyun
2350*4882a593Smuzhiyun if (rme9652->playback_substream == NULL) {
2351*4882a593Smuzhiyun rme9652_stop(rme9652);
2352*4882a593Smuzhiyun rme9652_set_thru(rme9652, -1, 0);
2353*4882a593Smuzhiyun }
2354*4882a593Smuzhiyun
2355*4882a593Smuzhiyun rme9652->capture_pid = current->pid;
2356*4882a593Smuzhiyun rme9652->capture_substream = substream;
2357*4882a593Smuzhiyun
2358*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
2359*4882a593Smuzhiyun
2360*4882a593Smuzhiyun snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
2361*4882a593Smuzhiyun snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_period_sizes);
2362*4882a593Smuzhiyun snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
2363*4882a593Smuzhiyun snd_rme9652_hw_rule_channels, rme9652,
2364*4882a593Smuzhiyun SNDRV_PCM_HW_PARAM_CHANNELS, -1);
2365*4882a593Smuzhiyun snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
2366*4882a593Smuzhiyun snd_rme9652_hw_rule_channels_rate, rme9652,
2367*4882a593Smuzhiyun SNDRV_PCM_HW_PARAM_RATE, -1);
2368*4882a593Smuzhiyun snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
2369*4882a593Smuzhiyun snd_rme9652_hw_rule_rate_channels, rme9652,
2370*4882a593Smuzhiyun SNDRV_PCM_HW_PARAM_CHANNELS, -1);
2371*4882a593Smuzhiyun return 0;
2372*4882a593Smuzhiyun }
2373*4882a593Smuzhiyun
snd_rme9652_capture_release(struct snd_pcm_substream * substream)2374*4882a593Smuzhiyun static int snd_rme9652_capture_release(struct snd_pcm_substream *substream)
2375*4882a593Smuzhiyun {
2376*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
2377*4882a593Smuzhiyun
2378*4882a593Smuzhiyun spin_lock_irq(&rme9652->lock);
2379*4882a593Smuzhiyun
2380*4882a593Smuzhiyun rme9652->capture_pid = -1;
2381*4882a593Smuzhiyun rme9652->capture_substream = NULL;
2382*4882a593Smuzhiyun
2383*4882a593Smuzhiyun spin_unlock_irq(&rme9652->lock);
2384*4882a593Smuzhiyun return 0;
2385*4882a593Smuzhiyun }
2386*4882a593Smuzhiyun
2387*4882a593Smuzhiyun static const struct snd_pcm_ops snd_rme9652_playback_ops = {
2388*4882a593Smuzhiyun .open = snd_rme9652_playback_open,
2389*4882a593Smuzhiyun .close = snd_rme9652_playback_release,
2390*4882a593Smuzhiyun .ioctl = snd_rme9652_ioctl,
2391*4882a593Smuzhiyun .hw_params = snd_rme9652_hw_params,
2392*4882a593Smuzhiyun .prepare = snd_rme9652_prepare,
2393*4882a593Smuzhiyun .trigger = snd_rme9652_trigger,
2394*4882a593Smuzhiyun .pointer = snd_rme9652_hw_pointer,
2395*4882a593Smuzhiyun .copy_user = snd_rme9652_playback_copy,
2396*4882a593Smuzhiyun .copy_kernel = snd_rme9652_playback_copy_kernel,
2397*4882a593Smuzhiyun .fill_silence = snd_rme9652_hw_silence,
2398*4882a593Smuzhiyun };
2399*4882a593Smuzhiyun
2400*4882a593Smuzhiyun static const struct snd_pcm_ops snd_rme9652_capture_ops = {
2401*4882a593Smuzhiyun .open = snd_rme9652_capture_open,
2402*4882a593Smuzhiyun .close = snd_rme9652_capture_release,
2403*4882a593Smuzhiyun .ioctl = snd_rme9652_ioctl,
2404*4882a593Smuzhiyun .hw_params = snd_rme9652_hw_params,
2405*4882a593Smuzhiyun .prepare = snd_rme9652_prepare,
2406*4882a593Smuzhiyun .trigger = snd_rme9652_trigger,
2407*4882a593Smuzhiyun .pointer = snd_rme9652_hw_pointer,
2408*4882a593Smuzhiyun .copy_user = snd_rme9652_capture_copy,
2409*4882a593Smuzhiyun .copy_kernel = snd_rme9652_capture_copy_kernel,
2410*4882a593Smuzhiyun };
2411*4882a593Smuzhiyun
snd_rme9652_create_pcm(struct snd_card * card,struct snd_rme9652 * rme9652)2412*4882a593Smuzhiyun static int snd_rme9652_create_pcm(struct snd_card *card,
2413*4882a593Smuzhiyun struct snd_rme9652 *rme9652)
2414*4882a593Smuzhiyun {
2415*4882a593Smuzhiyun struct snd_pcm *pcm;
2416*4882a593Smuzhiyun int err;
2417*4882a593Smuzhiyun
2418*4882a593Smuzhiyun if ((err = snd_pcm_new(card,
2419*4882a593Smuzhiyun rme9652->card_name,
2420*4882a593Smuzhiyun 0, 1, 1, &pcm)) < 0) {
2421*4882a593Smuzhiyun return err;
2422*4882a593Smuzhiyun }
2423*4882a593Smuzhiyun
2424*4882a593Smuzhiyun rme9652->pcm = pcm;
2425*4882a593Smuzhiyun pcm->private_data = rme9652;
2426*4882a593Smuzhiyun strcpy(pcm->name, rme9652->card_name);
2427*4882a593Smuzhiyun
2428*4882a593Smuzhiyun snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_rme9652_playback_ops);
2429*4882a593Smuzhiyun snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_rme9652_capture_ops);
2430*4882a593Smuzhiyun
2431*4882a593Smuzhiyun pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
2432*4882a593Smuzhiyun
2433*4882a593Smuzhiyun return 0;
2434*4882a593Smuzhiyun }
2435*4882a593Smuzhiyun
snd_rme9652_create(struct snd_card * card,struct snd_rme9652 * rme9652,int precise_ptr)2436*4882a593Smuzhiyun static int snd_rme9652_create(struct snd_card *card,
2437*4882a593Smuzhiyun struct snd_rme9652 *rme9652,
2438*4882a593Smuzhiyun int precise_ptr)
2439*4882a593Smuzhiyun {
2440*4882a593Smuzhiyun struct pci_dev *pci = rme9652->pci;
2441*4882a593Smuzhiyun int err;
2442*4882a593Smuzhiyun int status;
2443*4882a593Smuzhiyun unsigned short rev;
2444*4882a593Smuzhiyun
2445*4882a593Smuzhiyun rme9652->irq = -1;
2446*4882a593Smuzhiyun rme9652->card = card;
2447*4882a593Smuzhiyun
2448*4882a593Smuzhiyun pci_read_config_word(rme9652->pci, PCI_CLASS_REVISION, &rev);
2449*4882a593Smuzhiyun
2450*4882a593Smuzhiyun switch (rev & 0xff) {
2451*4882a593Smuzhiyun case 3:
2452*4882a593Smuzhiyun case 4:
2453*4882a593Smuzhiyun case 8:
2454*4882a593Smuzhiyun case 9:
2455*4882a593Smuzhiyun break;
2456*4882a593Smuzhiyun
2457*4882a593Smuzhiyun default:
2458*4882a593Smuzhiyun /* who knows? */
2459*4882a593Smuzhiyun return -ENODEV;
2460*4882a593Smuzhiyun }
2461*4882a593Smuzhiyun
2462*4882a593Smuzhiyun if ((err = pci_enable_device(pci)) < 0)
2463*4882a593Smuzhiyun return err;
2464*4882a593Smuzhiyun
2465*4882a593Smuzhiyun spin_lock_init(&rme9652->lock);
2466*4882a593Smuzhiyun
2467*4882a593Smuzhiyun if ((err = pci_request_regions(pci, "rme9652")) < 0)
2468*4882a593Smuzhiyun return err;
2469*4882a593Smuzhiyun rme9652->port = pci_resource_start(pci, 0);
2470*4882a593Smuzhiyun rme9652->iobase = ioremap(rme9652->port, RME9652_IO_EXTENT);
2471*4882a593Smuzhiyun if (rme9652->iobase == NULL) {
2472*4882a593Smuzhiyun dev_err(card->dev, "unable to remap region 0x%lx-0x%lx\n",
2473*4882a593Smuzhiyun rme9652->port, rme9652->port + RME9652_IO_EXTENT - 1);
2474*4882a593Smuzhiyun return -EBUSY;
2475*4882a593Smuzhiyun }
2476*4882a593Smuzhiyun
2477*4882a593Smuzhiyun if (request_irq(pci->irq, snd_rme9652_interrupt, IRQF_SHARED,
2478*4882a593Smuzhiyun KBUILD_MODNAME, rme9652)) {
2479*4882a593Smuzhiyun dev_err(card->dev, "unable to request IRQ %d\n", pci->irq);
2480*4882a593Smuzhiyun return -EBUSY;
2481*4882a593Smuzhiyun }
2482*4882a593Smuzhiyun rme9652->irq = pci->irq;
2483*4882a593Smuzhiyun card->sync_irq = rme9652->irq;
2484*4882a593Smuzhiyun rme9652->precise_ptr = precise_ptr;
2485*4882a593Smuzhiyun
2486*4882a593Smuzhiyun /* Determine the h/w rev level of the card. This seems like
2487*4882a593Smuzhiyun a particularly kludgy way to encode it, but its what RME
2488*4882a593Smuzhiyun chose to do, so we follow them ...
2489*4882a593Smuzhiyun */
2490*4882a593Smuzhiyun
2491*4882a593Smuzhiyun status = rme9652_read(rme9652, RME9652_status_register);
2492*4882a593Smuzhiyun if (rme9652_decode_spdif_rate(status&RME9652_F) == 1) {
2493*4882a593Smuzhiyun rme9652->hw_rev = 15;
2494*4882a593Smuzhiyun } else {
2495*4882a593Smuzhiyun rme9652->hw_rev = 11;
2496*4882a593Smuzhiyun }
2497*4882a593Smuzhiyun
2498*4882a593Smuzhiyun /* Differentiate between the standard Hammerfall, and the
2499*4882a593Smuzhiyun "Light", which does not have the expansion board. This
2500*4882a593Smuzhiyun method comes from information received from Mathhias
2501*4882a593Smuzhiyun Clausen at RME. Display the EEPROM and h/w revID where
2502*4882a593Smuzhiyun relevant.
2503*4882a593Smuzhiyun */
2504*4882a593Smuzhiyun
2505*4882a593Smuzhiyun switch (rev) {
2506*4882a593Smuzhiyun case 8: /* original eprom */
2507*4882a593Smuzhiyun strcpy(card->driver, "RME9636");
2508*4882a593Smuzhiyun if (rme9652->hw_rev == 15) {
2509*4882a593Smuzhiyun rme9652->card_name = "RME Digi9636 (Rev 1.5)";
2510*4882a593Smuzhiyun } else {
2511*4882a593Smuzhiyun rme9652->card_name = "RME Digi9636";
2512*4882a593Smuzhiyun }
2513*4882a593Smuzhiyun rme9652->ss_channels = RME9636_NCHANNELS;
2514*4882a593Smuzhiyun break;
2515*4882a593Smuzhiyun case 9: /* W36_G EPROM */
2516*4882a593Smuzhiyun strcpy(card->driver, "RME9636");
2517*4882a593Smuzhiyun rme9652->card_name = "RME Digi9636 (Rev G)";
2518*4882a593Smuzhiyun rme9652->ss_channels = RME9636_NCHANNELS;
2519*4882a593Smuzhiyun break;
2520*4882a593Smuzhiyun case 4: /* W52_G EPROM */
2521*4882a593Smuzhiyun strcpy(card->driver, "RME9652");
2522*4882a593Smuzhiyun rme9652->card_name = "RME Digi9652 (Rev G)";
2523*4882a593Smuzhiyun rme9652->ss_channels = RME9652_NCHANNELS;
2524*4882a593Smuzhiyun break;
2525*4882a593Smuzhiyun case 3: /* original eprom */
2526*4882a593Smuzhiyun strcpy(card->driver, "RME9652");
2527*4882a593Smuzhiyun if (rme9652->hw_rev == 15) {
2528*4882a593Smuzhiyun rme9652->card_name = "RME Digi9652 (Rev 1.5)";
2529*4882a593Smuzhiyun } else {
2530*4882a593Smuzhiyun rme9652->card_name = "RME Digi9652";
2531*4882a593Smuzhiyun }
2532*4882a593Smuzhiyun rme9652->ss_channels = RME9652_NCHANNELS;
2533*4882a593Smuzhiyun break;
2534*4882a593Smuzhiyun }
2535*4882a593Smuzhiyun
2536*4882a593Smuzhiyun rme9652->ds_channels = (rme9652->ss_channels - 2) / 2 + 2;
2537*4882a593Smuzhiyun
2538*4882a593Smuzhiyun pci_set_master(rme9652->pci);
2539*4882a593Smuzhiyun
2540*4882a593Smuzhiyun if ((err = snd_rme9652_initialize_memory(rme9652)) < 0) {
2541*4882a593Smuzhiyun return err;
2542*4882a593Smuzhiyun }
2543*4882a593Smuzhiyun
2544*4882a593Smuzhiyun if ((err = snd_rme9652_create_pcm(card, rme9652)) < 0) {
2545*4882a593Smuzhiyun return err;
2546*4882a593Smuzhiyun }
2547*4882a593Smuzhiyun
2548*4882a593Smuzhiyun if ((err = snd_rme9652_create_controls(card, rme9652)) < 0) {
2549*4882a593Smuzhiyun return err;
2550*4882a593Smuzhiyun }
2551*4882a593Smuzhiyun
2552*4882a593Smuzhiyun snd_rme9652_proc_init(rme9652);
2553*4882a593Smuzhiyun
2554*4882a593Smuzhiyun rme9652->last_spdif_sample_rate = -1;
2555*4882a593Smuzhiyun rme9652->last_adat_sample_rate = -1;
2556*4882a593Smuzhiyun rme9652->playback_pid = -1;
2557*4882a593Smuzhiyun rme9652->capture_pid = -1;
2558*4882a593Smuzhiyun rme9652->capture_substream = NULL;
2559*4882a593Smuzhiyun rme9652->playback_substream = NULL;
2560*4882a593Smuzhiyun
2561*4882a593Smuzhiyun snd_rme9652_set_defaults(rme9652);
2562*4882a593Smuzhiyun
2563*4882a593Smuzhiyun if (rme9652->hw_rev == 15) {
2564*4882a593Smuzhiyun rme9652_initialize_spdif_receiver (rme9652);
2565*4882a593Smuzhiyun }
2566*4882a593Smuzhiyun
2567*4882a593Smuzhiyun return 0;
2568*4882a593Smuzhiyun }
2569*4882a593Smuzhiyun
snd_rme9652_card_free(struct snd_card * card)2570*4882a593Smuzhiyun static void snd_rme9652_card_free(struct snd_card *card)
2571*4882a593Smuzhiyun {
2572*4882a593Smuzhiyun struct snd_rme9652 *rme9652 = (struct snd_rme9652 *) card->private_data;
2573*4882a593Smuzhiyun
2574*4882a593Smuzhiyun if (rme9652)
2575*4882a593Smuzhiyun snd_rme9652_free(rme9652);
2576*4882a593Smuzhiyun }
2577*4882a593Smuzhiyun
snd_rme9652_probe(struct pci_dev * pci,const struct pci_device_id * pci_id)2578*4882a593Smuzhiyun static int snd_rme9652_probe(struct pci_dev *pci,
2579*4882a593Smuzhiyun const struct pci_device_id *pci_id)
2580*4882a593Smuzhiyun {
2581*4882a593Smuzhiyun static int dev;
2582*4882a593Smuzhiyun struct snd_rme9652 *rme9652;
2583*4882a593Smuzhiyun struct snd_card *card;
2584*4882a593Smuzhiyun int err;
2585*4882a593Smuzhiyun
2586*4882a593Smuzhiyun if (dev >= SNDRV_CARDS)
2587*4882a593Smuzhiyun return -ENODEV;
2588*4882a593Smuzhiyun if (!enable[dev]) {
2589*4882a593Smuzhiyun dev++;
2590*4882a593Smuzhiyun return -ENOENT;
2591*4882a593Smuzhiyun }
2592*4882a593Smuzhiyun
2593*4882a593Smuzhiyun err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
2594*4882a593Smuzhiyun sizeof(struct snd_rme9652), &card);
2595*4882a593Smuzhiyun
2596*4882a593Smuzhiyun if (err < 0)
2597*4882a593Smuzhiyun return err;
2598*4882a593Smuzhiyun
2599*4882a593Smuzhiyun rme9652 = (struct snd_rme9652 *) card->private_data;
2600*4882a593Smuzhiyun card->private_free = snd_rme9652_card_free;
2601*4882a593Smuzhiyun rme9652->dev = dev;
2602*4882a593Smuzhiyun rme9652->pci = pci;
2603*4882a593Smuzhiyun err = snd_rme9652_create(card, rme9652, precise_ptr[dev]);
2604*4882a593Smuzhiyun if (err)
2605*4882a593Smuzhiyun goto free_card;
2606*4882a593Smuzhiyun
2607*4882a593Smuzhiyun strcpy(card->shortname, rme9652->card_name);
2608*4882a593Smuzhiyun
2609*4882a593Smuzhiyun sprintf(card->longname, "%s at 0x%lx, irq %d",
2610*4882a593Smuzhiyun card->shortname, rme9652->port, rme9652->irq);
2611*4882a593Smuzhiyun err = snd_card_register(card);
2612*4882a593Smuzhiyun if (err) {
2613*4882a593Smuzhiyun free_card:
2614*4882a593Smuzhiyun snd_card_free(card);
2615*4882a593Smuzhiyun return err;
2616*4882a593Smuzhiyun }
2617*4882a593Smuzhiyun pci_set_drvdata(pci, card);
2618*4882a593Smuzhiyun dev++;
2619*4882a593Smuzhiyun return 0;
2620*4882a593Smuzhiyun }
2621*4882a593Smuzhiyun
snd_rme9652_remove(struct pci_dev * pci)2622*4882a593Smuzhiyun static void snd_rme9652_remove(struct pci_dev *pci)
2623*4882a593Smuzhiyun {
2624*4882a593Smuzhiyun snd_card_free(pci_get_drvdata(pci));
2625*4882a593Smuzhiyun }
2626*4882a593Smuzhiyun
2627*4882a593Smuzhiyun static struct pci_driver rme9652_driver = {
2628*4882a593Smuzhiyun .name = KBUILD_MODNAME,
2629*4882a593Smuzhiyun .id_table = snd_rme9652_ids,
2630*4882a593Smuzhiyun .probe = snd_rme9652_probe,
2631*4882a593Smuzhiyun .remove = snd_rme9652_remove,
2632*4882a593Smuzhiyun };
2633*4882a593Smuzhiyun
2634*4882a593Smuzhiyun module_pci_driver(rme9652_driver);
2635