pcm.c 49.4 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0-or-later
Daniel Mack's avatar
Daniel Mack committed
2
3
4
5
/*
 */

#include <linux/init.h>
6
#include <linux/slab.h>
7
#include <linux/bitrev.h>
8
#include <linux/ratelimit.h>
Daniel Mack's avatar
Daniel Mack committed
9
10
#include <linux/usb.h>
#include <linux/usb/audio.h>
Daniel Mack's avatar
Daniel Mack committed
11
#include <linux/usb/audio-v2.h>
Daniel Mack's avatar
Daniel Mack committed
12
13
14
15
16
17
18
19

#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>

#include "usbaudio.h"
#include "card.h"
#include "quirks.h"
20
#include "endpoint.h"
Daniel Mack's avatar
Daniel Mack committed
21
22
#include "helper.h"
#include "pcm.h"
23
#include "clock.h"
24
#include "power.h"
25
#include "media.h"
Daniel Mack's avatar
Daniel Mack committed
26

27
28
29
#define SUBSTREAM_FLAG_DATA_EP_STARTED	0
#define SUBSTREAM_FLAG_SYNC_EP_STARTED	1

30
31
32
33
34
35
36
37
/* return the estimated delay based on USB frame counters */
snd_pcm_uframes_t snd_usb_pcm_delay(struct snd_usb_substream *subs,
				    unsigned int rate)
{
	int current_frame_number;
	int frame_diff;
	int est_delay;

38
39
40
	if (!subs->last_delay)
		return 0; /* short path */

41
42
43
44
45
46
47
48
49
50
	current_frame_number = usb_get_current_frame_number(subs->dev);
	/*
	 * HCD implementations use different widths, use lower 8 bits.
	 * The delay will be managed up to 256ms, which is more than
	 * enough
	 */
	frame_diff = (current_frame_number - subs->last_frame_number) & 0xff;

	/* Approximation based on number of samples per USB frame (ms),
	   some truncation for 44.1 but the estimate is good enough */
51
52
53
54
55
56
	est_delay =  frame_diff * rate / 1000;
	if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK)
		est_delay = subs->last_delay - est_delay;
	else
		est_delay = subs->last_delay + est_delay;

57
58
59
60
61
	if (est_delay < 0)
		est_delay = 0;
	return est_delay;
}

Daniel Mack's avatar
Daniel Mack committed
62
63
64
65
66
/*
 * return the current pcm pointer.  just based on the hwptr_done value.
 */
static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream)
{
67
	struct snd_usb_substream *subs = substream->runtime->private_data;
Daniel Mack's avatar
Daniel Mack committed
68
69
	unsigned int hwptr_done;

70
	if (atomic_read(&subs->stream->chip->shutdown))
71
		return SNDRV_PCM_POS_XRUN;
Daniel Mack's avatar
Daniel Mack committed
72
73
	spin_lock(&subs->lock);
	hwptr_done = subs->hwptr_done;
74
	substream->runtime->delay = snd_usb_pcm_delay(subs,
75
						substream->runtime->rate);
Daniel Mack's avatar
Daniel Mack committed
76
77
78
79
80
81
82
	spin_unlock(&subs->lock);
	return hwptr_done / (substream->runtime->frame_bits >> 3);
}

/*
 * find a matching audio format
 */
83
84
85
86
static struct audioformat *
find_format(struct list_head *fmt_list_head, snd_pcm_format_t format,
	    unsigned int rate, unsigned int channels, bool strict_match,
	    struct snd_usb_substream *subs)
Daniel Mack's avatar
Daniel Mack committed
87
{
88
	struct audioformat *fp;
Daniel Mack's avatar
Daniel Mack committed
89
90
91
	struct audioformat *found = NULL;
	int cur_attr = 0, attr;

92
	list_for_each_entry(fp, fmt_list_head, list) {
93
94
95
96
97
98
		if (strict_match) {
			if (!(fp->formats & pcm_format_to_bits(format)))
				continue;
			if (fp->channels != channels)
				continue;
		}
99
		if (rate < fp->rate_min || rate > fp->rate_max)
Daniel Mack's avatar
Daniel Mack committed
100
			continue;
101
		if (!(fp->rates & SNDRV_PCM_RATE_CONTINUOUS)) {
Daniel Mack's avatar
Daniel Mack committed
102
103
			unsigned int i;
			for (i = 0; i < fp->nr_rates; i++)
104
				if (fp->rate_table[i] == rate)
Daniel Mack's avatar
Daniel Mack committed
105
106
107
108
109
					break;
			if (i >= fp->nr_rates)
				continue;
		}
		attr = fp->ep_attr & USB_ENDPOINT_SYNCTYPE;
110
		if (!found) {
Daniel Mack's avatar
Daniel Mack committed
111
112
113
114
115
116
117
118
119
			found = fp;
			cur_attr = attr;
			continue;
		}
		/* avoid async out and adaptive in if the other method
		 * supports the same format.
		 * this is a workaround for the case like
		 * M-audio audiophile USB.
		 */
120
		if (subs && attr != cur_attr) {
Daniel Mack's avatar
Daniel Mack committed
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
			if ((attr == USB_ENDPOINT_SYNC_ASYNC &&
			     subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
			    (attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
			     subs->direction == SNDRV_PCM_STREAM_CAPTURE))
				continue;
			if ((cur_attr == USB_ENDPOINT_SYNC_ASYNC &&
			     subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
			    (cur_attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
			     subs->direction == SNDRV_PCM_STREAM_CAPTURE)) {
				found = fp;
				cur_attr = attr;
				continue;
			}
		}
		/* find the format with the largest max. packet size */
		if (fp->maxpacksize > found->maxpacksize) {
			found = fp;
			cur_attr = attr;
		}
	}
	return found;
}

144
145
146
static struct audioformat *
find_substream_format(struct snd_usb_substream *subs,
		      const struct snd_pcm_hw_params *params)
147
{
148
149
150
	return find_format(&subs->fmt_list, params_format(params),
			   params_rate(params), params_channels(params),
			   true, subs);
151
152
}

153
static int init_pitch_v1(struct snd_usb_audio *chip, int ep)
154
155
156
157
158
159
{
	struct usb_device *dev = chip->dev;
	unsigned char data[1];
	int err;

	data[0] = 1;
160
161
162
163
	err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
			      USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
			      UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep,
			      data, sizeof(data));
164
	return err;
165
}
Daniel Mack's avatar
Daniel Mack committed
166

167
static int init_pitch_v2(struct snd_usb_audio *chip, int ep)
168
169
170
171
172
173
{
	struct usb_device *dev = chip->dev;
	unsigned char data[1];
	int err;

	data[0] = 1;
174
175
176
177
	err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR,
			      USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT,
			      UAC2_EP_CS_PITCH << 8, 0,
			      data, sizeof(data));
178
	return err;
179
180
}

