Lines Matching +full:hw +full:- +full:channels
1 // SPDX-License-Identifier: GPL-2.0-only
3 * fireworks_pcm.c - a part of driver for Fireworks based devices
5 * Copyright (c) 2009-2010 Clemens Ladisch
6 * Copyright (c) 2013-2014 Takashi Sakamoto
12 * Fireworks changes its AMDTP channels for PCM data according to its sampling
14 * 0: 32.0- 48.0 kHz then snd_efw_hwinfo.amdtp_XX_pcm_channels applied
15 * 1: 88.2- 96.0 kHz then snd_efw_hwinfo.amdtp_XX_pcm_channels_2x applied
16 * 2: 176.4-192.0 kHz then snd_efw_hwinfo.amdtp_XX_pcm_channels_4x applied
18 * The number of PCM channels for analog input and output are always fixed but
19 * the number of PCM channels for digital input and output are differed.
22 * model, the number of PCM channels for digital input has more restriction
24 * - S/PDIF coaxial and optical : use input 1-2
25 * - ADAT optical at 32.0-48.0 kHz : use input 1-8
26 * - ADAT optical at 88.2-96.0 kHz : use input 1-4 (S/MUX format)
28 * The data in AMDTP channels for blank PCM channels are zero.
46 return ((int)index - 1) / 2; in get_multiplier_mode_with_index()
60 return -EINVAL; in snd_efw_get_multiplier_mode()
66 unsigned int *pcm_channels = rule->private; in hw_rule_rate()
91 unsigned int *pcm_channels = rule->private; in hw_rule_channels()
114 limit_channels(struct snd_pcm_hardware *hw, unsigned int *pcm_channels) in limit_channels() argument
118 hw->channels_min = UINT_MAX; in limit_channels()
119 hw->channels_max = 0; in limit_channels()
126 hw->channels_min = min(hw->channels_min, pcm_channels[mode]); in limit_channels()
127 hw->channels_max = max(hw->channels_max, pcm_channels[mode]); in limit_channels()
135 struct snd_pcm_runtime *runtime = substream->runtime; in pcm_init_hw_params()
140 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { in pcm_init_hw_params()
141 runtime->hw.formats = AM824_IN_PCM_FORMAT_BITS; in pcm_init_hw_params()
142 s = &efw->tx_stream; in pcm_init_hw_params()
143 pcm_channels = efw->pcm_capture_channels; in pcm_init_hw_params()
145 runtime->hw.formats = AM824_OUT_PCM_FORMAT_BITS; in pcm_init_hw_params()
146 s = &efw->rx_stream; in pcm_init_hw_params()
147 pcm_channels = efw->pcm_playback_channels; in pcm_init_hw_params()
151 runtime->hw.rates = efw->supported_sampling_rate; in pcm_init_hw_params()
154 limit_channels(&runtime->hw, pcm_channels); in pcm_init_hw_params()
158 SNDRV_PCM_HW_PARAM_RATE, -1); in pcm_init_hw_params()
164 SNDRV_PCM_HW_PARAM_CHANNELS, -1); in pcm_init_hw_params()
175 struct snd_efw *efw = substream->private_data; in pcm_open()
176 struct amdtp_domain *d = &efw->domain; in pcm_open()
192 mutex_lock(&efw->mutex); in pcm_open()
198 (efw->substreams_counter > 0 && d->events_per_period > 0)) { in pcm_open()
199 unsigned int frames_per_period = d->events_per_period; in pcm_open()
200 unsigned int frames_per_buffer = d->events_per_buffer; in pcm_open()
205 mutex_unlock(&efw->mutex); in pcm_open()
208 substream->runtime->hw.rate_min = sampling_rate; in pcm_open()
209 substream->runtime->hw.rate_max = sampling_rate; in pcm_open()
212 err = snd_pcm_hw_constraint_minmax(substream->runtime, in pcm_open()
216 mutex_unlock(&efw->mutex); in pcm_open()
220 err = snd_pcm_hw_constraint_minmax(substream->runtime, in pcm_open()
224 mutex_unlock(&efw->mutex); in pcm_open()
230 mutex_unlock(&efw->mutex); in pcm_open()
242 struct snd_efw *efw = substream->private_data; in pcm_close()
250 struct snd_efw *efw = substream->private_data; in pcm_hw_params()
253 if (substream->runtime->state == SNDRV_PCM_STATE_OPEN) { in pcm_hw_params()
258 mutex_lock(&efw->mutex); in pcm_hw_params()
262 ++efw->substreams_counter; in pcm_hw_params()
263 mutex_unlock(&efw->mutex); in pcm_hw_params()
271 struct snd_efw *efw = substream->private_data; in pcm_hw_free()
273 mutex_lock(&efw->mutex); in pcm_hw_free()
275 if (substream->runtime->state != SNDRV_PCM_STATE_OPEN) in pcm_hw_free()
276 --efw->substreams_counter; in pcm_hw_free()
280 mutex_unlock(&efw->mutex); in pcm_hw_free()
287 struct snd_efw *efw = substream->private_data; in pcm_capture_prepare()
292 amdtp_stream_pcm_prepare(&efw->tx_stream); in pcm_capture_prepare()
298 struct snd_efw *efw = substream->private_data; in pcm_playback_prepare()
303 amdtp_stream_pcm_prepare(&efw->rx_stream); in pcm_playback_prepare()
310 struct snd_efw *efw = substream->private_data; in pcm_capture_trigger()
314 amdtp_stream_pcm_trigger(&efw->tx_stream, substream); in pcm_capture_trigger()
317 amdtp_stream_pcm_trigger(&efw->tx_stream, NULL); in pcm_capture_trigger()
320 return -EINVAL; in pcm_capture_trigger()
327 struct snd_efw *efw = substream->private_data; in pcm_playback_trigger()
331 amdtp_stream_pcm_trigger(&efw->rx_stream, substream); in pcm_playback_trigger()
334 amdtp_stream_pcm_trigger(&efw->rx_stream, NULL); in pcm_playback_trigger()
337 return -EINVAL; in pcm_playback_trigger()
345 struct snd_efw *efw = sbstrm->private_data; in pcm_capture_pointer()
347 return amdtp_domain_stream_pcm_pointer(&efw->domain, &efw->tx_stream); in pcm_capture_pointer()
351 struct snd_efw *efw = sbstrm->private_data; in pcm_playback_pointer()
353 return amdtp_domain_stream_pcm_pointer(&efw->domain, &efw->rx_stream); in pcm_playback_pointer()
358 struct snd_efw *efw = substream->private_data; in pcm_capture_ack()
360 return amdtp_domain_stream_pcm_ack(&efw->domain, &efw->tx_stream); in pcm_capture_ack()
365 struct snd_efw *efw = substream->private_data; in pcm_playback_ack()
367 return amdtp_domain_stream_pcm_ack(&efw->domain, &efw->rx_stream); in pcm_playback_ack()
395 err = snd_pcm_new(efw->card, efw->card->driver, 0, 1, 1, &pcm); in snd_efw_create_pcm_devices()
399 pcm->private_data = efw; in snd_efw_create_pcm_devices()
400 pcm->nonatomic = true; in snd_efw_create_pcm_devices()
401 snprintf(pcm->name, sizeof(pcm->name), "%s PCM", efw->card->shortname); in snd_efw_create_pcm_devices()