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