xref: /OK3568_Linux_fs/kernel/sound/pci/rme9652/rme9652.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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