Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * dice_pcm.c - a part of driver for DICE based devices
0004  *
0005  * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
0006  * Copyright (c) 2014 Takashi Sakamoto <o-takashi@sakamocchi.jp>
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     // When source of clock is not internal or any stream is reserved for
0202     // transmission of PCM frames, the available sampling rate is limited
0203     // at current one.
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             // For double_pcm_frame quirk.
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         // For double_pcm_frame quirk.
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 }