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 int 133 pcm_init_hw_params(struct snd_efw *efw, 134 struct snd_pcm_substream *substream) 135 { 136 struct snd_pcm_runtime *runtime = substream->runtime; 137 struct amdtp_stream *s; 138 unsigned int *pcm_channels; 139 int err; 140 141 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 142 runtime->hw.formats = AM824_IN_PCM_FORMAT_BITS; 143 s = &efw->tx_stream; 144 pcm_channels = efw->pcm_capture_channels; 145 } else { 146 runtime->hw.formats = AM824_OUT_PCM_FORMAT_BITS; 147 s = &efw->rx_stream; 148 pcm_channels = efw->pcm_playback_channels; 149 } 150 151 /* limit rates */ 152 runtime->hw.rates = efw->supported_sampling_rate, 153 snd_pcm_limit_hw_rates(runtime); 154 155 limit_channels(&runtime->hw, pcm_channels); 156 157 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 158 hw_rule_channels, pcm_channels, 159 SNDRV_PCM_HW_PARAM_RATE, -1); 160 if (err < 0) 161 goto end; 162 163 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 164 hw_rule_rate, pcm_channels, 165 SNDRV_PCM_HW_PARAM_CHANNELS, -1); 166 if (err < 0) 167 goto end; 168 169 err = amdtp_am824_add_pcm_hw_constraints(s, runtime); 170 end: 171 return err; 172 } 173 174 static int pcm_open(struct snd_pcm_substream *substream) 175 { 176 struct snd_efw *efw = substream->private_data; 177 unsigned int sampling_rate; 178 enum snd_efw_clock_source clock_source; 179 int err; 180 181 err = snd_efw_stream_lock_try(efw); 182 if (err < 0) 183 goto end; 184 185 err = pcm_init_hw_params(efw, substream); 186 if (err < 0) 187 goto err_locked; 188 189 err = snd_efw_command_get_clock_source(efw, &clock_source); 190 if (err < 0) 191 goto err_locked; 192 193 /* 194 * When source of clock is not internal or any PCM streams are running, 195 * available sampling rate is limited at current sampling rate. 196 */ 197 if ((clock_source != SND_EFW_CLOCK_SOURCE_INTERNAL) || 198 amdtp_stream_pcm_running(&efw->tx_stream) || 199 amdtp_stream_pcm_running(&efw->rx_stream)) { 200 err = snd_efw_command_get_sampling_rate(efw, &sampling_rate); 201 if (err < 0) 202 goto err_locked; 203 substream->runtime->hw.rate_min = sampling_rate; 204 substream->runtime->hw.rate_max = sampling_rate; 205 } 206 207 snd_pcm_set_sync(substream); 208 end: 209 return err; 210 err_locked: 211 snd_efw_stream_lock_release(efw); 212 return err; 213 } 214 215 static int pcm_close(struct snd_pcm_substream *substream) 216 { 217 struct snd_efw *efw = substream->private_data; 218 snd_efw_stream_lock_release(efw); 219 return 0; 220 } 221 222 static int pcm_capture_hw_params(struct snd_pcm_substream *substream, 223 struct snd_pcm_hw_params *hw_params) 224 { 225 struct snd_efw *efw = 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(&efw->mutex); 235 efw->capture_substreams++; 236 mutex_unlock(&efw->mutex); 237 } 238 239 return 0; 240 } 241 static int pcm_playback_hw_params(struct snd_pcm_substream *substream, 242 struct snd_pcm_hw_params *hw_params) 243 { 244 struct snd_efw *efw = substream->private_data; 245 int err; 246 247 err = snd_pcm_lib_alloc_vmalloc_buffer(substream, 248 params_buffer_bytes(hw_params)); 249 if (err < 0) 250 return err; 251 252 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) { 253 mutex_lock(&efw->mutex); 254 efw->playback_substreams++; 255 mutex_unlock(&efw->mutex); 256 } 257 258 return 0; 259 } 260 261 static int pcm_capture_hw_free(struct snd_pcm_substream *substream) 262 { 263 struct snd_efw *efw = substream->private_data; 264 265 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) { 266 mutex_lock(&efw->mutex); 267 efw->capture_substreams--; 268 mutex_unlock(&efw->mutex); 269 } 270 271 snd_efw_stream_stop_duplex(efw); 272 273 return snd_pcm_lib_free_vmalloc_buffer(substream); 274 } 275 static int pcm_playback_hw_free(struct snd_pcm_substream *substream) 276 { 277 struct snd_efw *efw = substream->private_data; 278 279 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) { 280 mutex_lock(&efw->mutex); 281 efw->playback_substreams--; 282 mutex_unlock(&efw->mutex); 283 } 284 285 snd_efw_stream_stop_duplex(efw); 286 287 return snd_pcm_lib_free_vmalloc_buffer(substream); 288 } 289 290 static int pcm_capture_prepare(struct snd_pcm_substream *substream) 291 { 292 struct snd_efw *efw = substream->private_data; 293 struct snd_pcm_runtime *runtime = substream->runtime; 294 int err; 295 296 err = snd_efw_stream_start_duplex(efw, runtime->rate); 297 if (err >= 0) 298 amdtp_stream_pcm_prepare(&efw->tx_stream); 299 300 return err; 301 } 302 static int pcm_playback_prepare(struct snd_pcm_substream *substream) 303 { 304 struct snd_efw *efw = substream->private_data; 305 struct snd_pcm_runtime *runtime = substream->runtime; 306 int err; 307 308 err = snd_efw_stream_start_duplex(efw, runtime->rate); 309 if (err >= 0) 310 amdtp_stream_pcm_prepare(&efw->rx_stream); 311 312 return err; 313 } 314 315 static int pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd) 316 { 317 struct snd_efw *efw = substream->private_data; 318 319 switch (cmd) { 320 case SNDRV_PCM_TRIGGER_START: 321 amdtp_stream_pcm_trigger(&efw->tx_stream, substream); 322 break; 323 case SNDRV_PCM_TRIGGER_STOP: 324 amdtp_stream_pcm_trigger(&efw->tx_stream, NULL); 325 break; 326 default: 327 return -EINVAL; 328 } 329 330 return 0; 331 } 332 static int pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd) 333 { 334 struct snd_efw *efw = substream->private_data; 335 336 switch (cmd) { 337 case SNDRV_PCM_TRIGGER_START: 338 amdtp_stream_pcm_trigger(&efw->rx_stream, substream); 339 break; 340 case SNDRV_PCM_TRIGGER_STOP: 341 amdtp_stream_pcm_trigger(&efw->rx_stream, NULL); 342 break; 343 default: 344 return -EINVAL; 345 } 346 347 return 0; 348 } 349 350 static snd_pcm_uframes_t pcm_capture_pointer(struct snd_pcm_substream *sbstrm) 351 { 352 struct snd_efw *efw = sbstrm->private_data; 353 return amdtp_stream_pcm_pointer(&efw->tx_stream); 354 } 355 static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm) 356 { 357 struct snd_efw *efw = sbstrm->private_data; 358 return amdtp_stream_pcm_pointer(&efw->rx_stream); 359 } 360 361 static int pcm_capture_ack(struct snd_pcm_substream *substream) 362 { 363 struct snd_efw *efw = substream->private_data; 364 365 return amdtp_stream_pcm_ack(&efw->tx_stream); 366 } 367 368 static int pcm_playback_ack(struct snd_pcm_substream *substream) 369 { 370 struct snd_efw *efw = substream->private_data; 371 372 return amdtp_stream_pcm_ack(&efw->rx_stream); 373 } 374 375 int snd_efw_create_pcm_devices(struct snd_efw *efw) 376 { 377 static const struct snd_pcm_ops capture_ops = { 378 .open = pcm_open, 379 .close = pcm_close, 380 .ioctl = snd_pcm_lib_ioctl, 381 .hw_params = pcm_capture_hw_params, 382 .hw_free = pcm_capture_hw_free, 383 .prepare = pcm_capture_prepare, 384 .trigger = pcm_capture_trigger, 385 .pointer = pcm_capture_pointer, 386 .ack = pcm_capture_ack, 387 .page = snd_pcm_lib_get_vmalloc_page, 388 }; 389 static const struct snd_pcm_ops playback_ops = { 390 .open = pcm_open, 391 .close = pcm_close, 392 .ioctl = snd_pcm_lib_ioctl, 393 .hw_params = pcm_playback_hw_params, 394 .hw_free = pcm_playback_hw_free, 395 .prepare = pcm_playback_prepare, 396 .trigger = pcm_playback_trigger, 397 .pointer = pcm_playback_pointer, 398 .ack = pcm_playback_ack, 399 .page = snd_pcm_lib_get_vmalloc_page, 400 }; 401 struct snd_pcm *pcm; 402 int err; 403 404 err = snd_pcm_new(efw->card, efw->card->driver, 0, 1, 1, &pcm); 405 if (err < 0) 406 goto end; 407 408 pcm->private_data = efw; 409 snprintf(pcm->name, sizeof(pcm->name), "%s PCM", efw->card->shortname); 410 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops); 411 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops); 412 end: 413 return err; 414 } 415 416