1 // SPDX-License-Identifier: GPL-2.0-only
3 * oxfw_pcm.c - a part of driver for OXFW970/971 based devices
5 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
10 static int hw_rule_rate(struct snd_pcm_hw_params
*params
,
11 struct snd_pcm_hw_rule
*rule
)
13 u8
**formats
= rule
->private;
14 struct snd_interval
*r
=
15 hw_param_interval(params
, SNDRV_PCM_HW_PARAM_RATE
);
16 const struct snd_interval
*c
=
17 hw_param_interval_c(params
, SNDRV_PCM_HW_PARAM_CHANNELS
);
18 struct snd_interval t
= {
19 .min
= UINT_MAX
, .max
= 0, .integer
= 1
21 struct snd_oxfw_stream_formation formation
;
24 for (i
= 0; i
< SND_OXFW_STREAM_FORMAT_ENTRIES
; i
++) {
25 if (formats
[i
] == NULL
)
28 err
= snd_oxfw_stream_parse_format(formats
[i
], &formation
);
31 if (!snd_interval_test(c
, formation
.pcm
))
34 t
.min
= min(t
.min
, formation
.rate
);
35 t
.max
= max(t
.max
, formation
.rate
);
38 return snd_interval_refine(r
, &t
);
41 static int hw_rule_channels(struct snd_pcm_hw_params
*params
,
42 struct snd_pcm_hw_rule
*rule
)
44 u8
**formats
= rule
->private;
45 struct snd_interval
*c
=
46 hw_param_interval(params
, SNDRV_PCM_HW_PARAM_CHANNELS
);
47 const struct snd_interval
*r
=
48 hw_param_interval_c(params
, SNDRV_PCM_HW_PARAM_RATE
);
49 struct snd_oxfw_stream_formation formation
;
51 unsigned int count
, list
[SND_OXFW_STREAM_FORMAT_ENTRIES
] = {0};
54 for (i
= 0; i
< SND_OXFW_STREAM_FORMAT_ENTRIES
; i
++) {
55 if (formats
[i
] == NULL
)
58 err
= snd_oxfw_stream_parse_format(formats
[i
], &formation
);
61 if (!snd_interval_test(r
, formation
.rate
))
63 if (list
[count
] == formation
.pcm
)
66 for (j
= 0; j
< ARRAY_SIZE(list
); j
++) {
67 if (list
[j
] == formation
.pcm
)
70 if (j
== ARRAY_SIZE(list
)) {
71 list
[count
] = formation
.pcm
;
72 if (++count
== ARRAY_SIZE(list
))
77 return snd_interval_list(c
, count
, list
, 0);
80 static void limit_channels_and_rates(struct snd_pcm_hardware
*hw
, u8
**formats
)
82 struct snd_oxfw_stream_formation formation
;
85 hw
->channels_min
= UINT_MAX
;
88 hw
->rate_min
= UINT_MAX
;
92 for (i
= 0; i
< SND_OXFW_STREAM_FORMAT_ENTRIES
; i
++) {
93 if (formats
[i
] == NULL
)
96 err
= snd_oxfw_stream_parse_format(formats
[i
], &formation
);
100 hw
->channels_min
= min(hw
->channels_min
, formation
.pcm
);
101 hw
->channels_max
= max(hw
->channels_max
, formation
.pcm
);
103 hw
->rate_min
= min(hw
->rate_min
, formation
.rate
);
104 hw
->rate_max
= max(hw
->rate_max
, formation
.rate
);
105 hw
->rates
|= snd_pcm_rate_to_rate_bit(formation
.rate
);
109 static int init_hw_params(struct snd_oxfw
*oxfw
,
110 struct snd_pcm_substream
*substream
)
112 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
114 struct amdtp_stream
*stream
;
117 if (substream
->stream
== SNDRV_PCM_STREAM_CAPTURE
) {
118 runtime
->hw
.formats
= AM824_IN_PCM_FORMAT_BITS
;
119 stream
= &oxfw
->tx_stream
;
120 formats
= oxfw
->tx_stream_formats
;
122 runtime
->hw
.formats
= AM824_OUT_PCM_FORMAT_BITS
;
123 stream
= &oxfw
->rx_stream
;
124 formats
= oxfw
->rx_stream_formats
;
127 limit_channels_and_rates(&runtime
->hw
, formats
);
129 err
= snd_pcm_hw_rule_add(runtime
, 0, SNDRV_PCM_HW_PARAM_CHANNELS
,
130 hw_rule_channels
, formats
,
131 SNDRV_PCM_HW_PARAM_RATE
, -1);
135 err
= snd_pcm_hw_rule_add(runtime
, 0, SNDRV_PCM_HW_PARAM_RATE
,
136 hw_rule_rate
, formats
,
137 SNDRV_PCM_HW_PARAM_CHANNELS
, -1);
141 err
= amdtp_am824_add_pcm_hw_constraints(stream
, runtime
);
146 static int limit_to_current_params(struct snd_pcm_substream
*substream
)
148 struct snd_oxfw
*oxfw
= substream
->private_data
;
149 struct snd_oxfw_stream_formation formation
;
150 enum avc_general_plug_dir dir
;
153 if (substream
->stream
== SNDRV_PCM_STREAM_CAPTURE
)
154 dir
= AVC_GENERAL_PLUG_DIR_OUT
;
156 dir
= AVC_GENERAL_PLUG_DIR_IN
;
158 err
= snd_oxfw_stream_get_current_formation(oxfw
, dir
, &formation
);
162 substream
->runtime
->hw
.channels_min
= formation
.pcm
;
163 substream
->runtime
->hw
.channels_max
= formation
.pcm
;
164 substream
->runtime
->hw
.rate_min
= formation
.rate
;
165 substream
->runtime
->hw
.rate_max
= formation
.rate
;
170 static int pcm_open(struct snd_pcm_substream
*substream
)
172 struct snd_oxfw
*oxfw
= substream
->private_data
;
173 struct amdtp_domain
*d
= &oxfw
->domain
;
176 err
= snd_oxfw_stream_lock_try(oxfw
);
180 err
= init_hw_params(oxfw
, substream
);
184 mutex_lock(&oxfw
->mutex
);
186 // When source of clock is not internal or any stream is reserved for
187 // transmission of PCM frames, the available sampling rate is limited
189 if (oxfw
->substreams_count
> 0 && d
->events_per_period
> 0) {
190 unsigned int frames_per_period
= d
->events_per_period
;
191 unsigned int frames_per_buffer
= d
->events_per_buffer
;
193 err
= limit_to_current_params(substream
);
195 mutex_unlock(&oxfw
->mutex
);
199 if (frames_per_period
> 0) {
200 err
= snd_pcm_hw_constraint_minmax(substream
->runtime
,
201 SNDRV_PCM_HW_PARAM_PERIOD_SIZE
,
202 frames_per_period
, frames_per_period
);
204 mutex_unlock(&oxfw
->mutex
);
208 err
= snd_pcm_hw_constraint_minmax(substream
->runtime
,
209 SNDRV_PCM_HW_PARAM_BUFFER_SIZE
,
210 frames_per_buffer
, frames_per_buffer
);
212 mutex_unlock(&oxfw
->mutex
);
218 mutex_unlock(&oxfw
->mutex
);
220 snd_pcm_set_sync(substream
);
224 snd_oxfw_stream_lock_release(oxfw
);
228 static int pcm_close(struct snd_pcm_substream
*substream
)
230 struct snd_oxfw
*oxfw
= substream
->private_data
;
232 snd_oxfw_stream_lock_release(oxfw
);
236 static int pcm_capture_hw_params(struct snd_pcm_substream
*substream
,
237 struct snd_pcm_hw_params
*hw_params
)
239 struct snd_oxfw
*oxfw
= substream
->private_data
;
242 err
= snd_pcm_lib_malloc_pages(substream
, params_buffer_bytes(hw_params
));
246 if (substream
->runtime
->status
->state
== SNDRV_PCM_STATE_OPEN
) {
247 unsigned int rate
= params_rate(hw_params
);
248 unsigned int channels
= params_channels(hw_params
);
249 unsigned int frames_per_period
= params_period_size(hw_params
);
250 unsigned int frames_per_buffer
= params_buffer_size(hw_params
);
252 mutex_lock(&oxfw
->mutex
);
253 err
= snd_oxfw_stream_reserve_duplex(oxfw
, &oxfw
->tx_stream
,
254 rate
, channels
, frames_per_period
,
257 ++oxfw
->substreams_count
;
258 mutex_unlock(&oxfw
->mutex
);
263 static int pcm_playback_hw_params(struct snd_pcm_substream
*substream
,
264 struct snd_pcm_hw_params
*hw_params
)
266 struct snd_oxfw
*oxfw
= substream
->private_data
;
269 err
= snd_pcm_lib_malloc_pages(substream
, params_buffer_bytes(hw_params
));
273 if (substream
->runtime
->status
->state
== SNDRV_PCM_STATE_OPEN
) {
274 unsigned int rate
= params_rate(hw_params
);
275 unsigned int channels
= params_channels(hw_params
);
276 unsigned int frames_per_period
= params_period_size(hw_params
);
277 unsigned int frames_per_buffer
= params_buffer_size(hw_params
);
279 mutex_lock(&oxfw
->mutex
);
280 err
= snd_oxfw_stream_reserve_duplex(oxfw
, &oxfw
->rx_stream
,
281 rate
, channels
, frames_per_period
,
284 ++oxfw
->substreams_count
;
285 mutex_unlock(&oxfw
->mutex
);
291 static int pcm_capture_hw_free(struct snd_pcm_substream
*substream
)
293 struct snd_oxfw
*oxfw
= substream
->private_data
;
295 mutex_lock(&oxfw
->mutex
);
297 if (substream
->runtime
->status
->state
!= SNDRV_PCM_STATE_OPEN
)
298 --oxfw
->substreams_count
;
300 snd_oxfw_stream_stop_duplex(oxfw
);
302 mutex_unlock(&oxfw
->mutex
);
304 return snd_pcm_lib_free_pages(substream
);
306 static int pcm_playback_hw_free(struct snd_pcm_substream
*substream
)
308 struct snd_oxfw
*oxfw
= substream
->private_data
;
310 mutex_lock(&oxfw
->mutex
);
312 if (substream
->runtime
->status
->state
!= SNDRV_PCM_STATE_OPEN
)
313 --oxfw
->substreams_count
;
315 snd_oxfw_stream_stop_duplex(oxfw
);
317 mutex_unlock(&oxfw
->mutex
);
319 return snd_pcm_lib_free_pages(substream
);
322 static int pcm_capture_prepare(struct snd_pcm_substream
*substream
)
324 struct snd_oxfw
*oxfw
= substream
->private_data
;
327 mutex_lock(&oxfw
->mutex
);
328 err
= snd_oxfw_stream_start_duplex(oxfw
);
329 mutex_unlock(&oxfw
->mutex
);
333 amdtp_stream_pcm_prepare(&oxfw
->tx_stream
);
337 static int pcm_playback_prepare(struct snd_pcm_substream
*substream
)
339 struct snd_oxfw
*oxfw
= substream
->private_data
;
342 mutex_lock(&oxfw
->mutex
);
343 err
= snd_oxfw_stream_start_duplex(oxfw
);
344 mutex_unlock(&oxfw
->mutex
);
348 amdtp_stream_pcm_prepare(&oxfw
->rx_stream
);
353 static int pcm_capture_trigger(struct snd_pcm_substream
*substream
, int cmd
)
355 struct snd_oxfw
*oxfw
= substream
->private_data
;
356 struct snd_pcm_substream
*pcm
;
359 case SNDRV_PCM_TRIGGER_START
:
362 case SNDRV_PCM_TRIGGER_STOP
:
368 amdtp_stream_pcm_trigger(&oxfw
->tx_stream
, pcm
);
371 static int pcm_playback_trigger(struct snd_pcm_substream
*substream
, int cmd
)
373 struct snd_oxfw
*oxfw
= substream
->private_data
;
374 struct snd_pcm_substream
*pcm
;
377 case SNDRV_PCM_TRIGGER_START
:
380 case SNDRV_PCM_TRIGGER_STOP
:
386 amdtp_stream_pcm_trigger(&oxfw
->rx_stream
, pcm
);
390 static snd_pcm_uframes_t
pcm_capture_pointer(struct snd_pcm_substream
*sbstm
)
392 struct snd_oxfw
*oxfw
= sbstm
->private_data
;
394 return amdtp_domain_stream_pcm_pointer(&oxfw
->domain
, &oxfw
->tx_stream
);
396 static snd_pcm_uframes_t
pcm_playback_pointer(struct snd_pcm_substream
*sbstm
)
398 struct snd_oxfw
*oxfw
= sbstm
->private_data
;
400 return amdtp_domain_stream_pcm_pointer(&oxfw
->domain
, &oxfw
->rx_stream
);
403 static int pcm_capture_ack(struct snd_pcm_substream
*substream
)
405 struct snd_oxfw
*oxfw
= substream
->private_data
;
407 return amdtp_domain_stream_pcm_ack(&oxfw
->domain
, &oxfw
->tx_stream
);
410 static int pcm_playback_ack(struct snd_pcm_substream
*substream
)
412 struct snd_oxfw
*oxfw
= substream
->private_data
;
414 return amdtp_domain_stream_pcm_ack(&oxfw
->domain
, &oxfw
->rx_stream
);
417 int snd_oxfw_create_pcm(struct snd_oxfw
*oxfw
)
419 static const struct snd_pcm_ops capture_ops
= {
422 .ioctl
= snd_pcm_lib_ioctl
,
423 .hw_params
= pcm_capture_hw_params
,
424 .hw_free
= pcm_capture_hw_free
,
425 .prepare
= pcm_capture_prepare
,
426 .trigger
= pcm_capture_trigger
,
427 .pointer
= pcm_capture_pointer
,
428 .ack
= pcm_capture_ack
,
430 static const struct snd_pcm_ops playback_ops
= {
433 .ioctl
= snd_pcm_lib_ioctl
,
434 .hw_params
= pcm_playback_hw_params
,
435 .hw_free
= pcm_playback_hw_free
,
436 .prepare
= pcm_playback_prepare
,
437 .trigger
= pcm_playback_trigger
,
438 .pointer
= pcm_playback_pointer
,
439 .ack
= pcm_playback_ack
,
442 unsigned int cap
= 0;
445 if (oxfw
->has_output
)
448 err
= snd_pcm_new(oxfw
->card
, oxfw
->card
->driver
, 0, 1, cap
, &pcm
);
452 pcm
->private_data
= oxfw
;
453 strcpy(pcm
->name
, oxfw
->card
->shortname
);
454 snd_pcm_set_ops(pcm
, SNDRV_PCM_STREAM_PLAYBACK
, &playback_ops
);
456 snd_pcm_set_ops(pcm
, SNDRV_PCM_STREAM_CAPTURE
, &capture_ops
);
457 snd_pcm_lib_preallocate_pages_for_all(pcm
, SNDRV_DMA_TYPE_VMALLOC
,