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