Daniel Mack's avatar
Daniel Mack committed
181
/*
182
 * initialize the pitch control and sample rate
Daniel Mack's avatar
Daniel Mack committed
183
 */
184
int snd_usb_init_pitch(struct snd_usb_audio *chip,
Daniel Mack's avatar
Daniel Mack committed
185
186
		       struct audioformat *fmt)
{
187
188
	int err;

189
190
191
192
	/* if endpoint doesn't have pitch control, bail out */
	if (!(fmt->attributes & UAC_EP_CS_ATTR_PITCH_CONTROL))
		return 0;

193
194
	usb_audio_dbg(chip, "enable PITCH for EP 0x%x\n", fmt->endpoint);

195
	switch (fmt->protocol) {
196
	case UAC_VERSION_1:
197
198
199
200
201
		err = init_pitch_v1(chip, fmt->endpoint);
		break;
	case UAC_VERSION_2:
		err = init_pitch_v2(chip, fmt->endpoint);
		break;
202
	default:
203
204
		return 0;
	}
205

206
207
208
209
	if (err < 0) {
		usb_audio_err(chip, "failed to enable PITCH for EP 0x%x\n",
			      fmt->endpoint);
		return err;
210
	}
211
212

	return 0;
213
214
}

215
static bool stop_endpoints(struct snd_usb_substream *subs)
216
{
217
218
	bool stopped = 0;

219
220
	if (test_and_clear_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags)) {
		snd_usb_endpoint_stop(subs->sync_endpoint);
221
		stopped = true;
222
	}
223
	if (test_and_clear_bit(SUBSTREAM_FLAG_DATA_EP_STARTED, &subs->flags)) {
224
		snd_usb_endpoint_stop(subs->data_endpoint);
225
226
227
		stopped = true;
	}
	return stopped;
228
229
}

230
static int start_endpoints(struct snd_usb_substream *subs)
231
232
233
234
235
236
237
{
	int err;

	if (!subs->data_endpoint)
		return -EINVAL;

	if (!test_and_set_bit(SUBSTREAM_FLAG_DATA_EP_STARTED, &subs->flags)) {
238
		err = snd_usb_endpoint_start(subs->data_endpoint);
239
240
		if (err < 0) {
			clear_bit(SUBSTREAM_FLAG_DATA_EP_STARTED, &subs->flags);
241
			goto error;
242
243
244
245
246
		}
	}

	if (subs->sync_endpoint &&
	    !test_and_set_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags)) {
247
		err = snd_usb_endpoint_start(subs->sync_endpoint);
248
249
		if (err < 0) {
			clear_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags);
250
			goto error;
251
252
253
254
		}
	}

	return 0;
255
256
257
258

 error:
	stop_endpoints(subs);
	return err;
259
260
}

261
262
263
264
265
266
267
268
269
270
271
272
273
274
static void sync_pending_stops(struct snd_usb_substream *subs)
{
	snd_usb_endpoint_sync_pending_stop(subs->sync_endpoint);
	snd_usb_endpoint_sync_pending_stop(subs->data_endpoint);
}

/* PCM sync_stop callback */
static int snd_usb_pcm_sync_stop(struct snd_pcm_substream *substream)
{
	struct snd_usb_substream *subs = substream->runtime->private_data;

	if (!snd_usb_lock_shutdown(subs->stream->chip)) {
		sync_pending_stops(subs);
		snd_usb_unlock_shutdown(subs->stream->chip);
275
	}
276
	return 0;
277
278
}

279
/* Check whether the given iface:altsetting points to an implicit fb source */
280
static bool search_generic_implicit_fb(struct snd_usb_audio *chip, int ifnum,
281
282
283
				       unsigned int altsetting,
				       struct usb_host_interface **altsp,
				       unsigned int *ep)
284
{
285
286
287
288
	struct usb_host_interface *alts;
	struct usb_interface_descriptor *altsd;
	struct usb_endpoint_descriptor *epd;

289
	alts = snd_usb_get_host_interface(chip, ifnum, altsetting);
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
	if (!alts)
		return false;
	altsd = get_iface_desc(alts);
	if (altsd->bInterfaceClass != USB_CLASS_AUDIO ||
	    altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING ||
	    altsd->bInterfaceProtocol != UAC_VERSION_2 ||
	    altsd->bNumEndpoints < 1)
		return false;
	epd = get_endpoint(alts, 0);
	if (!usb_endpoint_is_isoc_in(epd) ||
	    (epd->bmAttributes & USB_ENDPOINT_USAGE_MASK) !=
					USB_ENDPOINT_USAGE_IMPLICIT_FB)
		return false;
	*ep = epd->bEndpointAddress;
	*altsp = alts;
	return true;
}

/* Like the function above, but specific to Roland with vendor class and hack */
309
static bool search_roland_implicit_fb(struct snd_usb_audio *chip, int ifnum,
310
311
312
313
314
				      unsigned int altsetting,
				      struct usb_host_interface **altsp,
				      unsigned int *ep)
{
	struct usb_host_interface *alts;
315
316
317
	struct usb_interface_descriptor *altsd;
	struct usb_endpoint_descriptor *epd;

318
	alts = snd_usb_get_host_interface(chip, ifnum, altsetting);
319
320
321
322
	if (!alts)
		return false;
	altsd = get_iface_desc(alts);
	if (altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC ||
323
	    (altsd->bInterfaceSubClass != 2 &&
324
	     altsd->bInterfaceProtocol != 2) ||
325
	    altsd->bNumEndpoints < 1)
326
327
		return false;
	epd = get_endpoint(alts, 0);
328
329
330
	if (!usb_endpoint_is_isoc_in(epd) ||
	    (epd->bmAttributes & USB_ENDPOINT_USAGE_MASK) !=
					USB_ENDPOINT_USAGE_IMPLICIT_FB)
331
		return false;
332
	*ep = epd->bEndpointAddress;
333
334
	*altsp = alts;
	return true;
335
336
}

