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 mutex_lock(&ff->mutex); 160 161 // When source of clock is not internal or any stream is reserved for 162 // transmission of PCM frames, the available sampling rate is limited 163 // at current one. 164 if (src != SND_FF_CLOCK_SRC_INTERNAL) { 165 for (i = 0; i < CIP_SFC_COUNT; ++i) { 166 if (amdtp_rate_table[i] == rate) 167 break; 168 } 169 170 // The unit is configured at sampling frequency which packet 171 // streaming engine can't support. 172 if (i >= CIP_SFC_COUNT) { 173 mutex_unlock(&ff->mutex); 174 err = -EIO; 175 goto release_lock; 176 } 177 178 substream->runtime->hw.rate_min = rate; 179 substream->runtime->hw.rate_max = rate; 180 } else { 181 if (ff->substreams_counter > 0) { 182 unsigned int frames_per_period = d->events_per_period; 183 unsigned int frames_per_buffer = d->events_per_buffer; 184 185 rate = amdtp_rate_table[ff->rx_stream.sfc]; 186 substream->runtime->hw.rate_min = rate; 187 substream->runtime->hw.rate_max = rate; 188 189 err = snd_pcm_hw_constraint_minmax(substream->runtime, 190 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 191 frames_per_period, frames_per_period); 192 if (err < 0) { 193 mutex_unlock(&ff->mutex); 194 goto release_lock; 195 } 196 197 err = snd_pcm_hw_constraint_minmax(substream->runtime, 198 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 199 frames_per_buffer, frames_per_buffer); 200 if (err < 0) { 201 mutex_unlock(&ff->mutex); 202 goto release_lock; 203 } 204 } 205 } 206 207 mutex_unlock(&ff->mutex); 208 209 snd_pcm_set_sync(substream); 210 211 return 0; 212 213 release_lock: 214 snd_ff_stream_lock_release(ff); 215 return err; 216 } 217 218 static int pcm_close(struct snd_pcm_substream *substream) 219 { 220 struct snd_ff *ff = substream->private_data; 221 222 snd_ff_stream_lock_release(ff); 223 224 return 0; 225 } 226 227 static int pcm_hw_params(struct snd_pcm_substream *substream, 228 struct snd_pcm_hw_params *hw_params) 229 { 230 struct snd_ff *ff = substream->private_data; 231 int err; 232 233 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); 234 if (err < 0) 235 return err; 236 237 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) { 238 unsigned int rate = params_rate(hw_params); 239 unsigned int frames_per_period = params_period_size(hw_params); 240 unsigned int frames_per_buffer = params_buffer_size(hw_params); 241 242 mutex_lock(&ff->mutex); 243 err = snd_ff_stream_reserve_duplex(ff, rate, frames_per_period, 244 frames_per_buffer); 245 if (err >= 0) 246 ++ff->substreams_counter; 247 mutex_unlock(&ff->mutex); 248 } 249 250 return err; 251 } 252 253 static int pcm_hw_free(struct snd_pcm_substream *substream) 254 { 255 struct snd_ff *ff = substream->private_data; 256 257 mutex_lock(&ff->mutex); 258 259 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) 260 --ff->substreams_counter; 261 262 snd_ff_stream_stop_duplex(ff); 263 264 mutex_unlock(&ff->mutex); 265 266 return snd_pcm_lib_free_pages(substream); 267 } 268 269 static int pcm_capture_prepare(struct snd_pcm_substream *substream) 270 { 271 struct snd_ff *ff = substream->private_data; 272 struct snd_pcm_runtime *runtime = substream->runtime; 273 int err; 274 275 mutex_lock(&ff->mutex); 276 277 err = snd_ff_stream_start_duplex(ff, runtime->rate); 278 if (err >= 0) 279 amdtp_stream_pcm_prepare(&ff->tx_stream); 280 281 mutex_unlock(&ff->mutex); 282 283 return err; 284 } 285 286 static int pcm_playback_prepare(struct snd_pcm_substream *substream) 287 { 288 struct snd_ff *ff = substream->private_data; 289 struct snd_pcm_runtime *runtime = substream->runtime; 290 int err; 291 292 mutex_lock(&ff->mutex); 293 294 err = snd_ff_stream_start_duplex(ff, runtime->rate); 295 if (err >= 0) 296 amdtp_stream_pcm_prepare(&ff->rx_stream); 297 298 mutex_unlock(&ff->mutex); 299 300 return err; 301 } 302 303 static int pcm_capture_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->tx_stream, substream); 310 break; 311 case SNDRV_PCM_TRIGGER_STOP: 312 amdtp_stream_pcm_trigger(&ff->tx_stream, NULL); 313 break; 314 default: 315 return -EINVAL; 316 } 317 318 return 0; 319 } 320 321 static int pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd) 322 { 323 struct snd_ff *ff = substream->private_data; 324 325 switch (cmd) { 326 case SNDRV_PCM_TRIGGER_START: 327 amdtp_stream_pcm_trigger(&ff->rx_stream, substream); 328 break; 329 case SNDRV_PCM_TRIGGER_STOP: 330 amdtp_stream_pcm_trigger(&ff->rx_stream, NULL); 331 break; 332 default: 333 return -EINVAL; 334 } 335 336 return 0; 337 } 338 339 static snd_pcm_uframes_t pcm_capture_pointer(struct snd_pcm_substream *sbstrm) 340 { 341 struct snd_ff *ff = sbstrm->private_data; 342 343 return amdtp_domain_stream_pcm_pointer(&ff->domain, &ff->tx_stream); 344 } 345 346 static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm) 347 { 348 struct snd_ff *ff = sbstrm->private_data; 349 350 return amdtp_domain_stream_pcm_pointer(&ff->domain, &ff->rx_stream); 351 } 352 353 static int pcm_capture_ack(struct snd_pcm_substream *substream) 354 { 355 struct snd_ff *ff = substream->private_data; 356 357 return amdtp_domain_stream_pcm_ack(&ff->domain, &ff->tx_stream); 358 } 359 360 static int pcm_playback_ack(struct snd_pcm_substream *substream) 361 { 362 struct snd_ff *ff = substream->private_data; 363 364 return amdtp_domain_stream_pcm_ack(&ff->domain, &ff->rx_stream); 365 } 366 367 int snd_ff_create_pcm_devices(struct snd_ff *ff) 368 { 369 static const struct snd_pcm_ops pcm_capture_ops = { 370 .open = pcm_open, 371 .close = pcm_close, 372 .ioctl = snd_pcm_lib_ioctl, 373 .hw_params = pcm_hw_params, 374 .hw_free = pcm_hw_free, 375 .prepare = pcm_capture_prepare, 376 .trigger = pcm_capture_trigger, 377 .pointer = pcm_capture_pointer, 378 .ack = pcm_capture_ack, 379 }; 380 static const struct snd_pcm_ops pcm_playback_ops = { 381 .open = pcm_open, 382 .close = pcm_close, 383 .ioctl = snd_pcm_lib_ioctl, 384 .hw_params = pcm_hw_params, 385 .hw_free = pcm_hw_free, 386 .prepare = pcm_playback_prepare, 387 .trigger = pcm_playback_trigger, 388 .pointer = pcm_playback_pointer, 389 .ack = pcm_playback_ack, 390 }; 391 struct snd_pcm *pcm; 392 int err; 393 394 err = snd_pcm_new(ff->card, ff->card->driver, 0, 1, 1, &pcm); 395 if (err < 0) 396 return err; 397 398 pcm->private_data = ff; 399 snprintf(pcm->name, sizeof(pcm->name), 400 "%s PCM", ff->card->shortname); 401 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_playback_ops); 402 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_capture_ops); 403 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_VMALLOC, 404 NULL, 0, 0); 405 406 return 0; 407 } 408