1 /* 2 * fireworks_pcm.c - a part of driver for Fireworks based devices 3 * 4 * Copyright (c) 2009-2010 Clemens Ladisch 5 * Copyright (c) 2013-2014 Takashi Sakamoto 6 * 7 * Licensed under the terms of the GNU General Public License, version 2. 8 */ 9 #include "./fireworks.h" 10 11 /* 12 * NOTE: 13 * Fireworks changes its AMDTP channels for PCM data according to its sampling 14 * rate. There are three modes. Here _XX is either _rx or _tx. 15 * 0: 32.0- 48.0 kHz then snd_efw_hwinfo.amdtp_XX_pcm_channels applied 16 * 1: 88.2- 96.0 kHz then snd_efw_hwinfo.amdtp_XX_pcm_channels_2x applied 17 * 2: 176.4-192.0 kHz then snd_efw_hwinfo.amdtp_XX_pcm_channels_4x applied 18 * 19 * The number of PCM channels for analog input and output are always fixed but 20 * the number of PCM channels for digital input and output are differed. 21 * 22 * Additionally, according to "AudioFire Owner's Manual Version 2.2", in some 23 * model, the number of PCM channels for digital input has more restriction 24 * depending on which digital interface is selected. 25 * - S/PDIF coaxial and optical : use input 1-2 26 * - ADAT optical at 32.0-48.0 kHz : use input 1-8 27 * - ADAT optical at 88.2-96.0 kHz : use input 1-4 (S/MUX format) 28 * 29 * The data in AMDTP channels for blank PCM channels are zero. 30 */ 31 static const unsigned int freq_table[] = { 32 /* multiplier mode 0 */ 33 [0] = 32000, 34 [1] = 44100, 35 [2] = 48000, 36 /* multiplier mode 1 */ 37 [3] = 88200, 38 [4] = 96000, 39 /* multiplier mode 2 */ 40 [5] = 176400, 41 [6] = 192000, 42 }; 43 44 static inline unsigned int 45 get_multiplier_mode_with_index(unsigned int index) 46 { 47 return ((int)index - 1) / 2; 48 } 49 50 int snd_efw_get_multiplier_mode(unsigned int sampling_rate, unsigned int *mode) 51 { 52 unsigned int i; 53 54 for (i = 0; i < ARRAY_SIZE(freq_table); i++) { 55 if (freq_table[i] == sampling_rate) { 56 *mode = get_multiplier_mode_with_index(i); 57 return 0; 58 } 59 } 60 61 return -EINVAL; 62 } 63 64 static int 65 hw_rule_rate(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) 66 { 67 unsigned int *pcm_channels = rule->private; 68 struct snd_interval *r = 69 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 70 const struct snd_interval *c = 71 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS); 72 struct snd_interval t = { 73 .min = UINT_MAX, .max = 0, .integer = 1 74 }; 75 unsigned int i, mode; 76 77 for (i = 0; i < ARRAY_SIZE(freq_table); i++) { 78 mode = get_multiplier_mode_with_index(i); 79 if (!snd_interval_test(c, pcm_channels[mode])) 80 continue; 81 82 t.min = min(t.min, freq_table[i]); 83 t.max = max(t.max, freq_table[i]); 84 } 85 86 return snd_interval_refine(r, &t); 87 } 88 89 static int 90 hw_rule_channels(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) 91 { 92 unsigned int *pcm_channels = rule->private; 93 struct snd_interval *c = 94 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); 95 const struct snd_interval *r = 96 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE); 97 struct snd_interval t = { 98 .min = UINT_MAX, .max = 0, .integer = 1 99 }; 100 unsigned int i, mode; 101 102 for (i = 0; i < ARRAY_SIZE(freq_table); i++) { 103 mode = get_multiplier_mode_with_index(i); 104 if (!snd_interval_test(r, freq_table[i])) 105 continue; 106 107 t.min = min(t.min, pcm_channels[mode]); 108 t.max = max(t.max, pcm_channels[mode]); 109 } 110 111 return snd_interval_refine(c, &t); 112 } 113 114 static void 115 limit_channels(struct snd_pcm_hardware *hw, unsigned int *pcm_channels) 116 { 117 unsigned int i, mode; 118 119 hw->channels_min = UINT_MAX; 120 hw->channels_max = 0; 121 122 for (i = 0; i < ARRAY_SIZE(freq_table); i++) { 123 mode = get_multiplier_mode_with_index(i); 124 if (pcm_channels[mode] == 0) 125 continue; 126 127 hw->channels_min = min(hw->channels_min, pcm_channels[mode]); 128 hw->channels_max = max(hw->channels_max, pcm_channels[mode]); 129 } 130 } 131 132 static void 133 limit_period_and_buffer(struct snd_pcm_hardware *hw) 134 { 135 hw->periods_min = 2; /* SNDRV_PCM_INFO_BATCH */ 136 hw->periods_max = UINT_MAX; 137 138 hw->period_bytes_min = 4 * hw->channels_max; /* bytes for a frame */ 139 140 /* Just to prevent from allocating much pages. */ 141 hw->period_bytes_max = hw->period_bytes_min * 2048; 142 hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min; 143 } 144 145 static int 146 pcm_init_hw_params(struct snd_efw *efw, 147 struct snd_pcm_substream *substream) 148 { 149 struct snd_pcm_runtime *runtime = substream->runtime; 150 struct amdtp_stream *s; 151 unsigned int *pcm_channels; 152 int err; 153 154 runtime->hw.info = SNDRV_PCM_INFO_BATCH | 155 SNDRV_PCM_INFO_BLOCK_TRANSFER | 156 SNDRV_PCM_INFO_INTERLEAVED | 157 SNDRV_PCM_INFO_JOINT_DUPLEX | 158 SNDRV_PCM_INFO_MMAP | 159 SNDRV_PCM_INFO_MMAP_VALID; 160 161 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 162 runtime->hw.formats = AM824_IN_PCM_FORMAT_BITS; 163 s = &efw->tx_stream; 164 pcm_channels = efw->pcm_capture_channels; 165 } else { 166 runtime->hw.formats = AM824_OUT_PCM_FORMAT_BITS; 167 s = &efw->rx_stream; 168 pcm_channels = efw->pcm_playback_channels; 169 } 170 171 /* limit rates */ 172 runtime->hw.rates = efw->supported_sampling_rate, 173 snd_pcm_limit_hw_rates(runtime); 174 175 limit_channels(&runtime->hw, pcm_channels); 176 limit_period_and_buffer(&runtime->hw); 177 178 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 179 hw_rule_channels, pcm_channels, 180 SNDRV_PCM_HW_PARAM_RATE, -1); 181 if (err < 0) 182 goto end; 183 184 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 185 hw_rule_rate, pcm_channels, 186 SNDRV_PCM_HW_PARAM_CHANNELS, -1); 187 if (err < 0) 188 goto end; 189 190 err = amdtp_am824_add_pcm_hw_constraints(s, runtime); 191 end: 192 return err; 193 } 194 195 static int pcm_open(struct snd_pcm_substream *substream) 196 { 197 struct snd_efw *efw = substream->private_data; 198 unsigned int sampling_rate; 199 enum snd_efw_clock_source clock_source; 200 int err; 201 202 err = snd_efw_stream_lock_try(efw); 203 if (err < 0) 204 goto end; 205 206 err = pcm_init_hw_params(efw, substream); 207 if (err < 0) 208 goto err_locked; 209 210 err = snd_efw_command_get_clock_source(efw, &clock_source); 211 if (err < 0) 212 goto err_locked; 213 214 /* 215 * When source of clock is not internal or any PCM streams are running, 216 * available sampling rate is limited at current sampling rate. 217 */ 218 if ((clock_source != SND_EFW_CLOCK_SOURCE_INTERNAL) || 219 amdtp_stream_pcm_running(&efw->tx_stream) || 220 amdtp_stream_pcm_running(&efw->rx_stream)) { 221 err = snd_efw_command_get_sampling_rate(efw, &sampling_rate); 222 if (err < 0) 223 goto err_locked; 224 substream->runtime->hw.rate_min = sampling_rate; 225 substream->runtime->hw.rate_max = sampling_rate; 226 } 227 228 snd_pcm_set_sync(substream); 229 end: 230 return err; 231 err_locked: 232 snd_efw_stream_lock_release(efw); 233 return err; 234 } 235 236 static int pcm_close(struct snd_pcm_substream *substream) 237 { 238 struct snd_efw *efw = substream->private_data; 239 snd_efw_stream_lock_release(efw); 240 return 0; 241 } 242 243 static int pcm_capture_hw_params(struct snd_pcm_substream *substream, 244 struct snd_pcm_hw_params *hw_params) 245 { 246 struct snd_efw *efw = substream->private_data; 247 int err; 248 249 err = snd_pcm_lib_alloc_vmalloc_buffer(substream, 250 params_buffer_bytes(hw_params)); 251 if (err < 0) 252 return err; 253 254 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) { 255 mutex_lock(&efw->mutex); 256 efw->capture_substreams++; 257 mutex_unlock(&efw->mutex); 258 } 259 260 amdtp_am824_set_pcm_format(&efw->tx_stream, params_format(hw_params)); 261 262 return 0; 263 } 264 static int pcm_playback_hw_params(struct snd_pcm_substream *substream, 265 struct snd_pcm_hw_params *hw_params) 266 { 267 struct snd_efw *efw = substream->private_data; 268 int err; 269 270 err = snd_pcm_lib_alloc_vmalloc_buffer(substream, 271 params_buffer_bytes(hw_params)); 272 if (err < 0) 273 return err; 274 275 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) { 276 mutex_lock(&efw->mutex); 277 efw->playback_substreams++; 278 mutex_unlock(&efw->mutex); 279 } 280 281 amdtp_am824_set_pcm_format(&efw->rx_stream, params_format(hw_params)); 282 283 return 0; 284 } 285 286 static int pcm_capture_hw_free(struct snd_pcm_substream *substream) 287 { 288 struct snd_efw *efw = substream->private_data; 289 290 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) { 291 mutex_lock(&efw->mutex); 292 efw->capture_substreams--; 293 mutex_unlock(&efw->mutex); 294 } 295 296 snd_efw_stream_stop_duplex(efw); 297 298 return snd_pcm_lib_free_vmalloc_buffer(substream); 299 } 300 static int pcm_playback_hw_free(struct snd_pcm_substream *substream) 301 { 302 struct snd_efw *efw = substream->private_data; 303 304 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) { 305 mutex_lock(&efw->mutex); 306 efw->playback_substreams--; 307 mutex_unlock(&efw->mutex); 308 } 309 310 snd_efw_stream_stop_duplex(efw); 311 312 return snd_pcm_lib_free_vmalloc_buffer(substream); 313 } 314 315 static int pcm_capture_prepare(struct snd_pcm_substream *substream) 316 { 317 struct snd_efw *efw = substream->private_data; 318 struct snd_pcm_runtime *runtime = substream->runtime; 319 int err; 320 321 err = snd_efw_stream_start_duplex(efw, runtime->rate); 322 if (err >= 0) 323 amdtp_stream_pcm_prepare(&efw->tx_stream); 324 325 return err; 326 } 327 static int pcm_playback_prepare(struct snd_pcm_substream *substream) 328 { 329 struct snd_efw *efw = substream->private_data; 330 struct snd_pcm_runtime *runtime = substream->runtime; 331 int err; 332 333 err = snd_efw_stream_start_duplex(efw, runtime->rate); 334 if (err >= 0) 335 amdtp_stream_pcm_prepare(&efw->rx_stream); 336 337 return err; 338 } 339 340 static int pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd) 341 { 342 struct snd_efw *efw = substream->private_data; 343 344 switch (cmd) { 345 case SNDRV_PCM_TRIGGER_START: 346 amdtp_stream_pcm_trigger(&efw->tx_stream, substream); 347 break; 348 case SNDRV_PCM_TRIGGER_STOP: 349 amdtp_stream_pcm_trigger(&efw->tx_stream, NULL); 350 break; 351 default: 352 return -EINVAL; 353 } 354 355 return 0; 356 } 357 static int pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd) 358 { 359 struct snd_efw *efw = substream->private_data; 360 361 switch (cmd) { 362 case SNDRV_PCM_TRIGGER_START: 363 amdtp_stream_pcm_trigger(&efw->rx_stream, substream); 364 break; 365 case SNDRV_PCM_TRIGGER_STOP: 366 amdtp_stream_pcm_trigger(&efw->rx_stream, NULL); 367 break; 368 default: 369 return -EINVAL; 370 } 371 372 return 0; 373 } 374 375 static snd_pcm_uframes_t pcm_capture_pointer(struct snd_pcm_substream *sbstrm) 376 { 377 struct snd_efw *efw = sbstrm->private_data; 378 return amdtp_stream_pcm_pointer(&efw->tx_stream); 379 } 380 static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm) 381 { 382 struct snd_efw *efw = sbstrm->private_data; 383 return amdtp_stream_pcm_pointer(&efw->rx_stream); 384 } 385 386 int snd_efw_create_pcm_devices(struct snd_efw *efw) 387 { 388 static const struct snd_pcm_ops capture_ops = { 389 .open = pcm_open, 390 .close = pcm_close, 391 .ioctl = snd_pcm_lib_ioctl, 392 .hw_params = pcm_capture_hw_params, 393 .hw_free = pcm_capture_hw_free, 394 .prepare = pcm_capture_prepare, 395 .trigger = pcm_capture_trigger, 396 .pointer = pcm_capture_pointer, 397 .page = snd_pcm_lib_get_vmalloc_page, 398 }; 399 static const struct snd_pcm_ops playback_ops = { 400 .open = pcm_open, 401 .close = pcm_close, 402 .ioctl = snd_pcm_lib_ioctl, 403 .hw_params = pcm_playback_hw_params, 404 .hw_free = pcm_playback_hw_free, 405 .prepare = pcm_playback_prepare, 406 .trigger = pcm_playback_trigger, 407 .pointer = pcm_playback_pointer, 408 .page = snd_pcm_lib_get_vmalloc_page, 409 .mmap = snd_pcm_lib_mmap_vmalloc, 410 }; 411 struct snd_pcm *pcm; 412 int err; 413 414 err = snd_pcm_new(efw->card, efw->card->driver, 0, 1, 1, &pcm); 415 if (err < 0) 416 goto end; 417 418 pcm->private_data = efw; 419 snprintf(pcm->name, sizeof(pcm->name), "%s PCM", efw->card->shortname); 420 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops); 421 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops); 422 end: 423 return err; 424 } 425 426