1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * ff-pcm.c - a part of driver for RME Fireface series 4 * 5 * Copyright (c) 2015-2017 Takashi Sakamoto 6 */ 7 8 #include "ff.h" 9 10 static int hw_rule_rate(struct snd_pcm_hw_params *params, 11 struct snd_pcm_hw_rule *rule) 12 { 13 const unsigned int *pcm_channels = rule->private; 14 struct snd_interval *r = 15 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 16 const struct snd_interval *c = 17 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS); 18 struct snd_interval t = { 19 .min = UINT_MAX, .max = 0, .integer = 1 20 }; 21 unsigned int i; 22 23 for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); i++) { 24 enum snd_ff_stream_mode mode; 25 int err; 26 27 err = snd_ff_stream_get_multiplier_mode(i, &mode); 28 if (err < 0) 29 continue; 30 31 if (!snd_interval_test(c, pcm_channels[mode])) 32 continue; 33 34 t.min = min(t.min, amdtp_rate_table[i]); 35 t.max = max(t.max, amdtp_rate_table[i]); 36 } 37 38 return snd_interval_refine(r, &t); 39 } 40 41 static int hw_rule_channels(struct snd_pcm_hw_params *params, 42 struct snd_pcm_hw_rule *rule) 43 { 44 const unsigned int *pcm_channels = rule->private; 45 struct snd_interval *c = 46 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); 47 const struct snd_interval *r = 48 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE); 49 struct snd_interval t = { 50 .min = UINT_MAX, .max = 0, .integer = 1 51 }; 52 unsigned int i; 53 54 for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); i++) { 55 enum snd_ff_stream_mode mode; 56 int err; 57 58 err = snd_ff_stream_get_multiplier_mode(i, &mode); 59 if (err < 0) 60 continue; 61 62 if (!snd_interval_test(r, amdtp_rate_table[i])) 63 continue; 64 65 t.min = min(t.min, pcm_channels[mode]); 66 t.max = max(t.max, pcm_channels[mode]); 67 } 68 69 return snd_interval_refine(c, &t); 70 } 71 72 static void limit_channels_and_rates(struct snd_pcm_hardware *hw, 73 const unsigned int *pcm_channels) 74 { 75 unsigned int rate, channels; 76 int i; 77 78 hw->channels_min = UINT_MAX; 79 hw->channels_max = 0; 80 hw->rate_min = UINT_MAX; 81 hw->rate_max = 0; 82 83 for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); i++) { 84 enum snd_ff_stream_mode mode; 85 int err; 86 87 err = snd_ff_stream_get_multiplier_mode(i, &mode); 88 if (err < 0) 89 continue; 90 91 channels = pcm_channels[mode]; 92 if (pcm_channels[mode] == 0) 93 continue; 94 hw->channels_min = min(hw->channels_min, channels); 95 hw->channels_max = max(hw->channels_max, channels); 96 97 rate = amdtp_rate_table[i]; 98 hw->rates |= snd_pcm_rate_to_rate_bit(rate); 99 hw->rate_min = min(hw->rate_min, rate); 100 hw->rate_max = max(hw->rate_max, rate); 101 } 102 } 103 104 static int pcm_init_hw_params(struct snd_ff *ff, 105 struct snd_pcm_substream *substream) 106 { 107 struct snd_pcm_runtime *runtime = substream->runtime; 108 struct amdtp_stream *s; 109 const unsigned int *pcm_channels; 110 int err; 111 112 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 113 runtime->hw.formats = SNDRV_PCM_FMTBIT_S32; 114 s = &ff->tx_stream; 115 pcm_channels = ff->spec->pcm_capture_channels; 116 } else { 117 runtime->hw.formats = SNDRV_PCM_FMTBIT_S32; 118 s = &ff->rx_stream; 119 pcm_channels = ff->spec->pcm_playback_channels; 120 } 121 122 limit_channels_and_rates(&runtime->hw, pcm_channels); 123 124 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 125 hw_rule_channels, (void *)pcm_channels, 126 SNDRV_PCM_HW_PARAM_RATE, -1); 127 if (err < 0) 128 return err; 129 130 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 131 hw_rule_rate, (void *)pcm_channels, 132 SNDRV_PCM_HW_PARAM_CHANNELS, -1); 133 if (err < 0) 134 return err; 135 136 return amdtp_ff_add_pcm_hw_constraints(s, runtime); 137 } 138 139 static int pcm_open(struct snd_pcm_substream *substream) 140 { 141 struct snd_ff *ff = substream->private_data; 142 struct amdtp_domain *d = &ff->domain; 143 unsigned int rate; 144 enum snd_ff_clock_src src; 145 int i, err; 146 147 err = snd_ff_stream_lock_try(ff); 148 if (err < 0) 149 return err; 150 151 err = pcm_init_hw_params(ff, substream); 152 if (err < 0) 153 goto release_lock; 154 155 err = ff->spec->protocol->get_clock(ff, &rate, &src); 156 if (err < 0) 157 goto release_lock; 158 159 scoped_guard(mutex, &ff->mutex) { 160 // When source of clock is not internal or any stream is reserved for 161 // transmission of PCM frames, the available sampling rate is limited 162 // at current one. 163 if (src != SND_FF_CLOCK_SRC_INTERNAL) { 164 for (i = 0; i < CIP_SFC_COUNT; ++i) { 165 if (amdtp_rate_table[i] == rate) 166 break; 167 } 168 169 // The unit is configured at sampling frequency which packet 170 // streaming engine can't support. 171 if (i >= CIP_SFC_COUNT) { 172 err = -EIO; 173 goto release_lock; 174 } 175 176 substream->runtime->hw.rate_min = rate; 177 substream->runtime->hw.rate_max = rate; 178 } else { 179 if (ff->substreams_counter > 0) { 180 unsigned int frames_per_period = d->events_per_period; 181 unsigned int frames_per_buffer = d->events_per_buffer; 182 183 rate = amdtp_rate_table[ff->rx_stream.sfc]; 184 substream->runtime->hw.rate_min = rate; 185 substream->runtime->hw.rate_max = rate; 186 187 err = snd_pcm_hw_constraint_minmax(substream->runtime, 188 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 189 frames_per_period, frames_per_period); 190 if (err < 0) 191 goto release_lock; 192 193 err = snd_pcm_hw_constraint_minmax(substream->runtime, 194 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 195 frames_per_buffer, frames_per_buffer); 196 if (err < 0) 197 goto release_lock; 198 } 199 } 200 } 201 202 snd_pcm_set_sync(substream); 203 204 return 0; 205 206 release_lock: 207 snd_ff_stream_lock_release(ff); 208 return err; 209 } 210 211 static int pcm_close(struct snd_pcm_substream *substream) 212 { 213 struct snd_ff *ff = substream->private_data; 214 215 snd_ff_stream_lock_release(ff); 216 217 return 0; 218 } 219 220 static int pcm_hw_params(struct snd_pcm_substream *substream, 221 struct snd_pcm_hw_params *hw_params) 222 { 223 struct snd_ff *ff = substream->private_data; 224 int err = 0; 225 226 if (substream->runtime->state == SNDRV_PCM_STATE_OPEN) { 227 unsigned int rate = params_rate(hw_params); 228 unsigned int frames_per_period = params_period_size(hw_params); 229 unsigned int frames_per_buffer = params_buffer_size(hw_params); 230 231 guard(mutex)(&ff->mutex); 232 err = snd_ff_stream_reserve_duplex(ff, rate, frames_per_period, 233 frames_per_buffer); 234 if (err >= 0) 235 ++ff->substreams_counter; 236 } 237 238 return err; 239 } 240 241 static int pcm_hw_free(struct snd_pcm_substream *substream) 242 { 243 struct snd_ff *ff = substream->private_data; 244 245 guard(mutex)(&ff->mutex); 246 247 if (substream->runtime->state != SNDRV_PCM_STATE_OPEN) 248 --ff->substreams_counter; 249 250 snd_ff_stream_stop_duplex(ff); 251 252 return 0; 253 } 254 255 static int pcm_capture_prepare(struct snd_pcm_substream *substream) 256 { 257 struct snd_ff *ff = substream->private_data; 258 struct snd_pcm_runtime *runtime = substream->runtime; 259 int err; 260 261 guard(mutex)(&ff->mutex); 262 263 err = snd_ff_stream_start_duplex(ff, runtime->rate); 264 if (err >= 0) 265 amdtp_stream_pcm_prepare(&ff->tx_stream); 266 267 return err; 268 } 269 270 static int pcm_playback_prepare(struct snd_pcm_substream *substream) 271 { 272 struct snd_ff *ff = substream->private_data; 273 struct snd_pcm_runtime *runtime = substream->runtime; 274 int err; 275 276 guard(mutex)(&ff->mutex); 277 278 err = snd_ff_stream_start_duplex(ff, runtime->rate); 279 if (err >= 0) 280 amdtp_stream_pcm_prepare(&ff->rx_stream); 281 282 return err; 283 } 284 285 static int pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd) 286 { 287 struct snd_ff *ff = substream->private_data; 288 289 switch (cmd) { 290 case SNDRV_PCM_TRIGGER_START: 291 amdtp_stream_pcm_trigger(&ff->tx_stream, substream); 292 break; 293 case SNDRV_PCM_TRIGGER_STOP: 294 amdtp_stream_pcm_trigger(&ff->tx_stream, NULL); 295 break; 296 default: 297 return -EINVAL; 298 } 299 300 return 0; 301 } 302 303 static int pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd) 304 { 305 struct snd_ff *ff = substream->private_data; 306 307 switch (cmd) { 308 case SNDRV_PCM_TRIGGER_START: 309 amdtp_stream_pcm_trigger(&ff->rx_stream, substream); 310 break; 311 case SNDRV_PCM_TRIGGER_STOP: 312 amdtp_stream_pcm_trigger(&ff->rx_stream, NULL); 313 break; 314 default: 315 return -EINVAL; 316 } 317 318 return 0; 319 } 320 321 static snd_pcm_uframes_t pcm_capture_pointer(struct snd_pcm_substream *sbstrm) 322 { 323 struct snd_ff *ff = sbstrm->private_data; 324 325 return amdtp_domain_stream_pcm_pointer(&ff->domain, &ff->tx_stream); 326 } 327 328 static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm) 329 { 330 struct snd_ff *ff = sbstrm->private_data; 331 332 return amdtp_domain_stream_pcm_pointer(&ff->domain, &ff->rx_stream); 333 } 334 335 static int pcm_capture_ack(struct snd_pcm_substream *substream) 336 { 337 struct snd_ff *ff = substream->private_data; 338 339 return amdtp_domain_stream_pcm_ack(&ff->domain, &ff->tx_stream); 340 } 341 342 static int pcm_playback_ack(struct snd_pcm_substream *substream) 343 { 344 struct snd_ff *ff = substream->private_data; 345 346 return amdtp_domain_stream_pcm_ack(&ff->domain, &ff->rx_stream); 347 } 348 349 int snd_ff_create_pcm_devices(struct snd_ff *ff) 350 { 351 static const struct snd_pcm_ops pcm_capture_ops = { 352 .open = pcm_open, 353 .close = pcm_close, 354 .hw_params = pcm_hw_params, 355 .hw_free = pcm_hw_free, 356 .prepare = pcm_capture_prepare, 357 .trigger = pcm_capture_trigger, 358 .pointer = pcm_capture_pointer, 359 .ack = pcm_capture_ack, 360 }; 361 static const struct snd_pcm_ops pcm_playback_ops = { 362 .open = pcm_open, 363 .close = pcm_close, 364 .hw_params = pcm_hw_params, 365 .hw_free = pcm_hw_free, 366 .prepare = pcm_playback_prepare, 367 .trigger = pcm_playback_trigger, 368 .pointer = pcm_playback_pointer, 369 .ack = pcm_playback_ack, 370 }; 371 struct snd_pcm *pcm; 372 int err; 373 374 err = snd_pcm_new(ff->card, ff->card->driver, 0, 1, 1, &pcm); 375 if (err < 0) 376 return err; 377 378 pcm->private_data = ff; 379 pcm->nonatomic = true; 380 snprintf(pcm->name, sizeof(pcm->name), 381 "%s PCM", ff->card->shortname); 382 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_playback_ops); 383 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_capture_ops); 384 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0); 385 386 return 0; 387 } 388