337
338
339
/* Setup an implicit feedback endpoint from a quirk. Returns 0 if no quirk
 * applies. Returns 1 if a quirk was found.
 */
340
341
342
static int audioformat_implicit_fb_quirk(struct snd_usb_audio *chip,
					 struct audioformat *fmt,
					 struct usb_host_interface *alts)
Daniel Mack's avatar
Daniel Mack committed
343
{
344
345
	struct usb_device *dev = chip->dev;
	struct usb_interface_descriptor *altsd = get_iface_desc(alts);
346
	struct usb_interface *iface;
347
	unsigned int attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
348
	unsigned int ep;
349
	unsigned int ifnum;
350

351
	switch (chip->usb_id) {
352
	case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */
353
	case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C600 */
354
	case USB_ID(0x22f0, 0x0006): /* Allen&Heath Qu-16 */
355
		ep = 0x81;
356
357
		ifnum = 3;
		goto add_sync_ep_from_ifnum;
358
359
	case USB_ID(0x0763, 0x2080): /* M-Audio FastTrack Ultra */
	case USB_ID(0x0763, 0x2081):
360
		ep = 0x81;
361
362
363
		ifnum = 2;
		goto add_sync_ep_from_ifnum;
	case USB_ID(0x2466, 0x8003): /* Fractal Audio Axe-Fx II */
364
	case USB_ID(0x0499, 0x172a): /* Yamaha MODX */
365
		ep = 0x86;
366
367
		ifnum = 2;
		goto add_sync_ep_from_ifnum;
368
369
370
371
	case USB_ID(0x2466, 0x8010): /* Fractal Audio Axe-Fx III */
		ep = 0x81;
		ifnum = 2;
		goto add_sync_ep_from_ifnum;
372
373
374
375
	case USB_ID(0x1686, 0xf029): /* Zoom UAC-2 */
		ep = 0x82;
		ifnum = 2;
		goto add_sync_ep_from_ifnum;
376
	case USB_ID(0x1397, 0x0001): /* Behringer UFX1604 */
377
	case USB_ID(0x1397, 0x0002): /* Behringer UFX1204 */
378
		ep = 0x81;
379
380
		ifnum = 1;
		goto add_sync_ep_from_ifnum;
381
382
383
384
385
386
	case USB_ID(0x07fd, 0x0004): /* MOTU MicroBook II/IIc */
		/* MicroBook IIc */
		if (altsd->bInterfaceClass == USB_CLASS_AUDIO)
			return 0;

		/* MicroBook II */
387
388
389
		ep = 0x84;
		ifnum = 0;
		goto add_sync_ep_from_ifnum;
390
	case USB_ID(0x07fd, 0x0008): /* MOTU M Series */
391
	case USB_ID(0x31e9, 0x0001): /* Solid State Logic SSL2 */
392
	case USB_ID(0x31e9, 0x0002): /* Solid State Logic SSL2+ */
393
	case USB_ID(0x0499, 0x172f): /* Steinberg UR22C */
394
	case USB_ID(0x0d9a, 0x00df): /* RTX6001 */
395
396
397
		ep = 0x81;
		ifnum = 2;
		goto add_sync_ep_from_ifnum;
398
	case USB_ID(0x2b73, 0x000a): /* Pioneer DJ DJM-900NXS2 */
399
	case USB_ID(0x2b73, 0x0017): /* Pioneer DJ DJM-250MK2 */
400
401
402
		ep = 0x82;
		ifnum = 0;
		goto add_sync_ep_from_ifnum;
403
404
405
	case USB_ID(0x0582, 0x01d8): /* BOSS Katana */
		/* BOSS Katana amplifiers do not need quirks */
		return 0;
406
	}
407

408
409
410
411
412
413
	/* Generic UAC2 implicit feedback */
	if (attr == USB_ENDPOINT_SYNC_ASYNC &&
	    altsd->bInterfaceClass == USB_CLASS_AUDIO &&
	    altsd->bInterfaceProtocol == UAC_VERSION_2 &&
	    altsd->bNumEndpoints == 1) {
		ifnum = altsd->bInterfaceNumber + 1;
414
		if (search_generic_implicit_fb(chip, ifnum,
415
416
417
418
419
420
					       altsd->bAlternateSetting,
					       &alts, &ep))
			goto add_sync_ep;
	}

	/* Roland/BOSS implicit feedback with vendor spec class */
421
	if (attr == USB_ENDPOINT_SYNC_ASYNC &&
422
423
424
	    altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC &&
	    altsd->bInterfaceProtocol == 2 &&
	    altsd->bNumEndpoints == 1 &&
425
426
	    USB_ID_VENDOR(chip->usb_id) == 0x0582 /* Roland */) {
		ifnum = altsd->bInterfaceNumber + 1;
427
		if (search_roland_implicit_fb(chip, ifnum,
428
429
430
431
					      altsd->bAlternateSetting,
					      &alts, &ep))
			goto add_sync_ep;
	}
432

433
434
435
	/* No quirk */
	return 0;

436
437
438
add_sync_ep_from_ifnum:
	iface = usb_ifnum_to_if(dev, ifnum);

439
	if (!iface || iface->num_altsetting < 2)
440
		return 0;
441
442
443

	alts = &iface->altsetting[1];

444
add_sync_ep:
445
446
447
	fmt->sync_ep = ep;
	fmt->sync_iface = ifnum;
	fmt->sync_altsetting = alts->desc.bAlternateSetting;
448
	fmt->sync_ep_idx = 0;
449
450
451
452
	fmt->implicit_fb = 1;
	dev_dbg(&dev->dev, "%d:%d: found implicit_fb sync_ep=%x, iface=%d, alt=%d\n",
		fmt->iface, fmt->altsetting, fmt->sync_ep, fmt->sync_iface,
		fmt->sync_altsetting);
453

454
	return 1;
455
456
}

