Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * fireworks_pcm.c - a part of driver for Fireworks based devices
0004  *
0005  * Copyright (c) 2009-2010 Clemens Ladisch
0006  * Copyright (c) 2013-2014 Takashi Sakamoto
0007  */
0008 #include "./fireworks.h"
0009 
0010 /*
0011  * NOTE:
0012  * Fireworks changes its AMDTP channels for PCM data according to its sampling
0013  * rate. There are three modes. Here _XX is either _rx or _tx.
0014  *  0:  32.0- 48.0 kHz then snd_efw_hwinfo.amdtp_XX_pcm_channels applied
0015  *  1:  88.2- 96.0 kHz then snd_efw_hwinfo.amdtp_XX_pcm_channels_2x applied
0016  *  2: 176.4-192.0 kHz then snd_efw_hwinfo.amdtp_XX_pcm_channels_4x applied
0017  *
0018  * The number of PCM channels for analog input and output are always fixed but
0019  * the number of PCM channels for digital input and output are differed.
0020  *
0021  * Additionally, according to "AudioFire Owner's Manual Version 2.2", in some
0022  * model, the number of PCM channels for digital input has more restriction
0023  * depending on which digital interface is selected.
0024  *  - S/PDIF coaxial and optical    : use input 1-2
0025  *  - ADAT optical at 32.0-48.0 kHz : use input 1-8
0026  *  - ADAT optical at 88.2-96.0 kHz : use input 1-4 (S/MUX format)
0027  *
0028  * The data in AMDTP channels for blank PCM channels are zero.
0029  */
0030 static const unsigned int freq_table[] = {
0031     /* multiplier mode 0 */
0032     [0] = 32000,
0033     [1] = 44100,
0034     [2] = 48000,
0035     /* multiplier mode 1 */
0036     [3] = 88200,
0037     [4] = 96000,
0038     /* multiplier mode 2 */
0039     [5] = 176400,
0040     [6] = 192000,
0041 };
0042 
0043 static inline unsigned int
0044 get_multiplier_mode_with_index(unsigned int index)
0045 {
0046     return ((int)index - 1) / 2;
0047 }
0048 
0049 int snd_efw_get_multiplier_mode(unsigned int sampling_rate, unsigned int *mode)
0050 {
0051     unsigned int i;
0052 
0053     for (i = 0; i < ARRAY_SIZE(freq_table); i++) {
0054         if (freq_table[i] == sampling_rate) {
0055             *mode = get_multiplier_mode_with_index(i);
0056             return 0;
0057         }
0058     }
0059 
0060     return -EINVAL;
0061 }
0062 
0063 static int
0064 hw_rule_rate(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
0065 {
0066     unsigned int *pcm_channels = rule->private;
0067     struct snd_interval *r =
0068         hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
0069     const struct snd_interval *c =
0070         hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS);
0071     struct snd_interval t = {
0072         .min = UINT_MAX, .max = 0, .integer = 1
0073     };
0074     unsigned int i, mode;
0075 
0076     for (i = 0; i < ARRAY_SIZE(freq_table); i++) {
0077         mode = get_multiplier_mode_with_index(i);
0078         if (!snd_interval_test(c, pcm_channels[mode]))
0079             continue;
0080 
0081         t.min = min(t.min, freq_table[i]);
0082         t.max = max(t.max, freq_table[i]);
0083     }
0084 
0085     return snd_interval_refine(r, &t);
0086 }
0087 
0088 static int
0089 hw_rule_channels(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
0090 {
0091     unsigned int *pcm_channels = rule->private;
0092     struct snd_interval *c =
0093         hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
0094     const struct snd_interval *r =
0095         hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE);
0096     struct snd_interval t = {
0097         .min = UINT_MAX, .max = 0, .integer = 1
0098     };
0099     unsigned int i, mode;
0100 
0101     for (i = 0; i < ARRAY_SIZE(freq_table); i++) {
0102         mode = get_multiplier_mode_with_index(i);
0103         if (!snd_interval_test(r, freq_table[i]))
0104             continue;
0105 
0106         t.min = min(t.min, pcm_channels[mode]);
0107         t.max = max(t.max, pcm_channels[mode]);
0108     }
0109 
0110     return snd_interval_refine(c, &t);
0111 }
0112 
0113 static void
0114 limit_channels(struct snd_pcm_hardware *hw, unsigned int *pcm_channels)
0115 {
0116     unsigned int i, mode;
0117 
0118     hw->channels_min = UINT_MAX;
0119     hw->channels_max = 0;
0120 
0121     for (i = 0; i < ARRAY_SIZE(freq_table); i++) {
0122         mode = get_multiplier_mode_with_index(i);
0123         if (pcm_channels[mode] == 0)
0124             continue;
0125 
0126         hw->channels_min = min(hw->channels_min, pcm_channels[mode]);
0127         hw->channels_max = max(hw->channels_max, pcm_channels[mode]);
0128     }
0129 }
0130 
0131 static int
0132 pcm_init_hw_params(struct snd_efw *efw,
0133            struct snd_pcm_substream *substream)
0134 {
0135     struct snd_pcm_runtime *runtime = substream->runtime;
0136     struct amdtp_stream *s;
0137     unsigned int *pcm_channels;
0138     int err;
0139 
0140     if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
0141         runtime->hw.formats = AM824_IN_PCM_FORMAT_BITS;
0142         s = &efw->tx_stream;
0143         pcm_channels = efw->pcm_capture_channels;
0144     } else {
0145         runtime->hw.formats = AM824_OUT_PCM_FORMAT_BITS;
0146         s = &efw->rx_stream;
0147         pcm_channels = efw->pcm_playback_channels;
0148     }
0149 
0150     /* limit rates */
0151     runtime->hw.rates = efw->supported_sampling_rate;
0152     snd_pcm_limit_hw_rates(runtime);
0153 
0154     limit_channels(&runtime->hw, pcm_channels);
0155 
0156     err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
0157                   hw_rule_channels, pcm_channels,
0158                   SNDRV_PCM_HW_PARAM_RATE, -1);
0159     if (err < 0)
0160         goto end;
0161 
0162     err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
0163                   hw_rule_rate, pcm_channels,
0164                   SNDRV_PCM_HW_PARAM_CHANNELS, -1);
0165     if (err < 0)
0166         goto end;
0167 
0168     err = amdtp_am824_add_pcm_hw_constraints(s, runtime);
0169 end:
0170     return err;
0171 }
0172 
0173 static int pcm_open(struct snd_pcm_substream *substream)
0174 {
0175     struct snd_efw *efw = substream->private_data;
0176     struct amdtp_domain *d = &efw->domain;
0177     enum snd_efw_clock_source clock_source;
0178     int err;
0179 
0180     err = snd_efw_stream_lock_try(efw);
0181     if (err < 0)
0182         return err;
0183 
0184     err = pcm_init_hw_params(efw, substream);
0185     if (err < 0)
0186         goto err_locked;
0187 
0188     err = snd_efw_command_get_clock_source(efw, &clock_source);
0189     if (err < 0)
0190         goto err_locked;
0191 
0192     mutex_lock(&efw->mutex);
0193 
0194     // When source of clock is not internal or any stream is reserved for
0195     // transmission of PCM frames, the available sampling rate is limited
0196     // at current one.
0197     if ((clock_source != SND_EFW_CLOCK_SOURCE_INTERNAL) ||
0198         (efw->substreams_counter > 0 && d->events_per_period > 0)) {
0199         unsigned int frames_per_period = d->events_per_period;
0200         unsigned int frames_per_buffer = d->events_per_buffer;
0201         unsigned int sampling_rate;
0202 
0203         err = snd_efw_command_get_sampling_rate(efw, &sampling_rate);
0204         if (err < 0) {
0205             mutex_unlock(&efw->mutex);
0206             goto err_locked;
0207         }
0208         substream->runtime->hw.rate_min = sampling_rate;
0209         substream->runtime->hw.rate_max = sampling_rate;
0210 
0211         if (frames_per_period > 0) {
0212             err = snd_pcm_hw_constraint_minmax(substream->runtime,
0213                     SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
0214                     frames_per_period, frames_per_period);
0215             if (err < 0) {
0216                 mutex_unlock(&efw->mutex);
0217                 goto err_locked;
0218             }
0219 
0220             err = snd_pcm_hw_constraint_minmax(substream->runtime,
0221                     SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
0222                     frames_per_buffer, frames_per_buffer);
0223             if (err < 0) {
0224                 mutex_unlock(&efw->mutex);
0225                 goto err_locked;
0226             }
0227         }
0228     }
0229 
0230     mutex_unlock(&efw->mutex);
0231 
0232     snd_pcm_set_sync(substream);
0233 
0234     return 0;
0235 err_locked:
0236     snd_efw_stream_lock_release(efw);
0237     return err;
0238 }
0239 
0240 static int pcm_close(struct snd_pcm_substream *substream)
0241 {
0242     struct snd_efw *efw = substream->private_data;
0243     snd_efw_stream_lock_release(efw);
0244     return 0;
0245 }
0246 
0247 static int pcm_hw_params(struct snd_pcm_substream *substream,
0248                  struct snd_pcm_hw_params *hw_params)
0249 {
0250     struct snd_efw *efw = substream->private_data;
0251     int err = 0;
0252 
0253     if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
0254         unsigned int rate = params_rate(hw_params);
0255         unsigned int frames_per_period = params_period_size(hw_params);
0256         unsigned int frames_per_buffer = params_buffer_size(hw_params);
0257 
0258         mutex_lock(&efw->mutex);
0259         err = snd_efw_stream_reserve_duplex(efw, rate,
0260                     frames_per_period, frames_per_buffer);
0261         if (err >= 0)
0262             ++efw->substreams_counter;
0263         mutex_unlock(&efw->mutex);
0264     }
0265 
0266     return err;
0267 }
0268 
0269 static int pcm_hw_free(struct snd_pcm_substream *substream)
0270 {
0271     struct snd_efw *efw = substream->private_data;
0272 
0273     mutex_lock(&efw->mutex);
0274 
0275     if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
0276         --efw->substreams_counter;
0277 
0278     snd_efw_stream_stop_duplex(efw);
0279 
0280     mutex_unlock(&efw->mutex);
0281 
0282     return 0;
0283 }
0284 
0285 static int pcm_capture_prepare(struct snd_pcm_substream *substream)
0286 {
0287     struct snd_efw *efw = substream->private_data;
0288     int err;
0289 
0290     err = snd_efw_stream_start_duplex(efw);
0291     if (err >= 0)
0292         amdtp_stream_pcm_prepare(&efw->tx_stream);
0293 
0294     return err;
0295 }
0296 static int pcm_playback_prepare(struct snd_pcm_substream *substream)
0297 {
0298     struct snd_efw *efw = substream->private_data;
0299     int err;
0300 
0301     err = snd_efw_stream_start_duplex(efw);
0302     if (err >= 0)
0303         amdtp_stream_pcm_prepare(&efw->rx_stream);
0304 
0305     return err;
0306 }
0307 
0308 static int pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
0309 {
0310     struct snd_efw *efw = substream->private_data;
0311 
0312     switch (cmd) {
0313     case SNDRV_PCM_TRIGGER_START:
0314         amdtp_stream_pcm_trigger(&efw->tx_stream, substream);
0315         break;
0316     case SNDRV_PCM_TRIGGER_STOP:
0317         amdtp_stream_pcm_trigger(&efw->tx_stream, NULL);
0318         break;
0319     default:
0320         return -EINVAL;
0321     }
0322 
0323     return 0;
0324 }
0325 static int pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
0326 {
0327     struct snd_efw *efw = substream->private_data;
0328 
0329     switch (cmd) {
0330     case SNDRV_PCM_TRIGGER_START:
0331         amdtp_stream_pcm_trigger(&efw->rx_stream, substream);
0332         break;
0333     case SNDRV_PCM_TRIGGER_STOP:
0334         amdtp_stream_pcm_trigger(&efw->rx_stream, NULL);
0335         break;
0336     default:
0337         return -EINVAL;
0338     }
0339 
0340     return 0;
0341 }
0342 
0343 static snd_pcm_uframes_t pcm_capture_pointer(struct snd_pcm_substream *sbstrm)
0344 {
0345     struct snd_efw *efw = sbstrm->private_data;
0346 
0347     return amdtp_domain_stream_pcm_pointer(&efw->domain, &efw->tx_stream);
0348 }
0349 static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm)
0350 {
0351     struct snd_efw *efw = sbstrm->private_data;
0352 
0353     return amdtp_domain_stream_pcm_pointer(&efw->domain, &efw->rx_stream);
0354 }
0355 
0356 static int pcm_capture_ack(struct snd_pcm_substream *substream)
0357 {
0358     struct snd_efw *efw = substream->private_data;
0359 
0360     return amdtp_domain_stream_pcm_ack(&efw->domain, &efw->tx_stream);
0361 }
0362 
0363 static int pcm_playback_ack(struct snd_pcm_substream *substream)
0364 {
0365     struct snd_efw *efw = substream->private_data;
0366 
0367     return amdtp_domain_stream_pcm_ack(&efw->domain, &efw->rx_stream);
0368 }
0369 
0370 int snd_efw_create_pcm_devices(struct snd_efw *efw)
0371 {
0372     static const struct snd_pcm_ops capture_ops = {
0373         .open       = pcm_open,
0374         .close      = pcm_close,
0375         .hw_params  = pcm_hw_params,
0376         .hw_free    = pcm_hw_free,
0377         .prepare    = pcm_capture_prepare,
0378         .trigger    = pcm_capture_trigger,
0379         .pointer    = pcm_capture_pointer,
0380         .ack        = pcm_capture_ack,
0381     };
0382     static const struct snd_pcm_ops playback_ops = {
0383         .open       = pcm_open,
0384         .close      = pcm_close,
0385         .hw_params  = pcm_hw_params,
0386         .hw_free    = pcm_hw_free,
0387         .prepare    = pcm_playback_prepare,
0388         .trigger    = pcm_playback_trigger,
0389         .pointer    = pcm_playback_pointer,
0390         .ack        = pcm_playback_ack,
0391     };
0392     struct snd_pcm *pcm;
0393     int err;
0394 
0395     err = snd_pcm_new(efw->card, efw->card->driver, 0, 1, 1, &pcm);
0396     if (err < 0)
0397         goto end;
0398 
0399     pcm->private_data = efw;
0400     snprintf(pcm->name, sizeof(pcm->name), "%s PCM", efw->card->shortname);
0401     snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops);
0402     snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops);
0403     snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
0404 end:
0405     return err;
0406 }
0407