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