457
458
int snd_usb_audioformat_set_sync_ep(struct snd_usb_audio *chip,
				    struct audioformat *fmt)
459
{
460
461
462
463
464
	struct usb_device *dev = chip->dev;
	struct usb_host_interface *alts;
	struct usb_interface_descriptor *altsd;
	unsigned int ep, attr, sync_attr;
	bool is_playback;
465
466
	int err;

467
	alts = snd_usb_get_host_interface(chip, fmt->iface, fmt->altsetting);
468
	if (!alts)
469
		return 0;
470
471
472
473
	altsd = get_iface_desc(alts);

	is_playback = !(get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN);
	if (is_playback) {
474
		err = audioformat_implicit_fb_quirk(chip, fmt, alts);
475
476
477
		if (err > 0)
			return 0;
	}
478

479
480
	if (altsd->bNumEndpoints < 2)
		return 0;
481

482
	attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
483
484
	if ((is_playback && (attr == USB_ENDPOINT_SYNC_SYNC ||
			     attr == USB_ENDPOINT_SYNC_ADAPTIVE)) ||
485
486
	    (!is_playback && attr != USB_ENDPOINT_SYNC_ADAPTIVE))
		return 0;
487

488
489
	sync_attr = get_endpoint(alts, 1)->bmAttributes;

490
491
492
493
494
495
	/*
	 * In case of illegal SYNC_NONE for OUT endpoint, we keep going to see
	 * if we don't find a sync endpoint, as on M-Audio Transit. In case of
	 * error fall back to SYNC mode and don't create sync endpoint
	 */

496
497
498
499
	/* check sync-pipe endpoint */
	/* ... and check descriptor size before accessing bSynchAddress
	   because there is a version of the SB Audigy 2 NX firmware lacking
	   the audio fields in the endpoint descriptors */
500
	if ((sync_attr & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC ||
501
	    (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
502
	     get_endpoint(alts, 1)->bSynchAddress != 0)) {
503
504
505
		dev_err(&dev->dev,
			"%d:%d : invalid sync pipe. bmAttributes %02x, bLength %d, bSynchAddress %02x\n",
			   fmt->iface, fmt->altsetting,
506
507
508
			   get_endpoint(alts, 1)->bmAttributes,
			   get_endpoint(alts, 1)->bLength,
			   get_endpoint(alts, 1)->bSynchAddress);
509
510
		if (is_playback && attr == USB_ENDPOINT_SYNC_NONE)
			return 0;
511
512
513
		return -EINVAL;
	}
	ep = get_endpoint(alts, 1)->bEndpointAddress;
514
	if (get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
515
	    get_endpoint(alts, 0)->bSynchAddress != 0 &&
516
517
	    ((is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) ||
	     (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)))) {
518
519
520
		dev_err(&dev->dev,
			"%d:%d : invalid sync pipe. is_playback %d, ep %02x, bSynchAddress %02x\n",
			   fmt->iface, fmt->altsetting,
521
			   is_playback, ep, get_endpoint(alts, 0)->bSynchAddress);
522
523
		if (is_playback && attr == USB_ENDPOINT_SYNC_NONE)
			return 0;
524
		return -EINVAL;
525
	}
Daniel Mack's avatar
Daniel Mack committed
526

527
528
529
	fmt->sync_ep = ep;
	fmt->sync_iface = altsd->bInterfaceNumber;
	fmt->sync_altsetting = altsd->bAlternateSetting;
530
	fmt->sync_ep_idx = 1;
531
532
533
534
535
536
537
538
539
540
	if ((sync_attr & USB_ENDPOINT_USAGE_MASK) == USB_ENDPOINT_USAGE_IMPLICIT_FB)
		fmt->implicit_fb = 1;

	dev_dbg(&dev->dev, "%d:%d: found sync_ep=0x%x, iface=%d, alt=%d, implicit_fb=%d\n",
		fmt->iface, fmt->altsetting, fmt->sync_ep, fmt->sync_iface,
		fmt->sync_altsetting, fmt->implicit_fb);

	return 0;
}

541
542
543
544
545
546
547
/*
 * Return the score of matching two audioformats.
 * Veto the audioformat if:
 * - It has no channels for some reason.
 * - Requested PCM format is not supported.
 * - Requested sample rate is not supported.
 */
548
static int match_endpoint_audioformats(struct snd_usb_substream *subs,
549
550
				       const struct audioformat *fp,
				       int rate, int channels,
551
				       snd_pcm_format_t pcm_format)
552
{
553
	int i, score;
554

555
	if (fp->channels < 1)
556
557
		return 0;

558
	if (!(fp->formats & pcm_format_to_bits(pcm_format)))
559
560
		return 0;

561
562
563
564
565
566
567
	if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) {
		if (rate < fp->rate_min || rate > fp->rate_max)
			return 0;
	} else {
		for (i = 0; i < fp->nr_rates; i++) {
			if (fp->rate_table[i] == rate)
				break;
568
		}
569
570
		if (i >= fp->nr_rates)
			return 0;
571
572
	}

573
	score = 1;
574
	if (fp->channels == channels)
575
576
577
578
579
		score++;

	return score;
}

580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
static int snd_usb_pcm_change_state(struct snd_usb_substream *subs, int state)
{
	int ret;

	if (!subs->str_pd)
		return 0;

	ret = snd_usb_power_domain_set(subs->stream->chip, subs->str_pd, state);
	if (ret < 0) {
		dev_err(&subs->dev->dev,
			"Cannot change Power Domain ID: %d to state: %d. Err: %d\n",
			subs->str_pd->pd_id, state, ret);
		return ret;
	}

	return 0;
}

int snd_usb_pcm_suspend(struct snd_usb_stream *as)
{
	int ret;

	ret = snd_usb_pcm_change_state(&as->substream[0], UAC3_PD_STATE_D2);
	if (ret < 0)
		return ret;

	ret = snd_usb_pcm_change_state(&as->substream[1], UAC3_PD_STATE_D2);
	if (ret < 0)
		return ret;

	return 0;
}

