1 // SPDX-License-Identifier: GPL-2.0-only
3 * motu-pcm.c - a part of driver for MOTU FireWire series
5 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
8 #include <sound/pcm_params.h>
11 static int motu_rate_constraint(struct snd_pcm_hw_params
*params
,
12 struct snd_pcm_hw_rule
*rule
)
14 struct snd_motu_packet_format
*formats
= rule
->private;
16 const struct snd_interval
*c
=
17 hw_param_interval_c(params
, SNDRV_PCM_HW_PARAM_CHANNELS
);
18 struct snd_interval
*r
=
19 hw_param_interval(params
, SNDRV_PCM_HW_PARAM_RATE
);
20 struct snd_interval rates
= {
21 .min
= UINT_MAX
, .max
= 0, .integer
= 1
23 unsigned int i
, pcm_channels
, rate
, mode
;
25 for (i
= 0; i
< ARRAY_SIZE(snd_motu_clock_rates
); ++i
) {
26 rate
= snd_motu_clock_rates
[i
];
29 pcm_channels
= formats
->pcm_chunks
[mode
];
30 if (!snd_interval_test(c
, pcm_channels
))
33 rates
.min
= min(rates
.min
, rate
);
34 rates
.max
= max(rates
.max
, rate
);
37 return snd_interval_refine(r
, &rates
);
40 static int motu_channels_constraint(struct snd_pcm_hw_params
*params
,
41 struct snd_pcm_hw_rule
*rule
)
43 struct snd_motu_packet_format
*formats
= rule
->private;
45 const struct snd_interval
*r
=
46 hw_param_interval_c(params
, SNDRV_PCM_HW_PARAM_RATE
);
47 struct snd_interval
*c
=
48 hw_param_interval(params
, SNDRV_PCM_HW_PARAM_CHANNELS
);
49 struct snd_interval channels
= {
50 .min
= UINT_MAX
, .max
= 0, .integer
= 1
52 unsigned int i
, pcm_channels
, rate
, mode
;
54 for (i
= 0; i
< ARRAY_SIZE(snd_motu_clock_rates
); ++i
) {
55 rate
= snd_motu_clock_rates
[i
];
58 if (!snd_interval_test(r
, rate
))
61 pcm_channels
= formats
->pcm_chunks
[mode
];
62 channels
.min
= min(channels
.min
, pcm_channels
);
63 channels
.max
= max(channels
.max
, pcm_channels
);
66 return snd_interval_refine(c
, &channels
);
69 static void limit_channels_and_rates(struct snd_motu
*motu
,
70 struct snd_pcm_runtime
*runtime
,
71 struct snd_motu_packet_format
*formats
)
73 struct snd_pcm_hardware
*hw
= &runtime
->hw
;
74 unsigned int i
, pcm_channels
, rate
, mode
;
76 hw
->channels_min
= UINT_MAX
;
79 for (i
= 0; i
< ARRAY_SIZE(snd_motu_clock_rates
); ++i
) {
80 rate
= snd_motu_clock_rates
[i
];
83 pcm_channels
= formats
->pcm_chunks
[mode
];
84 if (pcm_channels
== 0)
87 hw
->rates
|= snd_pcm_rate_to_rate_bit(rate
);
88 hw
->channels_min
= min(hw
->channels_min
, pcm_channels
);
89 hw
->channels_max
= max(hw
->channels_max
, pcm_channels
);
92 snd_pcm_limit_hw_rates(runtime
);
95 static int init_hw_info(struct snd_motu
*motu
,
96 struct snd_pcm_substream
*substream
)
98 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
99 struct snd_pcm_hardware
*hw
= &runtime
->hw
;
100 struct amdtp_stream
*stream
;
101 struct snd_motu_packet_format
*formats
;
104 if (substream
->stream
== SNDRV_PCM_STREAM_CAPTURE
) {
105 hw
->formats
= SNDRV_PCM_FMTBIT_S32
;
106 stream
= &motu
->tx_stream
;
107 formats
= &motu
->tx_packet_formats
;
109 hw
->formats
= SNDRV_PCM_FMTBIT_S32
;
110 stream
= &motu
->rx_stream
;
111 formats
= &motu
->rx_packet_formats
;
114 limit_channels_and_rates(motu
, runtime
, formats
);
116 err
= snd_pcm_hw_rule_add(runtime
, 0, SNDRV_PCM_HW_PARAM_RATE
,
117 motu_rate_constraint
, formats
,
118 SNDRV_PCM_HW_PARAM_CHANNELS
, -1);
121 err
= snd_pcm_hw_rule_add(runtime
, 0, SNDRV_PCM_HW_PARAM_CHANNELS
,
122 motu_channels_constraint
, formats
,
123 SNDRV_PCM_HW_PARAM_RATE
, -1);
127 return amdtp_motu_add_pcm_hw_constraints(stream
, runtime
);
130 static int pcm_open(struct snd_pcm_substream
*substream
)
132 struct snd_motu
*motu
= substream
->private_data
;
133 struct amdtp_domain
*d
= &motu
->domain
;
134 enum snd_motu_clock_source src
;
137 err
= snd_motu_stream_lock_try(motu
);
141 mutex_lock(&motu
->mutex
);
143 err
= snd_motu_stream_cache_packet_formats(motu
);
147 err
= init_hw_info(motu
, substream
);
151 err
= snd_motu_protocol_get_clock_source(motu
, &src
);
155 // When source of clock is not internal or any stream is reserved for
156 // transmission of PCM frames, the available sampling rate is limited
158 if ((src
!= SND_MOTU_CLOCK_SOURCE_INTERNAL
&&
159 src
!= SND_MOTU_CLOCK_SOURCE_SPH
) ||
160 (motu
->substreams_counter
> 0 && d
->events_per_period
> 0)) {
161 unsigned int frames_per_period
= d
->events_per_period
;
162 unsigned int frames_per_buffer
= d
->events_per_buffer
;
165 err
= snd_motu_protocol_get_clock_rate(motu
, &rate
);
169 substream
->runtime
->hw
.rate_min
= rate
;
170 substream
->runtime
->hw
.rate_max
= rate
;
172 if (frames_per_period
> 0) {
173 err
= snd_pcm_hw_constraint_minmax(substream
->runtime
,
174 SNDRV_PCM_HW_PARAM_PERIOD_SIZE
,
175 frames_per_period
, frames_per_period
);
179 err
= snd_pcm_hw_constraint_minmax(substream
->runtime
,
180 SNDRV_PCM_HW_PARAM_BUFFER_SIZE
,
181 frames_per_buffer
, frames_per_buffer
);
187 snd_pcm_set_sync(substream
);
189 mutex_unlock(&motu
->mutex
);
193 mutex_unlock(&motu
->mutex
);
194 snd_motu_stream_lock_release(motu
);
198 static int pcm_close(struct snd_pcm_substream
*substream
)
200 struct snd_motu
*motu
= substream
->private_data
;
202 snd_motu_stream_lock_release(motu
);
207 static int pcm_hw_params(struct snd_pcm_substream
*substream
,
208 struct snd_pcm_hw_params
*hw_params
)
210 struct snd_motu
*motu
= substream
->private_data
;
213 if (substream
->runtime
->status
->state
== SNDRV_PCM_STATE_OPEN
) {
214 unsigned int rate
= params_rate(hw_params
);
215 unsigned int frames_per_period
= params_period_size(hw_params
);
216 unsigned int frames_per_buffer
= params_buffer_size(hw_params
);
218 mutex_lock(&motu
->mutex
);
219 err
= snd_motu_stream_reserve_duplex(motu
, rate
,
220 frames_per_period
, frames_per_buffer
);
222 ++motu
->substreams_counter
;
223 mutex_unlock(&motu
->mutex
);
229 static int pcm_hw_free(struct snd_pcm_substream
*substream
)
231 struct snd_motu
*motu
= substream
->private_data
;
233 mutex_lock(&motu
->mutex
);
235 if (substream
->runtime
->status
->state
!= SNDRV_PCM_STATE_OPEN
)
236 --motu
->substreams_counter
;
238 snd_motu_stream_stop_duplex(motu
);
240 mutex_unlock(&motu
->mutex
);
245 static int capture_prepare(struct snd_pcm_substream
*substream
)
247 struct snd_motu
*motu
= substream
->private_data
;
250 mutex_lock(&motu
->mutex
);
251 err
= snd_motu_stream_start_duplex(motu
);
252 mutex_unlock(&motu
->mutex
);
254 amdtp_stream_pcm_prepare(&motu
->tx_stream
);
258 static int playback_prepare(struct snd_pcm_substream
*substream
)
260 struct snd_motu
*motu
= substream
->private_data
;
263 mutex_lock(&motu
->mutex
);
264 err
= snd_motu_stream_start_duplex(motu
);
265 mutex_unlock(&motu
->mutex
);
267 amdtp_stream_pcm_prepare(&motu
->rx_stream
);
272 static int capture_trigger(struct snd_pcm_substream
*substream
, int cmd
)
274 struct snd_motu
*motu
= substream
->private_data
;
277 case SNDRV_PCM_TRIGGER_START
:
278 amdtp_stream_pcm_trigger(&motu
->tx_stream
, substream
);
280 case SNDRV_PCM_TRIGGER_STOP
:
281 amdtp_stream_pcm_trigger(&motu
->tx_stream
, NULL
);
289 static int playback_trigger(struct snd_pcm_substream
*substream
, int cmd
)
291 struct snd_motu
*motu
= substream
->private_data
;
294 case SNDRV_PCM_TRIGGER_START
:
295 amdtp_stream_pcm_trigger(&motu
->rx_stream
, substream
);
297 case SNDRV_PCM_TRIGGER_STOP
:
298 amdtp_stream_pcm_trigger(&motu
->rx_stream
, NULL
);
307 static snd_pcm_uframes_t
capture_pointer(struct snd_pcm_substream
*substream
)
309 struct snd_motu
*motu
= substream
->private_data
;
311 return amdtp_domain_stream_pcm_pointer(&motu
->domain
, &motu
->tx_stream
);
313 static snd_pcm_uframes_t
playback_pointer(struct snd_pcm_substream
*substream
)
315 struct snd_motu
*motu
= substream
->private_data
;
317 return amdtp_domain_stream_pcm_pointer(&motu
->domain
, &motu
->rx_stream
);
320 static int capture_ack(struct snd_pcm_substream
*substream
)
322 struct snd_motu
*motu
= substream
->private_data
;
324 return amdtp_domain_stream_pcm_ack(&motu
->domain
, &motu
->tx_stream
);
327 static int playback_ack(struct snd_pcm_substream
*substream
)
329 struct snd_motu
*motu
= substream
->private_data
;
331 return amdtp_domain_stream_pcm_ack(&motu
->domain
, &motu
->rx_stream
);
334 int snd_motu_create_pcm_devices(struct snd_motu
*motu
)
336 static const struct snd_pcm_ops capture_ops
= {
339 .hw_params
= pcm_hw_params
,
340 .hw_free
= pcm_hw_free
,
341 .prepare
= capture_prepare
,
342 .trigger
= capture_trigger
,
343 .pointer
= capture_pointer
,
346 static const struct snd_pcm_ops playback_ops
= {
349 .hw_params
= pcm_hw_params
,
350 .hw_free
= pcm_hw_free
,
351 .prepare
= playback_prepare
,
352 .trigger
= playback_trigger
,
353 .pointer
= playback_pointer
,
359 err
= snd_pcm_new(motu
->card
, motu
->card
->driver
, 0, 1, 1, &pcm
);
362 pcm
->private_data
= motu
;
363 strcpy(pcm
->name
, motu
->card
->shortname
);
365 snd_pcm_set_ops(pcm
, SNDRV_PCM_STREAM_CAPTURE
, &capture_ops
);
366 snd_pcm_set_ops(pcm
, SNDRV_PCM_STREAM_PLAYBACK
, &playback_ops
);
367 snd_pcm_set_managed_buffer_all(pcm
, SNDRV_DMA_TYPE_VMALLOC
, NULL
, 0, 0);