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 = AMDTP_IN_PCM_FORMAT_BITS; 163 s = &efw->tx_stream; 164 pcm_channels = efw->pcm_capture_channels; 165 } else { 166 runtime->hw.formats = AMDTP_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_stream_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 atomic_inc(&efw->capture_substreams); 256 amdtp_stream_set_pcm_format(&efw->tx_stream, params_format(hw_params)); 257 258 return 0; 259 } 260 static int pcm_playback_hw_params(struct snd_pcm_substream *substream, 261 struct snd_pcm_hw_params *hw_params) 262 { 263 struct snd_efw *efw = substream->private_data; 264 int err; 265 266 err = snd_pcm_lib_alloc_vmalloc_buffer(substream, 267 params_buffer_bytes(hw_params)); 268 if (err < 0) 269 return err; 270 271 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) 272 atomic_inc(&efw->playback_substreams); 273 amdtp_stream_set_pcm_format(&efw->rx_stream, params_format(hw_params)); 274 275 return 0; 276 } 277 278 static int pcm_capture_hw_free(struct snd_pcm_substream *substream) 279 { 280 struct snd_efw *efw = substream->private_data; 281 282 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) 283 atomic_dec(&efw->capture_substreams); 284 285 snd_efw_stream_stop_duplex(efw); 286 287 return snd_pcm_lib_free_vmalloc_buffer(substream); 288 } 289 static int pcm_playback_hw_free(struct snd_pcm_substream *substream) 290 { 291 struct snd_efw *efw = substream->private_data; 292 293 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) 294 atomic_dec(&efw->playback_substreams); 295 296 snd_efw_stream_stop_duplex(efw); 297 298 return snd_pcm_lib_free_vmalloc_buffer(substream); 299 } 300 301 static int pcm_capture_prepare(struct snd_pcm_substream *substream) 302 { 303 struct snd_efw *efw = substream->private_data; 304 struct snd_pcm_runtime *runtime = substream->runtime; 305 int err; 306 307 err = snd_efw_stream_start_duplex(efw, runtime->rate); 308 if (err >= 0) 309 amdtp_stream_pcm_prepare(&efw->tx_stream); 310 311 return err; 312 } 313 static int pcm_playback_prepare(struct snd_pcm_substream *substream) 314 { 315 struct snd_efw *efw = substream->private_data; 316 struct snd_pcm_runtime *runtime = substream->runtime; 317 int err; 318 319 err = snd_efw_stream_start_duplex(efw, runtime->rate); 320 if (err >= 0) 321 amdtp_stream_pcm_prepare(&efw->rx_stream); 322 323 return err; 324 } 325 326 static int pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd) 327 { 328 struct snd_efw *efw = substream->private_data; 329 330 switch (cmd) { 331 case SNDRV_PCM_TRIGGER_START: 332 amdtp_stream_pcm_trigger(&efw->tx_stream, substream); 333 break; 334 case SNDRV_PCM_TRIGGER_STOP: 335 amdtp_stream_pcm_trigger(&efw->tx_stream, NULL); 336 break; 337 default: 338 return -EINVAL; 339 } 340 341 return 0; 342 } 343 static int pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd) 344 { 345 struct snd_efw *efw = substream->private_data; 346 347 switch (cmd) { 348 case SNDRV_PCM_TRIGGER_START: 349 amdtp_stream_pcm_trigger(&efw->rx_stream, substream); 350 break; 351 case SNDRV_PCM_TRIGGER_STOP: 352 amdtp_stream_pcm_trigger(&efw->rx_stream, NULL); 353 break; 354 default: 355 return -EINVAL; 356 } 357 358 return 0; 359 } 360 361 static snd_pcm_uframes_t pcm_capture_pointer(struct snd_pcm_substream *sbstrm) 362 { 363 struct snd_efw *efw = sbstrm->private_data; 364 return amdtp_stream_pcm_pointer(&efw->tx_stream); 365 } 366 static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm) 367 { 368 struct snd_efw *efw = sbstrm->private_data; 369 return amdtp_stream_pcm_pointer(&efw->rx_stream); 370 } 371 372 static const struct snd_pcm_ops pcm_capture_ops = { 373 .open = pcm_open, 374 .close = pcm_close, 375 .ioctl = snd_pcm_lib_ioctl, 376 .hw_params = pcm_capture_hw_params, 377 .hw_free = pcm_capture_hw_free, 378 .prepare = pcm_capture_prepare, 379 .trigger = pcm_capture_trigger, 380 .pointer = pcm_capture_pointer, 381 .page = snd_pcm_lib_get_vmalloc_page, 382 }; 383 384 static const struct snd_pcm_ops pcm_playback_ops = { 385 .open = pcm_open, 386 .close = pcm_close, 387 .ioctl = snd_pcm_lib_ioctl, 388 .hw_params = pcm_playback_hw_params, 389 .hw_free = pcm_playback_hw_free, 390 .prepare = pcm_playback_prepare, 391 .trigger = pcm_playback_trigger, 392 .pointer = pcm_playback_pointer, 393 .page = snd_pcm_lib_get_vmalloc_page, 394 .mmap = snd_pcm_lib_mmap_vmalloc, 395 }; 396 397 int snd_efw_create_pcm_devices(struct snd_efw *efw) 398 { 399 struct snd_pcm *pcm; 400 int err; 401 402 err = snd_pcm_new(efw->card, efw->card->driver, 0, 1, 1, &pcm); 403 if (err < 0) 404 goto end; 405 406 pcm->private_data = efw; 407 snprintf(pcm->name, sizeof(pcm->name), "%s PCM", efw->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 end: 411 return err; 412 } 413 414