int snd_usb_pcm_resume(struct snd_usb_stream *as)
{
	int ret;

617
	ret = snd_usb_pcm_change_state(&as->substream[0], UAC3_PD_STATE_D1);
618
619
620
	if (ret < 0)
		return ret;

621
	ret = snd_usb_pcm_change_state(&as->substream[1], UAC3_PD_STATE_D1);
622
623
624
625
626
627
	if (ret < 0)
		return ret;

	return 0;
}

628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
static struct snd_usb_substream *
find_matching_substream(struct snd_usb_audio *chip, int stream, int ep_num,
			int fmt_type)
{
	struct snd_usb_stream *as;
	struct snd_usb_substream *subs;

	list_for_each_entry(as, &chip->pcm_list, list) {
		subs = &as->substream[stream];
		if (as->fmt_type == fmt_type && subs->ep_num == ep_num)
			return subs;
	}

	return NULL;
}

static struct audioformat *
find_implicit_fb_sync_format(struct snd_usb_audio *chip,
			     const struct audioformat *target,
			     const struct snd_pcm_hw_params *params,
			     int stream)
{
	struct snd_usb_substream *subs;
	struct audioformat *fp, *sync_fmt;
	int score, high_score;

	subs = find_matching_substream(chip, stream, target->sync_ep,
				       target->fmt_type);
	if (!subs)
		return NULL;

	sync_fmt = NULL;
	high_score = 0;
	list_for_each_entry(fp, &subs->fmt_list, list) {
		score = match_endpoint_audioformats(subs, fp,
						    params_rate(params),
						    params_channels(params),
						    params_format(params));
		if (score > high_score) {
			sync_fmt = fp;
			high_score = score;
		}
	}

	return sync_fmt;
}

static void close_endpoints(struct snd_usb_audio *chip,
			    struct snd_usb_substream *subs)
{
	if (subs->data_endpoint) {
		snd_usb_endpoint_set_sync(chip, subs->data_endpoint, NULL);
		snd_usb_endpoint_close(chip, subs->data_endpoint);
		subs->data_endpoint = NULL;
	}

	if (subs->sync_endpoint) {
		snd_usb_endpoint_close(chip, subs->sync_endpoint);
		subs->sync_endpoint = NULL;
	}
}

static int configure_endpoints(struct snd_usb_audio *chip,
			       struct snd_usb_substream *subs)
{
	int err;

	if (subs->data_endpoint->need_setup) {
		/* stop any running stream beforehand */
		if (stop_endpoints(subs))
			sync_pending_stops(subs);
		err = snd_usb_endpoint_configure(chip, subs->data_endpoint);
		if (err < 0)
			return err;
		snd_usb_set_format_quirk(subs, subs->cur_audiofmt);
	}

	if (subs->sync_endpoint) {
		err = snd_usb_endpoint_configure(chip, subs->sync_endpoint);
		if (err < 0)
			return err;
	}

	return 0;
}

Daniel Mack's avatar
Daniel Mack committed
714
715
716
717
718
719
720
721
722
723
724
725
726
727
/*
 * hw_params callback
 *
 * allocate a buffer and set the given audio format.
 *
 * so far we use a physically linear buffer although packetize transfer
 * doesn't need a continuous area.
 * if sg buffer is supported on the later version of alsa, we'll follow
 * that.
 */
static int snd_usb_hw_params(struct snd_pcm_substream *substream,
			     struct snd_pcm_hw_params *hw_params)
{
	struct snd_usb_substream *subs = substream->runtime->private_data;
728
	struct snd_usb_audio *chip = subs->stream->chip;
Daniel Mack's avatar
Daniel Mack committed
729
	struct audioformat *fmt;
730
	struct audioformat *sync_fmt;
731
	int ret;
Daniel Mack's avatar
Daniel Mack committed
732

733
734
735
736
	ret = snd_media_start_pipeline(subs);
	if (ret)
		return ret;

737
	fmt = find_substream_format(subs, hw_params);
Daniel Mack's avatar
Daniel Mack committed
738
	if (!fmt) {
739
740
741
742
		usb_audio_dbg(chip,
			      "cannot find format: format=%s, rate=%d, channels=%d\n",
			      snd_pcm_format_name(params_format(hw_params)),
			      params_rate(hw_params), params_channels(hw_params));
743
744
		ret = -EINVAL;
		goto stop_pipeline;
Daniel Mack's avatar
Daniel Mack committed
745
746
	}

747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
	if (fmt->implicit_fb &&
	    (fmt->iface != fmt->sync_iface ||
	     fmt->altsetting != fmt->sync_altsetting)) {
		sync_fmt = find_implicit_fb_sync_format(chip, fmt, hw_params,
							!substream->stream);
		if (!sync_fmt) {
			usb_audio_dbg(chip,
				      "cannot find sync format: ep=0x%x, iface=%d:%d, format=%s, rate=%d, channels=%d\n",
				      fmt->sync_ep, fmt->sync_iface,
				      fmt->sync_altsetting,
				      snd_pcm_format_name(params_format(hw_params)),
				      params_rate(hw_params), params_channels(hw_params));
			ret = -EINVAL;
			goto stop_pipeline;
		}
	} else {
		sync_fmt = fmt;
	}

	ret = snd_usb_lock_shutdown(chip);
767
	if (ret < 0)
768
		goto stop_pipeline;
769
770
771
772
773

	ret = snd_usb_pcm_change_state(subs, UAC3_PD_STATE_D0);
	if (ret < 0)
		goto unlock;

774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
	if (subs->data_endpoint) {
		if (snd_usb_endpoint_compatible(chip, subs->data_endpoint,
						fmt, hw_params))
			goto unlock;
		close_endpoints(chip, subs);
	}

	subs->data_endpoint = snd_usb_endpoint_open(chip, fmt, hw_params, false);
	if (!subs->data_endpoint) {
		ret = -EINVAL;
		goto unlock;
	}

	if (fmt->sync_ep) {
		subs->sync_endpoint = snd_usb_endpoint_open(chip, sync_fmt,
							    hw_params,
							    fmt == sync_fmt);
		if (!subs->sync_endpoint) {
			ret = -EINVAL;
			goto unlock;
		}

		snd_usb_endpoint_set_sync(chip, subs->data_endpoint,
					  subs->sync_endpoint);
	}

