0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "dice.h"
0010
0011 static int dice_rate_constraint(struct snd_pcm_hw_params *params,
0012 struct snd_pcm_hw_rule *rule)
0013 {
0014 struct snd_pcm_substream *substream = rule->private;
0015 struct snd_dice *dice = substream->private_data;
0016 unsigned int index = substream->pcm->device;
0017
0018 const struct snd_interval *c =
0019 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS);
0020 struct snd_interval *r =
0021 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
0022 struct snd_interval rates = {
0023 .min = UINT_MAX, .max = 0, .integer = 1
0024 };
0025 unsigned int *pcm_channels;
0026 enum snd_dice_rate_mode mode;
0027 unsigned int i, rate;
0028
0029 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
0030 pcm_channels = dice->tx_pcm_chs[index];
0031 else
0032 pcm_channels = dice->rx_pcm_chs[index];
0033
0034 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) {
0035 rate = snd_dice_rates[i];
0036 if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0)
0037 continue;
0038
0039 if (!snd_interval_test(c, pcm_channels[mode]))
0040 continue;
0041
0042 rates.min = min(rates.min, rate);
0043 rates.max = max(rates.max, rate);
0044 }
0045
0046 return snd_interval_refine(r, &rates);
0047 }
0048
0049 static int dice_channels_constraint(struct snd_pcm_hw_params *params,
0050 struct snd_pcm_hw_rule *rule)
0051 {
0052 struct snd_pcm_substream *substream = rule->private;
0053 struct snd_dice *dice = substream->private_data;
0054 unsigned int index = substream->pcm->device;
0055
0056 const struct snd_interval *r =
0057 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE);
0058 struct snd_interval *c =
0059 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
0060 struct snd_interval channels = {
0061 .min = UINT_MAX, .max = 0, .integer = 1
0062 };
0063 unsigned int *pcm_channels;
0064 enum snd_dice_rate_mode mode;
0065 unsigned int i, rate;
0066
0067 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
0068 pcm_channels = dice->tx_pcm_chs[index];
0069 else
0070 pcm_channels = dice->rx_pcm_chs[index];
0071
0072 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) {
0073 rate = snd_dice_rates[i];
0074 if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0)
0075 continue;
0076
0077 if (!snd_interval_test(r, rate))
0078 continue;
0079
0080 channels.min = min(channels.min, pcm_channels[mode]);
0081 channels.max = max(channels.max, pcm_channels[mode]);
0082 }
0083
0084 return snd_interval_refine(c, &channels);
0085 }
0086
0087 static int limit_channels_and_rates(struct snd_dice *dice,
0088 struct snd_pcm_runtime *runtime,
0089 enum amdtp_stream_direction dir,
0090 unsigned int index)
0091 {
0092 struct snd_pcm_hardware *hw = &runtime->hw;
0093 unsigned int *pcm_channels;
0094 unsigned int i;
0095
0096 if (dir == AMDTP_IN_STREAM)
0097 pcm_channels = dice->tx_pcm_chs[index];
0098 else
0099 pcm_channels = dice->rx_pcm_chs[index];
0100
0101 hw->channels_min = UINT_MAX;
0102 hw->channels_max = 0;
0103
0104 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) {
0105 enum snd_dice_rate_mode mode;
0106 unsigned int rate, channels;
0107
0108 rate = snd_dice_rates[i];
0109 if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0)
0110 continue;
0111 hw->rates |= snd_pcm_rate_to_rate_bit(rate);
0112
0113 channels = pcm_channels[mode];
0114 if (channels == 0)
0115 continue;
0116 hw->channels_min = min(hw->channels_min, channels);
0117 hw->channels_max = max(hw->channels_max, channels);
0118 }
0119
0120 snd_pcm_limit_hw_rates(runtime);
0121
0122 return 0;
0123 }
0124
0125 static int init_hw_info(struct snd_dice *dice,
0126 struct snd_pcm_substream *substream)
0127 {
0128 struct snd_pcm_runtime *runtime = substream->runtime;
0129 struct snd_pcm_hardware *hw = &runtime->hw;
0130 unsigned int index = substream->pcm->device;
0131 enum amdtp_stream_direction dir;
0132 struct amdtp_stream *stream;
0133 int err;
0134
0135 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
0136 hw->formats = AM824_IN_PCM_FORMAT_BITS;
0137 dir = AMDTP_IN_STREAM;
0138 stream = &dice->tx_stream[index];
0139 } else {
0140 hw->formats = AM824_OUT_PCM_FORMAT_BITS;
0141 dir = AMDTP_OUT_STREAM;
0142 stream = &dice->rx_stream[index];
0143 }
0144
0145 err = limit_channels_and_rates(dice, substream->runtime, dir,
0146 index);
0147 if (err < 0)
0148 return err;
0149
0150 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
0151 dice_rate_constraint, substream,
0152 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
0153 if (err < 0)
0154 return err;
0155 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
0156 dice_channels_constraint, substream,
0157 SNDRV_PCM_HW_PARAM_RATE, -1);
0158 if (err < 0)
0159 return err;
0160
0161 return amdtp_am824_add_pcm_hw_constraints(stream, runtime);
0162 }
0163
0164 static int pcm_open(struct snd_pcm_substream *substream)
0165 {
0166 struct snd_dice *dice = substream->private_data;
0167 struct amdtp_domain *d = &dice->domain;
0168 unsigned int source;
0169 bool internal;
0170 int err;
0171
0172 err = snd_dice_stream_lock_try(dice);
0173 if (err < 0)
0174 return err;
0175
0176 err = init_hw_info(dice, substream);
0177 if (err < 0)
0178 goto err_locked;
0179
0180 err = snd_dice_transaction_get_clock_source(dice, &source);
0181 if (err < 0)
0182 goto err_locked;
0183 switch (source) {
0184 case CLOCK_SOURCE_AES1:
0185 case CLOCK_SOURCE_AES2:
0186 case CLOCK_SOURCE_AES3:
0187 case CLOCK_SOURCE_AES4:
0188 case CLOCK_SOURCE_AES_ANY:
0189 case CLOCK_SOURCE_ADAT:
0190 case CLOCK_SOURCE_TDIF:
0191 case CLOCK_SOURCE_WC:
0192 internal = false;
0193 break;
0194 default:
0195 internal = true;
0196 break;
0197 }
0198
0199 mutex_lock(&dice->mutex);
0200
0201
0202
0203
0204 if (!internal ||
0205 (dice->substreams_counter > 0 && d->events_per_period > 0)) {
0206 unsigned int frames_per_period = d->events_per_period;
0207 unsigned int frames_per_buffer = d->events_per_buffer;
0208 unsigned int rate;
0209
0210 err = snd_dice_transaction_get_rate(dice, &rate);
0211 if (err < 0) {
0212 mutex_unlock(&dice->mutex);
0213 goto err_locked;
0214 }
0215
0216 substream->runtime->hw.rate_min = rate;
0217 substream->runtime->hw.rate_max = rate;
0218
0219 if (frames_per_period > 0) {
0220
0221 if (rate > 96000 && !dice->disable_double_pcm_frames) {
0222 frames_per_period *= 2;
0223 frames_per_buffer *= 2;
0224 }
0225
0226 err = snd_pcm_hw_constraint_minmax(substream->runtime,
0227 SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
0228 frames_per_period, frames_per_period);
0229 if (err < 0) {
0230 mutex_unlock(&dice->mutex);
0231 goto err_locked;
0232 }
0233
0234 err = snd_pcm_hw_constraint_minmax(substream->runtime,
0235 SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
0236 frames_per_buffer, frames_per_buffer);
0237 if (err < 0) {
0238 mutex_unlock(&dice->mutex);
0239 goto err_locked;
0240 }
0241 }
0242 }
0243
0244 mutex_unlock(&dice->mutex);
0245
0246 snd_pcm_set_sync(substream);
0247
0248 return 0;
0249 err_locked:
0250 snd_dice_stream_lock_release(dice);
0251 return err;
0252 }
0253
0254 static int pcm_close(struct snd_pcm_substream *substream)
0255 {
0256 struct snd_dice *dice = substream->private_data;
0257
0258 snd_dice_stream_lock_release(dice);
0259
0260 return 0;
0261 }
0262
0263 static int pcm_hw_params(struct snd_pcm_substream *substream,
0264 struct snd_pcm_hw_params *hw_params)
0265 {
0266 struct snd_dice *dice = substream->private_data;
0267 int err = 0;
0268
0269 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
0270 unsigned int rate = params_rate(hw_params);
0271 unsigned int events_per_period = params_period_size(hw_params);
0272 unsigned int events_per_buffer = params_buffer_size(hw_params);
0273
0274 mutex_lock(&dice->mutex);
0275
0276 if (rate > 96000 && !dice->disable_double_pcm_frames) {
0277 events_per_period /= 2;
0278 events_per_buffer /= 2;
0279 }
0280 err = snd_dice_stream_reserve_duplex(dice, rate,
0281 events_per_period, events_per_buffer);
0282 if (err >= 0)
0283 ++dice->substreams_counter;
0284 mutex_unlock(&dice->mutex);
0285 }
0286
0287 return err;
0288 }
0289
0290 static int pcm_hw_free(struct snd_pcm_substream *substream)
0291 {
0292 struct snd_dice *dice = substream->private_data;
0293
0294 mutex_lock(&dice->mutex);
0295
0296 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
0297 --dice->substreams_counter;
0298
0299 snd_dice_stream_stop_duplex(dice);
0300
0301 mutex_unlock(&dice->mutex);
0302
0303 return 0;
0304 }
0305
0306 static int capture_prepare(struct snd_pcm_substream *substream)
0307 {
0308 struct snd_dice *dice = substream->private_data;
0309 struct amdtp_stream *stream = &dice->tx_stream[substream->pcm->device];
0310 int err;
0311
0312 mutex_lock(&dice->mutex);
0313 err = snd_dice_stream_start_duplex(dice);
0314 mutex_unlock(&dice->mutex);
0315 if (err >= 0)
0316 amdtp_stream_pcm_prepare(stream);
0317
0318 return 0;
0319 }
0320 static int playback_prepare(struct snd_pcm_substream *substream)
0321 {
0322 struct snd_dice *dice = substream->private_data;
0323 struct amdtp_stream *stream = &dice->rx_stream[substream->pcm->device];
0324 int err;
0325
0326 mutex_lock(&dice->mutex);
0327 err = snd_dice_stream_start_duplex(dice);
0328 mutex_unlock(&dice->mutex);
0329 if (err >= 0)
0330 amdtp_stream_pcm_prepare(stream);
0331
0332 return err;
0333 }
0334
0335 static int capture_trigger(struct snd_pcm_substream *substream, int cmd)
0336 {
0337 struct snd_dice *dice = substream->private_data;
0338 struct amdtp_stream *stream = &dice->tx_stream[substream->pcm->device];
0339
0340 switch (cmd) {
0341 case SNDRV_PCM_TRIGGER_START:
0342 amdtp_stream_pcm_trigger(stream, substream);
0343 break;
0344 case SNDRV_PCM_TRIGGER_STOP:
0345 amdtp_stream_pcm_trigger(stream, NULL);
0346 break;
0347 default:
0348 return -EINVAL;
0349 }
0350
0351 return 0;
0352 }
0353 static int playback_trigger(struct snd_pcm_substream *substream, int cmd)
0354 {
0355 struct snd_dice *dice = substream->private_data;
0356 struct amdtp_stream *stream = &dice->rx_stream[substream->pcm->device];
0357
0358 switch (cmd) {
0359 case SNDRV_PCM_TRIGGER_START:
0360 amdtp_stream_pcm_trigger(stream, substream);
0361 break;
0362 case SNDRV_PCM_TRIGGER_STOP:
0363 amdtp_stream_pcm_trigger(stream, NULL);
0364 break;
0365 default:
0366 return -EINVAL;
0367 }
0368
0369 return 0;
0370 }
0371
0372 static snd_pcm_uframes_t capture_pointer(struct snd_pcm_substream *substream)
0373 {
0374 struct snd_dice *dice = substream->private_data;
0375 struct amdtp_stream *stream = &dice->tx_stream[substream->pcm->device];
0376
0377 return amdtp_domain_stream_pcm_pointer(&dice->domain, stream);
0378 }
0379 static snd_pcm_uframes_t playback_pointer(struct snd_pcm_substream *substream)
0380 {
0381 struct snd_dice *dice = substream->private_data;
0382 struct amdtp_stream *stream = &dice->rx_stream[substream->pcm->device];
0383
0384 return amdtp_domain_stream_pcm_pointer(&dice->domain, stream);
0385 }
0386
0387 static int capture_ack(struct snd_pcm_substream *substream)
0388 {
0389 struct snd_dice *dice = substream->private_data;
0390 struct amdtp_stream *stream = &dice->tx_stream[substream->pcm->device];
0391
0392 return amdtp_domain_stream_pcm_ack(&dice->domain, stream);
0393 }
0394
0395 static int playback_ack(struct snd_pcm_substream *substream)
0396 {
0397 struct snd_dice *dice = substream->private_data;
0398 struct amdtp_stream *stream = &dice->rx_stream[substream->pcm->device];
0399
0400 return amdtp_domain_stream_pcm_ack(&dice->domain, stream);
0401 }
0402
0403 int snd_dice_create_pcm(struct snd_dice *dice)
0404 {
0405 static const struct snd_pcm_ops capture_ops = {
0406 .open = pcm_open,
0407 .close = pcm_close,
0408 .hw_params = pcm_hw_params,
0409 .hw_free = pcm_hw_free,
0410 .prepare = capture_prepare,
0411 .trigger = capture_trigger,
0412 .pointer = capture_pointer,
0413 .ack = capture_ack,
0414 };
0415 static const struct snd_pcm_ops playback_ops = {
0416 .open = pcm_open,
0417 .close = pcm_close,
0418 .hw_params = pcm_hw_params,
0419 .hw_free = pcm_hw_free,
0420 .prepare = playback_prepare,
0421 .trigger = playback_trigger,
0422 .pointer = playback_pointer,
0423 .ack = playback_ack,
0424 };
0425 struct snd_pcm *pcm;
0426 unsigned int capture, playback;
0427 int i, j;
0428 int err;
0429
0430 for (i = 0; i < MAX_STREAMS; i++) {
0431 capture = playback = 0;
0432 for (j = 0; j < SND_DICE_RATE_MODE_COUNT; ++j) {
0433 if (dice->tx_pcm_chs[i][j] > 0)
0434 capture = 1;
0435 if (dice->rx_pcm_chs[i][j] > 0)
0436 playback = 1;
0437 }
0438
0439 err = snd_pcm_new(dice->card, "DICE", i, playback, capture,
0440 &pcm);
0441 if (err < 0)
0442 return err;
0443 pcm->private_data = dice;
0444 strcpy(pcm->name, dice->card->shortname);
0445
0446 if (capture > 0)
0447 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
0448 &capture_ops);
0449
0450 if (playback > 0)
0451 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
0452 &playback_ops);
0453
0454 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC,
0455 NULL, 0, 0);
0456 }
0457
0458 return 0;
0459 }