1 /* 2 * motu-pcm.c - a part of driver for MOTU FireWire series 3 * 4 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp> 5 * 6 * Licensed under the terms of the GNU General Public License, version 2. 7 */ 8 9 #include <sound/pcm_params.h> 10 #include "motu.h" 11 12 static int motu_rate_constraint(struct snd_pcm_hw_params *params, 13 struct snd_pcm_hw_rule *rule) 14 { 15 struct snd_motu_packet_format *formats = rule->private; 16 17 const struct snd_interval *c = 18 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS); 19 struct snd_interval *r = 20 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 21 struct snd_interval rates = { 22 .min = UINT_MAX, .max = 0, .integer = 1 23 }; 24 unsigned int i, pcm_channels, rate, mode; 25 26 for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) { 27 rate = snd_motu_clock_rates[i]; 28 mode = i / 2; 29 30 pcm_channels = formats->fixed_part_pcm_chunks[mode] + 31 formats->differed_part_pcm_chunks[mode]; 32 if (!snd_interval_test(c, pcm_channels)) 33 continue; 34 35 rates.min = min(rates.min, rate); 36 rates.max = max(rates.max, rate); 37 } 38 39 return snd_interval_refine(r, &rates); 40 } 41 42 static int motu_channels_constraint(struct snd_pcm_hw_params *params, 43 struct snd_pcm_hw_rule *rule) 44 { 45 struct snd_motu_packet_format *formats = rule->private; 46 47 const struct snd_interval *r = 48 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE); 49 struct snd_interval *c = 50 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); 51 struct snd_interval channels = { 52 .min = UINT_MAX, .max = 0, .integer = 1 53 }; 54 unsigned int i, pcm_channels, rate, mode; 55 56 for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) { 57 rate = snd_motu_clock_rates[i]; 58 mode = i / 2; 59 60 if (!snd_interval_test(r, rate)) 61 continue; 62 63 pcm_channels = formats->fixed_part_pcm_chunks[mode] + 64 formats->differed_part_pcm_chunks[mode]; 65 channels.min = min(channels.min, pcm_channels); 66 channels.max = max(channels.max, pcm_channels); 67 } 68 69 return snd_interval_refine(c, &channels); 70 } 71 72 static void limit_channels_and_rates(struct snd_motu *motu, 73 struct snd_pcm_runtime *runtime, 74 struct snd_motu_packet_format *formats) 75 { 76 struct snd_pcm_hardware *hw = &runtime->hw; 77 unsigned int i, pcm_channels, rate, mode; 78 79 hw->channels_min = UINT_MAX; 80 hw->channels_max = 0; 81 82 for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) { 83 rate = snd_motu_clock_rates[i]; 84 mode = i / 2; 85 86 pcm_channels = formats->fixed_part_pcm_chunks[mode] + 87 formats->differed_part_pcm_chunks[mode]; 88 if (pcm_channels == 0) 89 continue; 90 91 hw->rates |= snd_pcm_rate_to_rate_bit(rate); 92 hw->channels_min = min(hw->channels_min, pcm_channels); 93 hw->channels_max = max(hw->channels_max, pcm_channels); 94 } 95 96 snd_pcm_limit_hw_rates(runtime); 97 } 98 99 static void limit_period_and_buffer(struct snd_pcm_hardware *hw) 100 { 101 hw->periods_min = 2; /* SNDRV_PCM_INFO_BATCH */ 102 hw->periods_max = UINT_MAX; 103 104 hw->period_bytes_min = 4 * hw->channels_max; /* byte for a frame */ 105 106 /* Just to prevent from allocating much pages. */ 107 hw->period_bytes_max = hw->period_bytes_min * 2048; 108 hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min; 109 } 110 111 static int init_hw_info(struct snd_motu *motu, 112 struct snd_pcm_substream *substream) 113 { 114 struct snd_pcm_runtime *runtime = substream->runtime; 115 struct snd_pcm_hardware *hw = &runtime->hw; 116 struct amdtp_stream *stream; 117 struct snd_motu_packet_format *formats; 118 int err; 119 120 hw->info = SNDRV_PCM_INFO_MMAP | 121 SNDRV_PCM_INFO_MMAP_VALID | 122 SNDRV_PCM_INFO_BATCH | 123 SNDRV_PCM_INFO_INTERLEAVED | 124 SNDRV_PCM_INFO_JOINT_DUPLEX | 125 SNDRV_PCM_INFO_BLOCK_TRANSFER; 126 127 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 128 hw->formats = SNDRV_PCM_FMTBIT_S32; 129 stream = &motu->tx_stream; 130 formats = &motu->tx_packet_formats; 131 } else { 132 hw->formats = SNDRV_PCM_FMTBIT_S32; 133 stream = &motu->rx_stream; 134 formats = &motu->rx_packet_formats; 135 } 136 137 limit_channels_and_rates(motu, runtime, formats); 138 limit_period_and_buffer(hw); 139 140 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 141 motu_rate_constraint, formats, 142 SNDRV_PCM_HW_PARAM_CHANNELS, -1); 143 if (err < 0) 144 return err; 145 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 146 motu_channels_constraint, formats, 147 SNDRV_PCM_HW_PARAM_RATE, -1); 148 if (err < 0) 149 return err; 150 151 return amdtp_motu_add_pcm_hw_constraints(stream, runtime); 152 } 153 154 static int pcm_open(struct snd_pcm_substream *substream) 155 { 156 struct snd_motu *motu = substream->private_data; 157 const struct snd_motu_protocol *const protocol = motu->spec->protocol; 158 enum snd_motu_clock_source src; 159 unsigned int rate; 160 int err; 161 162 err = snd_motu_stream_lock_try(motu); 163 if (err < 0) 164 return err; 165 166 mutex_lock(&motu->mutex); 167 168 err = protocol->cache_packet_formats(motu); 169 if (err < 0) 170 goto err_locked; 171 172 err = init_hw_info(motu, substream); 173 if (err < 0) 174 goto err_locked; 175 176 /* 177 * When source of clock is not internal or any PCM streams are running, 178 * available sampling rate is limited at current sampling rate. 179 */ 180 err = protocol->get_clock_source(motu, &src); 181 if (err < 0) 182 goto err_locked; 183 if (src != SND_MOTU_CLOCK_SOURCE_INTERNAL || 184 amdtp_stream_pcm_running(&motu->tx_stream) || 185 amdtp_stream_pcm_running(&motu->rx_stream)) { 186 err = protocol->get_clock_rate(motu, &rate); 187 if (err < 0) 188 goto err_locked; 189 substream->runtime->hw.rate_min = rate; 190 substream->runtime->hw.rate_max = rate; 191 } 192 193 snd_pcm_set_sync(substream); 194 195 mutex_unlock(&motu->mutex); 196 197 return err; 198 err_locked: 199 mutex_unlock(&motu->mutex); 200 snd_motu_stream_lock_release(motu); 201 return err; 202 } 203 204 static int pcm_close(struct snd_pcm_substream *substream) 205 { 206 struct snd_motu *motu = substream->private_data; 207 208 snd_motu_stream_lock_release(motu); 209 210 return 0; 211 } 212 213 static int capture_hw_params(struct snd_pcm_substream *substream, 214 struct snd_pcm_hw_params *hw_params) 215 { 216 struct snd_motu *motu = substream->private_data; 217 int err; 218 219 err = snd_pcm_lib_alloc_vmalloc_buffer(substream, 220 params_buffer_bytes(hw_params)); 221 if (err < 0) 222 return err; 223 224 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) { 225 mutex_lock(&motu->mutex); 226 motu->capture_substreams++; 227 mutex_unlock(&motu->mutex); 228 } 229 230 return 0; 231 } 232 static int playback_hw_params(struct snd_pcm_substream *substream, 233 struct snd_pcm_hw_params *hw_params) 234 { 235 struct snd_motu *motu = substream->private_data; 236 int err; 237 238 err = snd_pcm_lib_alloc_vmalloc_buffer(substream, 239 params_buffer_bytes(hw_params)); 240 if (err < 0) 241 return err; 242 243 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) { 244 mutex_lock(&motu->mutex); 245 motu->playback_substreams++; 246 mutex_unlock(&motu->mutex); 247 } 248 249 return 0; 250 } 251 252 static int capture_hw_free(struct snd_pcm_substream *substream) 253 { 254 struct snd_motu *motu = substream->private_data; 255 256 mutex_lock(&motu->mutex); 257 258 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) 259 motu->capture_substreams--; 260 261 snd_motu_stream_stop_duplex(motu); 262 263 mutex_unlock(&motu->mutex); 264 265 return snd_pcm_lib_free_vmalloc_buffer(substream); 266 } 267 268 static int playback_hw_free(struct snd_pcm_substream *substream) 269 { 270 struct snd_motu *motu = substream->private_data; 271 272 mutex_lock(&motu->mutex); 273 274 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) 275 motu->playback_substreams--; 276 277 snd_motu_stream_stop_duplex(motu); 278 279 mutex_unlock(&motu->mutex); 280 281 return snd_pcm_lib_free_vmalloc_buffer(substream); 282 } 283 284 static int capture_prepare(struct snd_pcm_substream *substream) 285 { 286 struct snd_motu *motu = substream->private_data; 287 int err; 288 289 mutex_lock(&motu->mutex); 290 err = snd_motu_stream_start_duplex(motu, substream->runtime->rate); 291 mutex_unlock(&motu->mutex); 292 if (err >= 0) 293 amdtp_stream_pcm_prepare(&motu->tx_stream); 294 295 return 0; 296 } 297 static int playback_prepare(struct snd_pcm_substream *substream) 298 { 299 struct snd_motu *motu = substream->private_data; 300 int err; 301 302 mutex_lock(&motu->mutex); 303 err = snd_motu_stream_start_duplex(motu, substream->runtime->rate); 304 mutex_unlock(&motu->mutex); 305 if (err >= 0) 306 amdtp_stream_pcm_prepare(&motu->rx_stream); 307 308 return err; 309 } 310 311 static int capture_trigger(struct snd_pcm_substream *substream, int cmd) 312 { 313 struct snd_motu *motu = substream->private_data; 314 315 switch (cmd) { 316 case SNDRV_PCM_TRIGGER_START: 317 amdtp_stream_pcm_trigger(&motu->tx_stream, substream); 318 break; 319 case SNDRV_PCM_TRIGGER_STOP: 320 amdtp_stream_pcm_trigger(&motu->tx_stream, NULL); 321 break; 322 default: 323 return -EINVAL; 324 } 325 326 return 0; 327 } 328 static int playback_trigger(struct snd_pcm_substream *substream, int cmd) 329 { 330 struct snd_motu *motu = substream->private_data; 331 332 switch (cmd) { 333 case SNDRV_PCM_TRIGGER_START: 334 amdtp_stream_pcm_trigger(&motu->rx_stream, substream); 335 break; 336 case SNDRV_PCM_TRIGGER_STOP: 337 amdtp_stream_pcm_trigger(&motu->rx_stream, NULL); 338 break; 339 default: 340 return -EINVAL; 341 } 342 343 return 0; 344 } 345 346 static snd_pcm_uframes_t capture_pointer(struct snd_pcm_substream *substream) 347 { 348 struct snd_motu *motu = substream->private_data; 349 350 return amdtp_stream_pcm_pointer(&motu->tx_stream); 351 } 352 static snd_pcm_uframes_t playback_pointer(struct snd_pcm_substream *substream) 353 { 354 struct snd_motu *motu = substream->private_data; 355 356 return amdtp_stream_pcm_pointer(&motu->rx_stream); 357 } 358 359 int snd_motu_create_pcm_devices(struct snd_motu *motu) 360 { 361 static struct snd_pcm_ops capture_ops = { 362 .open = pcm_open, 363 .close = pcm_close, 364 .ioctl = snd_pcm_lib_ioctl, 365 .hw_params = capture_hw_params, 366 .hw_free = capture_hw_free, 367 .prepare = capture_prepare, 368 .trigger = capture_trigger, 369 .pointer = capture_pointer, 370 .page = snd_pcm_lib_get_vmalloc_page, 371 .mmap = snd_pcm_lib_mmap_vmalloc, 372 }; 373 static struct snd_pcm_ops playback_ops = { 374 .open = pcm_open, 375 .close = pcm_close, 376 .ioctl = snd_pcm_lib_ioctl, 377 .hw_params = playback_hw_params, 378 .hw_free = playback_hw_free, 379 .prepare = playback_prepare, 380 .trigger = playback_trigger, 381 .pointer = playback_pointer, 382 .page = snd_pcm_lib_get_vmalloc_page, 383 .mmap = snd_pcm_lib_mmap_vmalloc, 384 }; 385 struct snd_pcm *pcm; 386 int err; 387 388 err = snd_pcm_new(motu->card, motu->card->driver, 0, 1, 1, &pcm); 389 if (err < 0) 390 return err; 391 pcm->private_data = motu; 392 strcpy(pcm->name, motu->card->shortname); 393 394 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops); 395 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops); 396 397 return 0; 398 } 399