	subs->interface = fmt->iface;
	subs->altset_idx = fmt->altset_idx;
	subs->cur_audiofmt = fmt;

	ret = configure_endpoints(chip, subs);
805
	if (ret < 0)
806
		goto unlock;
Daniel Mack's avatar
Daniel Mack committed
807

808
809
810
811
812
813
814
	subs->pcm_format = params_format(hw_params);
	subs->period_bytes = params_period_bytes(hw_params);
	subs->period_frames = params_period_size(hw_params);
	subs->buffer_periods = params_periods(hw_params);
	subs->channels = params_channels(hw_params);
	subs->cur_rate = params_rate(hw_params);

815
 unlock:
816
	if (ret < 0)
817
		close_endpoints(chip, subs);
818

819
	snd_usb_unlock_shutdown(chip);
820
 stop_pipeline:
821
822
823
	if (ret < 0)
		snd_media_stop_pipeline(subs);

824
	return ret;
Daniel Mack's avatar
Daniel Mack committed
825
826
827
828
829
830
831
832
833
834
}

/*
 * hw_free callback
 *
 * reset the audio format and release the buffer
 */
static int snd_usb_hw_free(struct snd_pcm_substream *substream)
{
	struct snd_usb_substream *subs = substream->runtime->private_data;
835
	struct snd_usb_audio *chip = subs->stream->chip;
Daniel Mack's avatar
Daniel Mack committed
836

837
	snd_media_stop_pipeline(subs);
Daniel Mack's avatar
Daniel Mack committed
838
839
840
	subs->cur_audiofmt = NULL;
	subs->cur_rate = 0;
	subs->period_bytes = 0;
841
	if (!snd_usb_lock_shutdown(chip)) {
842
843
844
		if (stop_endpoints(subs))
			sync_pending_stops(subs);
		close_endpoints(chip, subs);
845
		snd_usb_unlock_shutdown(chip);
846
	}
847

848
	return 0;
Daniel Mack's avatar
Daniel Mack committed
849
850
851
852
853
854
855
856
857
858
859
}

/*
 * prepare callback
 *
 * only a few subtle things...
 */
static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct snd_usb_substream *subs = runtime->private_data;
860
	struct snd_usb_audio *chip = subs->stream->chip;
861
	int ret;
Daniel Mack's avatar
Daniel Mack committed
862

863
	ret = snd_usb_lock_shutdown(chip);
864
865
	if (ret < 0)
		return ret;
866
867
868
869
	if (snd_BUG_ON(!subs->data_endpoint)) {
		ret = -EIO;
		goto unlock;
	}
870

871
	ret = configure_endpoints(chip, subs);
872
	if (ret < 0)
873
		goto unlock;
874

Daniel Mack's avatar
Daniel Mack committed
875
876
877
	/* reset the pointer */
	subs->hwptr_done = 0;
	subs->transfer_done = 0;
878
879
	subs->last_delay = 0;
	subs->last_frame_number = 0;
Daniel Mack's avatar
Daniel Mack committed
880
881
	runtime->delay = 0;

882
883
884
	/* for playback, submit the URBs now; otherwise, the first hwptr_done
	 * updates for all URBs would happen at the same time when starting */
	if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK)
885
		ret = start_endpoints(subs);
886

887
 unlock:
888
	snd_usb_unlock_shutdown(chip);
889
	return ret;
Daniel Mack's avatar
Daniel Mack committed
890
891
}

Takashi Iwai's avatar
Takashi Iwai committed
892
893
894
895
896
897
898
899
900
901
/*
 * h/w constraints
 */

#ifdef HW_CONST_DEBUG
#define hwc_debug(fmt, args...) pr_debug(fmt, ##args)
#else
#define hwc_debug(fmt, args...) do { } while(0)
#endif

902
static const struct snd_pcm_hardware snd_usb_hardware =
Daniel Mack's avatar
Daniel Mack committed
903
904
905
906
907
908
909
{
	.info =			SNDRV_PCM_INFO_MMAP |
				SNDRV_PCM_INFO_MMAP_VALID |
				SNDRV_PCM_INFO_BATCH |
				SNDRV_PCM_INFO_INTERLEAVED |
				SNDRV_PCM_INFO_BLOCK_TRANSFER |
				SNDRV_PCM_INFO_PAUSE,
910
911
	.channels_min =		1,
	.channels_max =		256,
Daniel Mack's avatar
Daniel Mack committed
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
	.buffer_bytes_max =	1024 * 1024,
	.period_bytes_min =	64,
	.period_bytes_max =	512 * 1024,
	.periods_min =		2,
	.periods_max =		1024,
};

static int hw_check_valid_format(struct snd_usb_substream *subs,
				 struct snd_pcm_hw_params *params,
				 struct audioformat *fp)
{
	struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
	struct snd_interval *ct = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
	struct snd_mask *fmts = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
	struct snd_interval *pt = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
927
	struct snd_mask check_fmts;
Daniel Mack's avatar
Daniel Mack committed
928
929
930
	unsigned int ptime;

	/* check the format */
931
932
933
934
935
	snd_mask_none(&check_fmts);
	check_fmts.bits[0] = (u32)fp->formats;
	check_fmts.bits[1] = (u32)(fp->formats >> 32);
	snd_mask_intersect(&check_fmts, fmts);
	if (snd_mask_empty(&check_fmts)) {
Daniel Mack's avatar
Daniel Mack committed
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
		hwc_debug("   > check: no supported format %d\n", fp->format);
		return 0;
	}
	/* check the channels */
	if (fp->channels < ct->min || fp->channels > ct->max) {
		hwc_debug("   > check: no valid channels %d (%d/%d)\n", fp->channels, ct->min, ct->max);
		return 0;
	}
	/* check the rate is within the range */
	if (fp->rate_min > it->max || (fp->rate_min == it->max && it->openmax)) {
		hwc_debug("   > check: rate_min %d > max %d\n", fp->rate_min, it->max);
		return 0;
	}
	if (fp->rate_max < it->min || (fp->rate_max == it->min && it->openmin)) {
		hwc_debug("   > check: rate_max %d < min %d\n", fp->rate_max, it->min);
		return 0;
	}
	/* check whether the period time is >= the data packet interval */
954
	if (subs->speed != USB_SPEED_FULL) {
Daniel Mack's avatar
Daniel Mack committed
955
956
957
958
959
960
961
962
963
		ptime = 125 * (1 << fp->datainterval);
		if (ptime > pt->max || (ptime == pt->max && pt->openmax)) {
			hwc_debug("   > check: ptime %u > max %u\n", ptime, pt->max);
			return 0;
		}
	}
	return 1;
}

