2 * ff-pcm.c - a part of driver for RME Fireface series
4 * Copyright (c) 2015-2017 Takashi Sakamoto
6 * Licensed under the terms of the GNU General Public License, version 2.
11 static int hw_rule_rate(struct snd_pcm_hw_params
*params
,
12 struct snd_pcm_hw_rule
*rule
)
14 const unsigned int *pcm_channels
= rule
->private;
15 struct snd_interval
*r
=
16 hw_param_interval(params
, SNDRV_PCM_HW_PARAM_RATE
);
17 const struct snd_interval
*c
=
18 hw_param_interval_c(params
, SNDRV_PCM_HW_PARAM_CHANNELS
);
19 struct snd_interval t
= {
20 .min
= UINT_MAX
, .max
= 0, .integer
= 1
24 for (i
= 0; i
< ARRAY_SIZE(amdtp_rate_table
); i
++) {
25 enum snd_ff_stream_mode mode
;
28 err
= snd_ff_stream_get_multiplier_mode(i
, &mode
);
32 if (!snd_interval_test(c
, pcm_channels
[mode
]))
35 t
.min
= min(t
.min
, amdtp_rate_table
[i
]);
36 t
.max
= max(t
.max
, amdtp_rate_table
[i
]);
39 return snd_interval_refine(r
, &t
);
42 static int hw_rule_channels(struct snd_pcm_hw_params
*params
,
43 struct snd_pcm_hw_rule
*rule
)
45 const unsigned int *pcm_channels
= rule
->private;
46 struct snd_interval
*c
=
47 hw_param_interval(params
, SNDRV_PCM_HW_PARAM_CHANNELS
);
48 const struct snd_interval
*r
=
49 hw_param_interval_c(params
, SNDRV_PCM_HW_PARAM_RATE
);
50 struct snd_interval t
= {
51 .min
= UINT_MAX
, .max
= 0, .integer
= 1
55 for (i
= 0; i
< ARRAY_SIZE(amdtp_rate_table
); i
++) {
56 enum snd_ff_stream_mode mode
;
59 err
= snd_ff_stream_get_multiplier_mode(i
, &mode
);
63 if (!snd_interval_test(r
, amdtp_rate_table
[i
]))
66 t
.min
= min(t
.min
, pcm_channels
[mode
]);
67 t
.max
= max(t
.max
, pcm_channels
[mode
]);
70 return snd_interval_refine(c
, &t
);
73 static void limit_channels_and_rates(struct snd_pcm_hardware
*hw
,
74 const unsigned int *pcm_channels
)
76 unsigned int rate
, channels
;
79 hw
->channels_min
= UINT_MAX
;
81 hw
->rate_min
= UINT_MAX
;
84 for (i
= 0; i
< ARRAY_SIZE(amdtp_rate_table
); i
++) {
85 enum snd_ff_stream_mode mode
;
88 err
= snd_ff_stream_get_multiplier_mode(i
, &mode
);
92 channels
= pcm_channels
[mode
];
93 if (pcm_channels
[mode
] == 0)
95 hw
->channels_min
= min(hw
->channels_min
, channels
);
96 hw
->channels_max
= max(hw
->channels_max
, channels
);
98 rate
= amdtp_rate_table
[i
];
99 hw
->rates
|= snd_pcm_rate_to_rate_bit(rate
);
100 hw
->rate_min
= min(hw
->rate_min
, rate
);
101 hw
->rate_max
= max(hw
->rate_max
, rate
);
105 static int pcm_init_hw_params(struct snd_ff
*ff
,
106 struct snd_pcm_substream
*substream
)
108 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
109 struct amdtp_stream
*s
;
110 const unsigned int *pcm_channels
;
113 if (substream
->stream
== SNDRV_PCM_STREAM_CAPTURE
) {
114 runtime
->hw
.formats
= SNDRV_PCM_FMTBIT_S32
;
116 pcm_channels
= ff
->spec
->pcm_capture_channels
;
118 runtime
->hw
.formats
= SNDRV_PCM_FMTBIT_S32
;
120 pcm_channels
= ff
->spec
->pcm_playback_channels
;
123 limit_channels_and_rates(&runtime
->hw
, pcm_channels
);
125 err
= snd_pcm_hw_rule_add(runtime
, 0, SNDRV_PCM_HW_PARAM_CHANNELS
,
126 hw_rule_channels
, (void *)pcm_channels
,
127 SNDRV_PCM_HW_PARAM_RATE
, -1);
131 err
= snd_pcm_hw_rule_add(runtime
, 0, SNDRV_PCM_HW_PARAM_RATE
,
132 hw_rule_rate
, (void *)pcm_channels
,
133 SNDRV_PCM_HW_PARAM_CHANNELS
, -1);
137 return amdtp_ff_add_pcm_hw_constraints(s
, runtime
);
140 static int pcm_open(struct snd_pcm_substream
*substream
)
142 struct snd_ff
*ff
= substream
->private_data
;
144 enum snd_ff_clock_src src
;
147 err
= snd_ff_stream_lock_try(ff
);
151 err
= pcm_init_hw_params(ff
, substream
);
155 err
= ff
->spec
->protocol
->get_clock(ff
, &rate
, &src
);
159 if (src
!= SND_FF_CLOCK_SRC_INTERNAL
) {
160 for (i
= 0; i
< CIP_SFC_COUNT
; ++i
) {
161 if (amdtp_rate_table
[i
] == rate
)
165 * The unit is configured at sampling frequency which packet
166 * streaming engine can't support.
168 if (i
>= CIP_SFC_COUNT
) {
173 substream
->runtime
->hw
.rate_min
= rate
;
174 substream
->runtime
->hw
.rate_max
= rate
;
176 if (amdtp_stream_pcm_running(&ff
->rx_stream
) ||
177 amdtp_stream_pcm_running(&ff
->tx_stream
)) {
178 rate
= amdtp_rate_table
[ff
->rx_stream
.sfc
];
179 substream
->runtime
->hw
.rate_min
= rate
;
180 substream
->runtime
->hw
.rate_max
= rate
;
184 snd_pcm_set_sync(substream
);
189 snd_ff_stream_lock_release(ff
);
193 static int pcm_close(struct snd_pcm_substream
*substream
)
195 struct snd_ff
*ff
= substream
->private_data
;
197 snd_ff_stream_lock_release(ff
);
202 static int pcm_capture_hw_params(struct snd_pcm_substream
*substream
,
203 struct snd_pcm_hw_params
*hw_params
)
205 struct snd_ff
*ff
= substream
->private_data
;
208 err
= snd_pcm_lib_alloc_vmalloc_buffer(substream
,
209 params_buffer_bytes(hw_params
));
213 if (substream
->runtime
->status
->state
== SNDRV_PCM_STATE_OPEN
) {
214 mutex_lock(&ff
->mutex
);
215 ff
->substreams_counter
++;
216 mutex_unlock(&ff
->mutex
);
222 static int pcm_playback_hw_params(struct snd_pcm_substream
*substream
,
223 struct snd_pcm_hw_params
*hw_params
)
225 struct snd_ff
*ff
= substream
->private_data
;
228 err
= snd_pcm_lib_alloc_vmalloc_buffer(substream
,
229 params_buffer_bytes(hw_params
));
233 if (substream
->runtime
->status
->state
== SNDRV_PCM_STATE_OPEN
) {
234 mutex_lock(&ff
->mutex
);
235 ff
->substreams_counter
++;
236 mutex_unlock(&ff
->mutex
);
242 static int pcm_capture_hw_free(struct snd_pcm_substream
*substream
)
244 struct snd_ff
*ff
= substream
->private_data
;
246 mutex_lock(&ff
->mutex
);
248 if (substream
->runtime
->status
->state
!= SNDRV_PCM_STATE_OPEN
)
249 ff
->substreams_counter
--;
251 snd_ff_stream_stop_duplex(ff
);
253 mutex_unlock(&ff
->mutex
);
255 return snd_pcm_lib_free_vmalloc_buffer(substream
);
258 static int pcm_playback_hw_free(struct snd_pcm_substream
*substream
)
260 struct snd_ff
*ff
= substream
->private_data
;
262 mutex_lock(&ff
->mutex
);
264 if (substream
->runtime
->status
->state
!= SNDRV_PCM_STATE_OPEN
)
265 ff
->substreams_counter
--;
267 snd_ff_stream_stop_duplex(ff
);
269 mutex_unlock(&ff
->mutex
);
271 return snd_pcm_lib_free_vmalloc_buffer(substream
);
274 static int pcm_capture_prepare(struct snd_pcm_substream
*substream
)
276 struct snd_ff
*ff
= substream
->private_data
;
277 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
280 mutex_lock(&ff
->mutex
);
282 err
= snd_ff_stream_start_duplex(ff
, runtime
->rate
);
284 amdtp_stream_pcm_prepare(&ff
->tx_stream
);
286 mutex_unlock(&ff
->mutex
);
291 static int pcm_playback_prepare(struct snd_pcm_substream
*substream
)
293 struct snd_ff
*ff
= substream
->private_data
;
294 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
297 mutex_lock(&ff
->mutex
);
299 err
= snd_ff_stream_start_duplex(ff
, runtime
->rate
);
301 amdtp_stream_pcm_prepare(&ff
->rx_stream
);
303 mutex_unlock(&ff
->mutex
);
308 static int pcm_capture_trigger(struct snd_pcm_substream
*substream
, int cmd
)
310 struct snd_ff
*ff
= substream
->private_data
;
313 case SNDRV_PCM_TRIGGER_START
:
314 amdtp_stream_pcm_trigger(&ff
->tx_stream
, substream
);
316 case SNDRV_PCM_TRIGGER_STOP
:
317 amdtp_stream_pcm_trigger(&ff
->tx_stream
, NULL
);
326 static int pcm_playback_trigger(struct snd_pcm_substream
*substream
, int cmd
)
328 struct snd_ff
*ff
= substream
->private_data
;
331 case SNDRV_PCM_TRIGGER_START
:
332 amdtp_stream_pcm_trigger(&ff
->rx_stream
, substream
);
334 case SNDRV_PCM_TRIGGER_STOP
:
335 amdtp_stream_pcm_trigger(&ff
->rx_stream
, NULL
);
344 static snd_pcm_uframes_t
pcm_capture_pointer(struct snd_pcm_substream
*sbstrm
)
346 struct snd_ff
*ff
= sbstrm
->private_data
;
348 return amdtp_stream_pcm_pointer(&ff
->tx_stream
);
351 static snd_pcm_uframes_t
pcm_playback_pointer(struct snd_pcm_substream
*sbstrm
)
353 struct snd_ff
*ff
= sbstrm
->private_data
;
355 return amdtp_stream_pcm_pointer(&ff
->rx_stream
);
358 static int pcm_capture_ack(struct snd_pcm_substream
*substream
)
360 struct snd_ff
*ff
= substream
->private_data
;
362 return amdtp_stream_pcm_ack(&ff
->tx_stream
);
365 static int pcm_playback_ack(struct snd_pcm_substream
*substream
)
367 struct snd_ff
*ff
= substream
->private_data
;
369 return amdtp_stream_pcm_ack(&ff
->rx_stream
);
372 int snd_ff_create_pcm_devices(struct snd_ff
*ff
)
374 static const struct snd_pcm_ops pcm_capture_ops
= {
377 .ioctl
= snd_pcm_lib_ioctl
,
378 .hw_params
= pcm_capture_hw_params
,
379 .hw_free
= pcm_capture_hw_free
,
380 .prepare
= pcm_capture_prepare
,
381 .trigger
= pcm_capture_trigger
,
382 .pointer
= pcm_capture_pointer
,
383 .ack
= pcm_capture_ack
,
384 .page
= snd_pcm_lib_get_vmalloc_page
,
386 static const struct snd_pcm_ops pcm_playback_ops
= {
389 .ioctl
= snd_pcm_lib_ioctl
,
390 .hw_params
= pcm_playback_hw_params
,
391 .hw_free
= pcm_playback_hw_free
,
392 .prepare
= pcm_playback_prepare
,
393 .trigger
= pcm_playback_trigger
,
394 .pointer
= pcm_playback_pointer
,
395 .ack
= pcm_playback_ack
,
396 .page
= snd_pcm_lib_get_vmalloc_page
,
401 err
= snd_pcm_new(ff
->card
, ff
->card
->driver
, 0, 1, 1, &pcm
);
405 pcm
->private_data
= ff
;
406 snprintf(pcm
->name
, sizeof(pcm
->name
),
407 "%s PCM", ff
->card
->shortname
);
408 snd_pcm_set_ops(pcm
, SNDRV_PCM_STREAM_PLAYBACK
, &pcm_playback_ops
);
409 snd_pcm_set_ops(pcm
, SNDRV_PCM_STREAM_CAPTURE
, &pcm_capture_ops
);