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 */ 31static 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 44static inline unsigned int 45get_multiplier_mode_with_index(unsigned int index) 46{ 47 return ((int)index - 1) / 2; 48} 49 50int 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 64static int 65hw_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 89static int 90hw_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 114static void 115limit_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 132static void 133limit_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 145static int 146pcm_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); 191end: 192 return err; 193} 194 195static 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); 229end: 230 return err; 231err_locked: 232 snd_efw_stream_lock_release(efw); 233 return err; 234} 235 236static 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 243static 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 257 amdtp_am824_set_pcm_format(&efw->tx_stream, params_format(hw_params)); 258 259 return 0; 260} 261static int pcm_playback_hw_params(struct snd_pcm_substream *substream, 262 struct snd_pcm_hw_params *hw_params) 263{ 264 struct snd_efw *efw = substream->private_data; 265 int err; 266 267 err = snd_pcm_lib_alloc_vmalloc_buffer(substream, 268 params_buffer_bytes(hw_params)); 269 if (err < 0) 270 return err; 271 272 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) 273 atomic_inc(&efw->playback_substreams); 274 275 amdtp_am824_set_pcm_format(&efw->rx_stream, params_format(hw_params)); 276 277 return 0; 278} 279 280static int pcm_capture_hw_free(struct snd_pcm_substream *substream) 281{ 282 struct snd_efw *efw = substream->private_data; 283 284 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) 285 atomic_dec(&efw->capture_substreams); 286 287 snd_efw_stream_stop_duplex(efw); 288 289 return snd_pcm_lib_free_vmalloc_buffer(substream); 290} 291static int pcm_playback_hw_free(struct snd_pcm_substream *substream) 292{ 293 struct snd_efw *efw = substream->private_data; 294 295 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) 296 atomic_dec(&efw->playback_substreams); 297 298 snd_efw_stream_stop_duplex(efw); 299 300 return snd_pcm_lib_free_vmalloc_buffer(substream); 301} 302 303static int pcm_capture_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->tx_stream); 312 313 return err; 314} 315static int pcm_playback_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->rx_stream); 324 325 return err; 326} 327 328static int pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd) 329{ 330 struct snd_efw *efw = substream->private_data; 331 332 switch (cmd) { 333 case SNDRV_PCM_TRIGGER_START: 334 amdtp_stream_pcm_trigger(&efw->tx_stream, substream); 335 break; 336 case SNDRV_PCM_TRIGGER_STOP: 337 amdtp_stream_pcm_trigger(&efw->tx_stream, NULL); 338 break; 339 default: 340 return -EINVAL; 341 } 342 343 return 0; 344} 345static int pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd) 346{ 347 struct snd_efw *efw = substream->private_data; 348 349 switch (cmd) { 350 case SNDRV_PCM_TRIGGER_START: 351 amdtp_stream_pcm_trigger(&efw->rx_stream, substream); 352 break; 353 case SNDRV_PCM_TRIGGER_STOP: 354 amdtp_stream_pcm_trigger(&efw->rx_stream, NULL); 355 break; 356 default: 357 return -EINVAL; 358 } 359 360 return 0; 361} 362 363static snd_pcm_uframes_t pcm_capture_pointer(struct snd_pcm_substream *sbstrm) 364{ 365 struct snd_efw *efw = sbstrm->private_data; 366 return amdtp_stream_pcm_pointer(&efw->tx_stream); 367} 368static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm) 369{ 370 struct snd_efw *efw = sbstrm->private_data; 371 return amdtp_stream_pcm_pointer(&efw->rx_stream); 372} 373 374static const struct snd_pcm_ops pcm_capture_ops = { 375 .open = pcm_open, 376 .close = pcm_close, 377 .ioctl = snd_pcm_lib_ioctl, 378 .hw_params = pcm_capture_hw_params, 379 .hw_free = pcm_capture_hw_free, 380 .prepare = pcm_capture_prepare, 381 .trigger = pcm_capture_trigger, 382 .pointer = pcm_capture_pointer, 383 .page = snd_pcm_lib_get_vmalloc_page, 384}; 385 386static const struct snd_pcm_ops pcm_playback_ops = { 387 .open = pcm_open, 388 .close = pcm_close, 389 .ioctl = snd_pcm_lib_ioctl, 390 .hw_params = pcm_playback_hw_params, 391 .hw_free = pcm_playback_hw_free, 392 .prepare = pcm_playback_prepare, 393 .trigger = pcm_playback_trigger, 394 .pointer = pcm_playback_pointer, 395 .page = snd_pcm_lib_get_vmalloc_page, 396 .mmap = snd_pcm_lib_mmap_vmalloc, 397}; 398 399int snd_efw_create_pcm_devices(struct snd_efw *efw) 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, &pcm_playback_ops); 411 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_capture_ops); 412end: 413 return err; 414} 415 416