964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
static int apply_hw_params_minmax(struct snd_interval *it, unsigned int rmin,
				  unsigned int rmax)
{
	int changed;

	if (rmin > rmax) {
		hwc_debug("  --> get empty\n");
		it->empty = 1;
		return -EINVAL;
	}

	changed = 0;
	if (it->min < rmin) {
		it->min = rmin;
		it->openmin = 0;
		changed = 1;
	}
	if (it->max > rmax) {
		it->max = rmax;
		it->openmax = 0;
		changed = 1;
	}
	if (snd_interval_checkempty(it)) {
		it->empty = 1;
		return -EINVAL;
	}
	hwc_debug("  --> (%d, %d) (changed = %d)\n", it->min, it->max, changed);
	return changed;
}

Daniel Mack's avatar
Daniel Mack committed
994
995
996
997
static int hw_rule_rate(struct snd_pcm_hw_params *params,
			struct snd_pcm_hw_rule *rule)
{
	struct snd_usb_substream *subs = rule->private;
998
	struct audioformat *fp;
Daniel Mack's avatar
Daniel Mack committed
999
	struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
1000
1001
	unsigned int rmin, rmax, r;
	int i;
Daniel Mack's avatar
Daniel Mack committed
1002
1003

	hwc_debug("hw_rule_rate: (%d,%d)\n", it->min, it->max);
1004
1005
	rmin = UINT_MAX;
	rmax = 0;
1006
	list_for_each_entry(fp, &subs->fmt_list, list) {
Daniel Mack's avatar
Daniel Mack committed
1007
1008
		if (!hw_check_valid_format(subs, params, fp))
			continue;
1009
1010
1011
1012
1013
1014
1015
1016
		if (fp->rate_table && fp->nr_rates) {
			for (i = 0; i < fp->nr_rates; i++) {
				r = fp->rate_table[i];
				if (!snd_interval_test(it, r))
					continue;
				rmin = min(rmin, r);
				rmax = max(rmax, r);
			}
Daniel Mack's avatar
Daniel Mack committed
1017
		} else {
1018
1019
			rmin = min(rmin, fp->rate_min);
			rmax = max(rmax, fp->rate_max);
Daniel Mack's avatar
Daniel Mack committed
1020
1021
1022
		}
	}

1023
	return apply_hw_params_minmax(it, rmin, rmax);
Daniel Mack's avatar
Daniel Mack committed
1024
1025
1026
1027
1028
1029
1030
}


static int hw_rule_channels(struct snd_pcm_hw_params *params,
			    struct snd_pcm_hw_rule *rule)
{
	struct snd_usb_substream *subs = rule->private;
1031
	struct audioformat *fp;
Daniel Mack's avatar
Daniel Mack committed
1032
1033
1034
1035
	struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
	unsigned int rmin, rmax;

	hwc_debug("hw_rule_channels: (%d,%d)\n", it->min, it->max);
1036
1037
	rmin = UINT_MAX;
	rmax = 0;
1038
	list_for_each_entry(fp, &subs->fmt_list, list) {
Daniel Mack's avatar
Daniel Mack committed
1039
1040
		if (!hw_check_valid_format(subs, params, fp))
			continue;
1041
1042
		rmin = min(rmin, fp->channels);
		rmax = max(rmax, fp->channels);
Daniel Mack's avatar
Daniel Mack committed
1043
1044
	}

1045
	return apply_hw_params_minmax(it, rmin, rmax);
Daniel Mack's avatar
Daniel Mack committed
1046
1047
1048
1049
1050
1051
}

static int hw_rule_format(struct snd_pcm_hw_params *params,
			  struct snd_pcm_hw_rule *rule)
{
	struct snd_usb_substream *subs = rule->private;
1052
	struct audioformat *fp;
Daniel Mack's avatar
Daniel Mack committed
1053
1054
1055
1056
1057
1058
1059
	struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
	u64 fbits;
	u32 oldbits[2];
	int changed;

	hwc_debug("hw_rule_format: %x:%x\n", fmt->bits[0], fmt->bits[1]);
	fbits = 0;
1060
	list_for_each_entry(fp, &subs->fmt_list, list) {
Daniel Mack's avatar
Daniel Mack committed
1061
1062
		if (!hw_check_valid_format(subs, params, fp))
			continue;
1063
		fbits |= fp->formats;
Daniel Mack's avatar
Daniel Mack committed
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
	}

	oldbits[0] = fmt->bits[0];
	oldbits[1] = fmt->bits[1];
	fmt->bits[0] &= (u32)fbits;
	fmt->bits[1] &= (u32)(fbits >> 32);
	if (!fmt->bits[0] && !fmt->bits[1]) {
		hwc_debug("  --> get empty\n");
		return -EINVAL;
	}
	changed = (oldbits[0] != fmt->bits[0] || oldbits[1] != fmt->bits[1]);
	hwc_debug("  --> %x:%x (changed = %d)\n", fmt->bits[0], fmt->bits[1], changed);
	return changed;
}

static int hw_rule_period_time(struct snd_pcm_hw_params *params,
			       struct snd_pcm_hw_rule *rule)
{
	struct snd_usb_substream *subs = rule->private;
	struct audioformat *fp;
	struct snd_interval *it;
	unsigned char min_datainterval;
	unsigned int pmin;

