0001
0002
0003
0004
0005
0006
0007
0008 #include "tascam.h"
0009
0010 static int pcm_init_hw_params(struct snd_tscm *tscm,
0011 struct snd_pcm_substream *substream)
0012 {
0013 struct snd_pcm_runtime *runtime = substream->runtime;
0014 struct snd_pcm_hardware *hw = &runtime->hw;
0015 struct amdtp_stream *stream;
0016 unsigned int pcm_channels;
0017
0018 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
0019 runtime->hw.formats = SNDRV_PCM_FMTBIT_S32;
0020 stream = &tscm->tx_stream;
0021 pcm_channels = tscm->spec->pcm_capture_analog_channels;
0022 } else {
0023 runtime->hw.formats = SNDRV_PCM_FMTBIT_S32;
0024 stream = &tscm->rx_stream;
0025 pcm_channels = tscm->spec->pcm_playback_analog_channels;
0026 }
0027
0028 if (tscm->spec->has_adat)
0029 pcm_channels += 8;
0030 if (tscm->spec->has_spdif)
0031 pcm_channels += 2;
0032 runtime->hw.channels_min = runtime->hw.channels_max = pcm_channels;
0033
0034 hw->rates = SNDRV_PCM_RATE_44100 |
0035 SNDRV_PCM_RATE_48000 |
0036 SNDRV_PCM_RATE_88200 |
0037 SNDRV_PCM_RATE_96000;
0038 snd_pcm_limit_hw_rates(runtime);
0039
0040 return amdtp_tscm_add_pcm_hw_constraints(stream, runtime);
0041 }
0042
0043 static int pcm_open(struct snd_pcm_substream *substream)
0044 {
0045 struct snd_tscm *tscm = substream->private_data;
0046 struct amdtp_domain *d = &tscm->domain;
0047 enum snd_tscm_clock clock;
0048 int err;
0049
0050 err = snd_tscm_stream_lock_try(tscm);
0051 if (err < 0)
0052 return err;
0053
0054 err = pcm_init_hw_params(tscm, substream);
0055 if (err < 0)
0056 goto err_locked;
0057
0058 err = snd_tscm_stream_get_clock(tscm, &clock);
0059 if (err < 0)
0060 goto err_locked;
0061
0062 mutex_lock(&tscm->mutex);
0063
0064
0065
0066
0067 if (clock != SND_TSCM_CLOCK_INTERNAL || tscm->substreams_counter > 0) {
0068 unsigned int frames_per_period = d->events_per_period;
0069 unsigned int frames_per_buffer = d->events_per_buffer;
0070 unsigned int rate;
0071
0072 err = snd_tscm_stream_get_rate(tscm, &rate);
0073 if (err < 0) {
0074 mutex_unlock(&tscm->mutex);
0075 goto err_locked;
0076 }
0077 substream->runtime->hw.rate_min = rate;
0078 substream->runtime->hw.rate_max = rate;
0079
0080 err = snd_pcm_hw_constraint_minmax(substream->runtime,
0081 SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
0082 frames_per_period, frames_per_period);
0083 if (err < 0) {
0084 mutex_unlock(&tscm->mutex);
0085 goto err_locked;
0086 }
0087
0088 err = snd_pcm_hw_constraint_minmax(substream->runtime,
0089 SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
0090 frames_per_buffer, frames_per_buffer);
0091 if (err < 0) {
0092 mutex_unlock(&tscm->mutex);
0093 goto err_locked;
0094 }
0095 }
0096
0097 mutex_unlock(&tscm->mutex);
0098
0099 snd_pcm_set_sync(substream);
0100
0101 return 0;
0102 err_locked:
0103 snd_tscm_stream_lock_release(tscm);
0104 return err;
0105 }
0106
0107 static int pcm_close(struct snd_pcm_substream *substream)
0108 {
0109 struct snd_tscm *tscm = substream->private_data;
0110
0111 snd_tscm_stream_lock_release(tscm);
0112
0113 return 0;
0114 }
0115
0116 static int pcm_hw_params(struct snd_pcm_substream *substream,
0117 struct snd_pcm_hw_params *hw_params)
0118 {
0119 struct snd_tscm *tscm = substream->private_data;
0120 int err = 0;
0121
0122 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
0123 unsigned int rate = params_rate(hw_params);
0124 unsigned int frames_per_period = params_period_size(hw_params);
0125 unsigned int frames_per_buffer = params_buffer_size(hw_params);
0126
0127 mutex_lock(&tscm->mutex);
0128 err = snd_tscm_stream_reserve_duplex(tscm, rate,
0129 frames_per_period, frames_per_buffer);
0130 if (err >= 0)
0131 ++tscm->substreams_counter;
0132 mutex_unlock(&tscm->mutex);
0133 }
0134
0135 return err;
0136 }
0137
0138 static int pcm_hw_free(struct snd_pcm_substream *substream)
0139 {
0140 struct snd_tscm *tscm = substream->private_data;
0141
0142 mutex_lock(&tscm->mutex);
0143
0144 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
0145 --tscm->substreams_counter;
0146
0147 snd_tscm_stream_stop_duplex(tscm);
0148
0149 mutex_unlock(&tscm->mutex);
0150
0151 return 0;
0152 }
0153
0154 static int pcm_capture_prepare(struct snd_pcm_substream *substream)
0155 {
0156 struct snd_tscm *tscm = substream->private_data;
0157 struct snd_pcm_runtime *runtime = substream->runtime;
0158 int err;
0159
0160 mutex_lock(&tscm->mutex);
0161
0162 err = snd_tscm_stream_start_duplex(tscm, runtime->rate);
0163 if (err >= 0)
0164 amdtp_stream_pcm_prepare(&tscm->tx_stream);
0165
0166 mutex_unlock(&tscm->mutex);
0167
0168 return err;
0169 }
0170
0171 static int pcm_playback_prepare(struct snd_pcm_substream *substream)
0172 {
0173 struct snd_tscm *tscm = substream->private_data;
0174 struct snd_pcm_runtime *runtime = substream->runtime;
0175 int err;
0176
0177 mutex_lock(&tscm->mutex);
0178
0179 err = snd_tscm_stream_start_duplex(tscm, runtime->rate);
0180 if (err >= 0)
0181 amdtp_stream_pcm_prepare(&tscm->rx_stream);
0182
0183 mutex_unlock(&tscm->mutex);
0184
0185 return err;
0186 }
0187
0188 static int pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
0189 {
0190 struct snd_tscm *tscm = substream->private_data;
0191
0192 switch (cmd) {
0193 case SNDRV_PCM_TRIGGER_START:
0194 amdtp_stream_pcm_trigger(&tscm->tx_stream, substream);
0195 break;
0196 case SNDRV_PCM_TRIGGER_STOP:
0197 amdtp_stream_pcm_trigger(&tscm->tx_stream, NULL);
0198 break;
0199 default:
0200 return -EINVAL;
0201 }
0202
0203 return 0;
0204 }
0205
0206 static int pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
0207 {
0208 struct snd_tscm *tscm = substream->private_data;
0209
0210 switch (cmd) {
0211 case SNDRV_PCM_TRIGGER_START:
0212 amdtp_stream_pcm_trigger(&tscm->rx_stream, substream);
0213 break;
0214 case SNDRV_PCM_TRIGGER_STOP:
0215 amdtp_stream_pcm_trigger(&tscm->rx_stream, NULL);
0216 break;
0217 default:
0218 return -EINVAL;
0219 }
0220
0221 return 0;
0222 }
0223
0224 static snd_pcm_uframes_t pcm_capture_pointer(struct snd_pcm_substream *sbstrm)
0225 {
0226 struct snd_tscm *tscm = sbstrm->private_data;
0227
0228 return amdtp_domain_stream_pcm_pointer(&tscm->domain, &tscm->tx_stream);
0229 }
0230
0231 static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm)
0232 {
0233 struct snd_tscm *tscm = sbstrm->private_data;
0234
0235 return amdtp_domain_stream_pcm_pointer(&tscm->domain, &tscm->rx_stream);
0236 }
0237
0238 static int pcm_capture_ack(struct snd_pcm_substream *substream)
0239 {
0240 struct snd_tscm *tscm = substream->private_data;
0241
0242 return amdtp_domain_stream_pcm_ack(&tscm->domain, &tscm->tx_stream);
0243 }
0244
0245 static int pcm_playback_ack(struct snd_pcm_substream *substream)
0246 {
0247 struct snd_tscm *tscm = substream->private_data;
0248
0249 return amdtp_domain_stream_pcm_ack(&tscm->domain, &tscm->rx_stream);
0250 }
0251
0252 int snd_tscm_create_pcm_devices(struct snd_tscm *tscm)
0253 {
0254 static const struct snd_pcm_ops capture_ops = {
0255 .open = pcm_open,
0256 .close = pcm_close,
0257 .hw_params = pcm_hw_params,
0258 .hw_free = pcm_hw_free,
0259 .prepare = pcm_capture_prepare,
0260 .trigger = pcm_capture_trigger,
0261 .pointer = pcm_capture_pointer,
0262 .ack = pcm_capture_ack,
0263 };
0264 static const struct snd_pcm_ops playback_ops = {
0265 .open = pcm_open,
0266 .close = pcm_close,
0267 .hw_params = pcm_hw_params,
0268 .hw_free = pcm_hw_free,
0269 .prepare = pcm_playback_prepare,
0270 .trigger = pcm_playback_trigger,
0271 .pointer = pcm_playback_pointer,
0272 .ack = pcm_playback_ack,
0273 };
0274 struct snd_pcm *pcm;
0275 int err;
0276
0277 err = snd_pcm_new(tscm->card, tscm->card->driver, 0, 1, 1, &pcm);
0278 if (err < 0)
0279 return err;
0280
0281 pcm->private_data = tscm;
0282 snprintf(pcm->name, sizeof(pcm->name),
0283 "%s PCM", tscm->card->shortname);
0284 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops);
0285 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops);
0286 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
0287
0288 return 0;
0289 }