0001
0002
0003
0004
0005
0006
0007
0008 #include <sound/pcm_params.h>
0009 #include "motu.h"
0010
0011 static int motu_rate_constraint(struct snd_pcm_hw_params *params,
0012 struct snd_pcm_hw_rule *rule)
0013 {
0014 struct snd_motu_packet_format *formats = rule->private;
0015
0016 const struct snd_interval *c =
0017 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS);
0018 struct snd_interval *r =
0019 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
0020 struct snd_interval rates = {
0021 .min = UINT_MAX, .max = 0, .integer = 1
0022 };
0023 unsigned int i, pcm_channels, rate, mode;
0024
0025 for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) {
0026 rate = snd_motu_clock_rates[i];
0027 mode = i / 2;
0028
0029 pcm_channels = formats->pcm_chunks[mode];
0030 if (!snd_interval_test(c, pcm_channels))
0031 continue;
0032
0033 rates.min = min(rates.min, rate);
0034 rates.max = max(rates.max, rate);
0035 }
0036
0037 return snd_interval_refine(r, &rates);
0038 }
0039
0040 static int motu_channels_constraint(struct snd_pcm_hw_params *params,
0041 struct snd_pcm_hw_rule *rule)
0042 {
0043 struct snd_motu_packet_format *formats = rule->private;
0044
0045 const struct snd_interval *r =
0046 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE);
0047 struct snd_interval *c =
0048 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
0049 struct snd_interval channels = {
0050 .min = UINT_MAX, .max = 0, .integer = 1
0051 };
0052 unsigned int i, pcm_channels, rate, mode;
0053
0054 for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) {
0055 rate = snd_motu_clock_rates[i];
0056 mode = i / 2;
0057
0058 if (!snd_interval_test(r, rate))
0059 continue;
0060
0061 pcm_channels = formats->pcm_chunks[mode];
0062 channels.min = min(channels.min, pcm_channels);
0063 channels.max = max(channels.max, pcm_channels);
0064 }
0065
0066 return snd_interval_refine(c, &channels);
0067 }
0068
0069 static void limit_channels_and_rates(struct snd_motu *motu,
0070 struct snd_pcm_runtime *runtime,
0071 struct snd_motu_packet_format *formats)
0072 {
0073 struct snd_pcm_hardware *hw = &runtime->hw;
0074 unsigned int i, pcm_channels, rate, mode;
0075
0076 hw->channels_min = UINT_MAX;
0077 hw->channels_max = 0;
0078
0079 for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) {
0080 rate = snd_motu_clock_rates[i];
0081 mode = i / 2;
0082
0083 pcm_channels = formats->pcm_chunks[mode];
0084 if (pcm_channels == 0)
0085 continue;
0086
0087 hw->rates |= snd_pcm_rate_to_rate_bit(rate);
0088 hw->channels_min = min(hw->channels_min, pcm_channels);
0089 hw->channels_max = max(hw->channels_max, pcm_channels);
0090 }
0091
0092 snd_pcm_limit_hw_rates(runtime);
0093 }
0094
0095 static int init_hw_info(struct snd_motu *motu,
0096 struct snd_pcm_substream *substream)
0097 {
0098 struct snd_pcm_runtime *runtime = substream->runtime;
0099 struct snd_pcm_hardware *hw = &runtime->hw;
0100 struct amdtp_stream *stream;
0101 struct snd_motu_packet_format *formats;
0102 int err;
0103
0104 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
0105 hw->formats = SNDRV_PCM_FMTBIT_S32;
0106 stream = &motu->tx_stream;
0107 formats = &motu->tx_packet_formats;
0108 } else {
0109 hw->formats = SNDRV_PCM_FMTBIT_S32;
0110 stream = &motu->rx_stream;
0111 formats = &motu->rx_packet_formats;
0112 }
0113
0114 limit_channels_and_rates(motu, runtime, formats);
0115
0116 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
0117 motu_rate_constraint, formats,
0118 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
0119 if (err < 0)
0120 return err;
0121 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
0122 motu_channels_constraint, formats,
0123 SNDRV_PCM_HW_PARAM_RATE, -1);
0124 if (err < 0)
0125 return err;
0126
0127 return amdtp_motu_add_pcm_hw_constraints(stream, runtime);
0128 }
0129
0130 static int pcm_open(struct snd_pcm_substream *substream)
0131 {
0132 struct snd_motu *motu = substream->private_data;
0133 struct amdtp_domain *d = &motu->domain;
0134 enum snd_motu_clock_source src;
0135 int err;
0136
0137 err = snd_motu_stream_lock_try(motu);
0138 if (err < 0)
0139 return err;
0140
0141 mutex_lock(&motu->mutex);
0142
0143 err = snd_motu_stream_cache_packet_formats(motu);
0144 if (err < 0)
0145 goto err_locked;
0146
0147 err = init_hw_info(motu, substream);
0148 if (err < 0)
0149 goto err_locked;
0150
0151 err = snd_motu_protocol_get_clock_source(motu, &src);
0152 if (err < 0)
0153 goto err_locked;
0154
0155
0156
0157
0158 if ((src != SND_MOTU_CLOCK_SOURCE_INTERNAL &&
0159 src != SND_MOTU_CLOCK_SOURCE_SPH) ||
0160 (motu->substreams_counter > 0 && d->events_per_period > 0)) {
0161 unsigned int frames_per_period = d->events_per_period;
0162 unsigned int frames_per_buffer = d->events_per_buffer;
0163 unsigned int rate;
0164
0165 err = snd_motu_protocol_get_clock_rate(motu, &rate);
0166 if (err < 0)
0167 goto err_locked;
0168
0169 substream->runtime->hw.rate_min = rate;
0170 substream->runtime->hw.rate_max = rate;
0171
0172 if (frames_per_period > 0) {
0173 err = snd_pcm_hw_constraint_minmax(substream->runtime,
0174 SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
0175 frames_per_period, frames_per_period);
0176 if (err < 0)
0177 goto err_locked;
0178
0179 err = snd_pcm_hw_constraint_minmax(substream->runtime,
0180 SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
0181 frames_per_buffer, frames_per_buffer);
0182 if (err < 0)
0183 goto err_locked;
0184 }
0185 }
0186
0187 snd_pcm_set_sync(substream);
0188
0189 mutex_unlock(&motu->mutex);
0190
0191 return 0;
0192 err_locked:
0193 mutex_unlock(&motu->mutex);
0194 snd_motu_stream_lock_release(motu);
0195 return err;
0196 }
0197
0198 static int pcm_close(struct snd_pcm_substream *substream)
0199 {
0200 struct snd_motu *motu = substream->private_data;
0201
0202 snd_motu_stream_lock_release(motu);
0203
0204 return 0;
0205 }
0206
0207 static int pcm_hw_params(struct snd_pcm_substream *substream,
0208 struct snd_pcm_hw_params *hw_params)
0209 {
0210 struct snd_motu *motu = substream->private_data;
0211 int err = 0;
0212
0213 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
0214 unsigned int rate = params_rate(hw_params);
0215 unsigned int frames_per_period = params_period_size(hw_params);
0216 unsigned int frames_per_buffer = params_buffer_size(hw_params);
0217
0218 mutex_lock(&motu->mutex);
0219 err = snd_motu_stream_reserve_duplex(motu, rate,
0220 frames_per_period, frames_per_buffer);
0221 if (err >= 0)
0222 ++motu->substreams_counter;
0223 mutex_unlock(&motu->mutex);
0224 }
0225
0226 return err;
0227 }
0228
0229 static int pcm_hw_free(struct snd_pcm_substream *substream)
0230 {
0231 struct snd_motu *motu = substream->private_data;
0232
0233 mutex_lock(&motu->mutex);
0234
0235 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
0236 --motu->substreams_counter;
0237
0238 snd_motu_stream_stop_duplex(motu);
0239
0240 mutex_unlock(&motu->mutex);
0241
0242 return 0;
0243 }
0244
0245 static int capture_prepare(struct snd_pcm_substream *substream)
0246 {
0247 struct snd_motu *motu = substream->private_data;
0248 int err;
0249
0250 mutex_lock(&motu->mutex);
0251 err = snd_motu_stream_start_duplex(motu);
0252 mutex_unlock(&motu->mutex);
0253 if (err >= 0)
0254 amdtp_stream_pcm_prepare(&motu->tx_stream);
0255
0256 return 0;
0257 }
0258 static int playback_prepare(struct snd_pcm_substream *substream)
0259 {
0260 struct snd_motu *motu = substream->private_data;
0261 int err;
0262
0263 mutex_lock(&motu->mutex);
0264 err = snd_motu_stream_start_duplex(motu);
0265 mutex_unlock(&motu->mutex);
0266 if (err >= 0)
0267 amdtp_stream_pcm_prepare(&motu->rx_stream);
0268
0269 return err;
0270 }
0271
0272 static int capture_trigger(struct snd_pcm_substream *substream, int cmd)
0273 {
0274 struct snd_motu *motu = substream->private_data;
0275
0276 switch (cmd) {
0277 case SNDRV_PCM_TRIGGER_START:
0278 amdtp_stream_pcm_trigger(&motu->tx_stream, substream);
0279 break;
0280 case SNDRV_PCM_TRIGGER_STOP:
0281 amdtp_stream_pcm_trigger(&motu->tx_stream, NULL);
0282 break;
0283 default:
0284 return -EINVAL;
0285 }
0286
0287 return 0;
0288 }
0289 static int playback_trigger(struct snd_pcm_substream *substream, int cmd)
0290 {
0291 struct snd_motu *motu = substream->private_data;
0292
0293 switch (cmd) {
0294 case SNDRV_PCM_TRIGGER_START:
0295 amdtp_stream_pcm_trigger(&motu->rx_stream, substream);
0296 break;
0297 case SNDRV_PCM_TRIGGER_STOP:
0298 amdtp_stream_pcm_trigger(&motu->rx_stream, NULL);
0299 break;
0300 default:
0301 return -EINVAL;
0302 }
0303
0304 return 0;
0305 }
0306
0307 static snd_pcm_uframes_t capture_pointer(struct snd_pcm_substream *substream)
0308 {
0309 struct snd_motu *motu = substream->private_data;
0310
0311 return amdtp_domain_stream_pcm_pointer(&motu->domain, &motu->tx_stream);
0312 }
0313 static snd_pcm_uframes_t playback_pointer(struct snd_pcm_substream *substream)
0314 {
0315 struct snd_motu *motu = substream->private_data;
0316
0317 return amdtp_domain_stream_pcm_pointer(&motu->domain, &motu->rx_stream);
0318 }
0319
0320 static int capture_ack(struct snd_pcm_substream *substream)
0321 {
0322 struct snd_motu *motu = substream->private_data;
0323
0324 return amdtp_domain_stream_pcm_ack(&motu->domain, &motu->tx_stream);
0325 }
0326
0327 static int playback_ack(struct snd_pcm_substream *substream)
0328 {
0329 struct snd_motu *motu = substream->private_data;
0330
0331 return amdtp_domain_stream_pcm_ack(&motu->domain, &motu->rx_stream);
0332 }
0333
0334 int snd_motu_create_pcm_devices(struct snd_motu *motu)
0335 {
0336 static const struct snd_pcm_ops capture_ops = {
0337 .open = pcm_open,
0338 .close = pcm_close,
0339 .hw_params = pcm_hw_params,
0340 .hw_free = pcm_hw_free,
0341 .prepare = capture_prepare,
0342 .trigger = capture_trigger,
0343 .pointer = capture_pointer,
0344 .ack = capture_ack,
0345 };
0346 static const struct snd_pcm_ops playback_ops = {
0347 .open = pcm_open,
0348 .close = pcm_close,
0349 .hw_params = pcm_hw_params,
0350 .hw_free = pcm_hw_free,
0351 .prepare = playback_prepare,
0352 .trigger = playback_trigger,
0353 .pointer = playback_pointer,
0354 .ack = playback_ack,
0355 };
0356 struct snd_pcm *pcm;
0357 int err;
0358
0359 err = snd_pcm_new(motu->card, motu->card->driver, 0, 1, 1, &pcm);
0360 if (err < 0)
0361 return err;
0362 pcm->private_data = motu;
0363 strcpy(pcm->name, motu->card->shortname);
0364
0365 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops);
0366 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops);
0367 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
0368
0369 return 0;
0370 }