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