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_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 unsigned int rate = params_rate(hw_params); 214 215 mutex_lock(&ff->mutex); 216 err = snd_ff_stream_reserve_duplex(ff, rate); 217 if (err >= 0) 218 ++ff->substreams_counter; 219 mutex_unlock(&ff->mutex); 220 } 221 222 return 0; 223 } 224 225 static int pcm_hw_free(struct snd_pcm_substream *substream) 226 { 227 struct snd_ff *ff = substream->private_data; 228 229 mutex_lock(&ff->mutex); 230 231 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) 232 --ff->substreams_counter; 233 234 snd_ff_stream_stop_duplex(ff); 235 236 mutex_unlock(&ff->mutex); 237 238 return snd_pcm_lib_free_vmalloc_buffer(substream); 239 } 240 241 static int pcm_capture_prepare(struct snd_pcm_substream *substream) 242 { 243 struct snd_ff *ff = substream->private_data; 244 struct snd_pcm_runtime *runtime = substream->runtime; 245 int err; 246 247 mutex_lock(&ff->mutex); 248 249 err = snd_ff_stream_start_duplex(ff, runtime->rate); 250 if (err >= 0) 251 amdtp_stream_pcm_prepare(&ff->tx_stream); 252 253 mutex_unlock(&ff->mutex); 254 255 return err; 256 } 257 258 static int pcm_playback_prepare(struct snd_pcm_substream *substream) 259 { 260 struct snd_ff *ff = substream->private_data; 261 struct snd_pcm_runtime *runtime = substream->runtime; 262 int err; 263 264 mutex_lock(&ff->mutex); 265 266 err = snd_ff_stream_start_duplex(ff, runtime->rate); 267 if (err >= 0) 268 amdtp_stream_pcm_prepare(&ff->rx_stream); 269 270 mutex_unlock(&ff->mutex); 271 272 return err; 273 } 274 275 static int pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd) 276 { 277 struct snd_ff *ff = substream->private_data; 278 279 switch (cmd) { 280 case SNDRV_PCM_TRIGGER_START: 281 amdtp_stream_pcm_trigger(&ff->tx_stream, substream); 282 break; 283 case SNDRV_PCM_TRIGGER_STOP: 284 amdtp_stream_pcm_trigger(&ff->tx_stream, NULL); 285 break; 286 default: 287 return -EINVAL; 288 } 289 290 return 0; 291 } 292 293 static int pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd) 294 { 295 struct snd_ff *ff = substream->private_data; 296 297 switch (cmd) { 298 case SNDRV_PCM_TRIGGER_START: 299 amdtp_stream_pcm_trigger(&ff->rx_stream, substream); 300 break; 301 case SNDRV_PCM_TRIGGER_STOP: 302 amdtp_stream_pcm_trigger(&ff->rx_stream, NULL); 303 break; 304 default: 305 return -EINVAL; 306 } 307 308 return 0; 309 } 310 311 static snd_pcm_uframes_t pcm_capture_pointer(struct snd_pcm_substream *sbstrm) 312 { 313 struct snd_ff *ff = sbstrm->private_data; 314 315 return amdtp_stream_pcm_pointer(&ff->tx_stream); 316 } 317 318 static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm) 319 { 320 struct snd_ff *ff = sbstrm->private_data; 321 322 return amdtp_stream_pcm_pointer(&ff->rx_stream); 323 } 324 325 static int pcm_capture_ack(struct snd_pcm_substream *substream) 326 { 327 struct snd_ff *ff = substream->private_data; 328 329 return amdtp_stream_pcm_ack(&ff->tx_stream); 330 } 331 332 static int pcm_playback_ack(struct snd_pcm_substream *substream) 333 { 334 struct snd_ff *ff = substream->private_data; 335 336 return amdtp_stream_pcm_ack(&ff->rx_stream); 337 } 338 339 int snd_ff_create_pcm_devices(struct snd_ff *ff) 340 { 341 static const struct snd_pcm_ops pcm_capture_ops = { 342 .open = pcm_open, 343 .close = pcm_close, 344 .ioctl = snd_pcm_lib_ioctl, 345 .hw_params = pcm_hw_params, 346 .hw_free = pcm_hw_free, 347 .prepare = pcm_capture_prepare, 348 .trigger = pcm_capture_trigger, 349 .pointer = pcm_capture_pointer, 350 .ack = pcm_capture_ack, 351 .page = snd_pcm_lib_get_vmalloc_page, 352 }; 353 static const struct snd_pcm_ops pcm_playback_ops = { 354 .open = pcm_open, 355 .close = pcm_close, 356 .ioctl = snd_pcm_lib_ioctl, 357 .hw_params = pcm_hw_params, 358 .hw_free = pcm_hw_free, 359 .prepare = pcm_playback_prepare, 360 .trigger = pcm_playback_trigger, 361 .pointer = pcm_playback_pointer, 362 .ack = pcm_playback_ack, 363 .page = snd_pcm_lib_get_vmalloc_page, 364 }; 365 struct snd_pcm *pcm; 366 int err; 367 368 err = snd_pcm_new(ff->card, ff->card->driver, 0, 1, 1, &pcm); 369 if (err < 0) 370 return err; 371 372 pcm->private_data = ff; 373 snprintf(pcm->name, sizeof(pcm->name), 374 "%s PCM", ff->card->shortname); 375 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_playback_ops); 376 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_capture_ops); 377 378 return 0; 379 } 380