1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (c) 2006-2008 Daniel Mack, Karsten Wiese
4*4882a593Smuzhiyun */
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun #include <linux/device.h>
7*4882a593Smuzhiyun #include <linux/spinlock.h>
8*4882a593Smuzhiyun #include <linux/slab.h>
9*4882a593Smuzhiyun #include <linux/init.h>
10*4882a593Smuzhiyun #include <linux/usb.h>
11*4882a593Smuzhiyun #include <sound/core.h>
12*4882a593Smuzhiyun #include <sound/pcm.h>
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun #include "device.h"
15*4882a593Smuzhiyun #include "audio.h"
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun #define N_URBS 32
18*4882a593Smuzhiyun #define CLOCK_DRIFT_TOLERANCE 5
19*4882a593Smuzhiyun #define FRAMES_PER_URB 8
20*4882a593Smuzhiyun #define BYTES_PER_FRAME 512
21*4882a593Smuzhiyun #define CHANNELS_PER_STREAM 2
22*4882a593Smuzhiyun #define BYTES_PER_SAMPLE 3
23*4882a593Smuzhiyun #define BYTES_PER_SAMPLE_USB 4
24*4882a593Smuzhiyun #define MAX_BUFFER_SIZE (128*1024)
25*4882a593Smuzhiyun #define MAX_ENDPOINT_SIZE 512
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun #define ENDPOINT_CAPTURE 2
28*4882a593Smuzhiyun #define ENDPOINT_PLAYBACK 6
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #define MAKE_CHECKBYTE(cdev,stream,i) \
31*4882a593Smuzhiyun (stream << 1) | (~(i / (cdev->n_streams * BYTES_PER_SAMPLE_USB)) & 1)
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun static const struct snd_pcm_hardware snd_usb_caiaq_pcm_hardware = {
34*4882a593Smuzhiyun .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
35*4882a593Smuzhiyun SNDRV_PCM_INFO_BLOCK_TRANSFER),
36*4882a593Smuzhiyun .formats = SNDRV_PCM_FMTBIT_S24_3BE,
37*4882a593Smuzhiyun .rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
38*4882a593Smuzhiyun SNDRV_PCM_RATE_96000),
39*4882a593Smuzhiyun .rate_min = 44100,
40*4882a593Smuzhiyun .rate_max = 0, /* will overwrite later */
41*4882a593Smuzhiyun .channels_min = CHANNELS_PER_STREAM,
42*4882a593Smuzhiyun .channels_max = CHANNELS_PER_STREAM,
43*4882a593Smuzhiyun .buffer_bytes_max = MAX_BUFFER_SIZE,
44*4882a593Smuzhiyun .period_bytes_min = 128,
45*4882a593Smuzhiyun .period_bytes_max = MAX_BUFFER_SIZE,
46*4882a593Smuzhiyun .periods_min = 1,
47*4882a593Smuzhiyun .periods_max = 1024,
48*4882a593Smuzhiyun };
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun static void
activate_substream(struct snd_usb_caiaqdev * cdev,struct snd_pcm_substream * sub)51*4882a593Smuzhiyun activate_substream(struct snd_usb_caiaqdev *cdev,
52*4882a593Smuzhiyun struct snd_pcm_substream *sub)
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun spin_lock(&cdev->spinlock);
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
57*4882a593Smuzhiyun cdev->sub_playback[sub->number] = sub;
58*4882a593Smuzhiyun else
59*4882a593Smuzhiyun cdev->sub_capture[sub->number] = sub;
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun spin_unlock(&cdev->spinlock);
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun static void
deactivate_substream(struct snd_usb_caiaqdev * cdev,struct snd_pcm_substream * sub)65*4882a593Smuzhiyun deactivate_substream(struct snd_usb_caiaqdev *cdev,
66*4882a593Smuzhiyun struct snd_pcm_substream *sub)
67*4882a593Smuzhiyun {
68*4882a593Smuzhiyun unsigned long flags;
69*4882a593Smuzhiyun spin_lock_irqsave(&cdev->spinlock, flags);
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
72*4882a593Smuzhiyun cdev->sub_playback[sub->number] = NULL;
73*4882a593Smuzhiyun else
74*4882a593Smuzhiyun cdev->sub_capture[sub->number] = NULL;
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun spin_unlock_irqrestore(&cdev->spinlock, flags);
77*4882a593Smuzhiyun }
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun static int
all_substreams_zero(struct snd_pcm_substream ** subs)80*4882a593Smuzhiyun all_substreams_zero(struct snd_pcm_substream **subs)
81*4882a593Smuzhiyun {
82*4882a593Smuzhiyun int i;
83*4882a593Smuzhiyun for (i = 0; i < MAX_STREAMS; i++)
84*4882a593Smuzhiyun if (subs[i] != NULL)
85*4882a593Smuzhiyun return 0;
86*4882a593Smuzhiyun return 1;
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun
stream_start(struct snd_usb_caiaqdev * cdev)89*4882a593Smuzhiyun static int stream_start(struct snd_usb_caiaqdev *cdev)
90*4882a593Smuzhiyun {
91*4882a593Smuzhiyun int i, ret;
92*4882a593Smuzhiyun struct device *dev = caiaqdev_to_dev(cdev);
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun dev_dbg(dev, "%s(%p)\n", __func__, cdev);
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun if (cdev->streaming)
97*4882a593Smuzhiyun return -EINVAL;
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun memset(cdev->sub_playback, 0, sizeof(cdev->sub_playback));
100*4882a593Smuzhiyun memset(cdev->sub_capture, 0, sizeof(cdev->sub_capture));
101*4882a593Smuzhiyun cdev->input_panic = 0;
102*4882a593Smuzhiyun cdev->output_panic = 0;
103*4882a593Smuzhiyun cdev->first_packet = 4;
104*4882a593Smuzhiyun cdev->streaming = 1;
105*4882a593Smuzhiyun cdev->warned = 0;
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun for (i = 0; i < N_URBS; i++) {
108*4882a593Smuzhiyun ret = usb_submit_urb(cdev->data_urbs_in[i], GFP_ATOMIC);
109*4882a593Smuzhiyun if (ret) {
110*4882a593Smuzhiyun dev_err(dev, "unable to trigger read #%d! (ret %d)\n",
111*4882a593Smuzhiyun i, ret);
112*4882a593Smuzhiyun cdev->streaming = 0;
113*4882a593Smuzhiyun return -EPIPE;
114*4882a593Smuzhiyun }
115*4882a593Smuzhiyun }
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun return 0;
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun
stream_stop(struct snd_usb_caiaqdev * cdev)120*4882a593Smuzhiyun static void stream_stop(struct snd_usb_caiaqdev *cdev)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun int i;
123*4882a593Smuzhiyun struct device *dev = caiaqdev_to_dev(cdev);
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun dev_dbg(dev, "%s(%p)\n", __func__, cdev);
126*4882a593Smuzhiyun if (!cdev->streaming)
127*4882a593Smuzhiyun return;
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun cdev->streaming = 0;
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun for (i = 0; i < N_URBS; i++) {
132*4882a593Smuzhiyun usb_kill_urb(cdev->data_urbs_in[i]);
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun if (test_bit(i, &cdev->outurb_active_mask))
135*4882a593Smuzhiyun usb_kill_urb(cdev->data_urbs_out[i]);
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun cdev->outurb_active_mask = 0;
139*4882a593Smuzhiyun }
140*4882a593Smuzhiyun
snd_usb_caiaq_substream_open(struct snd_pcm_substream * substream)141*4882a593Smuzhiyun static int snd_usb_caiaq_substream_open(struct snd_pcm_substream *substream)
142*4882a593Smuzhiyun {
143*4882a593Smuzhiyun struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(substream);
144*4882a593Smuzhiyun struct device *dev = caiaqdev_to_dev(cdev);
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun dev_dbg(dev, "%s(%p)\n", __func__, substream);
147*4882a593Smuzhiyun substream->runtime->hw = cdev->pcm_info;
148*4882a593Smuzhiyun snd_pcm_limit_hw_rates(substream->runtime);
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun return 0;
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun
snd_usb_caiaq_substream_close(struct snd_pcm_substream * substream)153*4882a593Smuzhiyun static int snd_usb_caiaq_substream_close(struct snd_pcm_substream *substream)
154*4882a593Smuzhiyun {
155*4882a593Smuzhiyun struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(substream);
156*4882a593Smuzhiyun struct device *dev = caiaqdev_to_dev(cdev);
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun dev_dbg(dev, "%s(%p)\n", __func__, substream);
159*4882a593Smuzhiyun if (all_substreams_zero(cdev->sub_playback) &&
160*4882a593Smuzhiyun all_substreams_zero(cdev->sub_capture)) {
161*4882a593Smuzhiyun /* when the last client has stopped streaming,
162*4882a593Smuzhiyun * all sample rates are allowed again */
163*4882a593Smuzhiyun stream_stop(cdev);
164*4882a593Smuzhiyun cdev->pcm_info.rates = cdev->samplerates;
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun return 0;
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun
snd_usb_caiaq_pcm_hw_free(struct snd_pcm_substream * sub)170*4882a593Smuzhiyun static int snd_usb_caiaq_pcm_hw_free(struct snd_pcm_substream *sub)
171*4882a593Smuzhiyun {
172*4882a593Smuzhiyun struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(sub);
173*4882a593Smuzhiyun deactivate_substream(cdev, sub);
174*4882a593Smuzhiyun return 0;
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun /* this should probably go upstream */
178*4882a593Smuzhiyun #if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 12
179*4882a593Smuzhiyun #error "Change this table"
180*4882a593Smuzhiyun #endif
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun static const unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100,
183*4882a593Smuzhiyun 48000, 64000, 88200, 96000, 176400, 192000 };
184*4882a593Smuzhiyun
snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream * substream)185*4882a593Smuzhiyun static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream)
186*4882a593Smuzhiyun {
187*4882a593Smuzhiyun int bytes_per_sample, bpp, ret, i;
188*4882a593Smuzhiyun int index = substream->number;
189*4882a593Smuzhiyun struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(substream);
190*4882a593Smuzhiyun struct snd_pcm_runtime *runtime = substream->runtime;
191*4882a593Smuzhiyun struct device *dev = caiaqdev_to_dev(cdev);
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun dev_dbg(dev, "%s(%p)\n", __func__, substream);
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
196*4882a593Smuzhiyun int out_pos;
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun switch (cdev->spec.data_alignment) {
199*4882a593Smuzhiyun case 0:
200*4882a593Smuzhiyun case 2:
201*4882a593Smuzhiyun out_pos = BYTES_PER_SAMPLE + 1;
202*4882a593Smuzhiyun break;
203*4882a593Smuzhiyun case 3:
204*4882a593Smuzhiyun default:
205*4882a593Smuzhiyun out_pos = 0;
206*4882a593Smuzhiyun break;
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun cdev->period_out_count[index] = out_pos;
210*4882a593Smuzhiyun cdev->audio_out_buf_pos[index] = out_pos;
211*4882a593Smuzhiyun } else {
212*4882a593Smuzhiyun int in_pos;
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun switch (cdev->spec.data_alignment) {
215*4882a593Smuzhiyun case 0:
216*4882a593Smuzhiyun in_pos = BYTES_PER_SAMPLE + 2;
217*4882a593Smuzhiyun break;
218*4882a593Smuzhiyun case 2:
219*4882a593Smuzhiyun in_pos = BYTES_PER_SAMPLE;
220*4882a593Smuzhiyun break;
221*4882a593Smuzhiyun case 3:
222*4882a593Smuzhiyun default:
223*4882a593Smuzhiyun in_pos = 0;
224*4882a593Smuzhiyun break;
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun cdev->period_in_count[index] = in_pos;
228*4882a593Smuzhiyun cdev->audio_in_buf_pos[index] = in_pos;
229*4882a593Smuzhiyun }
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun if (cdev->streaming)
232*4882a593Smuzhiyun return 0;
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun /* the first client that opens a stream defines the sample rate
235*4882a593Smuzhiyun * setting for all subsequent calls, until the last client closed. */
236*4882a593Smuzhiyun for (i=0; i < ARRAY_SIZE(rates); i++)
237*4882a593Smuzhiyun if (runtime->rate == rates[i])
238*4882a593Smuzhiyun cdev->pcm_info.rates = 1 << i;
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun snd_pcm_limit_hw_rates(runtime);
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun bytes_per_sample = BYTES_PER_SAMPLE;
243*4882a593Smuzhiyun if (cdev->spec.data_alignment >= 2)
244*4882a593Smuzhiyun bytes_per_sample++;
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun bpp = ((runtime->rate / 8000) + CLOCK_DRIFT_TOLERANCE)
247*4882a593Smuzhiyun * bytes_per_sample * CHANNELS_PER_STREAM * cdev->n_streams;
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun if (bpp > MAX_ENDPOINT_SIZE)
250*4882a593Smuzhiyun bpp = MAX_ENDPOINT_SIZE;
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun ret = snd_usb_caiaq_set_audio_params(cdev, runtime->rate,
253*4882a593Smuzhiyun runtime->sample_bits, bpp);
254*4882a593Smuzhiyun if (ret)
255*4882a593Smuzhiyun return ret;
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun ret = stream_start(cdev);
258*4882a593Smuzhiyun if (ret)
259*4882a593Smuzhiyun return ret;
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun cdev->output_running = 0;
262*4882a593Smuzhiyun wait_event_timeout(cdev->prepare_wait_queue, cdev->output_running, HZ);
263*4882a593Smuzhiyun if (!cdev->output_running) {
264*4882a593Smuzhiyun stream_stop(cdev);
265*4882a593Smuzhiyun return -EPIPE;
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun return 0;
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun
snd_usb_caiaq_pcm_trigger(struct snd_pcm_substream * sub,int cmd)271*4882a593Smuzhiyun static int snd_usb_caiaq_pcm_trigger(struct snd_pcm_substream *sub, int cmd)
272*4882a593Smuzhiyun {
273*4882a593Smuzhiyun struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(sub);
274*4882a593Smuzhiyun struct device *dev = caiaqdev_to_dev(cdev);
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun dev_dbg(dev, "%s(%p) cmd %d\n", __func__, sub, cmd);
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun switch (cmd) {
279*4882a593Smuzhiyun case SNDRV_PCM_TRIGGER_START:
280*4882a593Smuzhiyun case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
281*4882a593Smuzhiyun activate_substream(cdev, sub);
282*4882a593Smuzhiyun break;
283*4882a593Smuzhiyun case SNDRV_PCM_TRIGGER_STOP:
284*4882a593Smuzhiyun case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
285*4882a593Smuzhiyun deactivate_substream(cdev, sub);
286*4882a593Smuzhiyun break;
287*4882a593Smuzhiyun default:
288*4882a593Smuzhiyun return -EINVAL;
289*4882a593Smuzhiyun }
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun return 0;
292*4882a593Smuzhiyun }
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun static snd_pcm_uframes_t
snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream * sub)295*4882a593Smuzhiyun snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub)
296*4882a593Smuzhiyun {
297*4882a593Smuzhiyun int index = sub->number;
298*4882a593Smuzhiyun struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(sub);
299*4882a593Smuzhiyun snd_pcm_uframes_t ptr;
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun spin_lock(&cdev->spinlock);
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun if (cdev->input_panic || cdev->output_panic) {
304*4882a593Smuzhiyun ptr = SNDRV_PCM_POS_XRUN;
305*4882a593Smuzhiyun goto unlock;
306*4882a593Smuzhiyun }
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
309*4882a593Smuzhiyun ptr = bytes_to_frames(sub->runtime,
310*4882a593Smuzhiyun cdev->audio_out_buf_pos[index]);
311*4882a593Smuzhiyun else
312*4882a593Smuzhiyun ptr = bytes_to_frames(sub->runtime,
313*4882a593Smuzhiyun cdev->audio_in_buf_pos[index]);
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun unlock:
316*4882a593Smuzhiyun spin_unlock(&cdev->spinlock);
317*4882a593Smuzhiyun return ptr;
318*4882a593Smuzhiyun }
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun /* operators for both playback and capture */
321*4882a593Smuzhiyun static const struct snd_pcm_ops snd_usb_caiaq_ops = {
322*4882a593Smuzhiyun .open = snd_usb_caiaq_substream_open,
323*4882a593Smuzhiyun .close = snd_usb_caiaq_substream_close,
324*4882a593Smuzhiyun .hw_free = snd_usb_caiaq_pcm_hw_free,
325*4882a593Smuzhiyun .prepare = snd_usb_caiaq_pcm_prepare,
326*4882a593Smuzhiyun .trigger = snd_usb_caiaq_pcm_trigger,
327*4882a593Smuzhiyun .pointer = snd_usb_caiaq_pcm_pointer,
328*4882a593Smuzhiyun };
329*4882a593Smuzhiyun
check_for_elapsed_periods(struct snd_usb_caiaqdev * cdev,struct snd_pcm_substream ** subs)330*4882a593Smuzhiyun static void check_for_elapsed_periods(struct snd_usb_caiaqdev *cdev,
331*4882a593Smuzhiyun struct snd_pcm_substream **subs)
332*4882a593Smuzhiyun {
333*4882a593Smuzhiyun int stream, pb, *cnt;
334*4882a593Smuzhiyun struct snd_pcm_substream *sub;
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun for (stream = 0; stream < cdev->n_streams; stream++) {
337*4882a593Smuzhiyun sub = subs[stream];
338*4882a593Smuzhiyun if (!sub)
339*4882a593Smuzhiyun continue;
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun pb = snd_pcm_lib_period_bytes(sub);
342*4882a593Smuzhiyun cnt = (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
343*4882a593Smuzhiyun &cdev->period_out_count[stream] :
344*4882a593Smuzhiyun &cdev->period_in_count[stream];
345*4882a593Smuzhiyun
346*4882a593Smuzhiyun if (*cnt >= pb) {
347*4882a593Smuzhiyun snd_pcm_period_elapsed(sub);
348*4882a593Smuzhiyun *cnt %= pb;
349*4882a593Smuzhiyun }
350*4882a593Smuzhiyun }
351*4882a593Smuzhiyun }
352*4882a593Smuzhiyun
read_in_urb_mode0(struct snd_usb_caiaqdev * cdev,const struct urb * urb,const struct usb_iso_packet_descriptor * iso)353*4882a593Smuzhiyun static void read_in_urb_mode0(struct snd_usb_caiaqdev *cdev,
354*4882a593Smuzhiyun const struct urb *urb,
355*4882a593Smuzhiyun const struct usb_iso_packet_descriptor *iso)
356*4882a593Smuzhiyun {
357*4882a593Smuzhiyun unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
358*4882a593Smuzhiyun struct snd_pcm_substream *sub;
359*4882a593Smuzhiyun int stream, i;
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun if (all_substreams_zero(cdev->sub_capture))
362*4882a593Smuzhiyun return;
363*4882a593Smuzhiyun
364*4882a593Smuzhiyun for (i = 0; i < iso->actual_length;) {
365*4882a593Smuzhiyun for (stream = 0; stream < cdev->n_streams; stream++, i++) {
366*4882a593Smuzhiyun sub = cdev->sub_capture[stream];
367*4882a593Smuzhiyun if (sub) {
368*4882a593Smuzhiyun struct snd_pcm_runtime *rt = sub->runtime;
369*4882a593Smuzhiyun char *audio_buf = rt->dma_area;
370*4882a593Smuzhiyun int sz = frames_to_bytes(rt, rt->buffer_size);
371*4882a593Smuzhiyun audio_buf[cdev->audio_in_buf_pos[stream]++]
372*4882a593Smuzhiyun = usb_buf[i];
373*4882a593Smuzhiyun cdev->period_in_count[stream]++;
374*4882a593Smuzhiyun if (cdev->audio_in_buf_pos[stream] == sz)
375*4882a593Smuzhiyun cdev->audio_in_buf_pos[stream] = 0;
376*4882a593Smuzhiyun }
377*4882a593Smuzhiyun }
378*4882a593Smuzhiyun }
379*4882a593Smuzhiyun }
380*4882a593Smuzhiyun
read_in_urb_mode2(struct snd_usb_caiaqdev * cdev,const struct urb * urb,const struct usb_iso_packet_descriptor * iso)381*4882a593Smuzhiyun static void read_in_urb_mode2(struct snd_usb_caiaqdev *cdev,
382*4882a593Smuzhiyun const struct urb *urb,
383*4882a593Smuzhiyun const struct usb_iso_packet_descriptor *iso)
384*4882a593Smuzhiyun {
385*4882a593Smuzhiyun unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
386*4882a593Smuzhiyun unsigned char check_byte;
387*4882a593Smuzhiyun struct snd_pcm_substream *sub;
388*4882a593Smuzhiyun int stream, i;
389*4882a593Smuzhiyun
390*4882a593Smuzhiyun for (i = 0; i < iso->actual_length;) {
391*4882a593Smuzhiyun if (i % (cdev->n_streams * BYTES_PER_SAMPLE_USB) == 0) {
392*4882a593Smuzhiyun for (stream = 0;
393*4882a593Smuzhiyun stream < cdev->n_streams;
394*4882a593Smuzhiyun stream++, i++) {
395*4882a593Smuzhiyun if (cdev->first_packet)
396*4882a593Smuzhiyun continue;
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun check_byte = MAKE_CHECKBYTE(cdev, stream, i);
399*4882a593Smuzhiyun
400*4882a593Smuzhiyun if ((usb_buf[i] & 0x3f) != check_byte)
401*4882a593Smuzhiyun cdev->input_panic = 1;
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun if (usb_buf[i] & 0x80)
404*4882a593Smuzhiyun cdev->output_panic = 1;
405*4882a593Smuzhiyun }
406*4882a593Smuzhiyun }
407*4882a593Smuzhiyun cdev->first_packet = 0;
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun for (stream = 0; stream < cdev->n_streams; stream++, i++) {
410*4882a593Smuzhiyun sub = cdev->sub_capture[stream];
411*4882a593Smuzhiyun if (cdev->input_panic)
412*4882a593Smuzhiyun usb_buf[i] = 0;
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun if (sub) {
415*4882a593Smuzhiyun struct snd_pcm_runtime *rt = sub->runtime;
416*4882a593Smuzhiyun char *audio_buf = rt->dma_area;
417*4882a593Smuzhiyun int sz = frames_to_bytes(rt, rt->buffer_size);
418*4882a593Smuzhiyun audio_buf[cdev->audio_in_buf_pos[stream]++] =
419*4882a593Smuzhiyun usb_buf[i];
420*4882a593Smuzhiyun cdev->period_in_count[stream]++;
421*4882a593Smuzhiyun if (cdev->audio_in_buf_pos[stream] == sz)
422*4882a593Smuzhiyun cdev->audio_in_buf_pos[stream] = 0;
423*4882a593Smuzhiyun }
424*4882a593Smuzhiyun }
425*4882a593Smuzhiyun }
426*4882a593Smuzhiyun }
427*4882a593Smuzhiyun
read_in_urb_mode3(struct snd_usb_caiaqdev * cdev,const struct urb * urb,const struct usb_iso_packet_descriptor * iso)428*4882a593Smuzhiyun static void read_in_urb_mode3(struct snd_usb_caiaqdev *cdev,
429*4882a593Smuzhiyun const struct urb *urb,
430*4882a593Smuzhiyun const struct usb_iso_packet_descriptor *iso)
431*4882a593Smuzhiyun {
432*4882a593Smuzhiyun unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
433*4882a593Smuzhiyun struct device *dev = caiaqdev_to_dev(cdev);
434*4882a593Smuzhiyun int stream, i;
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun /* paranoia check */
437*4882a593Smuzhiyun if (iso->actual_length % (BYTES_PER_SAMPLE_USB * CHANNELS_PER_STREAM))
438*4882a593Smuzhiyun return;
439*4882a593Smuzhiyun
440*4882a593Smuzhiyun for (i = 0; i < iso->actual_length;) {
441*4882a593Smuzhiyun for (stream = 0; stream < cdev->n_streams; stream++) {
442*4882a593Smuzhiyun struct snd_pcm_substream *sub = cdev->sub_capture[stream];
443*4882a593Smuzhiyun char *audio_buf = NULL;
444*4882a593Smuzhiyun int c, n, sz = 0;
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun if (sub && !cdev->input_panic) {
447*4882a593Smuzhiyun struct snd_pcm_runtime *rt = sub->runtime;
448*4882a593Smuzhiyun audio_buf = rt->dma_area;
449*4882a593Smuzhiyun sz = frames_to_bytes(rt, rt->buffer_size);
450*4882a593Smuzhiyun }
451*4882a593Smuzhiyun
452*4882a593Smuzhiyun for (c = 0; c < CHANNELS_PER_STREAM; c++) {
453*4882a593Smuzhiyun /* 3 audio data bytes, followed by 1 check byte */
454*4882a593Smuzhiyun if (audio_buf) {
455*4882a593Smuzhiyun for (n = 0; n < BYTES_PER_SAMPLE; n++) {
456*4882a593Smuzhiyun audio_buf[cdev->audio_in_buf_pos[stream]++] = usb_buf[i+n];
457*4882a593Smuzhiyun
458*4882a593Smuzhiyun if (cdev->audio_in_buf_pos[stream] == sz)
459*4882a593Smuzhiyun cdev->audio_in_buf_pos[stream] = 0;
460*4882a593Smuzhiyun }
461*4882a593Smuzhiyun
462*4882a593Smuzhiyun cdev->period_in_count[stream] += BYTES_PER_SAMPLE;
463*4882a593Smuzhiyun }
464*4882a593Smuzhiyun
465*4882a593Smuzhiyun i += BYTES_PER_SAMPLE;
466*4882a593Smuzhiyun
467*4882a593Smuzhiyun if (usb_buf[i] != ((stream << 1) | c) &&
468*4882a593Smuzhiyun !cdev->first_packet) {
469*4882a593Smuzhiyun if (!cdev->input_panic)
470*4882a593Smuzhiyun dev_warn(dev, " EXPECTED: %02x got %02x, c %d, stream %d, i %d\n",
471*4882a593Smuzhiyun ((stream << 1) | c), usb_buf[i], c, stream, i);
472*4882a593Smuzhiyun cdev->input_panic = 1;
473*4882a593Smuzhiyun }
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun i++;
476*4882a593Smuzhiyun }
477*4882a593Smuzhiyun }
478*4882a593Smuzhiyun }
479*4882a593Smuzhiyun
480*4882a593Smuzhiyun if (cdev->first_packet > 0)
481*4882a593Smuzhiyun cdev->first_packet--;
482*4882a593Smuzhiyun }
483*4882a593Smuzhiyun
read_in_urb(struct snd_usb_caiaqdev * cdev,const struct urb * urb,const struct usb_iso_packet_descriptor * iso)484*4882a593Smuzhiyun static void read_in_urb(struct snd_usb_caiaqdev *cdev,
485*4882a593Smuzhiyun const struct urb *urb,
486*4882a593Smuzhiyun const struct usb_iso_packet_descriptor *iso)
487*4882a593Smuzhiyun {
488*4882a593Smuzhiyun struct device *dev = caiaqdev_to_dev(cdev);
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun if (!cdev->streaming)
491*4882a593Smuzhiyun return;
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun if (iso->actual_length < cdev->bpp)
494*4882a593Smuzhiyun return;
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun switch (cdev->spec.data_alignment) {
497*4882a593Smuzhiyun case 0:
498*4882a593Smuzhiyun read_in_urb_mode0(cdev, urb, iso);
499*4882a593Smuzhiyun break;
500*4882a593Smuzhiyun case 2:
501*4882a593Smuzhiyun read_in_urb_mode2(cdev, urb, iso);
502*4882a593Smuzhiyun break;
503*4882a593Smuzhiyun case 3:
504*4882a593Smuzhiyun read_in_urb_mode3(cdev, urb, iso);
505*4882a593Smuzhiyun break;
506*4882a593Smuzhiyun }
507*4882a593Smuzhiyun
508*4882a593Smuzhiyun if ((cdev->input_panic || cdev->output_panic) && !cdev->warned) {
509*4882a593Smuzhiyun dev_warn(dev, "streaming error detected %s %s\n",
510*4882a593Smuzhiyun cdev->input_panic ? "(input)" : "",
511*4882a593Smuzhiyun cdev->output_panic ? "(output)" : "");
512*4882a593Smuzhiyun cdev->warned = 1;
513*4882a593Smuzhiyun }
514*4882a593Smuzhiyun }
515*4882a593Smuzhiyun
fill_out_urb_mode_0(struct snd_usb_caiaqdev * cdev,struct urb * urb,const struct usb_iso_packet_descriptor * iso)516*4882a593Smuzhiyun static void fill_out_urb_mode_0(struct snd_usb_caiaqdev *cdev,
517*4882a593Smuzhiyun struct urb *urb,
518*4882a593Smuzhiyun const struct usb_iso_packet_descriptor *iso)
519*4882a593Smuzhiyun {
520*4882a593Smuzhiyun unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
521*4882a593Smuzhiyun struct snd_pcm_substream *sub;
522*4882a593Smuzhiyun int stream, i;
523*4882a593Smuzhiyun
524*4882a593Smuzhiyun for (i = 0; i < iso->length;) {
525*4882a593Smuzhiyun for (stream = 0; stream < cdev->n_streams; stream++, i++) {
526*4882a593Smuzhiyun sub = cdev->sub_playback[stream];
527*4882a593Smuzhiyun if (sub) {
528*4882a593Smuzhiyun struct snd_pcm_runtime *rt = sub->runtime;
529*4882a593Smuzhiyun char *audio_buf = rt->dma_area;
530*4882a593Smuzhiyun int sz = frames_to_bytes(rt, rt->buffer_size);
531*4882a593Smuzhiyun usb_buf[i] =
532*4882a593Smuzhiyun audio_buf[cdev->audio_out_buf_pos[stream]];
533*4882a593Smuzhiyun cdev->period_out_count[stream]++;
534*4882a593Smuzhiyun cdev->audio_out_buf_pos[stream]++;
535*4882a593Smuzhiyun if (cdev->audio_out_buf_pos[stream] == sz)
536*4882a593Smuzhiyun cdev->audio_out_buf_pos[stream] = 0;
537*4882a593Smuzhiyun } else
538*4882a593Smuzhiyun usb_buf[i] = 0;
539*4882a593Smuzhiyun }
540*4882a593Smuzhiyun
541*4882a593Smuzhiyun /* fill in the check bytes */
542*4882a593Smuzhiyun if (cdev->spec.data_alignment == 2 &&
543*4882a593Smuzhiyun i % (cdev->n_streams * BYTES_PER_SAMPLE_USB) ==
544*4882a593Smuzhiyun (cdev->n_streams * CHANNELS_PER_STREAM))
545*4882a593Smuzhiyun for (stream = 0; stream < cdev->n_streams; stream++, i++)
546*4882a593Smuzhiyun usb_buf[i] = MAKE_CHECKBYTE(cdev, stream, i);
547*4882a593Smuzhiyun }
548*4882a593Smuzhiyun }
549*4882a593Smuzhiyun
fill_out_urb_mode_3(struct snd_usb_caiaqdev * cdev,struct urb * urb,const struct usb_iso_packet_descriptor * iso)550*4882a593Smuzhiyun static void fill_out_urb_mode_3(struct snd_usb_caiaqdev *cdev,
551*4882a593Smuzhiyun struct urb *urb,
552*4882a593Smuzhiyun const struct usb_iso_packet_descriptor *iso)
553*4882a593Smuzhiyun {
554*4882a593Smuzhiyun unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
555*4882a593Smuzhiyun int stream, i;
556*4882a593Smuzhiyun
557*4882a593Smuzhiyun for (i = 0; i < iso->length;) {
558*4882a593Smuzhiyun for (stream = 0; stream < cdev->n_streams; stream++) {
559*4882a593Smuzhiyun struct snd_pcm_substream *sub = cdev->sub_playback[stream];
560*4882a593Smuzhiyun char *audio_buf = NULL;
561*4882a593Smuzhiyun int c, n, sz = 0;
562*4882a593Smuzhiyun
563*4882a593Smuzhiyun if (sub) {
564*4882a593Smuzhiyun struct snd_pcm_runtime *rt = sub->runtime;
565*4882a593Smuzhiyun audio_buf = rt->dma_area;
566*4882a593Smuzhiyun sz = frames_to_bytes(rt, rt->buffer_size);
567*4882a593Smuzhiyun }
568*4882a593Smuzhiyun
569*4882a593Smuzhiyun for (c = 0; c < CHANNELS_PER_STREAM; c++) {
570*4882a593Smuzhiyun for (n = 0; n < BYTES_PER_SAMPLE; n++) {
571*4882a593Smuzhiyun if (audio_buf) {
572*4882a593Smuzhiyun usb_buf[i+n] = audio_buf[cdev->audio_out_buf_pos[stream]++];
573*4882a593Smuzhiyun
574*4882a593Smuzhiyun if (cdev->audio_out_buf_pos[stream] == sz)
575*4882a593Smuzhiyun cdev->audio_out_buf_pos[stream] = 0;
576*4882a593Smuzhiyun } else {
577*4882a593Smuzhiyun usb_buf[i+n] = 0;
578*4882a593Smuzhiyun }
579*4882a593Smuzhiyun }
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun if (audio_buf)
582*4882a593Smuzhiyun cdev->period_out_count[stream] += BYTES_PER_SAMPLE;
583*4882a593Smuzhiyun
584*4882a593Smuzhiyun i += BYTES_PER_SAMPLE;
585*4882a593Smuzhiyun
586*4882a593Smuzhiyun /* fill in the check byte pattern */
587*4882a593Smuzhiyun usb_buf[i++] = (stream << 1) | c;
588*4882a593Smuzhiyun }
589*4882a593Smuzhiyun }
590*4882a593Smuzhiyun }
591*4882a593Smuzhiyun }
592*4882a593Smuzhiyun
fill_out_urb(struct snd_usb_caiaqdev * cdev,struct urb * urb,const struct usb_iso_packet_descriptor * iso)593*4882a593Smuzhiyun static inline void fill_out_urb(struct snd_usb_caiaqdev *cdev,
594*4882a593Smuzhiyun struct urb *urb,
595*4882a593Smuzhiyun const struct usb_iso_packet_descriptor *iso)
596*4882a593Smuzhiyun {
597*4882a593Smuzhiyun switch (cdev->spec.data_alignment) {
598*4882a593Smuzhiyun case 0:
599*4882a593Smuzhiyun case 2:
600*4882a593Smuzhiyun fill_out_urb_mode_0(cdev, urb, iso);
601*4882a593Smuzhiyun break;
602*4882a593Smuzhiyun case 3:
603*4882a593Smuzhiyun fill_out_urb_mode_3(cdev, urb, iso);
604*4882a593Smuzhiyun break;
605*4882a593Smuzhiyun }
606*4882a593Smuzhiyun }
607*4882a593Smuzhiyun
read_completed(struct urb * urb)608*4882a593Smuzhiyun static void read_completed(struct urb *urb)
609*4882a593Smuzhiyun {
610*4882a593Smuzhiyun struct snd_usb_caiaq_cb_info *info = urb->context;
611*4882a593Smuzhiyun struct snd_usb_caiaqdev *cdev;
612*4882a593Smuzhiyun struct device *dev;
613*4882a593Smuzhiyun struct urb *out = NULL;
614*4882a593Smuzhiyun int i, frame, len, send_it = 0, outframe = 0;
615*4882a593Smuzhiyun unsigned long flags;
616*4882a593Smuzhiyun size_t offset = 0;
617*4882a593Smuzhiyun
618*4882a593Smuzhiyun if (urb->status || !info)
619*4882a593Smuzhiyun return;
620*4882a593Smuzhiyun
621*4882a593Smuzhiyun cdev = info->cdev;
622*4882a593Smuzhiyun dev = caiaqdev_to_dev(cdev);
623*4882a593Smuzhiyun
624*4882a593Smuzhiyun if (!cdev->streaming)
625*4882a593Smuzhiyun return;
626*4882a593Smuzhiyun
627*4882a593Smuzhiyun /* find an unused output urb that is unused */
628*4882a593Smuzhiyun for (i = 0; i < N_URBS; i++)
629*4882a593Smuzhiyun if (test_and_set_bit(i, &cdev->outurb_active_mask) == 0) {
630*4882a593Smuzhiyun out = cdev->data_urbs_out[i];
631*4882a593Smuzhiyun break;
632*4882a593Smuzhiyun }
633*4882a593Smuzhiyun
634*4882a593Smuzhiyun if (!out) {
635*4882a593Smuzhiyun dev_err(dev, "Unable to find an output urb to use\n");
636*4882a593Smuzhiyun goto requeue;
637*4882a593Smuzhiyun }
638*4882a593Smuzhiyun
639*4882a593Smuzhiyun /* read the recently received packet and send back one which has
640*4882a593Smuzhiyun * the same layout */
641*4882a593Smuzhiyun for (frame = 0; frame < FRAMES_PER_URB; frame++) {
642*4882a593Smuzhiyun if (urb->iso_frame_desc[frame].status)
643*4882a593Smuzhiyun continue;
644*4882a593Smuzhiyun
645*4882a593Smuzhiyun len = urb->iso_frame_desc[outframe].actual_length;
646*4882a593Smuzhiyun out->iso_frame_desc[outframe].length = len;
647*4882a593Smuzhiyun out->iso_frame_desc[outframe].actual_length = 0;
648*4882a593Smuzhiyun out->iso_frame_desc[outframe].offset = offset;
649*4882a593Smuzhiyun offset += len;
650*4882a593Smuzhiyun
651*4882a593Smuzhiyun if (len > 0) {
652*4882a593Smuzhiyun spin_lock_irqsave(&cdev->spinlock, flags);
653*4882a593Smuzhiyun fill_out_urb(cdev, out, &out->iso_frame_desc[outframe]);
654*4882a593Smuzhiyun read_in_urb(cdev, urb, &urb->iso_frame_desc[frame]);
655*4882a593Smuzhiyun spin_unlock_irqrestore(&cdev->spinlock, flags);
656*4882a593Smuzhiyun check_for_elapsed_periods(cdev, cdev->sub_playback);
657*4882a593Smuzhiyun check_for_elapsed_periods(cdev, cdev->sub_capture);
658*4882a593Smuzhiyun send_it = 1;
659*4882a593Smuzhiyun }
660*4882a593Smuzhiyun
661*4882a593Smuzhiyun outframe++;
662*4882a593Smuzhiyun }
663*4882a593Smuzhiyun
664*4882a593Smuzhiyun if (send_it) {
665*4882a593Smuzhiyun out->number_of_packets = outframe;
666*4882a593Smuzhiyun usb_submit_urb(out, GFP_ATOMIC);
667*4882a593Smuzhiyun } else {
668*4882a593Smuzhiyun struct snd_usb_caiaq_cb_info *oinfo = out->context;
669*4882a593Smuzhiyun clear_bit(oinfo->index, &cdev->outurb_active_mask);
670*4882a593Smuzhiyun }
671*4882a593Smuzhiyun
672*4882a593Smuzhiyun requeue:
673*4882a593Smuzhiyun /* re-submit inbound urb */
674*4882a593Smuzhiyun for (frame = 0; frame < FRAMES_PER_URB; frame++) {
675*4882a593Smuzhiyun urb->iso_frame_desc[frame].offset = BYTES_PER_FRAME * frame;
676*4882a593Smuzhiyun urb->iso_frame_desc[frame].length = BYTES_PER_FRAME;
677*4882a593Smuzhiyun urb->iso_frame_desc[frame].actual_length = 0;
678*4882a593Smuzhiyun }
679*4882a593Smuzhiyun
680*4882a593Smuzhiyun urb->number_of_packets = FRAMES_PER_URB;
681*4882a593Smuzhiyun usb_submit_urb(urb, GFP_ATOMIC);
682*4882a593Smuzhiyun }
683*4882a593Smuzhiyun
write_completed(struct urb * urb)684*4882a593Smuzhiyun static void write_completed(struct urb *urb)
685*4882a593Smuzhiyun {
686*4882a593Smuzhiyun struct snd_usb_caiaq_cb_info *info = urb->context;
687*4882a593Smuzhiyun struct snd_usb_caiaqdev *cdev = info->cdev;
688*4882a593Smuzhiyun
689*4882a593Smuzhiyun if (!cdev->output_running) {
690*4882a593Smuzhiyun cdev->output_running = 1;
691*4882a593Smuzhiyun wake_up(&cdev->prepare_wait_queue);
692*4882a593Smuzhiyun }
693*4882a593Smuzhiyun
694*4882a593Smuzhiyun clear_bit(info->index, &cdev->outurb_active_mask);
695*4882a593Smuzhiyun }
696*4882a593Smuzhiyun
alloc_urbs(struct snd_usb_caiaqdev * cdev,int dir,int * ret)697*4882a593Smuzhiyun static struct urb **alloc_urbs(struct snd_usb_caiaqdev *cdev, int dir, int *ret)
698*4882a593Smuzhiyun {
699*4882a593Smuzhiyun int i, frame;
700*4882a593Smuzhiyun struct urb **urbs;
701*4882a593Smuzhiyun struct usb_device *usb_dev = cdev->chip.dev;
702*4882a593Smuzhiyun unsigned int pipe;
703*4882a593Smuzhiyun
704*4882a593Smuzhiyun pipe = (dir == SNDRV_PCM_STREAM_PLAYBACK) ?
705*4882a593Smuzhiyun usb_sndisocpipe(usb_dev, ENDPOINT_PLAYBACK) :
706*4882a593Smuzhiyun usb_rcvisocpipe(usb_dev, ENDPOINT_CAPTURE);
707*4882a593Smuzhiyun
708*4882a593Smuzhiyun urbs = kmalloc_array(N_URBS, sizeof(*urbs), GFP_KERNEL);
709*4882a593Smuzhiyun if (!urbs) {
710*4882a593Smuzhiyun *ret = -ENOMEM;
711*4882a593Smuzhiyun return NULL;
712*4882a593Smuzhiyun }
713*4882a593Smuzhiyun
714*4882a593Smuzhiyun for (i = 0; i < N_URBS; i++) {
715*4882a593Smuzhiyun urbs[i] = usb_alloc_urb(FRAMES_PER_URB, GFP_KERNEL);
716*4882a593Smuzhiyun if (!urbs[i]) {
717*4882a593Smuzhiyun *ret = -ENOMEM;
718*4882a593Smuzhiyun return urbs;
719*4882a593Smuzhiyun }
720*4882a593Smuzhiyun
721*4882a593Smuzhiyun urbs[i]->transfer_buffer =
722*4882a593Smuzhiyun kmalloc_array(BYTES_PER_FRAME, FRAMES_PER_URB,
723*4882a593Smuzhiyun GFP_KERNEL);
724*4882a593Smuzhiyun if (!urbs[i]->transfer_buffer) {
725*4882a593Smuzhiyun *ret = -ENOMEM;
726*4882a593Smuzhiyun return urbs;
727*4882a593Smuzhiyun }
728*4882a593Smuzhiyun
729*4882a593Smuzhiyun for (frame = 0; frame < FRAMES_PER_URB; frame++) {
730*4882a593Smuzhiyun struct usb_iso_packet_descriptor *iso =
731*4882a593Smuzhiyun &urbs[i]->iso_frame_desc[frame];
732*4882a593Smuzhiyun
733*4882a593Smuzhiyun iso->offset = BYTES_PER_FRAME * frame;
734*4882a593Smuzhiyun iso->length = BYTES_PER_FRAME;
735*4882a593Smuzhiyun }
736*4882a593Smuzhiyun
737*4882a593Smuzhiyun urbs[i]->dev = usb_dev;
738*4882a593Smuzhiyun urbs[i]->pipe = pipe;
739*4882a593Smuzhiyun urbs[i]->transfer_buffer_length = FRAMES_PER_URB
740*4882a593Smuzhiyun * BYTES_PER_FRAME;
741*4882a593Smuzhiyun urbs[i]->context = &cdev->data_cb_info[i];
742*4882a593Smuzhiyun urbs[i]->interval = 1;
743*4882a593Smuzhiyun urbs[i]->number_of_packets = FRAMES_PER_URB;
744*4882a593Smuzhiyun urbs[i]->complete = (dir == SNDRV_PCM_STREAM_CAPTURE) ?
745*4882a593Smuzhiyun read_completed : write_completed;
746*4882a593Smuzhiyun }
747*4882a593Smuzhiyun
748*4882a593Smuzhiyun *ret = 0;
749*4882a593Smuzhiyun return urbs;
750*4882a593Smuzhiyun }
751*4882a593Smuzhiyun
free_urbs(struct urb ** urbs)752*4882a593Smuzhiyun static void free_urbs(struct urb **urbs)
753*4882a593Smuzhiyun {
754*4882a593Smuzhiyun int i;
755*4882a593Smuzhiyun
756*4882a593Smuzhiyun if (!urbs)
757*4882a593Smuzhiyun return;
758*4882a593Smuzhiyun
759*4882a593Smuzhiyun for (i = 0; i < N_URBS; i++) {
760*4882a593Smuzhiyun if (!urbs[i])
761*4882a593Smuzhiyun continue;
762*4882a593Smuzhiyun
763*4882a593Smuzhiyun usb_kill_urb(urbs[i]);
764*4882a593Smuzhiyun kfree(urbs[i]->transfer_buffer);
765*4882a593Smuzhiyun usb_free_urb(urbs[i]);
766*4882a593Smuzhiyun }
767*4882a593Smuzhiyun
768*4882a593Smuzhiyun kfree(urbs);
769*4882a593Smuzhiyun }
770*4882a593Smuzhiyun
snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev * cdev)771*4882a593Smuzhiyun int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *cdev)
772*4882a593Smuzhiyun {
773*4882a593Smuzhiyun int i, ret;
774*4882a593Smuzhiyun struct device *dev = caiaqdev_to_dev(cdev);
775*4882a593Smuzhiyun
776*4882a593Smuzhiyun cdev->n_audio_in = max(cdev->spec.num_analog_audio_in,
777*4882a593Smuzhiyun cdev->spec.num_digital_audio_in) /
778*4882a593Smuzhiyun CHANNELS_PER_STREAM;
779*4882a593Smuzhiyun cdev->n_audio_out = max(cdev->spec.num_analog_audio_out,
780*4882a593Smuzhiyun cdev->spec.num_digital_audio_out) /
781*4882a593Smuzhiyun CHANNELS_PER_STREAM;
782*4882a593Smuzhiyun cdev->n_streams = max(cdev->n_audio_in, cdev->n_audio_out);
783*4882a593Smuzhiyun
784*4882a593Smuzhiyun dev_dbg(dev, "cdev->n_audio_in = %d\n", cdev->n_audio_in);
785*4882a593Smuzhiyun dev_dbg(dev, "cdev->n_audio_out = %d\n", cdev->n_audio_out);
786*4882a593Smuzhiyun dev_dbg(dev, "cdev->n_streams = %d\n", cdev->n_streams);
787*4882a593Smuzhiyun
788*4882a593Smuzhiyun if (cdev->n_streams > MAX_STREAMS) {
789*4882a593Smuzhiyun dev_err(dev, "unable to initialize device, too many streams.\n");
790*4882a593Smuzhiyun return -EINVAL;
791*4882a593Smuzhiyun }
792*4882a593Smuzhiyun
793*4882a593Smuzhiyun if (cdev->n_streams < 1) {
794*4882a593Smuzhiyun dev_err(dev, "bogus number of streams: %d\n", cdev->n_streams);
795*4882a593Smuzhiyun return -EINVAL;
796*4882a593Smuzhiyun }
797*4882a593Smuzhiyun
798*4882a593Smuzhiyun ret = snd_pcm_new(cdev->chip.card, cdev->product_name, 0,
799*4882a593Smuzhiyun cdev->n_audio_out, cdev->n_audio_in, &cdev->pcm);
800*4882a593Smuzhiyun
801*4882a593Smuzhiyun if (ret < 0) {
802*4882a593Smuzhiyun dev_err(dev, "snd_pcm_new() returned %d\n", ret);
803*4882a593Smuzhiyun return ret;
804*4882a593Smuzhiyun }
805*4882a593Smuzhiyun
806*4882a593Smuzhiyun cdev->pcm->private_data = cdev;
807*4882a593Smuzhiyun strlcpy(cdev->pcm->name, cdev->product_name, sizeof(cdev->pcm->name));
808*4882a593Smuzhiyun
809*4882a593Smuzhiyun memset(cdev->sub_playback, 0, sizeof(cdev->sub_playback));
810*4882a593Smuzhiyun memset(cdev->sub_capture, 0, sizeof(cdev->sub_capture));
811*4882a593Smuzhiyun
812*4882a593Smuzhiyun memcpy(&cdev->pcm_info, &snd_usb_caiaq_pcm_hardware,
813*4882a593Smuzhiyun sizeof(snd_usb_caiaq_pcm_hardware));
814*4882a593Smuzhiyun
815*4882a593Smuzhiyun /* setup samplerates */
816*4882a593Smuzhiyun cdev->samplerates = cdev->pcm_info.rates;
817*4882a593Smuzhiyun switch (cdev->chip.usb_id) {
818*4882a593Smuzhiyun case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
819*4882a593Smuzhiyun case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
820*4882a593Smuzhiyun case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_SESSIONIO):
821*4882a593Smuzhiyun case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_GUITARRIGMOBILE):
822*4882a593Smuzhiyun cdev->samplerates |= SNDRV_PCM_RATE_192000;
823*4882a593Smuzhiyun fallthrough;
824*4882a593Smuzhiyun case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO2DJ):
825*4882a593Smuzhiyun case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ):
826*4882a593Smuzhiyun case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
827*4882a593Smuzhiyun case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORAUDIO2):
828*4882a593Smuzhiyun cdev->samplerates |= SNDRV_PCM_RATE_88200;
829*4882a593Smuzhiyun break;
830*4882a593Smuzhiyun }
831*4882a593Smuzhiyun
832*4882a593Smuzhiyun snd_pcm_set_ops(cdev->pcm, SNDRV_PCM_STREAM_PLAYBACK,
833*4882a593Smuzhiyun &snd_usb_caiaq_ops);
834*4882a593Smuzhiyun snd_pcm_set_ops(cdev->pcm, SNDRV_PCM_STREAM_CAPTURE,
835*4882a593Smuzhiyun &snd_usb_caiaq_ops);
836*4882a593Smuzhiyun snd_pcm_set_managed_buffer_all(cdev->pcm, SNDRV_DMA_TYPE_VMALLOC,
837*4882a593Smuzhiyun NULL, 0, 0);
838*4882a593Smuzhiyun
839*4882a593Smuzhiyun cdev->data_cb_info =
840*4882a593Smuzhiyun kmalloc_array(N_URBS, sizeof(struct snd_usb_caiaq_cb_info),
841*4882a593Smuzhiyun GFP_KERNEL);
842*4882a593Smuzhiyun
843*4882a593Smuzhiyun if (!cdev->data_cb_info)
844*4882a593Smuzhiyun return -ENOMEM;
845*4882a593Smuzhiyun
846*4882a593Smuzhiyun cdev->outurb_active_mask = 0;
847*4882a593Smuzhiyun BUILD_BUG_ON(N_URBS > (sizeof(cdev->outurb_active_mask) * 8));
848*4882a593Smuzhiyun
849*4882a593Smuzhiyun for (i = 0; i < N_URBS; i++) {
850*4882a593Smuzhiyun cdev->data_cb_info[i].cdev = cdev;
851*4882a593Smuzhiyun cdev->data_cb_info[i].index = i;
852*4882a593Smuzhiyun }
853*4882a593Smuzhiyun
854*4882a593Smuzhiyun cdev->data_urbs_in = alloc_urbs(cdev, SNDRV_PCM_STREAM_CAPTURE, &ret);
855*4882a593Smuzhiyun if (ret < 0) {
856*4882a593Smuzhiyun kfree(cdev->data_cb_info);
857*4882a593Smuzhiyun free_urbs(cdev->data_urbs_in);
858*4882a593Smuzhiyun return ret;
859*4882a593Smuzhiyun }
860*4882a593Smuzhiyun
861*4882a593Smuzhiyun cdev->data_urbs_out = alloc_urbs(cdev, SNDRV_PCM_STREAM_PLAYBACK, &ret);
862*4882a593Smuzhiyun if (ret < 0) {
863*4882a593Smuzhiyun kfree(cdev->data_cb_info);
864*4882a593Smuzhiyun free_urbs(cdev->data_urbs_in);
865*4882a593Smuzhiyun free_urbs(cdev->data_urbs_out);
866*4882a593Smuzhiyun return ret;
867*4882a593Smuzhiyun }
868*4882a593Smuzhiyun
869*4882a593Smuzhiyun return 0;
870*4882a593Smuzhiyun }
871*4882a593Smuzhiyun
snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev * cdev)872*4882a593Smuzhiyun void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *cdev)
873*4882a593Smuzhiyun {
874*4882a593Smuzhiyun struct device *dev = caiaqdev_to_dev(cdev);
875*4882a593Smuzhiyun
876*4882a593Smuzhiyun dev_dbg(dev, "%s(%p)\n", __func__, cdev);
877*4882a593Smuzhiyun stream_stop(cdev);
878*4882a593Smuzhiyun free_urbs(cdev->data_urbs_in);
879*4882a593Smuzhiyun free_urbs(cdev->data_urbs_out);
880*4882a593Smuzhiyun kfree(cdev->data_cb_info);
881*4882a593Smuzhiyun }
882*4882a593Smuzhiyun
883