	it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
	hwc_debug("hw_rule_period_time: (%u,%u)\n", it->min, it->max);
	min_datainterval = 0xff;
	list_for_each_entry(fp, &subs->fmt_list, list) {
		if (!hw_check_valid_format(subs, params, fp))
			continue;
		min_datainterval = min(min_datainterval, fp->datainterval);
	}
	if (min_datainterval == 0xff) {
1097
		hwc_debug("  --> get empty\n");
Daniel Mack's avatar
Daniel Mack committed
1098
1099
1100
1101
		it->empty = 1;
		return -EINVAL;
	}
	pmin = 125 * (1 << min_datainterval);
1102
1103

	return apply_hw_params_minmax(it, pmin, UINT_MAX);
Daniel Mack's avatar
Daniel Mack committed
1104
1105
}

1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
/* apply PCM hw constraints from the concurrent sync EP */
static int apply_hw_constraint_from_sync(struct snd_pcm_runtime *runtime,
					 struct snd_usb_substream *subs)
{
	struct snd_usb_audio *chip = subs->stream->chip;
	struct snd_usb_endpoint *ep;
	struct audioformat *fp;
	int err;

	list_for_each_entry(fp, &subs->fmt_list, list) {
1116
		ep = snd_usb_get_endpoint(chip, fp->endpoint);
1117
1118
1119
1120
1121
		if (ep && ep->cur_rate)
			goto found;
		if (!fp->implicit_fb)
			continue;
		/* for the implicit fb, check the sync ep as well */
1122
		ep = snd_usb_get_endpoint(chip, fp->sync_ep);
1123
1124
1125
1126
1127
1128
1129
		if (ep && ep->cur_rate)
			goto found;
	}
	return 0;

 found:
	if (!find_format(&subs->fmt_list, ep->cur_format, ep->cur_rate,
1130
			 ep->cur_channels, false, NULL)) {
1131
1132
1133
1134
1135
1136
1137
		usb_audio_dbg(chip, "EP 0x%x being used, but not applicable\n",
			      ep->ep_num);
		return 0;
	}

	usb_audio_dbg(chip, "EP 0x%x being used, using fixed params:\n",
		      ep->ep_num);
1138
1139
	usb_audio_dbg(chip, "rate=%d, period_size=%d, periods=%d\n",
		      ep->cur_rate, ep->cur_period_frames,
1140
1141
		      ep->cur_buffer_periods);

1142
	runtime->hw.formats = subs->formats;
1143
1144
1145
1146
	runtime->hw.rate_min = runtime->hw.rate_max = ep->cur_rate;
	runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
	runtime->hw.periods_min = runtime->hw.periods_max =
		ep->cur_buffer_periods;
1147
1148
1149
1150
1151
1152
1153
1154

	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
				  hw_rule_channels, subs,
				  SNDRV_PCM_HW_PARAM_FORMAT,
				  SNDRV_PCM_HW_PARAM_RATE,
				  -1);
	if (err < 0)
		return err;
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164

	err = snd_pcm_hw_constraint_minmax(runtime,
					   SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
					   ep->cur_period_frames,
					   ep->cur_period_frames);
	if (err < 0)
		return err;

	return 1; /* notify the finding */
}
Daniel Mack's avatar
Daniel Mack committed
1165
1166
1167
1168
1169
1170
1171

/*
 * set up the runtime hardware information.
 */

static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substream *subs)
{
1172
	struct snd_usb_audio *chip = subs->stream->chip;
1173
	struct audioformat *fp;
Daniel Mack's avatar
Daniel Mack committed
1174
	unsigned int pt, ptmin;
1175
	int param_period_time_if_needed = -1;
Daniel Mack's avatar
Daniel Mack committed
1176
1177
	int err;

1178
1179
1180
1181
1182
1183
1184
1185
	mutex_lock(&chip->mutex);
	err = apply_hw_constraint_from_sync(runtime, subs);
	mutex_unlock(&chip->mutex);
	if (err < 0)
		return err;
	if (err > 0) /* found the matching? */
		goto add_extra_rules;

Daniel Mack's avatar
Daniel Mack committed
1186
1187
1188
1189
1190
1191
1192
1193
1194
	runtime->hw.formats = subs->formats;

	runtime->hw.rate_min = 0x7fffffff;
	runtime->hw.rate_max = 0;
	runtime->hw.channels_min = 256;
	runtime->hw.channels_max = 0;
	runtime->hw.rates = 0;
	ptmin = UINT_MAX;
	/* check min/max rates and channels */
1195
	list_for_each_entry(fp, &subs->fmt_list, list) {
Daniel Mack's avatar
Daniel Mack committed
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
		runtime->hw.rates |= fp->rates;
		if (runtime->hw.rate_min > fp->rate_min)
			runtime->hw.rate_min = fp->rate_min;
		if (runtime->hw.rate_max < fp->rate_max)
			runtime->hw.rate_max = fp->rate_max;
		if (runtime->hw.channels_min > fp->channels)
			runtime->hw.channels_min = fp->channels;
		if (runtime->hw.channels_max < fp->channels)
			runtime->hw.channels_max = fp->channels;
		if (fp->fmt_type == UAC_FORMAT_TYPE_II && fp->frame_size > 0) {
			/* FIXME: there might be more than one audio formats... */
			runtime->hw.period_bytes_min = runtime->hw.period_bytes_max =
				fp->frame_size;
		}
		pt = 125 * (1 << fp->datainterval);
		ptmin = min(ptmin, pt);
	}

	param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME;
1215
	if (subs->speed == USB_SPEED_FULL)
Daniel Mack's avatar
Daniel Mack committed
1216
1217
1218
1219
1220
		/* full speed devices have fixed data packet interval */
		ptmin = 1000;
	if (ptmin == 1000)
		/* if period time doesn't go below 1 ms, no rules needed */
		param_period_time_if_needed = -1;
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235

	err = snd_pcm_hw_constraint_minmax(runtime,
					   SNDRV_PCM_HW_PARAM_PERIOD_TIME,
					   ptmin, UINT_MAX);
	if (err < 0)
		return err;

	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				  hw_rule_rate, subs,
				  SNDRV_PCM_HW_PARAM_FORMAT,
				  SNDRV_PCM_HW_PARAM_CHANNELS,
				  param_period_time_if_needed,
				  -1);
	if (err < 0)
		return err;